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  }