github.com/dim4egster/coreth@v0.10.2/plugin/evm/atomic_trie_iterator_test.go (about) 1 // (c) 2020-2021, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package evm 5 6 import ( 7 "testing" 8 9 "github.com/dim4egster/qmallgo/chains/atomic" 10 "github.com/dim4egster/qmallgo/database/memdb" 11 "github.com/dim4egster/qmallgo/database/versiondb" 12 "github.com/dim4egster/qmallgo/ids" 13 "github.com/dim4egster/qmallgo/utils" 14 "github.com/ethereum/go-ethereum/common" 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func testSharedMemory() atomic.SharedMemory { 20 m := atomic.NewMemory(memdb.New()) 21 return m.NewSharedMemory(testCChainID) 22 } 23 24 func TestIteratorCanIterate(t *testing.T) { 25 lastAcceptedHeight := uint64(1000) 26 db := versiondb.New(memdb.New()) 27 codec := testTxCodec() 28 repo, err := NewAtomicTxRepository(db, codec, lastAcceptedHeight, nil, nil, nil) 29 assert.NoError(t, err) 30 31 // create state with multiple transactions 32 // since each test transaction generates random ID for blockchainID we should get 33 // multiple blockchain IDs per block in the overall combined atomic operation map 34 operationsMap := make(map[uint64]map[ids.ID]*atomic.Requests) 35 writeTxs(t, repo, 1, lastAcceptedHeight, constTxsPerHeight(3), nil, operationsMap) 36 37 // create an atomic trie 38 // on create it will initialize all the transactions from the above atomic repository 39 atomicBackend, err := NewAtomicBackend(db, testSharedMemory(), nil, repo, lastAcceptedHeight, common.Hash{}, 100) 40 assert.NoError(t, err) 41 atomicTrie1 := atomicBackend.AtomicTrie() 42 43 lastCommittedHash1, lastCommittedHeight1 := atomicTrie1.LastCommitted() 44 assert.NoError(t, err) 45 assert.NotEqual(t, common.Hash{}, lastCommittedHash1) 46 assert.EqualValues(t, 1000, lastCommittedHeight1) 47 48 verifyOperations(t, atomicTrie1, codec, lastCommittedHash1, 1, 1000, operationsMap) 49 50 // iterate on a new atomic trie to make sure there is no resident state affecting the data and the 51 // iterator 52 atomicBackend2, err := NewAtomicBackend(db, testSharedMemory(), nil, repo, lastAcceptedHeight, common.Hash{}, 100) 53 assert.NoError(t, err) 54 atomicTrie2 := atomicBackend2.AtomicTrie() 55 lastCommittedHash2, lastCommittedHeight2 := atomicTrie2.LastCommitted() 56 assert.NoError(t, err) 57 assert.NotEqual(t, common.Hash{}, lastCommittedHash2) 58 assert.EqualValues(t, 1000, lastCommittedHeight2) 59 60 verifyOperations(t, atomicTrie2, codec, lastCommittedHash1, 1, 1000, operationsMap) 61 } 62 63 func TestIteratorHandlesInvalidData(t *testing.T) { 64 require := require.New(t) 65 lastAcceptedHeight := uint64(1000) 66 db := versiondb.New(memdb.New()) 67 codec := testTxCodec() 68 repo, err := NewAtomicTxRepository(db, codec, lastAcceptedHeight, nil, nil, nil) 69 require.NoError(err) 70 71 // create state with multiple transactions 72 // since each test transaction generates random ID for blockchainID we should get 73 // multiple blockchain IDs per block in the overall combined atomic operation map 74 operationsMap := make(map[uint64]map[ids.ID]*atomic.Requests) 75 writeTxs(t, repo, 1, lastAcceptedHeight, constTxsPerHeight(3), nil, operationsMap) 76 77 // create an atomic trie 78 // on create it will initialize all the transactions from the above atomic repository 79 commitInterval := uint64(100) 80 atomicBackend, err := NewAtomicBackend(db, testSharedMemory(), nil, repo, lastAcceptedHeight, common.Hash{}, commitInterval) 81 require.NoError(err) 82 atomicTrie := atomicBackend.AtomicTrie() 83 84 lastCommittedHash, lastCommittedHeight := atomicTrie.LastCommitted() 85 require.NoError(err) 86 require.NotEqual(common.Hash{}, lastCommittedHash) 87 require.EqualValues(1000, lastCommittedHeight) 88 89 verifyOperations(t, atomicTrie, codec, lastCommittedHash, 1, 1000, operationsMap) 90 91 // Add a random key-value pair to the atomic trie in order to test that the iterator correctly 92 // handles an error when it runs into an unexpected key-value pair in the trie. 93 atomicTrieSnapshot, err := atomicTrie.OpenTrie(lastCommittedHash) 94 require.NoError(err) 95 require.NoError(atomicTrieSnapshot.TryUpdate(utils.RandomBytes(50), utils.RandomBytes(50))) 96 97 nextRoot, nodes, err := atomicTrieSnapshot.Commit(false) 98 require.NoError(err) 99 err = atomicTrie.InsertTrie(nodes, nextRoot) 100 require.NoError(err) 101 isCommit, err := atomicTrie.AcceptTrie(lastCommittedHeight+commitInterval, nextRoot) 102 require.NoError(err) 103 require.True(isCommit) 104 105 corruptedHash, _ := atomicTrie.LastCommitted() 106 iter, err := atomicTrie.Iterator(corruptedHash, nil) 107 require.NoError(err) 108 for iter.Next() { 109 } 110 require.Error(iter.Error()) 111 }