core/state/snapshot tests: fix testcase panic

This commit is contained in:
Martin Holst Swende 2020-02-11 16:23:05 +01:00
parent 15ed974487
commit f54d4a7d8e
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
3 changed files with 58 additions and 37 deletions

View file

@ -27,13 +27,11 @@ type leaf struct {
value []byte value []byte
} }
// trieGenerator is a very basic hexary trie builder which uses the same Trie type trieGeneratorFn func(in chan (leaf), out chan (common.Hash))
// as the rest of geth, with no enhancements or optimizations
type trieGenerator struct{}
//BenchmarkTrieGeneration/4K-8 73 15309586 ns/op 6614793 B/op 55006 allocs/op // PruneGenerate is a hexary trie builder which collapses old nodes, but is still
//BenchmarkTrieGeneration/10K-8 28 39538254 ns/op 16539589 B/op 137515 allocs/op // based on more or less the ordinary trie builder
func (gen *trieGenerator) Generate3(in chan (leaf), out chan (common.Hash)) { func PruneGenerate(in chan (leaf), out chan (common.Hash)) {
t := trie.NewHashTrie() t := trie.NewHashTrie()
for leaf := range in { for leaf := range in {
t.TryUpdate(leaf.key[:], leaf.value) t.TryUpdate(leaf.key[:], leaf.value)
@ -41,9 +39,9 @@ func (gen *trieGenerator) Generate3(in chan (leaf), out chan (common.Hash)) {
out <- t.Hash() out <- t.Hash()
} }
//BenchmarkTrieGeneration/4K-6 94 12598506 ns/op 6162370 B/op 57921 allocs/op // StdGenerate is a very basic hexary trie builder which uses the same Trie
//BenchmarkTrieGeneration/10K-6 37 33790908 ns/op 17278751 B/op 151002 allocs/op // as the rest of geth, with no enhancements or optimizations
func (gen *trieGenerator) Generate2(in chan (leaf), out chan (common.Hash)) { func StdGenerate(in chan (leaf), out chan (common.Hash)) {
t, _ := trie.New(common.Hash{}, trie.NewDatabase(memorydb.New())) t, _ := trie.New(common.Hash{}, trie.NewDatabase(memorydb.New()))
for leaf := range in { for leaf := range in {
t.TryUpdate(leaf.key[:], leaf.value) t.TryUpdate(leaf.key[:], leaf.value)
@ -51,9 +49,9 @@ func (gen *trieGenerator) Generate2(in chan (leaf), out chan (common.Hash)) {
out <- t.Hash() out <- t.Hash()
} }
//BenchmarkTrieGeneration/4K-6 115 12755614 ns/op 2303051 B/op 42678 allocs/op // AppendOnlyGenerate is a very basic hexary trie builder which uses the same Trie
//BenchmarkTrieGeneration/10K-6 46 25374595 ns/op 5754446 B/op 106676 allocs/op // as the rest of geth, but does not create as many objects while expanding the trie
func (gen *trieGenerator) Generate(in chan (leaf), out chan (common.Hash)) { func AppendOnlyGenerate(in chan (leaf), out chan (common.Hash)) {
t := trie.NewAppendOnlyTrie() t := trie.NewAppendOnlyTrie()
for leaf := range in { for leaf := range in {
t.TryUpdate(leaf.key[:], leaf.value) t.TryUpdate(leaf.key[:], leaf.value)

View file

@ -84,7 +84,7 @@ func (ti *testIterator) Hash() common.Hash {
} }
func (ti *testIterator) Account() []byte { func (ti *testIterator) Account() []byte {
return nil return []byte{ti.values[0]}
} }
func (ti *testIterator) Release() {} func (ti *testIterator) Release() {}

View file

@ -18,6 +18,7 @@ package snapshot
import ( import (
"encoding/binary" "encoding/binary"
"math/rand"
"sync" "sync"
"testing" "testing"
@ -26,7 +27,7 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
) )
func generateTrie(it AccountIterator, generator *trieGenerator) common.Hash { func generateTrie(it AccountIterator, generatorFn trieGeneratorFn) common.Hash {
var ( var (
in = make(chan leaf) // chan to pass leaves in = make(chan leaf) // chan to pass leaves
out = make(chan common.Hash) // chan to collect result out = make(chan common.Hash) // chan to collect result
@ -34,7 +35,7 @@ func generateTrie(it AccountIterator, generator *trieGenerator) common.Hash {
) )
wg.Add(1) wg.Add(1)
go func() { go func() {
generator.Generate3(in, out) generatorFn(in, out)
wg.Done() wg.Done()
}() }()
// Feed leaves // Feed leaves
@ -60,6 +61,7 @@ func TestTrieGeneration(t *testing.T) {
base.root: base, base.root: base,
}, },
} }
rand.Seed(1338)
// Stack three diff layers on top with various overlaps // Stack three diff layers on top with various overlaps
snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"),
randomAccountSet("0x11", "0x22", "0x33"), nil) randomAccountSet("0x11", "0x22", "0x33"), nil)
@ -67,10 +69,9 @@ func TestTrieGeneration(t *testing.T) {
// sorted accountlists are not included in the results. // sorted accountlists are not included in the results.
head := snaps.Snapshot(common.HexToHash("0x02")) head := snaps.Snapshot(common.HexToHash("0x02"))
it := head.(*diffLayer).AccountIterator(common.HexToHash("0x00")) it := head.(*diffLayer).AccountIterator(common.HexToHash("0x00"))
generator := &trieGenerator{} hash := generateTrie(it, AppendOnlyGenerate)
hash := generateTrie(it, generator) if got, exp := hash, common.HexToHash("333a7c170a3d97bd53321d0f39b1a6b9a35b286ad2d3b3ced72ca339197c5dca"); exp != got {
if exp, got := hash, common.HexToHash("807fbe7d4e4c62b80b1e7f682bb13ed409467df2a5903e5af44b88f6b08d0519"); exp != got { t.Fatalf("expected %x got %x", exp, got)
t.Fatalf("expected %v got %v", exp, got)
} }
} }
@ -86,6 +87,7 @@ func TestTrieGenerationAppendonly(t *testing.T) {
base.root: base, base.root: base,
}, },
} }
rand.Seed(1337)
// Stack three diff layers on top with various overlaps // Stack three diff layers on top with various overlaps
snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"),
randomAccountSet("0x11", "0x22", "0x33"), nil) randomAccountSet("0x11", "0x22", "0x33"), nil)
@ -93,13 +95,16 @@ func TestTrieGenerationAppendonly(t *testing.T) {
// sorted accountlists are not included in the results. // sorted accountlists are not included in the results.
head := snaps.Snapshot(common.HexToHash("0x02")) head := snaps.Snapshot(common.HexToHash("0x02"))
it := head.(*diffLayer).AccountIterator(common.HexToHash("0x00")) it := head.(*diffLayer).AccountIterator(common.HexToHash("0x00"))
generator := &trieGenerator{} hash := generateTrie(it, AppendOnlyGenerate)
hash := generateTrie(it, generator) if got, exp := hash, common.HexToHash("c9dd8a9602446bfcce27efbb0188a78761bf5473dd363f4ae2f17975a308344a"); exp != got {
if exp, got := hash, common.HexToHash("807fbe7d4e4c62b80b1e7f682bb13ed409467df2a5903e5af44b88f6b08d0519"); exp != got { t.Fatalf("expected %x got %x", exp, got)
t.Fatalf("expected %v got %v", exp, got)
} }
} }
// BenchmarkTrieGeneration/4K/standard-6 98 14141790 ns/op 6164989 B/op 57929 allocs/op
// BenchmarkTrieGeneration/4K/pruning-6 72 14015967 ns/op 6604020 B/op 54962 allocs/op
// BenchmarkTrieGeneration/10K/standard-6 42 30085495 ns/op 17280084 B/op 151006 allocs/op
// BenchmarkTrieGeneration/10K/pruning-6 32 34536586 ns/op 16510731 B/op 137402 allocs/op
func BenchmarkTrieGeneration(b *testing.B) { func BenchmarkTrieGeneration(b *testing.B) {
// Get a fairly large trie // Get a fairly large trie
// Create a custom account factory to recreate the same addresses // Create a custom account factory to recreate the same addresses
@ -129,13 +134,22 @@ func BenchmarkTrieGeneration(b *testing.B) {
head := snaps.Snapshot(common.HexToHash("0x02")) head := snaps.Snapshot(common.HexToHash("0x02"))
// Call it once to make it create the lists before test starts // Call it once to make it create the lists before test starts
head.(*diffLayer).AccountIterator(common.HexToHash("0x00")) head.(*diffLayer).AccountIterator(common.HexToHash("0x00"))
b.ResetTimer() b.Run("standard", func(b *testing.B) {
b.ReportAllocs() b.ResetTimer()
for i := 0; i < b.N; i++ { b.ReportAllocs()
it := head.(*diffLayer).AccountIterator(common.HexToHash("0x00")) for i := 0; i < b.N; i++ {
generator := &trieGenerator{} it := head.(*diffLayer).AccountIterator(common.HexToHash("0x00"))
generateTrie(it, generator) generateTrie(it, StdGenerate)
} }
})
b.Run("pruning", func(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
it := head.(*diffLayer).AccountIterator(common.HexToHash("0x00"))
generateTrie(it, PruneGenerate)
}
})
}) })
b.Run("10K", func(b *testing.B) { b.Run("10K", func(b *testing.B) {
// 4K accounts // 4K accounts
@ -143,12 +157,21 @@ func BenchmarkTrieGeneration(b *testing.B) {
head := snaps.Snapshot(common.HexToHash("0x02")) head := snaps.Snapshot(common.HexToHash("0x02"))
// Call it once to make it create the lists before test starts // Call it once to make it create the lists before test starts
head.(*diffLayer).AccountIterator(common.HexToHash("0x00")) head.(*diffLayer).AccountIterator(common.HexToHash("0x00"))
b.ResetTimer() b.Run("standard", func(b *testing.B) {
b.ReportAllocs() b.ResetTimer()
for i := 0; i < b.N; i++ { b.ReportAllocs()
it := head.(*diffLayer).AccountIterator(common.HexToHash("0x00")) for i := 0; i < b.N; i++ {
generator := &trieGenerator{} it := head.(*diffLayer).AccountIterator(common.HexToHash("0x00"))
generateTrie(it, generator) generateTrie(it, StdGenerate)
} }
})
b.Run("pruning", func(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
it := head.(*diffLayer).AccountIterator(common.HexToHash("0x00"))
generateTrie(it, PruneGenerate)
}
})
}) })
} }