Skip to content

feat(all): dynamic state sync #870

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 94 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
13bd773
wip: attempt to use upstream snap sync
Jan 29, 2025
97a3bf9
pass sender
Jan 29, 2025
3e8117e
reduce interval for testing
Jan 29, 2025
b64706e
debugging
Jan 29, 2025
e689c8f
accept EOF
Jan 29, 2025
783fdb1
debug
Jan 29, 2025
9582c84
connect it better
Jan 29, 2025
67dc7ba
debug
Jan 29, 2025
3640041
fix readBytes
Jan 29, 2025
c7a2200
use trie data for now
Jan 29, 2025
080ad82
hacking in some timeout
Jan 29, 2025
fe95c8c
try responding shorter
Jan 29, 2025
b3411a1
debug
Jan 29, 2025
e0bfcfb
try
Jan 29, 2025
83bbfad
debug
Jan 29, 2025
9f8fa8c
add retries
Jan 29, 2025
28b7f9d
patch in existing handler (server) logic
Jan 30, 2025
4c2749a
try
Jan 30, 2025
14a6407
try
Jan 30, 2025
b3ac9c5
try
Jan 30, 2025
9f614ba
debug
Jan 30, 2025
3380feb
try
Jan 30, 2025
1739b35
remove debug
Jan 30, 2025
c947e61
try
Jan 30, 2025
ac8a387
more changes
Jan 30, 2025
5369c80
make connector thread safe
Jan 30, 2025
47d367f
patch
Feb 1, 2025
07edc2d
remove unneeded change
Feb 1, 2025
dee2ec4
Prototyping block queueing
alarso16 Feb 20, 2025
019f059
Prototyped mechanism to switch pivot
alarso16 Feb 21, 2025
de215e1
Added more logging to see results
alarso16 Feb 21, 2025
43f9a34
Fixed hash passed to Syncer, will flush on pivot change
alarso16 Feb 21, 2025
95ca492
Added fixes from draft PR, changed incoming verification and acceptan…
alarso16 Feb 24, 2025
938a036
Commented out idea how to fix issue
alarso16 Feb 25, 2025
7d6c89c
Added logging used on test node
alarso16 Feb 25, 2025
5f1b790
Updated logging, ignore SetPreference, only update atomic state on re…
alarso16 Feb 25, 2025
a1627b2
Added simple queue to downloader for incoming blocks, flushing on piv…
alarso16 Feb 26, 2025
58cc3a8
Adjusted reindexing for buffer, adding additional error checking
alarso16 Feb 26, 2025
3562b00
Fixed buffer len error, added close channel, refactored for readability
alarso16 Feb 26, 2025
8c371fb
Adjusted logging to be more informative
alarso16 Feb 27, 2025
3e7bc69
Added additional logging, changed to pivot on multiple of interval
alarso16 Feb 27, 2025
d8e4b46
Big refactor of dynamic sync stuff - likely has bugs
alarso16 Feb 27, 2025
57d5a11
Fixes error where dl may be nil if not initialized
alarso16 Feb 27, 2025
5b44d2b
Reduce diff for unnecesary logs
alarso16 Feb 27, 2025
8b87bc6
Fixed some logging
alarso16 Feb 28, 2025
e7c93b2
Added a probably superfluous lock and logging for debugging
alarso16 Feb 28, 2025
ce0728f
Changed atomic lock to use channel, adjusted logging
alarso16 Feb 28, 2025
15bc3f3
Added additional logging for debugging
alarso16 Mar 3, 2025
43e2bbf
Fixed bug in finding evmBlock for specific hash
alarso16 Mar 3, 2025
e952bec
Updated to use on arbitrary blocks
alarso16 Mar 4, 2025
8eea877
Added debug logs to diagnose snapshot initialization and avoid deadlo…
alarso16 Mar 4, 2025
f864a9d
Added logging to debug snapshot beginning, added debug logging to hel…
alarso16 Mar 5, 2025
cf4e11b
Added graceful shutdown, removed unnecessary debug logs
alarso16 Mar 5, 2025
5ab02f0
Spot fixed some things related to acceptedDB to enable resuming
alarso16 Mar 5, 2025
ed101b3
Removed changes to pass useUpstream through to atomictrie, renabled a…
alarso16 Mar 6, 2025
c146ac1
Fixed atomic sync timing
alarso16 Mar 7, 2025
4f3b5e4
Fixed testing issues
alarso16 Mar 11, 2025
aa6b5a8
Merged libevm to allow testing on Fuji with Fortuna
alarso16 Mar 11, 2025
0d8e924
Fixed one lint issue and removed race for client.atomicDone
alarso16 Mar 11, 2025
ad5bbce
Fixed potential race condition in logging
alarso16 Mar 11, 2025
02e1903
Fixed concurrency issue in snap sync test and learned alphabetical order
alarso16 Mar 11, 2025
319e2e5
Changed timeout for test to check if this is issue, removed unnecessa…
alarso16 Mar 12, 2025
49d76e5
Fixed lint error, removed unnecessary operations and logging
alarso16 Mar 12, 2025
fbfe962
Slightly refactored Downloader to use interface outside of statesync …
alarso16 Mar 13, 2025
76eb41a
Removed unnecessary operations to blockchain, which required changing…
alarso16 Mar 13, 2025
fc64ed8
Separated finalization logic for atomic and state syncs
alarso16 Mar 14, 2025
d1b390a
Fixed static sync test errors, improved error messages
alarso16 Mar 14, 2025
e3d18f8
Added more shared-memory handling to prototype restarts.
alarso16 Mar 17, 2025
e996b5e
Added prototype for handling after vm handling
alarso16 Mar 17, 2025
8157786
Attempt to remove trie node check
alarso16 Mar 17, 2025
f009d1d
Fixed small trie indexing, lowered excessive logs
alarso16 Mar 19, 2025
89d294c
Updated block handling to ensure shared memory/atomic ops don't occur…
alarso16 Mar 21, 2025
4327cb1
Regenerate snapshot on snap sync completion (ugh)
alarso16 Mar 21, 2025
d86bd46
Comparisons for block height in shared memory options were incorrect
alarso16 Mar 21, 2025
b261571
Added upstream changes to snap-sync to correct stack trie usage for p…
alarso16 Mar 25, 2025
3e20c3a
Updated config to allow path-based state sync
alarso16 Mar 25, 2025
dadec58
Added copyright, separated shared memory and blockchain state on init…
alarso16 Mar 26, 2025
02dd991
Added error condition to ensure path scheme doesn't crash from prunin…
alarso16 Mar 27, 2025
6c72f06
Improved readability, fixed error attempting to verify snapshot
alarso16 Mar 27, 2025
6fabf9a
Fix verify error, downgrade log level
alarso16 Mar 28, 2025
ff076ca
Fixed initialization issue for pathdb
alarso16 Mar 28, 2025
9e8e88f
Refactored downloader to abstract snapsync operations to the same int…
alarso16 Apr 8, 2025
c08cc4b
Small logging changes, fixed channel errors
alarso16 Apr 8, 2025
1743861
Small bug fixes, comments + readability
alarso16 Apr 9, 2025
31c7b5b
Added cancelOnce to snap_manager, improved handling for different db …
alarso16 Apr 9, 2025
c6ba014
Address comments
alarso16 Apr 10, 2025
a454725
Addressed more comments
alarso16 Apr 10, 2025
27c6ae9
Fixed bug on finalization
alarso16 Apr 11, 2025
35d0911
Merged w/ maters, adjusted calls to reflect libevm structure
alarso16 Apr 11, 2025
d7491b2
Refactored to use syncQueue decoupled from dynamic syncer
alarso16 Apr 15, 2025
617485d
fix bugs from refactor
alarso16 Apr 15, 2025
dce3c1d
Remove unnecessary diffs from master
alarso16 Apr 15, 2025
0f58060
Bug fixes
alarso16 Apr 16, 2025
eef1a33
Fixed finalization bug, cleaned up Verify/Accept calls
alarso16 Apr 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions core/blockchain_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,20 @@ func (bc *BlockChain) HasBlockAndState(hash common.Hash, number uint64) bool {
return bc.HasState(block.Root())
}

// ContractCodeWithPrefix retrieves a blob of data associated with a contract
// hash either from ephemeral in-memory cache, or from persistent storage.
//
// If the code doesn't exist in the in-memory cache, check the storage with
// new code scheme.
func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) ([]byte, error) {
type codeReader interface {
ContractCodeWithPrefix(address common.Address, codeHash common.Hash) ([]byte, error)
}
// TODO(rjl493456442) The associated account address is also required
// in Verkle scheme. Fix it once snap-sync is supported for Verkle.
return bc.stateCache.(codeReader).ContractCodeWithPrefix(common.Address{}, hash)
}

// State returns a new mutable state based on the current HEAD block.
func (bc *BlockChain) State() (*state.StateDB, error) {
return bc.StateAt(bc.CurrentBlock().Root)
Expand Down
11 changes: 6 additions & 5 deletions core/state/snapshot/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,15 +372,16 @@
}

func stackTrieGenerate(db ethdb.KeyValueWriter, scheme string, owner common.Hash, in chan trieKV, out chan common.Hash) {
options := trie.NewStackTrieOptions()
var onTrieNode trie.OnTrieNode

Check failure on line 375 in core/state/snapshot/conversion.go

View workflow job for this annotation

GitHub Actions / Lint

undefined: trie.OnTrieNode) (typecheck)

Check failure on line 375 in core/state/snapshot/conversion.go

View workflow job for this annotation

GitHub Actions / Golang Unit Tests (macos-latest)

undefined: trie.OnTrieNode

Check failure on line 375 in core/state/snapshot/conversion.go

View workflow job for this annotation

GitHub Actions / Golang Unit Tests (ubuntu-22.04)

undefined: trie.OnTrieNode

Check failure on line 375 in core/state/snapshot/conversion.go

View workflow job for this annotation

GitHub Actions / Golang Unit Tests (ubuntu-latest)

undefined: trie.OnTrieNode

Check failure on line 375 in core/state/snapshot/conversion.go

View workflow job for this annotation

GitHub Actions / Golang Unit Tests (windows-latest)

undefined: trie.OnTrieNode
if db != nil {
options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) {
onTrieNode = func(path []byte, hash common.Hash, blob []byte) {
rawdb.WriteTrieNode(db, owner, path, hash, blob, scheme)
})
}
}
t := trie.NewStackTrie(options)
t := trie.NewStackTrie(onTrieNode)

for leaf := range in {
t.Update(leaf.key[:], leaf.value)
}
out <- t.Commit()
out <- t.Hash()
}
30 changes: 15 additions & 15 deletions core/state/snapshot/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func testGeneration(t *testing.T, scheme string) {
case <-time.After(250 * time.Millisecond):
t.Errorf("Snapshot generation failed")
}
checkSnapRoot(t, snap, root)
checkSnapRoot(t, snap, root, scheme)

// Signal abortion to the generator and wait for it to tear down
stop := make(chan struct{})
Expand Down Expand Up @@ -131,24 +131,24 @@ func testGenerateExistentState(t *testing.T, scheme string) {
case <-time.After(250 * time.Millisecond):
t.Errorf("Snapshot generation failed")
}
checkSnapRoot(t, snap, root)
checkSnapRoot(t, snap, root, scheme)

// Signal abortion to the generator and wait for it to tear down
stop := make(chan struct{})
snap.genAbort <- stop
<-stop
}

func checkSnapRoot(t *testing.T, snap *diskLayer, trieRoot common.Hash) {
func checkSnapRoot(t *testing.T, snap *diskLayer, trieRoot common.Hash, scheme string) {
t.Helper()
accIt := snap.AccountIterator(common.Hash{})
defer accIt.Release()
snapRoot, err := generateTrieRoot(nil, "", accIt, common.Hash{}, stackTrieGenerate,
snapRoot, err := generateTrieRoot(nil, scheme, accIt, common.Hash{}, stackTrieGenerate,
func(db ethdb.KeyValueWriter, accountHash, codeHash common.Hash, stat *generateStats) (common.Hash, error) {
storageIt, _ := snap.StorageIterator(accountHash, common.Hash{})
defer storageIt.Release()

hash, err := generateTrieRoot(nil, "", storageIt, accountHash, stackTrieGenerate, nil, stat, false)
hash, err := generateTrieRoot(nil, scheme, storageIt, accountHash, stackTrieGenerate, nil, stat, false)
if err != nil {
return common.Hash{}, err
}
Expand Down Expand Up @@ -347,7 +347,7 @@ func testGenerateExistentStateWithWrongStorage(t *testing.T, scheme string) {
case <-time.After(250 * time.Millisecond):
t.Errorf("Snapshot generation failed")
}
checkSnapRoot(t, snap, root)
checkSnapRoot(t, snap, root, scheme)
// Signal abortion to the generator and wait for it to tear down
stop := make(chan struct{})
snap.genAbort <- stop
Expand Down Expand Up @@ -409,7 +409,7 @@ func testGenerateExistentStateWithWrongAccounts(t *testing.T, scheme string) {
case <-time.After(250 * time.Millisecond):
t.Errorf("Snapshot generation failed")
}
checkSnapRoot(t, snap, root)
checkSnapRoot(t, snap, root, scheme)

// Signal abortion to the generator and wait for it to tear down
stop := make(chan struct{})
Expand Down Expand Up @@ -600,7 +600,7 @@ func testGenerateWithExtraAccounts(t *testing.T, scheme string) {
case <-time.After(250 * time.Millisecond):
t.Errorf("Snapshot generation failed")
}
checkSnapRoot(t, snap, root)
checkSnapRoot(t, snap, root, scheme)

// Signal abortion to the generator and wait for it to tear down
stop := make(chan struct{})
Expand Down Expand Up @@ -662,7 +662,7 @@ func testGenerateWithManyExtraAccounts(t *testing.T, scheme string) {
case <-time.After(5 * time.Second):
t.Errorf("Snapshot generation failed")
}
checkSnapRoot(t, snap, root)
checkSnapRoot(t, snap, root, scheme)
// Signal abortion to the generator and wait for it to tear down
stop := make(chan struct{})
snap.genAbort <- stop
Expand Down Expand Up @@ -710,7 +710,7 @@ func testGenerateWithExtraBeforeAndAfter(t *testing.T, scheme string) {
case <-time.After(250 * time.Millisecond):
t.Errorf("Snapshot generation failed")
}
checkSnapRoot(t, snap, root)
checkSnapRoot(t, snap, root, scheme)
// Signal abortion to the generator and wait for it to tear down
stop := make(chan struct{})
snap.genAbort <- stop
Expand Down Expand Up @@ -749,7 +749,7 @@ func testGenerateWithMalformedSnapdata(t *testing.T, scheme string) {
case <-time.After(250 * time.Millisecond):
t.Errorf("Snapshot generation failed")
}
checkSnapRoot(t, snap, root)
checkSnapRoot(t, snap, root, scheme)
// Signal abortion to the generator and wait for it to tear down
stop := make(chan struct{})
snap.genAbort <- stop
Expand Down Expand Up @@ -784,7 +784,7 @@ func testGenerateFromEmptySnap(t *testing.T, scheme string) {
case <-time.After(1 * time.Second):
t.Errorf("Snapshot generation failed")
}
checkSnapRoot(t, snap, root)
checkSnapRoot(t, snap, root, scheme)
// Signal abortion to the generator and wait for it to tear down
stop := make(chan struct{})
snap.genAbort <- stop
Expand Down Expand Up @@ -834,7 +834,7 @@ func testGenerateWithIncompleteStorage(t *testing.T, scheme string) {
case <-time.After(250 * time.Millisecond):
t.Errorf("Snapshot generation failed")
}
checkSnapRoot(t, snap, root)
checkSnapRoot(t, snap, root, scheme)
// Signal abortion to the generator and wait for it to tear down
stop := make(chan struct{})
snap.genAbort <- stop
Expand Down Expand Up @@ -929,7 +929,7 @@ func testGenerateCompleteSnapshotWithDanglingStorage(t *testing.T, scheme string
case <-time.After(3 * time.Second):
t.Errorf("Snapshot generation failed")
}
checkSnapRoot(t, snap, root)
checkSnapRoot(t, snap, root, scheme)

// Signal abortion to the generator and wait for it to tear down
stop := make(chan struct{})
Expand Down Expand Up @@ -966,7 +966,7 @@ func testGenerateBrokenSnapshotWithDanglingStorage(t *testing.T, scheme string)
case <-time.After(3 * time.Second):
t.Errorf("Snapshot generation failed")
}
checkSnapRoot(t, snap, root)
checkSnapRoot(t, snap, root, scheme)

// Signal abortion to the generator and wait for it to tear down
stop := make(chan struct{})
Expand Down
32 changes: 32 additions & 0 deletions eth/protocols/snap/discovery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2020 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package snap

import (
"github.com/ava-labs/libevm/rlp"
)

// enrEntry is the ENR entry which advertises `snap` protocol on the discovery.
type enrEntry struct {
// Ignore additional fields (for forward compatibility).
Rest []rlp.RawValue `rlp:"tail"`
}

// ENRKey implements enr.Entry.
func (e enrEntry) ENRKey() string {
return "snap"
}
Loading
Loading