github.com/klaytn/klaytn@v1.10.2/tests/transaction_validation_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 "testing" 23 "time" 24 25 "github.com/klaytn/klaytn/blockchain" 26 "github.com/klaytn/klaytn/blockchain/types" 27 "github.com/klaytn/klaytn/blockchain/types/accountkey" 28 "github.com/klaytn/klaytn/common" 29 "github.com/klaytn/klaytn/common/profile" 30 "github.com/klaytn/klaytn/crypto" 31 "github.com/klaytn/klaytn/kerrors" 32 "github.com/klaytn/klaytn/log" 33 "github.com/klaytn/klaytn/params" 34 "github.com/stretchr/testify/assert" 35 ) 36 37 // TestValidatingUnavailableContractExecution tests validation logic of invalid contract execution transaction. 38 // TxPool will invalidate contract execution transactions sending to un-executable account even though the recipient is a contract account. 39 func TestValidatingUnavailableContractExecution(t *testing.T) { 40 log.EnableLogForTest(log.LvlCrit, log.LvlTrace) 41 prof := profile.NewProfiler() 42 43 // Initialize blockchain 44 start := time.Now() 45 bcdata, err := NewBCData(6, 4) 46 if err != nil { 47 t.Fatal(err) 48 } 49 prof.Profile("main_init_blockchain", time.Now().Sub(start)) 50 defer bcdata.Shutdown() 51 52 // Initialize address-balance map for verification 53 start = time.Now() 54 accountMap := NewAccountMap() 55 if err := accountMap.Initialize(bcdata); err != nil { 56 t.Fatal(err) 57 } 58 prof.Profile("main_init_accountMap", time.Now().Sub(start)) 59 60 signer := types.LatestSignerForChainID(bcdata.bc.Config().ChainID) 61 gasPrice := new(big.Int).SetUint64(bcdata.bc.Config().UnitPrice) 62 63 // reservoir account 64 reservoir := &TestAccountType{ 65 Addr: *bcdata.addrs[0], 66 Keys: []*ecdsa.PrivateKey{bcdata.privKeys[0]}, 67 Nonce: uint64(0), 68 } 69 70 // various accounts preparation 71 contract, err := createAnonymousAccount("98275a145bc1726eb0445433088f5f882f8a4a9499135239cfb4040e78991dab") 72 contract.Addr = common.Address{} 73 74 invalidContract, err := createAnonymousAccount("11115a145bc1726eb0445433088f5f882f8a4a9499135239cfb4040e78911111") 75 invalidContract.Addr = common.Address{} 76 77 EOA, err := createDefaultAccount(accountkey.AccountKeyTypeLegacy) 78 assert.Equal(t, nil, err) 79 80 code = "0x608060405234801561001057600080fd5b506101de806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631a39d8ef81146100805780636353586b146100a757806370a08231146100ca578063fd6b7ef8146100f8575b3360009081526001602052604081208054349081019091558154019055005b34801561008c57600080fd5b5061009561010d565b60408051918252519081900360200190f35b6100c873ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100d657600080fd5b5061009573ffffffffffffffffffffffffffffffffffffffff60043516610147565b34801561010457600080fd5b506100c8610159565b60005481565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604081208054349081019091558154019055565b60016020526000908152604090205481565b336000908152600160205260408120805490829055908111156101af57604051339082156108fc029083906000818181858888f193505050501561019c576101af565b3360009081526001602052604090208190555b505600a165627a7a72305820627ca46bb09478a015762806cc00c431230501118c7c26c30ac58c4e09e51c4f0029" 81 82 // Prepare. creates various types of accounts tried to be executed 83 { 84 var txs types.Transactions 85 86 // tx to create a contract account 87 values := map[types.TxValueKeyType]interface{}{ 88 types.TxValueKeyNonce: reservoir.GetNonce(), 89 types.TxValueKeyAmount: new(big.Int).SetUint64(0), 90 types.TxValueKeyGasLimit: gasLimit, 91 types.TxValueKeyGasPrice: gasPrice, 92 types.TxValueKeyHumanReadable: false, 93 types.TxValueKeyTo: (*common.Address)(nil), 94 types.TxValueKeyFrom: reservoir.GetAddr(), 95 types.TxValueKeyData: common.FromHex(code), 96 types.TxValueKeyCodeFormat: params.CodeFormatEVM, 97 } 98 tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values) 99 assert.Equal(t, nil, err) 100 101 err = tx.SignWithKeys(signer, reservoir.Keys) 102 assert.Equal(t, nil, err) 103 104 txs = append(txs, tx) 105 106 contract.Addr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce) 107 108 reservoir.Nonce += 1 109 110 // tx2 to create a invalid contract account 111 values = map[types.TxValueKeyType]interface{}{ 112 types.TxValueKeyNonce: reservoir.GetNonce(), 113 types.TxValueKeyAmount: new(big.Int).SetUint64(0), 114 types.TxValueKeyGasLimit: gasLimit, 115 types.TxValueKeyGasPrice: gasPrice, 116 types.TxValueKeyHumanReadable: false, 117 types.TxValueKeyTo: (*common.Address)(nil), 118 types.TxValueKeyFrom: reservoir.GetAddr(), 119 types.TxValueKeyData: []byte{}, // the invalid contract doesn't have contract code 120 types.TxValueKeyCodeFormat: params.CodeFormatEVM, 121 } 122 tx2, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values) 123 assert.Equal(t, nil, err) 124 125 err = tx2.SignWithKeys(signer, reservoir.Keys) 126 assert.Equal(t, nil, err) 127 128 txs = append(txs, tx2) 129 130 invalidContract.Addr = crypto.CreateAddress(reservoir.Addr, reservoir.Nonce) 131 132 reservoir.Nonce += 1 133 134 // tx3 to create an EOA account 135 tx3, _, err := generateDefaultTx(reservoir, EOA, types.TxTypeValueTransfer, contract.Addr) 136 assert.Equal(t, nil, err) 137 138 err = tx3.SignWithKeys(signer, reservoir.Keys) 139 assert.Equal(t, nil, err) 140 141 txs = append(txs, tx3) 142 reservoir.Nonce += 1 143 144 if err := bcdata.GenABlockWithTransactions(accountMap, txs, prof); err != nil { 145 t.Fatal(err) 146 } 147 } 148 149 // make TxPool to test validation in 'TxPool add' process 150 txpool := blockchain.NewTxPool(blockchain.DefaultTxPoolConfig, bcdata.bc.Config(), bcdata.bc) 151 152 // 1. contract execution transaction to the contract account. 153 { 154 tx, _ := genSmartContractExecution(t, signer, reservoir, contract, nil, gasPrice) 155 156 err = txpool.AddRemote(tx) 157 assert.Equal(t, nil, err) 158 } 159 160 // 2. contract execution transaction to the invalid contract account. 161 { 162 tx, _ := genSmartContractExecution(t, signer, reservoir, invalidContract, nil, gasPrice) 163 164 err = txpool.AddRemote(tx) 165 assert.Equal(t, kerrors.ErrNotProgramAccount, err) 166 } 167 168 // 3. contract execution transaction to the EOA account. 169 { 170 tx, _ := genSmartContractExecution(t, signer, reservoir, EOA, nil, gasPrice) 171 172 err = txpool.AddRemote(tx) 173 assert.Equal(t, kerrors.ErrNotProgramAccount, err) 174 } 175 176 if testing.Verbose() { 177 prof.PrintProfileInfo() 178 } 179 }