mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
eth/protocols/snap: pass the tries forward
This commit is contained in:
parent
ce41860874
commit
9d30ad513b
1 changed files with 32 additions and 5 deletions
|
|
@ -42,6 +42,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/p2p/msgrate"
|
"github.com/ethereum/go-ethereum/p2p/msgrate"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
|
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||||
"golang.org/x/crypto/sha3"
|
"golang.org/x/crypto/sha3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -224,6 +225,8 @@ type storageResponse struct {
|
||||||
slots [][][]byte // Storage slot values in the returned range
|
slots [][][]byte // Storage slot values in the returned range
|
||||||
|
|
||||||
cont bool // Whether the last storage range has a continuation
|
cont bool // Whether the last storage range has a continuation
|
||||||
|
|
||||||
|
tr *trie.Trie // Trie of any non-complete storage chuunk.
|
||||||
}
|
}
|
||||||
|
|
||||||
// trienodeHealRequest tracks a pending state trie request to ensure responses
|
// trienodeHealRequest tracks a pending state trie request to ensure responses
|
||||||
|
|
@ -2086,11 +2089,32 @@ func (s *Syncer) processStorageResponse(res *storageResponse) {
|
||||||
for j := 0; j < len(res.hashes[i]); j++ {
|
for j := 0; j < len(res.hashes[i]); j++ {
|
||||||
rawdb.WriteStorageSnapshot(batch, account, res.hashes[i][j], res.slots[i][j])
|
rawdb.WriteStorageSnapshot(batch, account, res.hashes[i][j], res.slots[i][j])
|
||||||
|
|
||||||
|
_, nodes, err := res.tr.Commit(false)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Failed to commit stack slots", "err", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// OBS! TODO: Do not write incomplete nodes
|
||||||
|
// - nodes which contain unresolved hashes,
|
||||||
|
// - or their parents,
|
||||||
|
var boundaryRight []byte
|
||||||
|
//var boundaryLeft []byte TODO
|
||||||
|
|
||||||
|
nodes.ForEachWithOrder(func(path string, n *trienode.Node) {
|
||||||
|
if boundaryRight == nil {
|
||||||
|
boundaryRight = []byte(path)
|
||||||
|
}
|
||||||
|
if bytes.HasPrefix(boundaryRight, []byte(path)) {
|
||||||
|
return // a right-hand boundary
|
||||||
|
}
|
||||||
|
rawdb.WriteTrieNode(batch, nodes.Owner, []byte(path), n.Hash, n.Blob, s.scheme)
|
||||||
|
})
|
||||||
|
|
||||||
// If we're storing large contracts, generate the trie nodes
|
// If we're storing large contracts, generate the trie nodes
|
||||||
// on the fly to not trash the gluing points
|
// on the fly to not trash the gluing points
|
||||||
if i == len(res.hashes)-1 && res.subTask != nil {
|
//if i == len(res.hashes)-1 && res.subTask != nil {
|
||||||
res.subTask.genTrie.Update(res.hashes[i][j][:], res.slots[i][j])
|
// res.subTask.genTrie.Update(res.hashes[i][j][:], res.slots[i][j])
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Large contracts could have generated new trie nodes, flush them to disk
|
// Large contracts could have generated new trie nodes, flush them to disk
|
||||||
|
|
@ -2632,7 +2656,7 @@ func (s *Syncer) OnStorage(peer SyncPeer, id uint64, hashes [][]common.Hash, slo
|
||||||
|
|
||||||
// Reconstruct the partial tries from the response and verify them
|
// Reconstruct the partial tries from the response and verify them
|
||||||
var cont bool
|
var cont bool
|
||||||
|
var tr *trie.Trie
|
||||||
for i := 0; i < len(hashes); i++ {
|
for i := 0; i < len(hashes); i++ {
|
||||||
// Convert the keys and proofs into an internal format
|
// Convert the keys and proofs into an internal format
|
||||||
keys := make([][]byte, len(hashes[i]))
|
keys := make([][]byte, len(hashes[i]))
|
||||||
|
|
@ -2640,6 +2664,8 @@ func (s *Syncer) OnStorage(peer SyncPeer, id uint64, hashes [][]common.Hash, slo
|
||||||
keys[j] = common.CopyBytes(key[:])
|
keys[j] = common.CopyBytes(key[:])
|
||||||
}
|
}
|
||||||
nodes := make(light.NodeList, 0, len(proof))
|
nodes := make(light.NodeList, 0, len(proof))
|
||||||
|
// Proofs always concern only the _last_ account (which, in the case
|
||||||
|
// of a non-zero origin, is also the first).
|
||||||
if i == len(hashes)-1 {
|
if i == len(hashes)-1 {
|
||||||
for _, node := range proof {
|
for _, node := range proof {
|
||||||
nodes = append(nodes, node)
|
nodes = append(nodes, node)
|
||||||
|
|
@ -2664,7 +2690,7 @@ func (s *Syncer) OnStorage(peer SyncPeer, id uint64, hashes [][]common.Hash, slo
|
||||||
if len(keys) > 0 {
|
if len(keys) > 0 {
|
||||||
end = keys[len(keys)-1]
|
end = keys[len(keys)-1]
|
||||||
}
|
}
|
||||||
cont, trie, err = trie.VerifyRangeProof(req.roots[i], req.origin[:], end, keys, slots[i], proofdb)
|
cont, tr, err = trie.VerifyRangeProof(req.roots[i], req.origin[:], end, keys, slots[i], proofdb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.scheduleRevertStorageRequest(req) // reschedule request
|
s.scheduleRevertStorageRequest(req) // reschedule request
|
||||||
logger.Warn("Storage range failed proof", "err", err)
|
logger.Warn("Storage range failed proof", "err", err)
|
||||||
|
|
@ -2681,6 +2707,7 @@ func (s *Syncer) OnStorage(peer SyncPeer, id uint64, hashes [][]common.Hash, slo
|
||||||
hashes: hashes,
|
hashes: hashes,
|
||||||
slots: slots,
|
slots: slots,
|
||||||
cont: cont,
|
cont: cont,
|
||||||
|
tr: tr,
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
case req.deliver <- response:
|
case req.deliver <- response:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue