Skip to content
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

trie: add Commit-sequence tests for stacktrie commit #21643

Merged
merged 1 commit into from
Sep 30, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 58 additions & 1 deletion trie/trie_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,9 @@ func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) {

// spongeDb is a dummy db backend which accumulates writes in a sponge
type spongeDb struct {
sponge hash.Hash
sponge hash.Hash
id string
journal []string
}

func (s *spongeDb) Has(key []byte) (bool, error) { panic("implement me") }
Expand All @@ -676,6 +678,11 @@ func (s *spongeDb) Stat(property string) (string, error) { panic("implement
func (s *spongeDb) Compact(start []byte, limit []byte) error { panic("implement me") }
func (s *spongeDb) Close() error { return nil }
func (s *spongeDb) Put(key []byte, value []byte) error {
valbrief := value
if len(valbrief) > 8 {
valbrief = valbrief[:8]
}
s.journal = append(s.journal, fmt.Sprintf("%v: PUT([%x...], [%d bytes] %x...)\n", s.id, key[:8], len(value), valbrief))
s.sponge.Write(key)
s.sponge.Write(value)
return nil
Expand Down Expand Up @@ -793,6 +800,56 @@ func TestCommitSequenceRandomBlobs(t *testing.T) {
}
}

func TestCommitSequenceStackTrie(t *testing.T) {
for count := 1; count < 200; count++ {
prng := rand.New(rand.NewSource(int64(count)))
// This spongeDb is used to check the sequence of disk-db-writes
s := &spongeDb{sponge: sha3.NewLegacyKeccak256(), id: "a"}
db := NewDatabase(s)
trie, _ := New(common.Hash{}, db)
// Another sponge is used for the stacktrie commits
stackTrieSponge := &spongeDb{sponge: sha3.NewLegacyKeccak256(), id: "b"}
stTrie := NewStackTrie(stackTrieSponge)
// Fill the trie with elements
for i := 1; i < count; i++ {
// For the stack trie, we need to do inserts in proper order
key := make([]byte, 32)
binary.BigEndian.PutUint64(key, uint64(i))
var val []byte
// 50% short elements, 50% large elements
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we also insert elements that are < 32 ?

if prng.Intn(2) == 0 {
val = make([]byte, 1+prng.Intn(32))
} else {
val = make([]byte, 1+prng.Intn(1024))
}
prng.Read(val)
trie.TryUpdate(key, common.CopyBytes(val))
stTrie.TryUpdate(key, common.CopyBytes(val))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a machine to test this myself, I wonder if the byte copy really necessary for StackTrie?

}
// Flush trie -> database
root, _ := trie.Commit(nil)
// Flush memdb -> disk (sponge)
db.Commit(root, false, nil)
// And flush stacktrie -> disk
stRoot := stTrie.Commit(stTrie.db)
if stRoot != root {
t.Fatalf("root wrong, got %x exp %x", stRoot, root)
}
if got, exp := stackTrieSponge.sponge.Sum(nil), s.sponge.Sum(nil); !bytes.Equal(got, exp) {
// Show the journal
t.Logf("Expected:")
for i, v := range s.journal {
t.Logf("op %d: %v", i, v)
}
t.Logf("Stacktrie:")
for i, v := range stackTrieSponge.journal {
t.Logf("op %d: %v", i, v)
}
t.Fatalf("test %d, disk write sequence wrong:\ngot %x exp %x\n", count, got, exp)
}
}
}

// BenchmarkCommitAfterHashFixedSize benchmarks the Commit (after Hash) of a fixed number of updates to a trie.
// This benchmark is meant to capture the difference on efficiency of small versus large changes. Typically,
// storage tries are small (a couple of entries), whereas the full post-block account trie update is large (a couple
Expand Down