Skip to content

Commit e55f444

Browse files
karalabecp-wjhan
authored andcommitted
trie: check childrens' existence concurrently for snap heal (ethereum#25694)
1 parent 908f152 commit e55f444

File tree

1 file changed

+39
-18
lines changed

1 file changed

+39
-18
lines changed

trie/sync.go

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package trie
1919
import (
2020
"errors"
2121
"fmt"
22+
"sync"
2223

2324
"github.com/ethereum/go-ethereum/common"
2425
"github.com/ethereum/go-ethereum/common/prque"
@@ -381,26 +382,26 @@ func (s *Sync) scheduleCodeRequest(req *codeRequest) {
381382
// retrieval scheduling.
382383
func (s *Sync) children(req *nodeRequest, object node) ([]*nodeRequest, error) {
383384
// Gather all the children of the node, irrelevant whether known or not
384-
type child struct {
385+
type childNode struct {
385386
path []byte
386387
node node
387388
}
388-
var children []child
389+
var children []childNode
389390

390391
switch node := (object).(type) {
391392
case *shortNode:
392393
key := node.Key
393394
if hasTerm(key) {
394395
key = key[:len(key)-1]
395396
}
396-
children = []child{{
397+
children = []childNode{{
397398
node: node.Val,
398399
path: append(append([]byte(nil), req.path...), key...),
399400
}}
400401
case *fullNode:
401402
for i := 0; i < 17; i++ {
402403
if node.Children[i] != nil {
403-
children = append(children, child{
404+
children = append(children, childNode{
404405
node: node.Children[i],
405406
path: append(append([]byte(nil), req.path...), byte(i)),
406407
})
@@ -410,7 +411,10 @@ func (s *Sync) children(req *nodeRequest, object node) ([]*nodeRequest, error) {
410411
panic(fmt.Sprintf("unknown node: %+v", node))
411412
}
412413
// Iterate over the children, and request all unknown ones
413-
requests := make([]*nodeRequest, 0, len(children))
414+
var (
415+
missing = make(chan *nodeRequest, len(children))
416+
pending sync.WaitGroup
417+
)
414418
for _, child := range children {
415419
// Notify any external watcher of a new key/value node
416420
if req.callback != nil {
@@ -433,19 +437,36 @@ func (s *Sync) children(req *nodeRequest, object node) ([]*nodeRequest, error) {
433437
if s.membatch.hasNode(child.path) {
434438
continue
435439
}
436-
// If database says duplicate, then at least the trie node is present
437-
// and we hold the assumption that it's NOT legacy contract code.
438-
chash := common.BytesToHash(node)
439-
if rawdb.HasTrieNode(s.database, chash) {
440-
continue
441-
}
442-
// Locally unknown node, schedule for retrieval
443-
requests = append(requests, &nodeRequest{
444-
path: child.path,
445-
hash: chash,
446-
parent: req,
447-
callback: req.callback,
448-
})
440+
// Check the presence of children concurrently
441+
pending.Add(1)
442+
go func(child childNode) {
443+
defer pending.Done()
444+
445+
// If database says duplicate, then at least the trie node is present
446+
// and we hold the assumption that it's NOT legacy contract code.
447+
chash := common.BytesToHash(node)
448+
if rawdb.HasTrieNode(s.database, chash) {
449+
return
450+
}
451+
// Locally unknown node, schedule for retrieval
452+
missing <- &nodeRequest{
453+
path: child.path,
454+
hash: chash,
455+
parent: req,
456+
callback: req.callback,
457+
}
458+
}(child)
459+
}
460+
}
461+
pending.Wait()
462+
463+
requests := make([]*nodeRequest, 0, len(children))
464+
for done := false; !done; {
465+
select {
466+
case miss := <-missing:
467+
requests = append(requests, miss)
468+
default:
469+
done = true
449470
}
450471
}
451472
return requests, nil

0 commit comments

Comments
 (0)