core/state: address comments

This commit is contained in:
rjl493456442 2020-04-29 10:24:05 +08:00
parent ee2bca5f5c
commit 2021cd8461
3 changed files with 28 additions and 22 deletions

View file

@ -130,7 +130,7 @@ func (stat *generateStats) report() {
ctx = append(ctx, []interface{}{"slots", stat.slots}...) ctx = append(ctx, []interface{}{"slots", stat.slots}...)
} }
ctx = append(ctx, []interface{}{"elapsed", common.PrettyDuration(time.Since(stat.start))}...) ctx = append(ctx, []interface{}{"elapsed", common.PrettyDuration(time.Since(stat.start))}...)
log.Info("Generating trie hash from snapshot", ctx) log.Info("Generating trie hash from snapshot", ctx...)
} }
// reportDone prints the last log when the whole generation is finished. // reportDone prints the last log when the whole generation is finished.
@ -144,7 +144,7 @@ func (stat *generateStats) reportDone() {
ctx = append(ctx, []interface{}{"slots", stat.slots}...) ctx = append(ctx, []interface{}{"slots", stat.slots}...)
} }
ctx = append(ctx, []interface{}{"elapsed", common.PrettyDuration(time.Since(stat.start))}...) ctx = append(ctx, []interface{}{"elapsed", common.PrettyDuration(time.Since(stat.start))}...)
log.Info("Generated trie hash from snapshot", ctx) log.Info("Generated trie hash from snapshot", ctx...)
} }
// generateTrieRoot generates the trie hash based on the snapshot iterator. // generateTrieRoot generates the trie hash based on the snapshot iterator.
@ -154,6 +154,7 @@ func generateTrieRoot(it Iterator, account common.Hash, generatorFn trieGenerato
var ( var (
in = make(chan trieKV) // chan to pass leaves in = make(chan trieKV) // chan to pass leaves
out = make(chan common.Hash, 1) // chan to collect result out = make(chan common.Hash, 1) // chan to collect result
stoplog = make(chan bool, 1) // 1-size buffer, works when logging is not enabled
wg sync.WaitGroup wg sync.WaitGroup
) )
// Spin up a go-routine for trie hash re-generation // Spin up a go-routine for trie hash re-generation
@ -165,28 +166,36 @@ func generateTrieRoot(it Iterator, account common.Hash, generatorFn trieGenerato
// Spin up a go-routine for progress logging // Spin up a go-routine for progress logging
if report && stats != nil { if report && stats != nil {
stopLogging := make(chan struct{}) wg.Add(1)
defer close(stopLogging)
go func() { go func() {
defer wg.Done() defer wg.Done()
timer := time.NewTimer(0) timer := time.NewTimer(0)
defer timer.Stop() defer timer.Stop()
<-timer.C // discard the initial tick
for { for {
select { select {
case <-timer.C: case <-timer.C:
stats.report() stats.report()
timer.Reset(time.Second * 8) timer.Reset(time.Second * 8)
case <-stopLogging: case success := <-stoplog:
if success {
stats.reportDone() stats.reportDone()
}
return return
} }
} }
}() }()
} }
// stop is a helper function to shutdown the background threads
// and return the re-generated trie hash.
stop := func(success bool) common.Hash {
close(in)
result := <-out
stoplog <- success
wg.Wait()
return result
}
var ( var (
logged = time.Now() logged = time.Now()
processed = uint64(0) processed = uint64(0)
@ -203,31 +212,31 @@ func generateTrieRoot(it Iterator, account common.Hash, generatorFn trieGenerato
if leafCallback == nil { if leafCallback == nil {
fullData, err = FullAccountRLP(it.(AccountIterator).Account()) fullData, err = FullAccountRLP(it.(AccountIterator).Account())
if err != nil { if err != nil {
close(in) stop(false)
return common.Hash{}, err return common.Hash{}, err
} }
} else { } else {
account, err := FullAccount(it.(AccountIterator).Account()) account, err := FullAccount(it.(AccountIterator).Account())
if err != nil { if err != nil {
close(in) stop(false)
return common.Hash{}, err return common.Hash{}, err
} }
// Apply the leaf callback. Normally the callback is used to traverse // Apply the leaf callback. Normally the callback is used to traverse
// the storage trie and re-generate the subtrie root. // the storage trie and re-generate the subtrie root.
subroot := leafCallback(it.Hash(), stats) subroot := leafCallback(it.Hash(), stats)
if !bytes.Equal(account.Root, subroot.Bytes()) { if !bytes.Equal(account.Root, subroot.Bytes()) {
close(in) stop(false)
return common.Hash{}, fmt.Errorf("invalid subroot(%x), want %x, got %x", it.Hash(), account.Root, subroot) return common.Hash{}, fmt.Errorf("invalid subroot(%x), want %x, got %x", it.Hash(), account.Root, subroot)
} }
fullData, err = rlp.EncodeToBytes(account) fullData, err = rlp.EncodeToBytes(account)
if err != nil { if err != nil {
close(in) stop(false)
return common.Hash{}, err return common.Hash{}, err
} }
} }
leaf = trieKV{it.Hash(), fullData} leaf = trieKV{it.Hash(), fullData}
} else { } else {
leaf = trieKV{it.Hash(), it.(StorageIterator).Slot()} leaf = trieKV{it.Hash(), common.CopyBytes(it.(StorageIterator).Slot())}
} }
in <- leaf in <- leaf
@ -251,9 +260,7 @@ func generateTrieRoot(it Iterator, account common.Hash, generatorFn trieGenerato
stats.progress(0, processed, account, last) stats.progress(0, processed, account, last)
} }
} }
close(in) result := stop(true)
result := <-out
wg.Wait()
return result, nil return result, nil
} }

View file

@ -69,7 +69,6 @@ func TestMergeBasics(t *testing.T) {
accounts[h] = data accounts[h] = data
if rand.Intn(4) == 0 { if rand.Intn(4) == 0 {
destructs[h] = struct{}{} destructs[h] = struct{}{}
delete(destructs, h)
} }
if rand.Intn(2) == 0 { if rand.Intn(2) == 0 {
accStorage := make(map[common.Hash][]byte) accStorage := make(map[common.Hash][]byte)

View file

@ -79,8 +79,8 @@ func (dl *diffLayer) initBinaryStorageIterator(account common.Hash) Iterator {
l.bDone = true l.bDone = true
return l return l
} }
// Even if the storage in the parent layer is destructed, // The parent is disk layer, don't need to take care "destructed"
// still return the normal iterator with both-branch enabled. // anymore.
b, _ := dl.Parent().StorageIterator(account, common.Hash{}) b, _ := dl.Parent().StorageIterator(account, common.Hash{})
l := &binaryIterator{ l := &binaryIterator{
a: a, a: a,