github.com/klaytn/klaytn@v1.10.2/tests/tx_fee_ratio_range_test.go (about)

     1  // Copyright 2019 The klaytn Authors
     2  // This file is part of the klaytn library.
     3  //
     4  // The klaytn library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The klaytn library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package tests
    18  
    19  import (
    20  	"crypto/ecdsa"
    21  	"fmt"
    22  	"math/big"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/klaytn/klaytn/blockchain"
    27  	"github.com/klaytn/klaytn/blockchain/types"
    28  	"github.com/klaytn/klaytn/blockchain/types/accountkey"
    29  	"github.com/klaytn/klaytn/common"
    30  	"github.com/klaytn/klaytn/common/profile"
    31  	"github.com/klaytn/klaytn/crypto"
    32  	"github.com/klaytn/klaytn/kerrors"
    33  	"github.com/klaytn/klaytn/log"
    34  	"github.com/klaytn/klaytn/params"
    35  	"github.com/stretchr/testify/assert"
    36  )
    37  
    38  // TestTxFeeRatioRange checks the range of the fee ratio.
    39  func TestTxFeeRatioRange(t *testing.T) {
    40  	testCases := []struct {
    41  		feeRatio types.FeeRatio
    42  		expected error
    43  	}{
    44  		{0, kerrors.ErrFeeRatioOutOfRange},
    45  		{1, nil},
    46  		{99, nil},
    47  		{100, kerrors.ErrFeeRatioOutOfRange},
    48  	}
    49  
    50  	for _, test := range testCases {
    51  		name := fmt.Sprintf("%d", test.feeRatio)
    52  		t.Run(name, func(t *testing.T) {
    53  			testTxFeeRatioRange(t, test.feeRatio, test.expected)
    54  		})
    55  	}
    56  }
    57  
    58  func testTxFeeRatioRange(t *testing.T, feeRatio types.FeeRatio, expected error) {
    59  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
    60  	prof := profile.NewProfiler()
    61  
    62  	// Initialize blockchain
    63  	start := time.Now()
    64  	bcdata, err := NewBCData(6, 4)
    65  	if err != nil {
    66  		t.Fatal(err)
    67  	}
    68  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
    69  	defer bcdata.Shutdown()
    70  
    71  	// Initialize address-balance map for verification
    72  	start = time.Now()
    73  	accountMap := NewAccountMap()
    74  	if err := accountMap.Initialize(bcdata); err != nil {
    75  		t.Fatal(err)
    76  	}
    77  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
    78  
    79  	// reservoir account
    80  	reservoir := &TestAccountType{
    81  		Addr:  *bcdata.addrs[0],
    82  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
    83  		Nonce: uint64(0),
    84  	}
    85  
    86  	reservoir2 := &TestAccountType{
    87  		Addr:  *bcdata.addrs[1],
    88  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[1]},
    89  		Nonce: uint64(0),
    90  	}
    91  
    92  	reservoir3 := &TestAccountType{
    93  		Addr:  *bcdata.addrs[2],
    94  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[2]},
    95  		Nonce: uint64(0),
    96  	}
    97  
    98  	contract, err := createAnonymousAccount("a5c9a50938a089618167c9d67dbebc0deaffc3c76ddc6b40c2777ae59438e989")
    99  	assert.Equal(t, nil, err)
   100  
   101  	code := common.FromHex("0x608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029")
   102  
   103  	signer := types.MakeSigner(bcdata.bc.Config(), bcdata.bc.CurrentHeader().Number)
   104  
   105  	gasPrice := new(big.Int).SetUint64(bcdata.bc.Config().UnitPrice)
   106  
   107  	// 0. Initial setting: deploy a smart contract to execute later
   108  	{
   109  		var txs types.Transactions
   110  
   111  		amount := new(big.Int).SetUint64(0)
   112  
   113  		values := map[types.TxValueKeyType]interface{}{
   114  			types.TxValueKeyNonce:         reservoir.Nonce,
   115  			types.TxValueKeyFrom:          reservoir.Addr,
   116  			types.TxValueKeyTo:            (*common.Address)(nil),
   117  			types.TxValueKeyAmount:        amount,
   118  			types.TxValueKeyGasLimit:      gasLimit,
   119  			types.TxValueKeyGasPrice:      gasPrice,
   120  			types.TxValueKeyHumanReadable: false,
   121  			types.TxValueKeyData:          code,
   122  			types.TxValueKeyCodeFormat:    params.CodeFormatEVM,
   123  		}
   124  		tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values)
   125  		assert.Equal(t, nil, err)
   126  
   127  		err = tx.SignWithKeys(signer, reservoir.Keys)
   128  		assert.Equal(t, nil, err)
   129  
   130  		txs = append(txs, tx)
   131  
   132  		if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil {
   133  			t.Fatal(err)
   134  		}
   135  
   136  		contract.Addr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce)
   137  
   138  		reservoir.Nonce += 1
   139  	}
   140  
   141  	// make TxPool to test validation in 'TxPool add' process
   142  	txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc)
   143  
   144  	// 1. TxTypeFeeDelegatedValueTransferWithRatio
   145  	{
   146  		amount := new(big.Int).SetUint64(10000)
   147  		values := map[types.TxValueKeyType]interface{}{
   148  			types.TxValueKeyNonce:              reservoir.Nonce,
   149  			types.TxValueKeyFrom:               reservoir.Addr,
   150  			types.TxValueKeyTo:                 reservoir3.Addr,
   151  			types.TxValueKeyAmount:             amount,
   152  			types.TxValueKeyGasLimit:           gasLimit,
   153  			types.TxValueKeyGasPrice:           gasPrice,
   154  			types.TxValueKeyFeePayer:           reservoir2.Addr,
   155  			types.TxValueKeyFeeRatioOfFeePayer: feeRatio,
   156  		}
   157  		tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedValueTransferWithRatio, values)
   158  		assert.Equal(t, nil, err)
   159  
   160  		err = tx.SignWithKeys(signer, reservoir.Keys)
   161  		assert.Equal(t, nil, err)
   162  
   163  		err = tx.SignFeePayerWithKeys(signer, reservoir2.Keys)
   164  		assert.Equal(t, nil, err)
   165  
   166  		err = txpool.AddRemote(tx)
   167  		assert.Equal(t, expected, err)
   168  
   169  		reservoir.Nonce += 1
   170  	}
   171  
   172  	// 2. TxTypeFeeDelegatedValueTransferMemoWithRatio
   173  	{
   174  		amount := new(big.Int).SetUint64(10000)
   175  		values := map[types.TxValueKeyType]interface{}{
   176  			types.TxValueKeyNonce:              reservoir.Nonce,
   177  			types.TxValueKeyFrom:               reservoir.Addr,
   178  			types.TxValueKeyTo:                 reservoir3.Addr,
   179  			types.TxValueKeyAmount:             amount,
   180  			types.TxValueKeyGasLimit:           gasLimit,
   181  			types.TxValueKeyGasPrice:           gasPrice,
   182  			types.TxValueKeyData:               []byte("hello"),
   183  			types.TxValueKeyFeePayer:           reservoir2.Addr,
   184  			types.TxValueKeyFeeRatioOfFeePayer: feeRatio,
   185  		}
   186  		tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedValueTransferMemoWithRatio, values)
   187  		assert.Equal(t, nil, err)
   188  
   189  		err = tx.SignWithKeys(signer, reservoir.Keys)
   190  		assert.Equal(t, nil, err)
   191  
   192  		err = tx.SignFeePayerWithKeys(signer, reservoir2.Keys)
   193  		assert.Equal(t, nil, err)
   194  
   195  		err = txpool.AddRemote(tx)
   196  		assert.Equal(t, expected, err)
   197  
   198  		reservoir.Nonce += 1
   199  	}
   200  
   201  	// 3. TxTypeFeeDelegatedAccountUpdateWithRatio
   202  	{
   203  		values := map[types.TxValueKeyType]interface{}{
   204  			types.TxValueKeyNonce:              reservoir.Nonce,
   205  			types.TxValueKeyFrom:               reservoir.Addr,
   206  			types.TxValueKeyGasLimit:           gasLimit,
   207  			types.TxValueKeyGasPrice:           gasPrice,
   208  			types.TxValueKeyAccountKey:         accountkey.NewAccountKeyPublicWithValue(&reservoir.Keys[0].PublicKey),
   209  			types.TxValueKeyFeePayer:           reservoir2.Addr,
   210  			types.TxValueKeyFeeRatioOfFeePayer: feeRatio,
   211  		}
   212  		tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedAccountUpdateWithRatio, values)
   213  		assert.Equal(t, nil, err)
   214  
   215  		err = tx.SignWithKeys(signer, reservoir.Keys)
   216  		assert.Equal(t, nil, err)
   217  
   218  		err = tx.SignFeePayerWithKeys(signer, reservoir2.Keys)
   219  		assert.Equal(t, nil, err)
   220  
   221  		err = txpool.AddRemote(tx)
   222  		assert.Equal(t, expected, err)
   223  
   224  		reservoir.Nonce += 1
   225  	}
   226  
   227  	// 4, TxTypeFeeDelegatedSmartContractDeployWithRatio
   228  	{
   229  		amount := new(big.Int).SetUint64(10000)
   230  		values := map[types.TxValueKeyType]interface{}{
   231  			types.TxValueKeyNonce:              reservoir.Nonce,
   232  			types.TxValueKeyFrom:               reservoir.Addr,
   233  			types.TxValueKeyTo:                 (*common.Address)(nil),
   234  			types.TxValueKeyAmount:             amount,
   235  			types.TxValueKeyGasLimit:           gasLimit,
   236  			types.TxValueKeyGasPrice:           gasPrice,
   237  			types.TxValueKeyHumanReadable:      false,
   238  			types.TxValueKeyData:               []byte{0x80},
   239  			types.TxValueKeyFeePayer:           reservoir2.Addr,
   240  			types.TxValueKeyFeeRatioOfFeePayer: feeRatio,
   241  			types.TxValueKeyCodeFormat:         params.CodeFormatEVM,
   242  		}
   243  		tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedSmartContractDeployWithRatio, values)
   244  		assert.Equal(t, nil, err)
   245  
   246  		err = tx.SignWithKeys(signer, reservoir.Keys)
   247  		assert.Equal(t, nil, err)
   248  
   249  		err = tx.SignFeePayerWithKeys(signer, reservoir2.Keys)
   250  		assert.Equal(t, nil, err)
   251  
   252  		err = txpool.AddRemote(tx)
   253  		assert.Equal(t, expected, err)
   254  
   255  		reservoir.Nonce += 1
   256  	}
   257  
   258  	// 5. TxTypeFeeDelegatedSmartContractExecutionWithRatio
   259  	{
   260  		amount := new(big.Int).SetUint64(10000)
   261  		values := map[types.TxValueKeyType]interface{}{
   262  			types.TxValueKeyNonce:              reservoir.Nonce,
   263  			types.TxValueKeyFrom:               reservoir.Addr,
   264  			types.TxValueKeyTo:                 contract.Addr,
   265  			types.TxValueKeyAmount:             amount,
   266  			types.TxValueKeyGasLimit:           gasLimit,
   267  			types.TxValueKeyGasPrice:           gasPrice,
   268  			types.TxValueKeyData:               []byte{0x80},
   269  			types.TxValueKeyFeePayer:           reservoir2.Addr,
   270  			types.TxValueKeyFeeRatioOfFeePayer: feeRatio,
   271  		}
   272  		tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedSmartContractExecutionWithRatio, values)
   273  		assert.Equal(t, nil, err)
   274  
   275  		err = tx.SignWithKeys(signer, reservoir.Keys)
   276  		assert.Equal(t, nil, err)
   277  
   278  		err = tx.SignFeePayerWithKeys(signer, reservoir2.Keys)
   279  		assert.Equal(t, nil, err)
   280  
   281  		err = txpool.AddRemote(tx)
   282  		assert.Equal(t, expected, err)
   283  
   284  		reservoir.Nonce += 1
   285  	}
   286  
   287  	// 6. TxTypeFeeDelegatedCancelWithRatio
   288  	{
   289  		values := map[types.TxValueKeyType]interface{}{
   290  			types.TxValueKeyNonce:              reservoir.Nonce,
   291  			types.TxValueKeyFrom:               reservoir.Addr,
   292  			types.TxValueKeyGasLimit:           gasLimit,
   293  			types.TxValueKeyGasPrice:           gasPrice,
   294  			types.TxValueKeyFeePayer:           reservoir2.Addr,
   295  			types.TxValueKeyFeeRatioOfFeePayer: feeRatio,
   296  		}
   297  		tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedCancelWithRatio, values)
   298  		assert.Equal(t, nil, err)
   299  
   300  		err = tx.SignWithKeys(signer, reservoir.Keys)
   301  		assert.Equal(t, nil, err)
   302  
   303  		err = tx.SignFeePayerWithKeys(signer, reservoir2.Keys)
   304  		assert.Equal(t, nil, err)
   305  
   306  		err = txpool.AddRemote(tx)
   307  		assert.Equal(t, expected, err)
   308  
   309  		reservoir.Nonce += 1
   310  	}
   311  }