From e303aeb5ee6b964a9225543e82fbed1a56f64be6 Mon Sep 17 00:00:00 2001 From: Andrew Ashikhmin <34320705+yperbasis@users.noreply.github.com> Date: Sat, 20 Mar 2021 10:38:45 +0100 Subject: [PATCH] Simple test for layout of TrieOfAccountsBucket (#1563) --- common/dbutils/bucket.go | 2 +- eth/stagedsync/stage_interhashes_test.go | 65 ++++++++++++++++++++++++ ethdb/kv_lmdb.go | 7 ++- ethdb/kv_mdbx.go | 7 ++- 4 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 eth/stagedsync/stage_interhashes_test.go diff --git a/common/dbutils/bucket.go b/common/dbutils/bucket.go index a535e9b5da..08e9f1bcc5 100644 --- a/common/dbutils/bucket.go +++ b/common/dbutils/bucket.go @@ -110,7 +110,7 @@ hasHash - mark prefixes which hashes are saved in current trie_account record (a v v v v v +------------------+ +----------------------+ +---------------+ +---------------+ +---------------+ | Account: | | BranchNode: 0x0B0004 | | Account: | | Account: | | Account: | -| 0x0B0000... | | has no record in | | 0x0B01... | | 0x0B0301... | | 0x050304... | +| 0x0B0000... | | has no record in | | 0x0B01... | | 0x0B0301... | | 0x0B0304... | | in HashedAccount | | TrieAccount | | | | | | | +------------------+ +----------------------+ +---------------+ +---------------+ +---------------+ | | diff --git a/eth/stagedsync/stage_interhashes_test.go b/eth/stagedsync/stage_interhashes_test.go new file mode 100644 index 0000000000..25e2d95fbd --- /dev/null +++ b/eth/stagedsync/stage_interhashes_test.go @@ -0,0 +1,65 @@ +package stagedsync + +import ( + "testing" + + "github.com/ledgerwatch/turbo-geth/common" + "github.com/ledgerwatch/turbo-geth/common/dbutils" + "github.com/ledgerwatch/turbo-geth/core/types/accounts" + "github.com/ledgerwatch/turbo-geth/ethdb" + "github.com/ledgerwatch/turbo-geth/turbo/trie" + "github.com/stretchr/testify/assert" +) + +func addTestAccount(db ethdb.Putter, hash common.Hash, balance uint64) error { + acc := accounts.NewAccount() + acc.Balance.SetUint64(balance) + encoded := make([]byte, acc.EncodingLengthForStorage()) + acc.EncodeForStorage(encoded) + return db.Put(dbutils.HashedAccountsBucket, hash[:], encoded) +} + +func TestTrieOfAccountsLayout(t *testing.T) { + db := ethdb.NewMemDatabase() + + hash1 := common.HexToHash("0xB000000000000000000000000000000000000000000000000000000000000000") + assert.Nil(t, addTestAccount(db, hash1, 300_000_000_000)) + + hash2 := common.HexToHash("0xB040000000000000000000000000000000000000000000000000000000000000") + assert.Nil(t, addTestAccount(db, hash2, 100_000_000_000)) + + hash3 := common.HexToHash("0xB041000000000000000000000000000000000000000000000000000000000000") + assert.Nil(t, addTestAccount(db, hash3, 200_000_000_000)) + + hash4 := common.HexToHash("0xB100000000000000000000000000000000000000000000000000000000000000") + assert.Nil(t, addTestAccount(db, hash4, 400_000_000_000)) + + hash5 := common.HexToHash("0xB310000000000000000000000000000000000000000000000000000000000000") + assert.Nil(t, addTestAccount(db, hash5, 800_000_000_000)) + + hash6 := common.HexToHash("0xB340000000000000000000000000000000000000000000000000000000000000") + assert.Nil(t, addTestAccount(db, hash6, 100_000_000_000)) + + err := RegenerateIntermediateHashes("IH", db, false /* checkRoot */, nil /* cache */, getTmpDir(), common.Hash{} /* expectedRootHash */, nil /* quit */) + assert.Nil(t, err) + + account_trie := make(map[string][]byte) + + err = db.Walk(dbutils.TrieOfAccountsBucket, []byte{}, 0, func(k, v []byte) (bool, error) { + account_trie[string(k)] = v + return true, nil + }) + assert.Nil(t, err) + + assert.Equal(t, 2, len(account_trie)) + + hasState1, hasTree1, hasHash1, _, _ := trie.UnmarshalTrieNode(account_trie[string(common.FromHex("0B"))]) + assert.Equal(t, uint16(0b1011), hasState1) + assert.Equal(t, uint16(0b0001), hasTree1) + assert.Equal(t, uint16(0b1001), hasHash1) + + hasState2, hasTree2, hasHash2, _, _ := trie.UnmarshalTrieNode(account_trie[string(common.FromHex("0B00"))]) + assert.Equal(t, uint16(0b10001), hasState2) + assert.Equal(t, uint16(0b00000), hasTree2) + assert.Equal(t, uint16(0b10000), hasHash2) +} diff --git a/ethdb/kv_lmdb.go b/ethdb/kv_lmdb.go index 796a0e17fe..968a92f5f0 100644 --- a/ethdb/kv_lmdb.go +++ b/ethdb/kv_lmdb.go @@ -1320,8 +1320,13 @@ func (c *LmdbCursor) Append(k []byte, v []byte) error { func (c *LmdbCursor) Close() { if c.c != nil { c.c.Close() + l := len(c.tx.cursors) + if l == 0 { + c.c = nil + return + } //TODO: Find a better solution to avoid the leak? - newCursors := make([]*lmdb.Cursor, len(c.tx.cursors)-1) + newCursors := make([]*lmdb.Cursor, l-1) i := 0 for _, cc := range c.tx.cursors { if cc != c.c { diff --git a/ethdb/kv_mdbx.go b/ethdb/kv_mdbx.go index eb5e26447a..b7d8b18d43 100644 --- a/ethdb/kv_mdbx.go +++ b/ethdb/kv_mdbx.go @@ -1375,8 +1375,13 @@ func (c *MdbxCursor) Append(k []byte, v []byte) error { func (c *MdbxCursor) Close() { if c.c != nil { c.c.Close() + l := len(c.tx.cursors) + if l == 0 { + c.c = nil + return + } //TODO: Find a better solution to avoid the leak? - newCursors := make([]*mdbx.Cursor, len(c.tx.cursors)-1) + newCursors := make([]*mdbx.Cursor, l-1) i := 0 for _, cc := range c.tx.cursors { if cc != c.c { -- GitLab