github.com/klaytn/klaytn@v1.10.2/datasync/chaindatafetcher/kas/repository_transactions_test.go (about) 1 package kas 2 3 import ( 4 "math/big" 5 "strings" 6 "testing" 7 8 "github.com/klaytn/klaytn/blockchain" 9 "github.com/klaytn/klaytn/blockchain/types" 10 "github.com/klaytn/klaytn/common" 11 "github.com/klaytn/klaytn/crypto" 12 "github.com/klaytn/klaytn/params" 13 "github.com/stretchr/testify/assert" 14 ) 15 16 // TODO-ChainDataFetcher add more tx types test cases 17 func genNewValueTransfer(from, to common.Address, nonce, amount, gasLimit, gasPrice *big.Int) *types.Transaction { 18 tx, err := types.NewTransactionWithMap(types.TxTypeValueTransfer, map[types.TxValueKeyType]interface{}{ 19 types.TxValueKeyNonce: nonce.Uint64(), 20 types.TxValueKeyTo: to, 21 types.TxValueKeyAmount: amount, 22 types.TxValueKeyGasLimit: gasLimit.Uint64(), 23 types.TxValueKeyGasPrice: gasPrice, 24 types.TxValueKeyFrom: from, 25 }) 26 if err != nil { 27 panic(err) 28 } 29 30 err = tx.Sign(signer, key) 31 if err != nil { 32 panic(err) 33 } 34 35 return tx 36 } 37 38 func checkValidChainEventsPosted(t *testing.T, expectedBlocks, expectedTxsPerBlock int, events []blockchain.ChainEvent) { 39 assert.Equal(t, expectedBlocks, len(events)) 40 for _, ev := range events { 41 assert.Equal(t, expectedTxsPerBlock, len(ev.Block.Transactions())) 42 } 43 } 44 45 func TestRepository_TransformToTxs_Success(t *testing.T) { 46 // define transaction contents 47 from := address 48 randKey, _ := crypto.GenerateKey() 49 to := crypto.PubkeyToAddress(randKey.PublicKey) 50 amount := new(big.Int).SetUint64(100) 51 gasLimit := big.NewInt(500000) 52 gasPrice := new(big.Int).SetUint64(1 * params.Peb) 53 54 // make a chain event including a value transfer transaction 55 numBlocks := 1 56 numTxsPerBlock := 1 57 events, err := makeChainEventsWithInternalTraces(numBlocks, func(i int, block *blockchain.BlockGen) { 58 nonce := new(big.Int).SetUint64(block.TxNonce(from)) 59 tx := genNewValueTransfer(from, to, nonce, amount, gasLimit, gasPrice) 60 block.AddTx(tx) 61 }) 62 assert.NoError(t, err) 63 64 checkValidChainEventsPosted(t, numBlocks, numTxsPerBlock, events) 65 66 ev := events[0] 67 txs, _ := transformToTxs(ev) 68 69 for _, tx := range txs { 70 assert.Equal(t, from.Bytes(), tx.FromAddr) 71 assert.Equal(t, to.Bytes(), tx.ToAddr) 72 assert.Equal(t, "0x"+amount.Text(16), tx.Value) 73 assert.Equal(t, gasPrice.Uint64(), tx.GasPrice) 74 t.Log(tx.Value) 75 } 76 } 77 78 func (s *SuiteRepository) TestRepository_InsertTransactions_Panics_EmptyChainEvent() { 79 s.Panics(func() { s.repo.InsertTransactions(blockchain.ChainEvent{}) }) 80 } 81 82 func (s *SuiteRepository) TestRepository_bulkInsertTransaction_Success() { 83 from := genRandomAddress() 84 to := genRandomAddress() 85 feePayer := genRandomAddress() 86 87 expected := &Tx{ 88 TransactionId: 2020*(1000000*100000) + (0 * 10000) + 0, 89 FromAddr: from.Bytes(), 90 ToAddr: to.Bytes(), 91 Value: "0x1234", 92 TransactionHash: common.HexToHash("0xd17153512821d290a29589e1decfbd26b6c2792faffe0d1e2aa664d3f4820fd1").Bytes(), 93 Status: 1, 94 Timestamp: 9999, 95 TypeInt: int(types.TxTypeValueTransfer), 96 GasPrice: 8888, 97 GasUsed: 7777, 98 FeePayer: feePayer.Bytes(), 99 FeeRatio: uint(30), 100 Internal: false, 101 } 102 103 err := s.repo.bulkInsertTransactions([]*Tx{expected}) 104 s.NoError(err) 105 106 actual := &Tx{} 107 s.NoError(s.repo.db.Where("fromAddr = ?", from.Bytes()).Take(actual).Error) 108 s.Equal(expected, actual) 109 } 110 111 func (s *SuiteRepository) TestRepository_bulkInsertTransactions_Success_NoTransaction() { 112 s.Nil(s.repo.bulkInsertTransactions(nil)) 113 } 114 115 func (s *SuiteRepository) TestRepository_bulkInsertTransactions_Fail_NoTxhash() { 116 tx := &Tx{ 117 FromAddr: genRandomAddress().Bytes(), 118 ToAddr: genRandomAddress().Bytes(), 119 Value: "0x1", 120 } 121 122 err := s.repo.bulkInsertTransactions([]*Tx{tx}) 123 s.Error(err) 124 s.True(strings.Contains(err.Error(), "'transactionHash' cannot be null")) 125 } 126 127 func createChainEventsWithTooManyTxs() ([]blockchain.ChainEvent, error) { 128 // define transaction contents 129 from := address 130 randKey, _ := crypto.GenerateKey() 131 to := crypto.PubkeyToAddress(randKey.PublicKey) 132 amount := new(big.Int).SetUint64(100) 133 gasLimit := big.NewInt(500000) 134 gasPrice := new(big.Int).SetUint64(1 * params.Peb) 135 136 // make a chain event including a value transfer transaction 137 numBlocks := 1 138 return makeChainEventsWithInternalTraces(numBlocks, func(i int, block *blockchain.BlockGen) { 139 for idx := 0; idx < maxPlaceholders/placeholdersPerTxItem+1; idx++ { 140 nonce := new(big.Int).SetUint64(block.TxNonce(from)) 141 tx := genNewValueTransfer(from, to, nonce, amount, gasLimit, gasPrice) 142 block.AddTx(tx) 143 } 144 }) 145 } 146 147 func (s *SuiteRepository) TestRepository_bulkInsertTransactions_Fail_TooManyPlaceholders() { 148 events, err := createChainEventsWithTooManyTxs() 149 s.NoError(err) 150 151 ev := events[0] 152 txs, _ := transformToTxs(ev) 153 err = s.repo.bulkInsertTransactions(txs) 154 s.Error(err) 155 s.True(strings.Contains(err.Error(), "Prepared statement contains too many placeholders")) 156 } 157 158 func (s *SuiteRepository) TestRepository_InsertTransactions_Success_TooManyPlaceholders() { 159 events, err := createChainEventsWithTooManyTxs() 160 s.NoError(err) 161 162 ev := events[0] 163 err = s.repo.InsertTransactions(ev) 164 s.NoError(err) 165 } 166 167 func (s *SuiteRepository) TestRepository_InsertTransactions_Success_EmptyBlock() { 168 numBlocks := 1 169 numTxsPerBlock := 0 170 events, err := makeChainEventsWithInternalTraces(numBlocks, nil) 171 s.NoError(err) 172 173 checkValidChainEventsPosted(s.T(), numBlocks, numTxsPerBlock, events) 174 s.NoError(s.repo.InsertTransactions(events[0])) 175 }