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  }