From f6d83d38fbb1f590d90230a0d82aa014ba09e781 Mon Sep 17 00:00:00 2001 From: Giulio Date: Sat, 1 Feb 2025 16:03:50 +0100 Subject: [PATCH 01/33] save --- cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go index f6f4d10a5d2..ccc90daea73 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go @@ -154,10 +154,9 @@ func (f *forkGraphDisk) DumpBeaconStateOnDisk(blockRoot libcommon.Hash, bs *stat return err } - b := bytes.NewBuffer(f.sszBuffer) - b.Reset() + var b bytes.Buffer - if err := bs.EncodeCaches(b); err != nil { + if err := bs.EncodeCaches(&b); err != nil { log.Error("failed to encode caches", "err", err) return err } From 29dd20cecb1d738f9f1ac43b4fe800455ee75bc0 Mon Sep 17 00:00:00 2001 From: Giulio Date: Sun, 2 Feb 2025 22:48:03 +0100 Subject: [PATCH 02/33] save --- .../fork_graph/fork_graph_disk_fs.go | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go index ccc90daea73..0931f22b453 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go @@ -88,20 +88,20 @@ func (f *forkGraphDisk) readBeaconStateFromDisk(blockRoot libcommon.Hash, out *s } // decode the cache file - cacheFile, err := f.fs.Open(getBeaconStateCacheFilename(blockRoot)) - if err != nil { - return - } - defer cacheFile.Close() + // cacheFile, err := f.fs.Open(getBeaconStateCacheFilename(blockRoot)) + // if err != nil { + // return + // } + // defer cacheFile.Close() - b := bytes.Buffer{} - if _, err := io.Copy(&b, cacheFile); err != nil { - return nil, err - } + // b := bytes.Buffer{} + // if _, err := io.Copy(&b, cacheFile); err != nil { + // return nil, err + // } - if err := bs.DecodeCaches(&b); err != nil { - return nil, err - } + // if err := bs.DecodeCaches(&b); err != nil { + // return nil, err + // } return } @@ -154,16 +154,17 @@ func (f *forkGraphDisk) DumpBeaconStateOnDisk(blockRoot libcommon.Hash, bs *stat return err } + if err = dumpedFile.Sync(); err != nil { + log.Error("failed to sync dumped file", "err", err) + return + } + var b bytes.Buffer if err := bs.EncodeCaches(&b); err != nil { log.Error("failed to encode caches", "err", err) return err } - if err = dumpedFile.Sync(); err != nil { - log.Error("failed to sync dumped file", "err", err) - return - } cacheFile, err := f.fs.OpenFile(getBeaconStateCacheFilename(blockRoot), os.O_TRUNC|os.O_CREATE|os.O_RDWR, 0o755) if err != nil { From c249cdc88d981cd67b1104cff2eb317e7dce031d Mon Sep 17 00:00:00 2001 From: Giulio Date: Sun, 2 Feb 2025 22:55:14 +0100 Subject: [PATCH 03/33] save --- cl/cltypes/solid/hash_list.go | 22 ------ cl/cltypes/solid/hash_vector.go | 9 --- cl/cltypes/solid/uint64_list.go | 9 --- cl/cltypes/solid/uint64_vector.go | 9 --- cl/cltypes/solid/uint64slice_byte.go | 22 ------ cl/cltypes/solid/validator_set.go | 33 -------- cl/merkle_tree/merkle_tree.go | 75 ------------------- cl/merkle_tree/merkle_tree_test.go | 12 --- cl/phase1/core/state/cache.go | 75 ------------------- .../fork_graph/fork_graph_disk_fs.go | 40 ---------- 10 files changed, 306 deletions(-) diff --git a/cl/cltypes/solid/hash_list.go b/cl/cltypes/solid/hash_list.go index cca7e5c435c..f937d8a5c19 100644 --- a/cl/cltypes/solid/hash_list.go +++ b/cl/cltypes/solid/hash_list.go @@ -18,7 +18,6 @@ package solid import ( "encoding/json" - "io" libcommon "github.com/erigontech/erigon-lib/common" "github.com/erigontech/erigon-lib/common/length" @@ -190,24 +189,3 @@ func (h *hashList) Range(fn func(int, libcommon.Hash, int) bool) { func (h *hashList) Pop() libcommon.Hash { panic("didnt ask, dont need it, go fuck yourself") } - -func (h *hashList) ReadMerkleTree(r io.Reader) error { - if h.MerkleTree == nil { - h.MerkleTree = &merkle_tree.MerkleTree{} - h.MerkleTree.Initialize(h.l, merkle_tree.OptimalMaxTreeCacheDepth, func(idx int, out []byte) { - copy(out, h.u[idx*length.Hash:(idx+1)*length.Hash]) - }, /*limit=*/ nil) - } - return h.MerkleTree.ReadMerkleTree(r) -} - -func (h *hashList) WriteMerkleTree(w io.Writer) error { - if h.MerkleTree == nil { - cap := uint64(h.c) - h.MerkleTree = &merkle_tree.MerkleTree{} - h.MerkleTree.Initialize(h.l, merkle_tree.OptimalMaxTreeCacheDepth, func(idx int, out []byte) { - copy(out, h.u[idx*length.Hash:(idx+1)*length.Hash]) - }, /*limit=*/ &cap) - } - return h.MerkleTree.WriteMerkleTree(w) -} diff --git a/cl/cltypes/solid/hash_vector.go b/cl/cltypes/solid/hash_vector.go index 0f73ff9784b..1126f24e049 100644 --- a/cl/cltypes/solid/hash_vector.go +++ b/cl/cltypes/solid/hash_vector.go @@ -18,7 +18,6 @@ package solid import ( "encoding/json" - "io" libcommon "github.com/erigontech/erigon-lib/common" "github.com/erigontech/erigon-lib/common/length" @@ -118,11 +117,3 @@ func (h *hashVector) Range(fn func(int, libcommon.Hash, int) bool) { func (h *hashVector) Pop() libcommon.Hash { panic("didnt ask, dont need it, go fuck yourself") } - -func (h *hashVector) ReadMerkleTree(r io.Reader) error { - return h.u.ReadMerkleTree(r) -} - -func (h *hashVector) WriteMerkleTree(w io.Writer) error { - return h.u.WriteMerkleTree(w) -} diff --git a/cl/cltypes/solid/uint64_list.go b/cl/cltypes/solid/uint64_list.go index d21a5f8555e..e728c9b5bad 100644 --- a/cl/cltypes/solid/uint64_list.go +++ b/cl/cltypes/solid/uint64_list.go @@ -18,7 +18,6 @@ package solid import ( "encoding/json" - "io" "github.com/erigontech/erigon-lib/types/clonable" ) @@ -119,14 +118,6 @@ func (arr *uint64ListSSZ) Append(v uint64) { arr.u.Append(v) } -func (arr *uint64ListSSZ) ReadMerkleTree(r io.Reader) error { - return arr.u.ReadMerkleTree(r) -} - -func (arr *uint64ListSSZ) WriteMerkleTree(w io.Writer) error { - return arr.u.WriteMerkleTree(w) -} - // Check if it is sorted and check if there are duplicates. O(N) complexity. func IsUint64SortedSet(set IterableSSZ[uint64]) bool { for i := 0; i < set.Length()-1; i++ { diff --git a/cl/cltypes/solid/uint64_vector.go b/cl/cltypes/solid/uint64_vector.go index 104ac7d51bc..60e133c72f8 100644 --- a/cl/cltypes/solid/uint64_vector.go +++ b/cl/cltypes/solid/uint64_vector.go @@ -18,7 +18,6 @@ package solid import ( "encoding/json" - "io" "github.com/erigontech/erigon-lib/types/clonable" ) @@ -110,11 +109,3 @@ func (arr *uint64VectorSSZ) Pop() uint64 { func (arr *uint64VectorSSZ) Append(uint64) { panic("not implemented") } - -func (arr *uint64VectorSSZ) ReadMerkleTree(r io.Reader) error { - return arr.u.ReadMerkleTree(r) -} - -func (arr *uint64VectorSSZ) WriteMerkleTree(w io.Writer) error { - return arr.u.WriteMerkleTree(w) -} diff --git a/cl/cltypes/solid/uint64slice_byte.go b/cl/cltypes/solid/uint64slice_byte.go index 750e9378ffb..6c80390fa13 100644 --- a/cl/cltypes/solid/uint64slice_byte.go +++ b/cl/cltypes/solid/uint64slice_byte.go @@ -19,7 +19,6 @@ package solid import ( "encoding/binary" "encoding/json" - "io" "strconv" "github.com/erigontech/erigon-lib/common/length" @@ -229,24 +228,3 @@ func (arr *byteBasedUint64Slice) DecodeSSZ(buf []byte, _ int) error { func (arr *byteBasedUint64Slice) EncodingSizeSSZ() int { return arr.l * 8 } - -func (arr *byteBasedUint64Slice) ReadMerkleTree(r io.Reader) error { - if arr.MerkleTree == nil { - arr.MerkleTree = &merkle_tree.MerkleTree{} - arr.MerkleTree.Initialize((arr.l+3)/4, merkle_tree.OptimalMaxTreeCacheDepth, func(idx int, out []byte) { - copy(out, arr.u[idx*length.Hash:]) - }, nil) - } - return arr.MerkleTree.ReadMerkleTree(r) -} - -func (arr *byteBasedUint64Slice) WriteMerkleTree(w io.Writer) error { - if arr.MerkleTree == nil { - arr.MerkleTree = &merkle_tree.MerkleTree{} - cap := uint64((arr.c*8 + length.Hash - 1) / length.Hash) - arr.MerkleTree.Initialize((arr.l+3)/4, merkle_tree.OptimalMaxTreeCacheDepth, func(idx int, out []byte) { - copy(out, arr.u[idx*length.Hash:]) - }, &cap) - } - return arr.MerkleTree.WriteMerkleTree(w) -} diff --git a/cl/cltypes/solid/validator_set.go b/cl/cltypes/solid/validator_set.go index 79e94d67b4c..4500694a63c 100644 --- a/cl/cltypes/solid/validator_set.go +++ b/cl/cltypes/solid/validator_set.go @@ -18,7 +18,6 @@ package solid import ( "encoding/json" - "io" libcommon "github.com/erigontech/erigon-lib/common" "github.com/erigontech/erigon-lib/types/clonable" @@ -377,35 +376,3 @@ func (v *ValidatorSet) UnmarshalJSON(data []byte) error { } return nil } - -func (v *ValidatorSet) ReadMerkleTree(r io.Reader) error { - if v.MerkleTree == nil { - v.MerkleTree = &merkle_tree.MerkleTree{} - hashBuffer := make([]byte, 8*32) - v.MerkleTree.Initialize(v.l, merkle_tree.OptimalMaxTreeCacheDepth, func(idx int, out []byte) { - validator := v.Get(idx) - if err := validator.CopyHashBufferTo(hashBuffer); err != nil { - panic(err) - } - hashBuffer = hashBuffer[:(8 * 32)] - if err := merkle_tree.MerkleRootFromFlatLeaves(hashBuffer, out); err != nil { - panic(err) - } - }, nil) - } - return v.MerkleTree.ReadMerkleTree(r) -} - -func (arr *ValidatorSet) WriteMerkleTree(w io.Writer) error { - if arr.MerkleTree == nil { - arr.MerkleTree = &merkle_tree.MerkleTree{} - cap := uint64(arr.c) - arr.MerkleTree.Initialize(arr.l, merkle_tree.OptimalMaxTreeCacheDepth, func(idx int, out []byte) { - validator := arr.Get(idx) - if err := validator.CopyHashBufferTo(out); err != nil { - panic(err) - } - }, &cap) - } - return arr.MerkleTree.WriteMerkleTree(w) -} diff --git a/cl/merkle_tree/merkle_tree.go b/cl/merkle_tree/merkle_tree.go index 819ab224dda..73d638881f8 100644 --- a/cl/merkle_tree/merkle_tree.go +++ b/cl/merkle_tree/merkle_tree.go @@ -2,25 +2,17 @@ package merkle_tree import ( "bytes" - "encoding/binary" - "io" "sync" "sync/atomic" libcommon "github.com/erigontech/erigon-lib/common" "github.com/erigontech/erigon-lib/common/length" - "github.com/erigontech/erigon-lib/common/math" ) func ceil(num, divisor int) int { return (num + (divisor - 1)) / divisor } -type HashTreeEncodable interface { - WriteMerkleTree(w io.Writer) error - ReadMerkleTree(r io.Reader) error -} - const OptimalMaxTreeCacheDepth = 12 type MerkleTree struct { @@ -35,8 +27,6 @@ type MerkleTree struct { mu sync.RWMutex } -var _ HashTreeEncodable = (*MerkleTree)(nil) - // Layout of the layers: // 0-n: intermediate layers @@ -320,68 +310,3 @@ func (m *MerkleTree) computeLayer(layerIdx int) { } } } - -// Write writes the Merkle tree to the given writer. -func (m *MerkleTree) WriteMerkleTree(w io.Writer) error { - if err := binary.Write(w, binary.BigEndian, uint32(len(m.layers))); err != nil { - return err - } - for _, layer := range m.layers { - if err := binary.Write(w, binary.BigEndian, uint32(len(layer))); err != nil { - return err - } - if _, err := w.Write(layer); err != nil { - return err - } - } - - if err := binary.Write(w, binary.BigEndian, uint32(m.leavesCount)); err != nil { - return err - } - if m.limit != nil { - if err := binary.Write(w, binary.BigEndian, *m.limit); err != nil { - return err - } - } else { - if err := binary.Write(w, binary.BigEndian, uint64(math.MaxUint64)); err != nil { - return err - } - } - return nil -} - -// Read reads the Merkle tree from the given reader. -func (m *MerkleTree) ReadMerkleTree(r io.Reader) error { - var layersCount uint32 - if err := binary.Read(r, binary.BigEndian, &layersCount); err != nil { - return err - } - m.layers = make([][]byte, layersCount) - for i := 0; i < int(layersCount); i++ { - var layerSize uint32 - if err := binary.Read(r, binary.BigEndian, &layerSize); err != nil { - return err - } - m.layers[i] = make([]byte, layerSize) - if _, err := io.ReadFull(r, m.layers[i]); err != nil { - return err - } - } - leavesCount := uint32(0) - - if err := binary.Read(r, binary.BigEndian, &leavesCount); err != nil { - return err - } - m.leavesCount = int(leavesCount) - var limit uint64 - if err := binary.Read(r, binary.BigEndian, &limit); err != nil { - return err - } - if limit == math.MaxUint64 { - m.limit = nil - } else { - m.limit = new(uint64) - *m.limit = limit - } - return nil -} diff --git a/cl/merkle_tree/merkle_tree_test.go b/cl/merkle_tree/merkle_tree_test.go index 36b5f2e89eb..3034a81cd8e 100644 --- a/cl/merkle_tree/merkle_tree_test.go +++ b/cl/merkle_tree/merkle_tree_test.go @@ -1,7 +1,6 @@ package merkle_tree_test import ( - "bytes" "testing" "github.com/erigontech/erigon-lib/common" @@ -142,15 +141,4 @@ func TestMerkleTreeAppendLeafWithLowMaxDepthAndLimitAndTestWR(t *testing.T) { testBuffer[128] = 5 expectedRoot := getExpectedRootWithLimit(testBuffer, int(lm)) require.Equal(t, mt.ComputeRoot(), expectedRoot) - // adding 3 more empty leaves should not change the root - mt.AppendLeaf() - mt.AppendLeaf() - mt.AppendLeaf() - - var buffer bytes.Buffer - require.NoError(t, mt.WriteMerkleTree(&buffer)) - - mt2 := merkle_tree.MerkleTree{} - require.NoError(t, mt2.ReadMerkleTree(&buffer)) - require.Equal(t, mt.ComputeRoot(), expectedRoot) } diff --git a/cl/phase1/core/state/cache.go b/cl/phase1/core/state/cache.go index fd62c015e3d..49ab5903974 100644 --- a/cl/phase1/core/state/cache.go +++ b/cl/phase1/core/state/cache.go @@ -19,11 +19,9 @@ package state import ( "crypto/sha256" "encoding/binary" - "io" "runtime" "github.com/erigontech/erigon/cl/cltypes/solid" - "github.com/erigontech/erigon/cl/merkle_tree" "github.com/erigontech/erigon/cl/phase1/core/state/lru" "github.com/erigontech/erigon/cl/phase1/core/state/raw" "github.com/erigontech/erigon/cl/phase1/core/state/shuffling" @@ -286,76 +284,3 @@ func (b *CachingBeaconState) InitBeaconState() error { return nil } - -// EncodeCaches, encodes the beacon state caches into a byte slice -func (b *CachingBeaconState) EncodeCaches(w io.Writer) error { - if _, err := w.Write(b.previousStateRoot[:]); err != nil { - return err - } - - // Write merkle tree caches - if err := b.BeaconState.ValidatorSet().WriteMerkleTree(w); err != nil { - return err - } - if err := b.BeaconState.RandaoMixes().(merkle_tree.HashTreeEncodable).WriteMerkleTree(w); err != nil { - return err - } - if err := b.BeaconState.Balances().(merkle_tree.HashTreeEncodable).WriteMerkleTree(w); err != nil { - return err - } - if err := b.BeaconState.Slashings().(merkle_tree.HashTreeEncodable).WriteMerkleTree(w); err != nil { - return err - } - if err := b.BeaconState.StateRoots().(merkle_tree.HashTreeEncodable).WriteMerkleTree(w); err != nil { - return err - } - if err := b.BeaconState.BlockRoots().(merkle_tree.HashTreeEncodable).WriteMerkleTree(w); err != nil { - return err - } - if b.Version() >= clparams.AltairVersion { - if err := b.BeaconState.InactivityScores().(merkle_tree.HashTreeEncodable).WriteMerkleTree(w); err != nil { - return err - } - } - - return nil -} - -func (b *CachingBeaconState) DecodeCaches(r io.Reader) error { - b.shuffledSetsCache, _ = lru.New[common.Hash, []uint64]("beacon_shuffled_sets_cache", shuffledSetsCacheSize) - b.activeValidatorsCache, _ = lru.New[uint64, []uint64]("beacon_active_validators_cache", activeValidatorsCacheSize) - b.totalActiveBalanceCache = nil - b.proposerIndex = nil - - if _, err := r.Read(b.previousStateRoot[:]); err != nil { - return err - } - - // Read merkle tree caches - if err := b.BeaconState.ValidatorSet().ReadMerkleTree(r); err != nil { - return err - } - if err := b.BeaconState.RandaoMixes().(merkle_tree.HashTreeEncodable).ReadMerkleTree(r); err != nil { - return err - } - - if err := b.BeaconState.Balances().(merkle_tree.HashTreeEncodable).ReadMerkleTree(r); err != nil { - return err - } - if err := b.BeaconState.Slashings().(merkle_tree.HashTreeEncodable).ReadMerkleTree(r); err != nil { - return err - } - if err := b.BeaconState.StateRoots().(merkle_tree.HashTreeEncodable).ReadMerkleTree(r); err != nil { - return err - } - if err := b.BeaconState.BlockRoots().(merkle_tree.HashTreeEncodable).ReadMerkleTree(r); err != nil { - return err - } - if b.Version() >= clparams.AltairVersion { - if err := b.BeaconState.InactivityScores().(merkle_tree.HashTreeEncodable).ReadMerkleTree(r); err != nil { - return err - } - } - - return nil -} diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go index 0931f22b453..c5018f66a91 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go @@ -17,7 +17,6 @@ package fork_graph import ( - "bytes" "encoding/binary" "fmt" "io" @@ -87,22 +86,6 @@ func (f *forkGraphDisk) readBeaconStateFromDisk(blockRoot libcommon.Hash, out *s return nil, fmt.Errorf("failed to decode beacon state: %w, root: %x, len: %d, decLen: %d, bs: %+v", err, blockRoot, n, len(f.sszBuffer), bs) } - // decode the cache file - // cacheFile, err := f.fs.Open(getBeaconStateCacheFilename(blockRoot)) - // if err != nil { - // return - // } - // defer cacheFile.Close() - - // b := bytes.Buffer{} - // if _, err := io.Copy(&b, cacheFile); err != nil { - // return nil, err - // } - - // if err := bs.DecodeCaches(&b); err != nil { - // return nil, err - // } - return } @@ -159,28 +142,5 @@ func (f *forkGraphDisk) DumpBeaconStateOnDisk(blockRoot libcommon.Hash, bs *stat return } - var b bytes.Buffer - - if err := bs.EncodeCaches(&b); err != nil { - log.Error("failed to encode caches", "err", err) - return err - } - - cacheFile, err := f.fs.OpenFile(getBeaconStateCacheFilename(blockRoot), os.O_TRUNC|os.O_CREATE|os.O_RDWR, 0o755) - if err != nil { - log.Error("failed to open cache file", "err", err) - return - } - defer cacheFile.Close() - - if _, err = cacheFile.Write(b.Bytes()); err != nil { - log.Error("failed to write cache file", "err", err) - return - } - if err = cacheFile.Sync(); err != nil { - log.Error("failed to sync cache file", "err", err) - return - } - return } From 081c74c8e11da4f550b2a873e92a6a738eda1f29 Mon Sep 17 00:00:00 2001 From: Giulio Date: Sun, 2 Feb 2025 23:26:01 +0100 Subject: [PATCH 04/33] save --- cl/beacon/synced_data/interface.go | 1 + cl/beacon/synced_data/synced_data.go | 39 ++++++++++++++--- .../forkchoice/fork_graph/fork_graph_disk.go | 43 +++++++++++++++++-- cl/phase1/network/blobs.go | 6 +-- 4 files changed, 78 insertions(+), 11 deletions(-) diff --git a/cl/beacon/synced_data/interface.go b/cl/beacon/synced_data/interface.go index 304ac4be2a7..765d3a4e8fd 100644 --- a/cl/beacon/synced_data/interface.go +++ b/cl/beacon/synced_data/interface.go @@ -30,6 +30,7 @@ type SyncedData interface { OnHeadState(newState *state.CachingBeaconState) error UnsetHeadState() ViewHeadState(fn ViewHeadStateFn) error + ViewPreviousHeadState(fn ViewHeadStateFn) error Syncing() bool HeadSlot() uint64 HeadRoot() common.Hash diff --git a/cl/beacon/synced_data/synced_data.go b/cl/beacon/synced_data/synced_data.go index ef79ac49194..aeecbe67ab3 100644 --- a/cl/beacon/synced_data/synced_data.go +++ b/cl/beacon/synced_data/synced_data.go @@ -30,7 +30,10 @@ import ( "github.com/erigontech/erigon/cl/phase1/core/state" ) -var ErrNotSynced = errors.New("not synced") +var ( + ErrNotSynced = errors.New("not synced") + ErrPreviousStateNotAvailable = errors.New("previous state not available") +) var _ SyncedData = (*SyncedDataManager)(nil) @@ -43,11 +46,11 @@ type SyncedDataManager struct { headRoot atomic.Value headSlot atomic.Uint64 - headState *state.CachingBeaconState + headState *state.CachingBeaconState + previousHeadState *state.CachingBeaconState accessLock sync.RWMutex // lock used for accessing atomic methods - - mu sync.RWMutex + mu sync.RWMutex } func NewSyncedDataManager(cfg *clparams.BeaconChainConfig, enabled bool) *SyncedDataManager { @@ -57,6 +60,7 @@ func NewSyncedDataManager(cfg *clparams.BeaconChainConfig, enabled bool) *Synced } } +// OnHeadState updates the current head state and tracks the previous state. func (s *SyncedDataManager) OnHeadState(newState *state.CachingBeaconState) (err error) { if !s.enabled { return @@ -67,8 +71,21 @@ func (s *SyncedDataManager) OnHeadState(newState *state.CachingBeaconState) (err s.accessLock.Lock() defer s.accessLock.Unlock() + // Save current state as previous state, if available. + if s.headState != nil { + if s.previousHeadState != nil { + err = s.headState.CopyInto(s.previousHeadState) + } else { + s.previousHeadState, err = s.headState.Copy() + } + if err != nil { + return err + } + } + var blkRoot common.Hash + // Update headState with the new state. if s.headState == nil { s.headState, err = newState.Copy() } else { @@ -83,9 +100,10 @@ func (s *SyncedDataManager) OnHeadState(newState *state.CachingBeaconState) (err } s.headSlot.Store(newState.Slot()) s.headRoot.Store(blkRoot) - return err + return nil } +// ViewHeadState allows safe, read-only access to the current head state. func (s *SyncedDataManager) ViewHeadState(fn ViewHeadStateFn) error { _, synced := s.headRoot.Load().(common.Hash) if !s.enabled || !synced { @@ -112,6 +130,16 @@ func (s *SyncedDataManager) ViewHeadState(fn ViewHeadStateFn) error { return nil } +// ViewPreviousHeadState allows safe, read-only access to the previous head state. +func (s *SyncedDataManager) ViewPreviousHeadState(fn ViewHeadStateFn) error { + s.mu.RLock() + defer s.mu.RUnlock() + if s.previousHeadState == nil { + return ErrPreviousStateNotAvailable + } + return fn(s.previousHeadState) +} + func (s *SyncedDataManager) Syncing() bool { _, synced := s.headRoot.Load().(common.Hash) return !synced @@ -147,6 +175,7 @@ func (s *SyncedDataManager) UnsetHeadState() { s.headRoot = atomic.Value{} s.headSlot.Store(uint64(0)) s.headState = nil + s.previousHeadState = nil } func (s *SyncedDataManager) ValidatorPublicKeyByIndex(index int) (common.Bytes48, error) { diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index 51ab1b82c7b..ab8fa756db0 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -30,6 +30,7 @@ import ( "github.com/erigontech/erigon-lib/log/v3" "github.com/erigontech/erigon/cl/beacon/beacon_router_configuration" "github.com/erigontech/erigon/cl/beacon/beaconevents" + "github.com/erigontech/erigon/cl/beacon/synced_data" "github.com/erigontech/erigon/cl/clparams" "github.com/erigontech/erigon/cl/cltypes" "github.com/erigontech/erigon/cl/cltypes/lightclient_utils" @@ -126,14 +127,15 @@ type forkGraphDisk struct { sszSnappyWriter *snappy.Writer sszSnappyReader *snappy.Reader - rcfg beacon_router_configuration.RouterConfiguration - emitter *beaconevents.EventEmitter + rcfg beacon_router_configuration.RouterConfiguration + emitter *beaconevents.EventEmitter + syncedData synced_data.SyncedData stateDumpLock sync.Mutex } // Initialize fork graph with a new state -func NewForkGraphDisk(anchorState *state.CachingBeaconState, aferoFs afero.Fs, rcfg beacon_router_configuration.RouterConfiguration, emitter *beaconevents.EventEmitter) ForkGraph { +func NewForkGraphDisk(anchorState *state.CachingBeaconState, syncedData synced_data.SyncedData, aferoFs afero.Fs, rcfg beacon_router_configuration.RouterConfiguration, emitter *beaconevents.EventEmitter) ForkGraph { farthestExtendingPath := make(map[libcommon.Hash]bool) anchorRoot, err := anchorState.BlockRoot() if err != nil { @@ -156,6 +158,7 @@ func NewForkGraphDisk(anchorState *state.CachingBeaconState, aferoFs afero.Fs, r anchorSlot: anchorState.Slot(), rcfg: rcfg, emitter: emitter, + syncedData: syncedData, } f.lowestAvailableBlock.Store(anchorState.Slot()) f.headers.Store(libcommon.Hash(anchorRoot), &anchorHeader) @@ -341,6 +344,35 @@ func (f *forkGraphDisk) GetState(blockRoot libcommon.Hash, alwaysCopy bool) (*st return f.getState(blockRoot, alwaysCopy, false) } +func (f *forkGraphDisk) useCachedStateIfPossible(blockRoot libcommon.Hash, in *state.CachingBeaconState) (out *state.CachingBeaconState, ok bool, err error) { + // check if the state is in the cache + err = f.syncedData.ViewPreviousHeadState(func(prevHeadState *state.CachingBeaconState) error { + prevHeadBlockRoot, err := prevHeadState.BlockRoot() + if err != nil { + return err + } + if prevHeadBlockRoot != blockRoot { + return nil + } + ok = true + + var err2 error + if in != nil { + err2 = prevHeadState.CopyInto(in) + out = in + } else { + out, err2 = prevHeadState.Copy() + } + + return err2 + }) + if errors.Is(err, synced_data.ErrPreviousStateNotAvailable) || errors.Is(err, synced_data.ErrNotSynced) { + err = nil + } + + return +} + func (f *forkGraphDisk) getState(blockRoot libcommon.Hash, alwaysCopy bool, addChainSegment bool) (*state.CachingBeaconState, error) { if f.currentState != nil && !alwaysCopy { currentStateBlockRoot, err := f.currentState.BlockRoot() @@ -351,6 +383,11 @@ func (f *forkGraphDisk) getState(blockRoot libcommon.Hash, alwaysCopy bool, addC return f.currentState, nil } } + if addChainSegment && !alwaysCopy { + if state, ok, err := f.useCachedStateIfPossible(blockRoot, f.currentState); ok { + return state, err + } + } // collect all blocks between greatest extending node path and block. blocksInTheWay := []*cltypes.SignedBeaconBlock{} diff --git a/cl/phase1/network/blobs.go b/cl/phase1/network/blobs.go index e06a1796a66..0c22760f357 100644 --- a/cl/phase1/network/blobs.go +++ b/cl/phase1/network/blobs.go @@ -102,11 +102,11 @@ Loop: // this is so we do not get stuck on a side-fork responses, pid, err := r.SendBlobsSidecarByIdentifierReq(ctx, req) if err != nil { - log.Debug("RequestBlobsFrantically: error", "err", err, "peer", pid) + log.Trace("RequestBlobsFrantically: error", "err", err, "peer", pid) return } if responses == nil { - log.Debug("RequestBlobsFrantically: response is nil", "peer", pid) + log.Trace("RequestBlobsFrantically: response is nil", "peer", pid) return } if len(atomicResp.Load().(*PeerAndSidecars).Responses) > 0 { @@ -120,7 +120,7 @@ Loop: case <-ctx.Done(): return nil, ctx.Err() case <-timer.C: - log.Debug("RequestBlobsFrantically: timeout") + log.Trace("RequestBlobsFrantically: timeout") return nil, errors.New("timeout") default: if len(atomicResp.Load().(*PeerAndSidecars).Responses) > 0 { From e12f243339a34782cee1a6475b44fdd5ebbc2085 Mon Sep 17 00:00:00 2001 From: Giulio Date: Sun, 2 Feb 2025 23:26:27 +0100 Subject: [PATCH 05/33] save --- cl/phase1/forkchoice/fork_graph/fork_graph_disk.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index ab8fa756db0..1760003c093 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -352,8 +352,10 @@ func (f *forkGraphDisk) useCachedStateIfPossible(blockRoot libcommon.Hash, in *s return err } if prevHeadBlockRoot != blockRoot { + log.Warn("Not Using cached state", "blockRoot", blockRoot) return nil } + log.Warn("Using cached state", "blockRoot", blockRoot) ok = true var err2 error From 14cfa5ccd2fa03d2f6ca4c0184068c1dd055dd12 Mon Sep 17 00:00:00 2001 From: Giulio Date: Sun, 2 Feb 2025 23:26:59 +0100 Subject: [PATCH 06/33] save --- cmd/caplin/caplin1/run.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/caplin/caplin1/run.go b/cmd/caplin/caplin1/run.go index 01ec38030a4..258db8d8ca4 100644 --- a/cmd/caplin/caplin1/run.go +++ b/cmd/caplin/caplin1/run.go @@ -271,7 +271,7 @@ func RunCaplinService(ctx context.Context, engine execution_client.ExecutionEngi pksRegistry := public_keys_registry.NewHeadViewPublicKeysRegistry(syncedDataManager) forkChoice, err := forkchoice.NewForkChoiceStore( - ethClock, state, engine, pool, fork_graph.NewForkGraphDisk(state, fcuFs, config.BeaconAPIRouter, emitters), + ethClock, state, engine, pool, fork_graph.NewForkGraphDisk(state, syncedDataManager, fcuFs, config.BeaconAPIRouter, emitters), emitters, syncedDataManager, blobStorage, validatorMonitor, pksRegistry, doLMDSampling) if err != nil { logger.Error("Could not create forkchoice", "err", err) From 760f8ece10e03e44d93e73c2ee65c6224582e0db Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 00:17:38 +0100 Subject: [PATCH 07/33] save --- .../forkchoice/fork_graph/fork_graph_disk.go | 1 + cl/phase1/network/services/block_service.go | 24 +++++++------------ 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index 1760003c093..2df3fde41e7 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -351,6 +351,7 @@ func (f *forkGraphDisk) useCachedStateIfPossible(blockRoot libcommon.Hash, in *s if err != nil { return err } + if prevHeadBlockRoot != blockRoot { log.Warn("Not Using cached state", "blockRoot", blockRoot) return nil diff --git a/cl/phase1/network/services/block_service.go b/cl/phase1/network/services/block_service.go index c7db448c797..52fa8407f31 100644 --- a/cl/phase1/network/services/block_service.go +++ b/cl/phase1/network/services/block_service.go @@ -202,19 +202,14 @@ func (b *blockService) scheduleBlockForLaterProcessing(block *cltypes.SignedBeac // processAndStoreBlock processes and stores a block func (b *blockService) processAndStoreBlock(ctx context.Context, block *cltypes.SignedBeaconBlock) error { - // group, _ := errgroup.WithContext(ctx) - - // group.Go(func() error { - // return b.forkchoiceStore.ProcessBlockExecution(ctx, block) - // }) - // group.Go(func() error { - // return b.forkchoiceStore.ProcessBlockConsensus(ctx, block) - // }) + blockRoot, err := block.Block.HashSSZ() + if err != nil { + return err + } - // err := group.Wait() - // if err != nil { - // return err - // } + if _, ok := b.forkchoiceStore.GetHeader(blockRoot); ok { + return nil + } if err := b.db.Update(ctx, func(tx kv.RwTx) error { return beacon_indicies.WriteBeaconBlockAndIndicies(ctx, tx, block, false) @@ -222,10 +217,7 @@ func (b *blockService) processAndStoreBlock(ctx context.Context, block *cltypes. return err } isNewPayload := true - blockRoot, err := block.Block.HashSSZ() - if err != nil { - return err - } + if _, exist := b.forkchoiceStore.GetHeader(blockRoot); exist { isNewPayload = false } From 6a747fe481a1ce9f0efff82fddf5d1cf1852cf9c Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 00:18:56 +0100 Subject: [PATCH 08/33] save --- cl/phase1/network/services/block_service.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cl/phase1/network/services/block_service.go b/cl/phase1/network/services/block_service.go index 52fa8407f31..7d47bfd001b 100644 --- a/cl/phase1/network/services/block_service.go +++ b/cl/phase1/network/services/block_service.go @@ -216,12 +216,12 @@ func (b *blockService) processAndStoreBlock(ctx context.Context, block *cltypes. }); err != nil { return err } - isNewPayload := true + // isNewPayload := true - if _, exist := b.forkchoiceStore.GetHeader(blockRoot); exist { - isNewPayload = false - } - if err := b.forkchoiceStore.OnBlock(ctx, block, isNewPayload, true, true); err != nil { + // if _, exist := b.forkchoiceStore.GetHeader(blockRoot); exist { + // isNewPayload = false + // } + if err := b.forkchoiceStore.OnBlock(ctx, block, true, true, true); err != nil { return err } go b.importBlockOperations(block) From 764905d17a6b936aa3cb843bfd3fd4232986386e Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 00:20:33 +0100 Subject: [PATCH 09/33] save --- cl/phase1/forkchoice/on_block.go | 74 --------------------- cl/phase1/network/services/block_service.go | 4 -- 2 files changed, 78 deletions(-) diff --git a/cl/phase1/forkchoice/on_block.go b/cl/phase1/forkchoice/on_block.go index 5d7fd4a7f94..76dfc2eb1e4 100644 --- a/cl/phase1/forkchoice/on_block.go +++ b/cl/phase1/forkchoice/on_block.go @@ -80,80 +80,6 @@ func collectOnBlockLatencyToUnixTime(ethClock eth_clock.EthereumClock, slot uint monitor.ObserveBlockImportingLatency(initialSlotTime) } -func (f *ForkChoiceStore) ProcessBlockExecution(ctx context.Context, block *cltypes.SignedBeaconBlock) error { - blockRoot, err := block.Block.HashSSZ() - if err != nil { - return err - } - - if f.engine == nil || f.verifiedExecutionPayload.Contains(blockRoot) { - return nil - } - - var versionedHashes []libcommon.Hash - if f.engine != nil && block.Version() >= clparams.DenebVersion { - versionedHashes = []libcommon.Hash{} - solid.RangeErr[*cltypes.KZGCommitment](block.Block.Body.BlobKzgCommitments, func(i1 int, k *cltypes.KZGCommitment, i2 int) error { - versionedHash, err := utils.KzgCommitmentToVersionedHash(libcommon.Bytes48(*k)) - if err != nil { - return err - } - versionedHashes = append(versionedHashes, versionedHash) - return nil - }) - } - - if block.Version() >= clparams.DenebVersion { - if err := verifyKzgCommitmentsAgainstTransactions(f.beaconCfg, block.Block.Body.ExecutionPayload, block.Block.Body.BlobKzgCommitments); err != nil { - return fmt.Errorf("OnBlock: failed to process kzg commitments: %v", err) - } - } - - var executionRequestsList []hexutility.Bytes = nil - if block.Version() >= clparams.ElectraVersion { - executionRequestsList = block.Block.Body.GetExecutionRequestsList() - } - - timeStartExec := time.Now() - payloadStatus, err := f.engine.NewPayload(ctx, block.Block.Body.ExecutionPayload, &block.Block.ParentRoot, versionedHashes, executionRequestsList) - monitor.ObserveNewPayloadTime(timeStartExec) - switch payloadStatus { - case execution_client.PayloadStatusInvalidated: - log.Warn("OnBlock: block is invalid", "block", libcommon.Hash(blockRoot), "err", err) - f.forkGraph.MarkHeaderAsInvalid(blockRoot) - // remove from optimistic candidate - if err := f.optimisticStore.InvalidateBlock(block.Block); err != nil { - return fmt.Errorf("failed to remove block from optimistic store: %v", err) - } - return errors.New("block is invalid") - case execution_client.PayloadStatusValidated: - log.Trace("OnBlock: block is validated", "block", libcommon.Hash(blockRoot)) - // remove from optimistic candidate - if err := f.optimisticStore.ValidateBlock(block.Block); err != nil { - return fmt.Errorf("failed to validate block in optimistic store: %v", err) - } - f.verifiedExecutionPayload.Add(blockRoot, struct{}{}) - } - if err != nil { - return fmt.Errorf("newPayload failed: %v", err) - } - return nil -} - -func (f *ForkChoiceStore) ProcessBlockConsensus(ctx context.Context, block *cltypes.SignedBeaconBlock) error { - f.mu.Lock() - defer f.mu.Unlock() - start := time.Now() - _, _, err := f.forkGraph.AddChainSegment(block, true, true) - if err != nil { - return fmt.Errorf("ProcessBlockConsensus: replay block, status %+v", err) - } - if time.Since(start) > 1*time.Millisecond { - log.Debug("OnBlock", "elapsed", time.Since(start), "slot", block.Block.Slot) - } - return nil -} - func (f *ForkChoiceStore) OnBlock(ctx context.Context, block *cltypes.SignedBeaconBlock, newPayload, fullValidation, checkDataAvaiability bool) error { f.mu.Lock() defer f.mu.Unlock() diff --git a/cl/phase1/network/services/block_service.go b/cl/phase1/network/services/block_service.go index 7d47bfd001b..95eafced7f4 100644 --- a/cl/phase1/network/services/block_service.go +++ b/cl/phase1/network/services/block_service.go @@ -216,11 +216,7 @@ func (b *blockService) processAndStoreBlock(ctx context.Context, block *cltypes. }); err != nil { return err } - // isNewPayload := true - // if _, exist := b.forkchoiceStore.GetHeader(blockRoot); exist { - // isNewPayload = false - // } if err := b.forkchoiceStore.OnBlock(ctx, block, true, true, true); err != nil { return err } From 592c7443856ba21b5179939723603f14b4c0634f Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 00:21:29 +0100 Subject: [PATCH 10/33] save --- cl/phase1/forkchoice/fork_graph/fork_graph_disk.go | 5 +---- cl/phase1/forkchoice/fork_graph/interface.go | 2 +- cl/phase1/forkchoice/on_block.go | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index 2df3fde41e7..6f7fe9ba3e5 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -182,7 +182,7 @@ func (f *forkGraphDisk) isBlockRootTheCurrentState(blockRoot libcommon.Hash) boo } // Add a new node and edge to the graph -func (f *forkGraphDisk) AddChainSegment(signedBlock *cltypes.SignedBeaconBlock, fullValidation, shallowImport bool) (*state.CachingBeaconState, ChainSegmentInsertionResult, error) { +func (f *forkGraphDisk) AddChainSegment(signedBlock *cltypes.SignedBeaconBlock, fullValidation bool) (*state.CachingBeaconState, ChainSegmentInsertionResult, error) { block := signedBlock.Block blockRoot, err := block.HashSSZ() if err != nil { @@ -276,9 +276,6 @@ func (f *forkGraphDisk) AddChainSegment(signedBlock *cltypes.SignedBeaconBlock, } f.currentState = newState - if shallowImport { - return newState, Success, nil - } // update diff storages. if f.rcfg.Beacon || f.rcfg.Validator || f.rcfg.Lighthouse { diff --git a/cl/phase1/forkchoice/fork_graph/interface.go b/cl/phase1/forkchoice/fork_graph/interface.go index dc96f6de320..173cc7a9cd9 100644 --- a/cl/phase1/forkchoice/fork_graph/interface.go +++ b/cl/phase1/forkchoice/fork_graph/interface.go @@ -35,7 +35,7 @@ import ( * to analyze and manipulate the state of the blockchain. */ type ForkGraph interface { - AddChainSegment(signedBlock *cltypes.SignedBeaconBlock, fullValidation, shallowImport bool) (*state.CachingBeaconState, ChainSegmentInsertionResult, error) + AddChainSegment(signedBlock *cltypes.SignedBeaconBlock, fullValidation bool) (*state.CachingBeaconState, ChainSegmentInsertionResult, error) GetHeader(blockRoot libcommon.Hash) (*cltypes.BeaconBlockHeader, bool) GetState(blockRoot libcommon.Hash, alwaysCopy bool) (*state.CachingBeaconState, error) GetCurrentJustifiedCheckpoint(blockRoot libcommon.Hash) (solid.Checkpoint, bool) diff --git a/cl/phase1/forkchoice/on_block.go b/cl/phase1/forkchoice/on_block.go index 76dfc2eb1e4..9a06fa65d45 100644 --- a/cl/phase1/forkchoice/on_block.go +++ b/cl/phase1/forkchoice/on_block.go @@ -171,7 +171,7 @@ func (f *ForkChoiceStore) OnBlock(ctx context.Context, block *cltypes.SignedBeac } log.Trace("OnBlock: engine", "elapsed", time.Since(startEngine)) startStateProcess := time.Now() - lastProcessedState, status, err := f.forkGraph.AddChainSegment(block, fullValidation, false) + lastProcessedState, status, err := f.forkGraph.AddChainSegment(block, fullValidation) if err != nil { return err } From 9a1fe88c9dbad8c9647f18f5545601953220b2e1 Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 00:22:26 +0100 Subject: [PATCH 11/33] save --- cl/phase1/forkchoice/interface.go | 3 --- cl/phase1/forkchoice/mock_services/forkchoice_mock.go | 8 -------- 2 files changed, 11 deletions(-) diff --git a/cl/phase1/forkchoice/interface.go b/cl/phase1/forkchoice/interface.go index 22ebb9a398e..fcee6a3a83d 100644 --- a/cl/phase1/forkchoice/interface.go +++ b/cl/phase1/forkchoice/interface.go @@ -93,7 +93,4 @@ type ForkChoiceStorageWriter interface { OnTick(time uint64) SetSynced(synced bool) ProcessAttestingIndicies(attestation *solid.Attestation, attestionIndicies []uint64) - - ProcessBlockExecution(ctx context.Context, block *cltypes.SignedBeaconBlock) error - ProcessBlockConsensus(ctx context.Context, block *cltypes.SignedBeaconBlock) error } diff --git a/cl/phase1/forkchoice/mock_services/forkchoice_mock.go b/cl/phase1/forkchoice/mock_services/forkchoice_mock.go index 877bcb13378..a6bae30313f 100644 --- a/cl/phase1/forkchoice/mock_services/forkchoice_mock.go +++ b/cl/phase1/forkchoice/mock_services/forkchoice_mock.go @@ -367,11 +367,3 @@ func (f *ForkChoiceStorageMock) IsRootOptimistic(root common.Hash) bool { func (f *ForkChoiceStorageMock) IsHeadOptimistic() bool { return false } - -func (f *ForkChoiceStorageMock) ProcessBlockConsensus(ctx context.Context, block *cltypes.SignedBeaconBlock) error { - return nil -} - -func (f *ForkChoiceStorageMock) ProcessBlockExecution(ctx context.Context, block *cltypes.SignedBeaconBlock) error { - return nil -} From 6e1ab39ea689ea15cfceff76b038c95e7727309f Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 00:23:49 +0100 Subject: [PATCH 12/33] save --- cl/phase1/forkchoice/fork_graph/fork_graph_disk.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index 6f7fe9ba3e5..b51afb9c121 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -350,10 +350,10 @@ func (f *forkGraphDisk) useCachedStateIfPossible(blockRoot libcommon.Hash, in *s } if prevHeadBlockRoot != blockRoot { - log.Warn("Not Using cached state", "blockRoot", blockRoot) + log.Warn("Not Using cached state", "blockRoot", blockRoot, "prevHeadBlockRoot", prevHeadBlockRoot) return nil } - log.Warn("Using cached state", "blockRoot", blockRoot) + log.Warn("Using cached state", "blockRoot", blockRoot, "prevHeadBlockRoot", prevHeadBlockRoot) ok = true var err2 error From d41751e522712cc7ab1f9b99ed80243757480509 Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 00:25:02 +0100 Subject: [PATCH 13/33] save --- cl/phase1/forkchoice/fork_graph/fork_graph_disk.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index b51afb9c121..41bbe72802a 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -25,6 +25,7 @@ import ( "github.com/golang/snappy" "github.com/spf13/afero" + "github.com/erigontech/erigon-lib/common" libcommon "github.com/erigontech/erigon-lib/common" "github.com/erigontech/erigon-lib/common/dbg" "github.com/erigontech/erigon-lib/log/v3" @@ -204,6 +205,8 @@ func (f *forkGraphDisk) AddChainSegment(signedBlock *cltypes.SignedBeaconBlock, if isBlockRootTheCurrentState { newState = f.currentState } else { + + fmt.Println("A", common.Hash(blockRoot)) newState, err = f.getState(block.ParentRoot, false, true) if err != nil { return nil, LogisticError, fmt.Errorf("AddChainSegment: %w, parentRoot: %x", err, block.ParentRoot) From 9335b7861a68a0572e1bc3421ba78d06cc2c67f1 Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 00:27:31 +0100 Subject: [PATCH 14/33] save --- cl/phase1/forkchoice/fork_graph/fork_graph_disk.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index 41bbe72802a..5b3b25e1752 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -19,6 +19,7 @@ package fork_graph import ( "errors" "fmt" + "runtime/debug" "sync" "sync/atomic" @@ -352,7 +353,9 @@ func (f *forkGraphDisk) useCachedStateIfPossible(blockRoot libcommon.Hash, in *s return err } + debug.PrintStack() if prevHeadBlockRoot != blockRoot { + // print stack log.Warn("Not Using cached state", "blockRoot", blockRoot, "prevHeadBlockRoot", prevHeadBlockRoot) return nil } From 0a0de4a75bc99a8d25af2c802acc086ecb324dc3 Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 00:45:41 +0100 Subject: [PATCH 15/33] save --- cl/phase1/core/state/copy.go | 21 ++----------------- .../forkchoice/fork_graph/fork_graph_disk.go | 3 --- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/cl/phase1/core/state/copy.go b/cl/phase1/core/state/copy.go index 580a17422bb..044c527cfa0 100644 --- a/cl/phase1/core/state/copy.go +++ b/cl/phase1/core/state/copy.go @@ -42,27 +42,10 @@ func (bs *CachingBeaconState) reinitCaches() error { if bs.Version() == clparams.Phase0Version { return bs.InitBeaconState() } - if bs.publicKeyIndicies == nil { - bs.publicKeyIndicies = make(map[[48]byte]uint64) - } + bs.publicKeyIndicies = make(map[[48]byte]uint64) - // We regenerate public keys from the copied state to avoid concurrency issues. - for k, idx := range bs.publicKeyIndicies { - if idx >= uint64(bs.ValidatorSet().Length()) { - delete(bs.publicKeyIndicies, k) - continue - } - pk := bs.ValidatorSet().Get(int(idx)).PublicKey() - if pk != k { - delete(bs.publicKeyIndicies, k) - } - } bs.ForEachValidator(func(v solid.Validator, idx, total int) bool { - pk := v.PublicKey() - if _, ok := bs.publicKeyIndicies[pk]; ok { - return true - } - bs.publicKeyIndicies[pk] = uint64(idx) + bs.publicKeyIndicies[v.PublicKey()] = uint64(idx) return true }) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index 5b3b25e1752..a2de1f915a2 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -26,7 +26,6 @@ import ( "github.com/golang/snappy" "github.com/spf13/afero" - "github.com/erigontech/erigon-lib/common" libcommon "github.com/erigontech/erigon-lib/common" "github.com/erigontech/erigon-lib/common/dbg" "github.com/erigontech/erigon-lib/log/v3" @@ -206,8 +205,6 @@ func (f *forkGraphDisk) AddChainSegment(signedBlock *cltypes.SignedBeaconBlock, if isBlockRootTheCurrentState { newState = f.currentState } else { - - fmt.Println("A", common.Hash(blockRoot)) newState, err = f.getState(block.ParentRoot, false, true) if err != nil { return nil, LogisticError, fmt.Errorf("AddChainSegment: %w, parentRoot: %x", err, block.ParentRoot) From 28d37a861b25969699db38eb7483ec31577ca14e Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 00:56:22 +0100 Subject: [PATCH 16/33] save --- cl/merkle_tree/merkle_tree.go | 51 +++++++++++++---------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/cl/merkle_tree/merkle_tree.go b/cl/merkle_tree/merkle_tree.go index 73d638881f8..8ff3acbe7bb 100644 --- a/cl/merkle_tree/merkle_tree.go +++ b/cl/merkle_tree/merkle_tree.go @@ -201,44 +201,31 @@ func (m *MerkleTree) CopyInto(other *MerkleTree) { m.mu.RLock() defer m.mu.RUnlock() defer other.mu.Unlock() - //other.computeLeaf = m.computeLeaf - if len(other.layers) > len(m.layers) { - // reset the internal layers - for i := len(m.layers); i < len(other.layers); i++ { - other.layers[i] = other.layers[i][:0] - } - other.layers = other.layers[:len(m.layers)] - } - if len(m.layers) > len(other.layers) { - for len(other.layers) != len(m.layers) { - idx := len(other.layers) - other.layers = append(other.layers, make([]byte, len(m.layers[idx]), (len(m.layers[idx])*3)/2)) - } - } - - for i := 0; i < len(m.layers); i++ { - // If the destination buffer is too short, extend it - if len(m.layers[i]) > cap(other.layers[i]) { - other.layers[i] = make([]byte, len(m.layers[i]), (len(m.layers[i])*3)/2) - } - // Normalizr the destination length - other.layers[i] = other.layers[i][:len(m.layers[i])] - - // Now that the 2 slices are of equal length we can do a simple memcopy - copy(other.layers[i], m.layers[i]) + // Create a new slice of layers and copy each layer. + newLayers := make([][]byte, len(m.layers)) + for i, layer := range m.layers { + newLayer := make([]byte, len(layer)) + copy(newLayer, layer) + newLayers[i] = newLayer } + other.layers = newLayers + // Copy scalar values. other.leavesCount = m.leavesCount - other.limit = m.limit - //other.dirtyLeaves = make([]atomic.Bool, len(m.dirtyLeaves)) + if m.limit != nil { + other.limit = new(uint64) + *other.limit = *m.limit + } else { + other.limit = nil + } - for i := 0; i < len(m.dirtyLeaves); i++ { - if i >= len(other.dirtyLeaves) { - other.dirtyLeaves = append(other.dirtyLeaves, atomic.Bool{}) - } - other.dirtyLeaves[i].Store(m.dirtyLeaves[i].Load()) + // Create a new slice of dirtyLeaves and copy the state. + newDirty := make([]atomic.Bool, len(m.dirtyLeaves)) + for i := range m.dirtyLeaves { + newDirty[i].Store(m.dirtyLeaves[i].Load()) } + other.dirtyLeaves = newDirty } func (m *MerkleTree) finishHashing(lastLayerIdx int, root []byte) { From b32f8c02e836972d3334d28fe04a52e9d9369ce2 Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 01:08:20 +0100 Subject: [PATCH 17/33] save --- cl/merkle_tree/merkle_tree.go | 51 ++++++++++++------- cl/phase1/core/state/raw/hashing.go | 8 +++ .../forkchoice/fork_graph/fork_graph_disk.go | 5 ++ 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/cl/merkle_tree/merkle_tree.go b/cl/merkle_tree/merkle_tree.go index 8ff3acbe7bb..73d638881f8 100644 --- a/cl/merkle_tree/merkle_tree.go +++ b/cl/merkle_tree/merkle_tree.go @@ -201,31 +201,44 @@ func (m *MerkleTree) CopyInto(other *MerkleTree) { m.mu.RLock() defer m.mu.RUnlock() defer other.mu.Unlock() + //other.computeLeaf = m.computeLeaf + if len(other.layers) > len(m.layers) { + // reset the internal layers + for i := len(m.layers); i < len(other.layers); i++ { + other.layers[i] = other.layers[i][:0] + } + other.layers = other.layers[:len(m.layers)] + } - // Create a new slice of layers and copy each layer. - newLayers := make([][]byte, len(m.layers)) - for i, layer := range m.layers { - newLayer := make([]byte, len(layer)) - copy(newLayer, layer) - newLayers[i] = newLayer + if len(m.layers) > len(other.layers) { + for len(other.layers) != len(m.layers) { + idx := len(other.layers) + other.layers = append(other.layers, make([]byte, len(m.layers[idx]), (len(m.layers[idx])*3)/2)) + } } - other.layers = newLayers - // Copy scalar values. - other.leavesCount = m.leavesCount - if m.limit != nil { - other.limit = new(uint64) - *other.limit = *m.limit - } else { - other.limit = nil + for i := 0; i < len(m.layers); i++ { + // If the destination buffer is too short, extend it + if len(m.layers[i]) > cap(other.layers[i]) { + other.layers[i] = make([]byte, len(m.layers[i]), (len(m.layers[i])*3)/2) + } + // Normalizr the destination length + other.layers[i] = other.layers[i][:len(m.layers[i])] + + // Now that the 2 slices are of equal length we can do a simple memcopy + copy(other.layers[i], m.layers[i]) } - // Create a new slice of dirtyLeaves and copy the state. - newDirty := make([]atomic.Bool, len(m.dirtyLeaves)) - for i := range m.dirtyLeaves { - newDirty[i].Store(m.dirtyLeaves[i].Load()) + other.leavesCount = m.leavesCount + other.limit = m.limit + //other.dirtyLeaves = make([]atomic.Bool, len(m.dirtyLeaves)) + + for i := 0; i < len(m.dirtyLeaves); i++ { + if i >= len(other.dirtyLeaves) { + other.dirtyLeaves = append(other.dirtyLeaves, atomic.Bool{}) + } + other.dirtyLeaves[i].Store(m.dirtyLeaves[i].Load()) } - other.dirtyLeaves = newDirty } func (m *MerkleTree) finishHashing(lastLayerIdx int, root []byte) { diff --git a/cl/phase1/core/state/raw/hashing.go b/cl/phase1/core/state/raw/hashing.go index e340b1e3f2a..6e456169d1b 100644 --- a/cl/phase1/core/state/raw/hashing.go +++ b/cl/phase1/core/state/raw/hashing.go @@ -17,6 +17,7 @@ package raw import ( + "fmt" "sync" libcommon "github.com/erigontech/erigon-lib/common" @@ -43,6 +44,13 @@ func (b *BeaconState) HashSSZ() (out [32]byte, err error) { return } +func (b *BeaconState) PrintLeaves() { + fmt.Println("TRACE: BeaconState leaves:") + for i := 0; i < len(b.leaves); i += 32 { + println(i/32, libcommon.BytesToHash(b.leaves[i:i+32])) + } +} + func (b *BeaconState) CurrentSyncCommitteeBranch() ([][32]byte, error) { if err := b.computeDirtyLeaves(); err != nil { return nil, err diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index a2de1f915a2..4be531181f8 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -269,12 +269,17 @@ func (f *forkGraphDisk) AddChainSegment(signedBlock *cltypes.SignedBeaconBlock, if invalidBlockErr := transition.TransitionState(newState, signedBlock, blockRewardsCollector, fullValidation); invalidBlockErr != nil { // Add block to list of invalid blocks log.Warn("Invalid beacon block", "slot", block.Slot, "blockRoot", libcommon.Bytes2Hex(blockRoot[:]), "reason", invalidBlockErr) + newState.PrintLeaves() f.badBlocks.Store(libcommon.Hash(blockRoot), struct{}{}) f.currentState = nil return nil, InvalidBlock, invalidBlockErr } f.blockRewards.Store(libcommon.Hash(blockRoot), blockRewardsCollector) } + if _, ok := f.badBlocks.Load(libcommon.Hash(blockRoot)); ok { + fmt.Println("TRACE: Correct BeaconState leaves:") + newState.PrintLeaves() + } f.currentState = newState From d09581079cb9dfcb2e05673c6f47f8c3b022feac Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 01:08:30 +0100 Subject: [PATCH 18/33] save --- cl/phase1/forkchoice/fork_graph/fork_graph_disk.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index 4be531181f8..a75dbaabda9 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -277,7 +277,7 @@ func (f *forkGraphDisk) AddChainSegment(signedBlock *cltypes.SignedBeaconBlock, f.blockRewards.Store(libcommon.Hash(blockRoot), blockRewardsCollector) } if _, ok := f.badBlocks.Load(libcommon.Hash(blockRoot)); ok { - fmt.Println("TRACE: Correct BeaconState leaves:") + fmt.Println("TRACE: Correct BeaconState leaves:", "slot", block.Slot) newState.PrintLeaves() } From 9a51c20a563e54e1e7f4fac0ce5d6f294abe8fe2 Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 01:09:55 +0100 Subject: [PATCH 19/33] save --- cl/phase1/core/state/raw/hashing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cl/phase1/core/state/raw/hashing.go b/cl/phase1/core/state/raw/hashing.go index 6e456169d1b..11e43d2d568 100644 --- a/cl/phase1/core/state/raw/hashing.go +++ b/cl/phase1/core/state/raw/hashing.go @@ -47,7 +47,7 @@ func (b *BeaconState) HashSSZ() (out [32]byte, err error) { func (b *BeaconState) PrintLeaves() { fmt.Println("TRACE: BeaconState leaves:") for i := 0; i < len(b.leaves); i += 32 { - println(i/32, libcommon.BytesToHash(b.leaves[i:i+32])) + fmt.Println(i/32, libcommon.BytesToHash(b.leaves[i:i+32])) } } From f64803e8015fb960e3aadf5e6d00500653aff016 Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 01:28:00 +0100 Subject: [PATCH 20/33] save --- cl/cltypes/solid/validator_set.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/cl/cltypes/solid/validator_set.go b/cl/cltypes/solid/validator_set.go index 4500694a63c..94dbb074161 100644 --- a/cl/cltypes/solid/validator_set.go +++ b/cl/cltypes/solid/validator_set.go @@ -140,8 +140,17 @@ func (v *ValidatorSet) CopyTo(t *ValidatorSet) { t.MerkleTree = &merkle_tree.MerkleTree{} } v.MerkleTree.CopyInto(t.MerkleTree) + + hashBuffer := make([]byte, 8*32) t.MerkleTree.SetComputeLeafFn(func(idx int, out []byte) { - copy(out, t.buffer[idx*validatorSize:]) + validator := v.Get(idx) + if err := validator.CopyHashBufferTo(hashBuffer); err != nil { + panic(err) + } + hashBuffer = hashBuffer[:(8 * 32)] + if err := merkle_tree.MerkleRootFromFlatLeaves(hashBuffer, out); err != nil { + panic(err) + } }) } else { t.MerkleTree = nil From df630d7809da587b0f0f173311a968a59e0610c3 Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 01:47:56 +0100 Subject: [PATCH 21/33] save --- .../forkchoice/fork_graph/fork_graph_disk.go | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index a75dbaabda9..9e05bd76df4 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -348,6 +348,33 @@ func (f *forkGraphDisk) GetState(blockRoot libcommon.Hash, alwaysCopy bool) (*st } func (f *forkGraphDisk) useCachedStateIfPossible(blockRoot libcommon.Hash, in *state.CachingBeaconState) (out *state.CachingBeaconState, ok bool, err error) { + if f.syncedData.HeadRoot() == blockRoot { + err = f.syncedData.ViewHeadState(func(headState *state.CachingBeaconState) error { + headBlockRoot, err := headState.BlockRoot() + if err != nil { + return err + } + if headBlockRoot != blockRoot { + return nil + } + ok = true + var err2 error + log.Warn("Using current cached state", "blockRoot", blockRoot, "prevHeadBlockRoot", prevHeadBlockRoot) + + if in != nil { + err2 = headState.CopyInto(in) + out = in + } else { + out, err2 = headState.Copy() + } + return err2 + }) + if errors.Is(err, synced_data.ErrNotSynced) { + err = nil + } + return + } + // check if the state is in the cache err = f.syncedData.ViewPreviousHeadState(func(prevHeadState *state.CachingBeaconState) error { prevHeadBlockRoot, err := prevHeadState.BlockRoot() From b832f6c82cc7ca11615c31b89f27f33c2264795b Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 01:48:54 +0100 Subject: [PATCH 22/33] save --- cl/phase1/forkchoice/fork_graph/fork_graph_disk.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index 9e05bd76df4..5af6c1868d7 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -359,7 +359,7 @@ func (f *forkGraphDisk) useCachedStateIfPossible(blockRoot libcommon.Hash, in *s } ok = true var err2 error - log.Warn("Using current cached state", "blockRoot", blockRoot, "prevHeadBlockRoot", prevHeadBlockRoot) + log.Warn("Using current cached state", "blockRoot", blockRoot, "headBlockRoot", libcommon.Hash(headBlockRoot)) if in != nil { err2 = headState.CopyInto(in) @@ -385,10 +385,10 @@ func (f *forkGraphDisk) useCachedStateIfPossible(blockRoot libcommon.Hash, in *s debug.PrintStack() if prevHeadBlockRoot != blockRoot { // print stack - log.Warn("Not Using cached state", "blockRoot", blockRoot, "prevHeadBlockRoot", prevHeadBlockRoot) + log.Warn("Not Using cached state", "blockRoot", blockRoot, "prevHeadBlockRoot", libcommon.Hash(prevHeadBlockRoot)) return nil } - log.Warn("Using cached state", "blockRoot", blockRoot, "prevHeadBlockRoot", prevHeadBlockRoot) + log.Warn("Using cached state", "blockRoot", blockRoot, "prevHeadBlockRoot", libcommon.Hash(prevHeadBlockRoot)) ok = true var err2 error From 2e9e0e055915a4522931d0776d5bd857749e7cb7 Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 02:12:59 +0100 Subject: [PATCH 23/33] save --- cl/clparams/config.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cl/clparams/config.go b/cl/clparams/config.go index e942b12d7be..eb82c224692 100644 --- a/cl/clparams/config.go +++ b/cl/clparams/config.go @@ -124,9 +124,8 @@ const ( var ( MainnetBootstrapNodes = []string{ - // Teku team's bootnode - "enr:-KG4QOtcP9X1FbIMOe17QNMKqDxCpm14jcX5tiOE4_TyMrFqbmhPZHK_ZPG2Gxb1GE2xdtodOfx9-cgvNtxnRyHEmC0ghGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQDE8KdiXNlY3AyNTZrMaEDhpehBDbZjM_L9ek699Y7vhUJ-eAdMyQW_Fil522Y0fODdGNwgiMog3VkcIIjKA", - "enr:-KG4QL-eqFoHy0cI31THvtZjpYUu_Jdw_MO7skQRJxY1g5HTN1A0epPCU6vi0gLGUgrzpU-ygeMSS8ewVxDpKfYmxMMGhGV0aDKQtTA_KgAAAAD__________4JpZIJ2NIJpcIQ2_DUbiXNlY3AyNTZrMaED8GJ2vzUqgL6-KD1xalo1CsmY4X1HaDnyl6Y_WayCo9GDdGNwgiMog3VkcIIjKA", + "enr:-KG4QNTx85fjxABbSq_Rta9wy56nQ1fHK0PewJbGjLm1M4bMGx5-3Qq4ZX2-iFJ0pys_O90sVXNNOxp2E7afBsGsBrgDhGV0aDKQu6TalgMAAAD__________4JpZIJ2NIJpcIQEnfA2iXNlY3AyNTZrMaECGXWQ-rQ2KZKRH1aOW4IlPDBkY4XDphxg9pxKytFCkayDdGNwgiMog3VkcIIjKA", + "enr:-KG4QF4B5WrlFcRhUU6dZETwY5ZzAXnA0vGC__L1Kdw602nDZwXSTs5RFXFIFUnbQJmhNGVU6OIX7KVrCSTODsz1tK4DhGV0aDKQu6TalgMAAAD__________4JpZIJ2NIJpcIQExNYEiXNlY3AyNTZrMaECQmM9vp7KhaXhI-nqL_R0ovULLCFSFTa9CPPSdb1zPX6DdGNwgiMog3VkcIIjKA", // Prylab team's bootnodes "enr:-Ku4QImhMc1z8yCiNJ1TyUxdcfNucje3BGwEHzodEZUan8PherEo4sF7pPHPSIB1NNuSg5fZy7qFsjmUKs2ea1Whi0EBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQOVphkDqal4QzPMksc5wnpuC3gvSC8AfbFOnZY_On34wIN1ZHCCIyg", "enr:-Ku4QP2xDnEtUXIjzJ_DhlCRN9SN99RYQPJL92TMlSv7U5C1YnYLjwOQHgZIUXw6c-BvRg2Yc2QsZxxoS_pPRVe0yK8Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQMeFF5GrS7UZpAH2Ly84aLK-TyvH-dRo0JM1i8yygH50YN1ZHCCJxA", From d3e4bdef9648167eaba3fbc2c1869c979f461fd5 Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 02:35:34 +0100 Subject: [PATCH 24/33] save --- cl/phase1/forkchoice/fork_graph/fork_graph_disk.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index 5af6c1868d7..2bc6ea85895 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -19,7 +19,6 @@ package fork_graph import ( "errors" "fmt" - "runtime/debug" "sync" "sync/atomic" @@ -382,7 +381,6 @@ func (f *forkGraphDisk) useCachedStateIfPossible(blockRoot libcommon.Hash, in *s return err } - debug.PrintStack() if prevHeadBlockRoot != blockRoot { // print stack log.Warn("Not Using cached state", "blockRoot", blockRoot, "prevHeadBlockRoot", libcommon.Hash(prevHeadBlockRoot)) From d98659a8ad774777c1bc2d206d484b2db6260f3e Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 02:35:51 +0100 Subject: [PATCH 25/33] save --- cl/phase1/forkchoice/fork_graph/fork_graph_disk.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index 2bc6ea85895..dda5fdb9b14 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -347,7 +347,7 @@ func (f *forkGraphDisk) GetState(blockRoot libcommon.Hash, alwaysCopy bool) (*st } func (f *forkGraphDisk) useCachedStateIfPossible(blockRoot libcommon.Hash, in *state.CachingBeaconState) (out *state.CachingBeaconState, ok bool, err error) { - if f.syncedData.HeadRoot() == blockRoot { + if f.syncedData.HeadRoot() == blockRoot && false { err = f.syncedData.ViewHeadState(func(headState *state.CachingBeaconState) error { headBlockRoot, err := headState.BlockRoot() if err != nil { From b757ecac919914a54265e84df07e7afda0b58a97 Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 02:42:39 +0100 Subject: [PATCH 26/33] save --- cl/cltypes/solid/validator_set.go | 2 +- cl/phase1/forkchoice/fork_graph/fork_graph_disk.go | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cl/cltypes/solid/validator_set.go b/cl/cltypes/solid/validator_set.go index 94dbb074161..0f944350352 100644 --- a/cl/cltypes/solid/validator_set.go +++ b/cl/cltypes/solid/validator_set.go @@ -143,7 +143,7 @@ func (v *ValidatorSet) CopyTo(t *ValidatorSet) { hashBuffer := make([]byte, 8*32) t.MerkleTree.SetComputeLeafFn(func(idx int, out []byte) { - validator := v.Get(idx) + validator := t.Get(idx) if err := validator.CopyHashBufferTo(hashBuffer); err != nil { panic(err) } diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index dda5fdb9b14..3b16e32437e 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -382,7 +382,6 @@ func (f *forkGraphDisk) useCachedStateIfPossible(blockRoot libcommon.Hash, in *s } if prevHeadBlockRoot != blockRoot { - // print stack log.Warn("Not Using cached state", "blockRoot", blockRoot, "prevHeadBlockRoot", libcommon.Hash(prevHeadBlockRoot)) return nil } From f6e26f60ca9e80288ce2d30965c274c3bae1c79e Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 02:47:35 +0100 Subject: [PATCH 27/33] save --- cl/phase1/forkchoice/fork_graph/fork_graph_disk.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index 3b16e32437e..46f7f1233ee 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -347,7 +347,7 @@ func (f *forkGraphDisk) GetState(blockRoot libcommon.Hash, alwaysCopy bool) (*st } func (f *forkGraphDisk) useCachedStateIfPossible(blockRoot libcommon.Hash, in *state.CachingBeaconState) (out *state.CachingBeaconState, ok bool, err error) { - if f.syncedData.HeadRoot() == blockRoot && false { + if f.syncedData.HeadRoot() == blockRoot { err = f.syncedData.ViewHeadState(func(headState *state.CachingBeaconState) error { headBlockRoot, err := headState.BlockRoot() if err != nil { From 622ec8c6e05e57763b2ee08883363d2ebd208440 Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 03:18:58 +0100 Subject: [PATCH 28/33] save --- cl/phase1/forkchoice/fork_graph/fork_graph_disk.go | 9 +++------ cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go | 4 ---- cl/phase1/forkchoice/fork_graph/fork_graph_test.go | 10 +++++----- cl/spectest/consensus_tests/fork_choice.go | 2 +- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index 46f7f1233ee..02e79c5254e 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -268,17 +268,12 @@ func (f *forkGraphDisk) AddChainSegment(signedBlock *cltypes.SignedBeaconBlock, if invalidBlockErr := transition.TransitionState(newState, signedBlock, blockRewardsCollector, fullValidation); invalidBlockErr != nil { // Add block to list of invalid blocks log.Warn("Invalid beacon block", "slot", block.Slot, "blockRoot", libcommon.Bytes2Hex(blockRoot[:]), "reason", invalidBlockErr) - newState.PrintLeaves() f.badBlocks.Store(libcommon.Hash(blockRoot), struct{}{}) f.currentState = nil return nil, InvalidBlock, invalidBlockErr } f.blockRewards.Store(libcommon.Hash(blockRoot), blockRewardsCollector) } - if _, ok := f.badBlocks.Load(libcommon.Hash(blockRoot)); ok { - fmt.Println("TRACE: Correct BeaconState leaves:", "slot", block.Slot) - newState.PrintLeaves() - } f.currentState = newState @@ -347,6 +342,9 @@ func (f *forkGraphDisk) GetState(blockRoot libcommon.Hash, alwaysCopy bool) (*st } func (f *forkGraphDisk) useCachedStateIfPossible(blockRoot libcommon.Hash, in *state.CachingBeaconState) (out *state.CachingBeaconState, ok bool, err error) { + if f.syncedData == nil { + return + } if f.syncedData.HeadRoot() == blockRoot { err = f.syncedData.ViewHeadState(func(headState *state.CachingBeaconState) error { headBlockRoot, err := headState.BlockRoot() @@ -532,7 +530,6 @@ func (f *forkGraphDisk) Prune(pruneSlot uint64) (err error) { f.headers.Delete(root) f.blockRewards.Delete(root) f.fs.Remove(getBeaconStateFilename(root)) - f.fs.Remove(getBeaconStateCacheFilename(root)) } log.Debug("Pruned old blocks", "pruneSlot", pruneSlot) return diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go index c5018f66a91..c670623fd8c 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk_fs.go @@ -34,10 +34,6 @@ func getBeaconStateFilename(blockRoot libcommon.Hash) string { return fmt.Sprintf("%x.snappy_ssz", blockRoot) } -func getBeaconStateCacheFilename(blockRoot libcommon.Hash) string { - return fmt.Sprintf("%x.cache", blockRoot) -} - func (f *forkGraphDisk) readBeaconStateFromDisk(blockRoot libcommon.Hash, out *state.CachingBeaconState) (bs *state.CachingBeaconState, err error) { var file afero.File f.stateDumpLock.Lock() diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_test.go b/cl/phase1/forkchoice/fork_graph/fork_graph_test.go index ba507d7dba2..733b73a9ec3 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_test.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_test.go @@ -50,21 +50,21 @@ func TestForkGraphInDisk(t *testing.T) { require.NoError(t, utils.DecodeSSZSnappy(blockC, block2, int(clparams.Phase0Version))) require.NoError(t, utils.DecodeSSZSnappy(anchorState, anchor, int(clparams.Phase0Version))) emitter := beaconevents.NewEventEmitter() - graph := NewForkGraphDisk(anchorState, afero.NewMemMapFs(), beacon_router_configuration.RouterConfiguration{}, emitter) - _, status, err := graph.AddChainSegment(blockA, true, false) + graph := NewForkGraphDisk(anchorState, nil, afero.NewMemMapFs(), beacon_router_configuration.RouterConfiguration{}, emitter) + _, status, err := graph.AddChainSegment(blockA, true) require.NoError(t, err) require.Equal(t, status, Success) // Now make blockC a bad block blockC.Block.ProposerIndex = 81214459 // some invalid thing - _, status, err = graph.AddChainSegment(blockC, true, false) + _, status, err = graph.AddChainSegment(blockC, true) require.Error(t, err) require.Equal(t, status, InvalidBlock) // Save current state hash - _, status, err = graph.AddChainSegment(blockB, true, false) + _, status, err = graph.AddChainSegment(blockB, true) require.NoError(t, err) require.Equal(t, status, Success) // Try again with same should yield success - _, status, err = graph.AddChainSegment(blockB, true, false) + _, status, err = graph.AddChainSegment(blockB, true) require.NoError(t, err) require.Equal(t, status, PreValidated) } diff --git a/cl/spectest/consensus_tests/fork_choice.go b/cl/spectest/consensus_tests/fork_choice.go index 8f367e87722..e0cbe959e5c 100644 --- a/cl/spectest/consensus_tests/fork_choice.go +++ b/cl/spectest/consensus_tests/fork_choice.go @@ -209,7 +209,7 @@ func (b *ForkChoice) Run(t *testing.T, root fs.FS, c spectest.TestCase) (err err validatorMonitor := monitor.NewValidatorMonitor(false, nil, nil, nil) forkStore, err := forkchoice.NewForkChoiceStore( ethClock, anchorState, nil, pool.NewOperationsPool(&clparams.MainnetBeaconConfig), - fork_graph.NewForkGraphDisk(anchorState, afero.NewMemMapFs(), beacon_router_configuration.RouterConfiguration{}, emitters), + fork_graph.NewForkGraphDisk(anchorState, nil, afero.NewMemMapFs(), beacon_router_configuration.RouterConfiguration{}, emitters), emitters, synced_data.NewSyncedDataManager(&clparams.MainnetBeaconConfig, true), blobStorage, validatorMonitor, public_keys_registry.NewInMemoryPublicKeysRegistry(), false) require.NoError(t, err) forkStore.SetSynced(true) From c487e016723953c06b994acc38e3295dbc164c9b Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 03:22:11 +0100 Subject: [PATCH 29/33] save --- .../mock_services/synced_data_mock.go | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/cl/beacon/synced_data/mock_services/synced_data_mock.go b/cl/beacon/synced_data/mock_services/synced_data_mock.go index 6eebd97dbf0..e9ccd838127 100644 --- a/cl/beacon/synced_data/mock_services/synced_data_mock.go +++ b/cl/beacon/synced_data/mock_services/synced_data_mock.go @@ -462,3 +462,41 @@ func (c *MockSyncedDataViewHeadStateCall) DoAndReturn(f func(synced_data.ViewHea c.Call = c.Call.DoAndReturn(f) return c } + +// ViewPreviousHeadState mocks base method. +func (m *MockSyncedData) ViewPreviousHeadState(arg0 synced_data.ViewHeadStateFn) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ViewPreviousHeadState", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// ViewPreviousHeadState indicates an expected call of ViewPreviousHeadState. +func (mr *MockSyncedDataMockRecorder) ViewPreviousHeadState(arg0 any) *MockSyncedDataViewPreviousHeadStateCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ViewPreviousHeadState", reflect.TypeOf((*MockSyncedData)(nil).ViewPreviousHeadState), arg0) + return &MockSyncedDataViewPreviousHeadStateCall{Call: call} +} + +// MockSyncedDataViewPreviousHeadStateCall wrap *gomock.Call +type MockSyncedDataViewPreviousHeadStateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSyncedDataViewPreviousHeadStateCall) Return(arg0 error) *MockSyncedDataViewPreviousHeadStateCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSyncedDataViewPreviousHeadStateCall) Do(f func(synced_data.ViewHeadStateFn) error) *MockSyncedDataViewPreviousHeadStateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSyncedDataViewPreviousHeadStateCall) DoAndReturn(f func(synced_data.ViewHeadStateFn) error) *MockSyncedDataViewPreviousHeadStateCall { + c.Call = c.Call.DoAndReturn(f) + return c +} From c14b954337c759a67aebb976e4070f28efbcb2ac Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 03:27:28 +0100 Subject: [PATCH 30/33] save --- cl/phase1/forkchoice/fork_graph/fork_graph_disk.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go index 02e79c5254e..f7aeff38765 100644 --- a/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go +++ b/cl/phase1/forkchoice/fork_graph/fork_graph_disk.go @@ -356,7 +356,6 @@ func (f *forkGraphDisk) useCachedStateIfPossible(blockRoot libcommon.Hash, in *s } ok = true var err2 error - log.Warn("Using current cached state", "blockRoot", blockRoot, "headBlockRoot", libcommon.Hash(headBlockRoot)) if in != nil { err2 = headState.CopyInto(in) @@ -380,10 +379,9 @@ func (f *forkGraphDisk) useCachedStateIfPossible(blockRoot libcommon.Hash, in *s } if prevHeadBlockRoot != blockRoot { - log.Warn("Not Using cached state", "blockRoot", blockRoot, "prevHeadBlockRoot", libcommon.Hash(prevHeadBlockRoot)) + log.Warn("Not Using a cached beacon state", "blockRoot", blockRoot) return nil } - log.Warn("Using cached state", "blockRoot", blockRoot, "prevHeadBlockRoot", libcommon.Hash(prevHeadBlockRoot)) ok = true var err2 error From f78b0c6a6b9b30213da62302fc25634817efd433 Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 11:05:18 +0100 Subject: [PATCH 31/33] save --- cl/phase1/forkchoice/fork_choice_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cl/phase1/forkchoice/fork_choice_test.go b/cl/phase1/forkchoice/fork_choice_test.go index 199fa90a1c8..cdd59e1e06e 100644 --- a/cl/phase1/forkchoice/fork_choice_test.go +++ b/cl/phase1/forkchoice/fork_choice_test.go @@ -85,7 +85,7 @@ func TestForkChoiceBasic(t *testing.T) { pool := pool.NewOperationsPool(&clparams.MainnetBeaconConfig) emitters := beaconevents.NewEventEmitter() validatorMonitor := monitor.NewValidatorMonitor(false, nil, nil, nil) - store, err := forkchoice.NewForkChoiceStore(nil, anchorState, nil, pool, fork_graph.NewForkGraphDisk(anchorState, afero.NewMemMapFs(), beacon_router_configuration.RouterConfiguration{}, emitters), emitters, sd, nil, validatorMonitor, public_keys_registry.NewInMemoryPublicKeysRegistry(), false) + store, err := forkchoice.NewForkChoiceStore(nil, anchorState, nil, pool, fork_graph.NewForkGraphDisk(anchorState, nil, afero.NewMemMapFs(), beacon_router_configuration.RouterConfiguration{}, emitters), emitters, sd, nil, validatorMonitor, public_keys_registry.NewInMemoryPublicKeysRegistry(), false) require.NoError(t, err) // first steps store.OnTick(0) @@ -149,7 +149,7 @@ func TestForkChoiceChainBellatrix(t *testing.T) { pool := pool.NewOperationsPool(&clparams.MainnetBeaconConfig) emitters := beaconevents.NewEventEmitter() sd := synced_data.NewSyncedDataManager(&clparams.MainnetBeaconConfig, true) - store, err := forkchoice.NewForkChoiceStore(nil, anchorState, nil, pool, fork_graph.NewForkGraphDisk(anchorState, afero.NewMemMapFs(), beacon_router_configuration.RouterConfiguration{ + store, err := forkchoice.NewForkChoiceStore(nil, anchorState, nil, pool, fork_graph.NewForkGraphDisk(anchorState, nil, afero.NewMemMapFs(), beacon_router_configuration.RouterConfiguration{ Beacon: true, }, emitters), emitters, sd, nil, nil, public_keys_registry.NewInMemoryPublicKeysRegistry(), false) store.OnTick(2000) From bdd2b4460f430cbf70c82b64484c9138673ea0f9 Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 11:51:51 +0100 Subject: [PATCH 32/33] save --- cl/phase1/core/state/ssz_test.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cl/phase1/core/state/ssz_test.go b/cl/phase1/core/state/ssz_test.go index 3b12c0d642f..a9b53077751 100644 --- a/cl/phase1/core/state/ssz_test.go +++ b/cl/phase1/core/state/ssz_test.go @@ -17,7 +17,6 @@ package state import ( - "bytes" _ "embed" "testing" @@ -53,9 +52,4 @@ func TestBeaconStatePhase0EncodingDecoding(t *testing.T) { root, err := state.HashSSZ() require.NoError(t, err) require.Equal(t, libcommon.Hash(root), libcommon.HexToHash("0xf23b6266af40567516afeee250c1f8c06e9800f34a990a210604c380b506e053")) - // Lets test the caches too - var w bytes.Buffer - require.NoError(t, state.EncodeCaches(&w)) - - require.NoError(t, state.DecodeCaches(&w)) } From 9098697f87d69ba6f514cbcf4a9543e980b7d5cf Mon Sep 17 00:00:00 2001 From: Giulio Date: Mon, 3 Feb 2025 20:46:06 +0100 Subject: [PATCH 33/33] save --- cl/cltypes/solid/validator_set.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cl/cltypes/solid/validator_set.go b/cl/cltypes/solid/validator_set.go index 0f944350352..da5f0272392 100644 --- a/cl/cltypes/solid/validator_set.go +++ b/cl/cltypes/solid/validator_set.go @@ -156,7 +156,7 @@ func (v *ValidatorSet) CopyTo(t *ValidatorSet) { t.MerkleTree = nil } // skip copying (unsupported for phase0) - t.phase0Data = make([]Phase0Data, t.l) + t.phase0Data = make([]Phase0Data, v.l) copy(t.buffer, v.buffer) copy(t.attesterBits, v.attesterBits) t.attesterBits = t.attesterBits[:v.l]