-
Notifications
You must be signed in to change notification settings - Fork 20.2k
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
eth/protocols/snap: fix the flaws in the snap sync #22553
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One nitpick
One thing I've been testing with (no issues found so far) is adding a func verifyTrie(db ethdb.KeyValueStore, root common.Hash, t *testing.T) {
triedb := trie.NewDatabase(db)
accTrie, err := trie.New(root, triedb)
if err != nil {
t.Fatal(err)
}
accounts, slots := 0, 0
accIt := trie.NewIterator(accTrie.NodeIterator(nil))
for accIt.Next() {
var acc struct {
Nonce uint64
Balance *big.Int
Root common.Hash
CodeHash []byte
}
if err := rlp.DecodeBytes(accIt.Value, &acc); err != nil {
log.Crit("Invalid account encountered during snapshot creation", "err", err)
}
accounts++
if acc.Root != emptyRoot {
storeTrie, err := trie.NewSecure(acc.Root, triedb)
if err != nil {
t.Fatal(err)
}
storeIt := trie.NewIterator(storeTrie.NodeIterator(nil))
for storeIt.Next() {
slots++
}
if err := storeIt.Err; err != nil {
t.Fatal(err)
}
}
}
if err := accIt.Err; err != nil {
t.Fatal(err)
}
t.Logf("accounts: %d, slots: %d", accounts, slots)
} |
Should we fix the sender/part too? diff --git a/eth/protocols/snap/handler.go b/eth/protocols/snap/handler.go
index b9515b8a39..0b4f83a75e 100644
--- a/eth/protocols/snap/handler.go
+++ b/eth/protocols/snap/handler.go
@@ -256,8 +256,13 @@ func handleMessage(backend Backend, peer *Peer) error {
var (
storage []*StorageData
last common.Hash
+ aborted = false
)
- for it.Next() && size < hardLimit {
+ for it.Next() {
+ if size > hardLimit {
+ aborted = true
+ break
+ }
hash, slot := it.Hash(), common.CopyBytes(it.Slot())
// Track the returned interval for the Merkle proofs
@@ -280,7 +285,7 @@ func handleMessage(backend Backend, peer *Peer) error {
// Generate the Merkle proofs for the first and last storage slot, but
// only if the response was capped. If the entire storage trie included
// in the response, no need for any proofs.
- if origin != (common.Hash{}) || size >= hardLimit {
+ if origin != (common.Hash{}) || aborted {
// Request started at a non-zero hash or was capped prematurely, add
// the endpoint Merkle proofs
accTrie, err := trie.New(req.Root, backend.Chain().StateCache().TrieDB())
|
@holiman I think if the last slot exceeds the limit, we should also generate the proof. Please check if this version works for you diff --git a/eth/protocols/snap/handler.go b/eth/protocols/snap/handler.go
index b9515b8a3..bd2964e91 100644
--- a/eth/protocols/snap/handler.go
+++ b/eth/protocols/snap/handler.go
@@ -256,8 +256,13 @@ func handleMessage(backend Backend, peer *Peer) error {
var (
storage []*StorageData
last common.Hash
+ abort bool
)
- for it.Next() && size < hardLimit {
+ for it.Next() {
+ if size >= hardLimit {
+ abort = true
+ break
+ }
hash, slot := it.Hash(), common.CopyBytes(it.Slot())
// Track the returned interval for the Merkle proofs
@@ -271,6 +276,7 @@ func handleMessage(backend Backend, peer *Peer) error {
})
// If we've exceeded the request threshold, abort
if bytes.Compare(hash[:], limit[:]) >= 0 {
+ abort = true
break
}
}
@@ -280,7 +286,7 @@ func handleMessage(backend Backend, peer *Peer) error {
// Generate the Merkle proofs for the first and last storage slot, but
// only if the response was capped. If the entire storage trie included
// in the response, no need for any proofs.
- if origin != (common.Hash{}) || size >= hardLimit {
+ if abort {
// Request started at a non-zero hash or was capped prematurely, add
// the endpoint Merkle proofs
accTrie, err := trie.New(req.Root, backend.Chain().StateCache().TrieDB())
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
J'approuf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
* eth/protocols/snap: fix snap sync * eth/protocols/snap: fix tests * eth: fix tiny * eth: update tests * eth: update tests * core/state/snapshot: testcase for ethereum#22534 * eth/protocols/snap: fix boundary loss on full-but-proven range * core/state/snapshot: lintfix * eth: address comment * eth: fix handler Co-authored-by: Martin Holst Swende <martin@swende.se> Co-authored-by: Péter Szilágyi <peterke@gmail.com>
No description provided.