github.com/klaytn/klaytn@v1.10.2/tests/tx_code_format_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  	"math/big"
    22  	"strings"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/klaytn/klaytn/blockchain/types"
    27  	"github.com/klaytn/klaytn/common"
    28  	"github.com/klaytn/klaytn/common/profile"
    29  	"github.com/klaytn/klaytn/kerrors"
    30  	"github.com/klaytn/klaytn/log"
    31  	"github.com/klaytn/klaytn/params"
    32  	"github.com/stretchr/testify/assert"
    33  )
    34  
    35  type genTxWithCodeFormat func(t *testing.T, signer types.Signer, from TestAccount, payer TestAccount, gasPrice *big.Int, codeFormat params.CodeFormat) *types.Transaction
    36  
    37  func TestCodeFormat(t *testing.T) {
    38  	testFunctions := []struct {
    39  		Name  string
    40  		genTx genTxWithCodeFormat
    41  	}{
    42  		{"SmartContractDeployWithValidCodeFormat", genSmartContractDeployWithCodeFormat},
    43  		{"FeeDelegatedSmartContractDeployWithValidCodeFormat", genFeeDelegatedSmartContractDeployWithCodeFormat},
    44  		{"FeeDelegatedWithRatioSmartContractDeployWithValidCodeFormat", genFeeDelegatedWithRatioSmartContractDeployWithCodeFormat},
    45  		{"SmartContractDeployWithInvalidCodeFormat", genSmartContractDeployWithCodeFormat},
    46  		{"FeeDelegatedSmartContractDeployWithInvalidCodeFormat", genFeeDelegatedSmartContractDeployWithCodeFormat},
    47  		{"FeeDelegatedWithRatioSmartContractDeployWithInvalidCodeFormat", genFeeDelegatedWithRatioSmartContractDeployWithCodeFormat},
    48  	}
    49  
    50  	log.EnableLogForTest(log.LvlCrit, log.LvlTrace)
    51  	prof := profile.NewProfiler()
    52  
    53  	// Initialize blockchain
    54  	start := time.Now()
    55  	bcdata, err := NewBCData(6, 4)
    56  	assert.Equal(t, nil, err)
    57  	prof.Profile("main_init_blockchain", time.Now().Sub(start))
    58  
    59  	defer bcdata.Shutdown()
    60  
    61  	// Initialize address-balance map for verification
    62  	start = time.Now()
    63  	accountMap := NewAccountMap()
    64  	if err := accountMap.Initialize(bcdata); err != nil {
    65  		t.Fatal(err)
    66  	}
    67  	prof.Profile("main_init_accountMap", time.Now().Sub(start))
    68  
    69  	// reservoir account
    70  	var reservoir TestAccount
    71  	reservoir = &TestAccountType{
    72  		Addr:  *bcdata.addrs[0],
    73  		Keys:  []*ecdsa.PrivateKey{bcdata.privKeys[0]},
    74  		Nonce: uint64(0),
    75  	}
    76  
    77  	signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID)
    78  	gasPrice := new(big.Int).SetUint64(bcdata.bc.Config().UnitPrice)
    79  
    80  	testCodeFormat := func(tx *types.Transaction, state error) {
    81  		receipt, err := applyTransaction(t, bcdata, tx)
    82  		if err != nil {
    83  			assert.Equal(t, state, err)
    84  			assert.Equal(t, (*types.Receipt)(nil), receipt)
    85  		} else {
    86  			assert.Equal(t, nil, err)
    87  			assert.Equal(t, types.ReceiptStatusSuccessful, receipt.Status)
    88  		}
    89  	}
    90  
    91  	for _, f := range testFunctions {
    92  		codeFormat := params.CodeFormatEVM
    93  		state := error(nil)
    94  		var tx *types.Transaction
    95  
    96  		if strings.Contains(f.Name, "WithInvalid") {
    97  			codeFormat = params.CodeFormatLast
    98  			state = kerrors.ErrInvalidCodeFormat
    99  		}
   100  
   101  		if strings.Contains(f.Name, "FeeDelegated") {
   102  			tx = f.genTx(t, signer, reservoir, reservoir, gasPrice, codeFormat)
   103  		} else {
   104  			tx = f.genTx(t, signer, reservoir, nil, gasPrice, codeFormat)
   105  		}
   106  
   107  		t.Run(f.Name, func(t *testing.T) {
   108  			testCodeFormat(tx, state)
   109  		})
   110  	}
   111  }
   112  
   113  func genSmartContractDeployWithCodeFormat(t *testing.T, signer types.Signer, from TestAccount, payer TestAccount, gasPrice *big.Int, codeFormat params.CodeFormat) *types.Transaction {
   114  	values := genMapForDeployWithCodeFormat(t, from, gasPrice, codeFormat)
   115  
   116  	tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values)
   117  	assert.Equal(t, nil, err)
   118  
   119  	err = tx.SignWithKeys(signer, from.GetTxKeys())
   120  	assert.Equal(t, nil, err)
   121  
   122  	return tx
   123  }
   124  
   125  func genFeeDelegatedSmartContractDeployWithCodeFormat(t *testing.T, signer types.Signer, from TestAccount, payer TestAccount, gasPrice *big.Int, codeFormat params.CodeFormat) *types.Transaction {
   126  	values := genMapForDeployWithCodeFormat(t, from, gasPrice, codeFormat)
   127  	values[types.TxValueKeyFeePayer] = payer.GetAddr()
   128  
   129  	tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedSmartContractDeploy, values)
   130  	assert.Equal(t, nil, err)
   131  
   132  	err = tx.SignWithKeys(signer, from.GetTxKeys())
   133  	assert.Equal(t, nil, err)
   134  
   135  	err = tx.SignFeePayerWithKeys(signer, payer.GetFeeKeys())
   136  	assert.Equal(t, nil, err)
   137  
   138  	return tx
   139  }
   140  
   141  func genFeeDelegatedWithRatioSmartContractDeployWithCodeFormat(t *testing.T, signer types.Signer, from TestAccount, payer TestAccount, gasPrice *big.Int, codeFormat params.CodeFormat) *types.Transaction {
   142  	values := genMapForDeployWithCodeFormat(t, from, gasPrice, codeFormat)
   143  	values[types.TxValueKeyFeePayer] = payer.GetAddr()
   144  	values[types.TxValueKeyFeeRatioOfFeePayer] = types.FeeRatio(30)
   145  
   146  	tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedSmartContractDeployWithRatio, values)
   147  	assert.Equal(t, nil, err)
   148  
   149  	err = tx.SignWithKeys(signer, from.GetTxKeys())
   150  	assert.Equal(t, nil, err)
   151  
   152  	err = tx.SignFeePayerWithKeys(signer, payer.GetFeeKeys())
   153  	assert.Equal(t, nil, err)
   154  
   155  	return tx
   156  }
   157  
   158  func genMapForDeployWithCodeFormat(t *testing.T, from TestAccount, gasPrice *big.Int, codeFormat params.CodeFormat) map[types.TxValueKeyType]interface{} {
   159  	values := map[types.TxValueKeyType]interface{}{
   160  		types.TxValueKeyNonce:         from.GetNonce(),
   161  		types.TxValueKeyAmount:        new(big.Int).SetUint64(0),
   162  		types.TxValueKeyGasLimit:      gasLimit,
   163  		types.TxValueKeyGasPrice:      gasPrice,
   164  		types.TxValueKeyTo:            (*common.Address)(nil),
   165  		types.TxValueKeyHumanReadable: false,
   166  		types.TxValueKeyFrom:          from.GetAddr(),
   167  		types.TxValueKeyData:          common.FromHex(code),
   168  		types.TxValueKeyCodeFormat:    codeFormat,
   169  	}
   170  
   171  	return values
   172  }