github.com/klaytn/klaytn@v1.12.1/blockchain/vm/evm_test.go (about) 1 package vm 2 3 import ( 4 "errors" 5 "math" 6 "math/big" 7 "testing" 8 9 "github.com/klaytn/klaytn/blockchain/state" 10 "github.com/klaytn/klaytn/common" 11 "github.com/klaytn/klaytn/kerrors" 12 "github.com/klaytn/klaytn/params" 13 "github.com/klaytn/klaytn/storage/database" 14 "github.com/stretchr/testify/assert" 15 ) 16 17 // Block data 18 var ( 19 Block4 = big.NewInt(4) // Block number before the istanbulHF 20 Block5 = big.NewInt(5) // Block number after the istanbulHF(also istanbulHF Block number) 21 ) 22 23 type TestData struct { 24 addr string 25 input []byte 26 // Test condition 27 isDeployedAfterIstanbulHF bool // contract deployment time 28 block *big.Int // block when execution is done 29 // Expect field 30 expectGas uint64 31 expectRet string 32 expectErr error 33 } 34 35 func runPrecompiledContractTestWithHFCondition(t *testing.T, config *params.ChainConfig, testData []TestData) { 36 for _, tc := range testData { 37 // Make StateDB 38 callerAddr := common.BytesToAddress([]byte("contract")) 39 statedb, _ := state.New(common.Hash{}, state.NewDatabase(database.NewMemoryDBManager()), nil, nil) 40 statedb.CreateSmartContractAccount(callerAddr, params.CodeFormatEVM, params.Rules{IsIstanbul: tc.isDeployedAfterIstanbulHF}) 41 42 // Make EVM environment 43 blockCtx := BlockContext{ 44 CanTransfer: func(StateDB, common.Address, *big.Int) bool { return true }, 45 Transfer: func(StateDB, common.Address, common.Address, *big.Int) {}, 46 BlockNumber: tc.block, 47 } 48 vmenv := NewEVM(blockCtx, TxContext{}, statedb, config, &Config{}) 49 50 // run 51 ret, gas, err := vmenv.Call(AccountRef(callerAddr), common.HexToAddress(tc.addr), tc.input, math.MaxUint64, new(big.Int)) 52 53 // compare with expected data 54 assert.Equal(t, tc.expectRet, common.Bytes2Hex(ret)) 55 assert.Equal(t, tc.expectGas, math.MaxUint64-gas) 56 assert.Equal(t, tc.expectErr, err) 57 } 58 } 59 60 func TestPrecompiledContractAddressMapping(t *testing.T) { 61 var ( 62 // Test Input 63 vmLogInput = []byte("Hello") 64 feePayerInput = []byte("") 65 validateInput = common.Hex2Bytes("00000000000000000000000000000001234567890000000000000000000000000000000000000000000000000000000000000000db38e383310a432f1cec0bfbd765fe67c9932b02295b1f2062a785eec288b2f962d578d163a8b13c9cee127e0b24c01d1906979ac3bc6a763bf95c50999ca97c01") 66 // Expected Output 67 vmLogOutput = "" 68 feePayerOutput = "000000000000000000000000636f6e7472616374" 69 validateOutput = "00" 70 // Test ChainConfig 71 config = ¶ms.ChainConfig{IstanbulCompatibleBlock: Block5} // Set IstanbulCompatible block number as '5' 72 ) 73 74 runPrecompiledContractTestWithHFCondition(t, config, []TestData{ 75 // Expect Normal Behavior 76 // Condition 1. Caller Contract Deploy - before IstanbulCompatible, Call - before istanbulCompatible 77 {"0x009", vmLogInput, false, Block4, 200, vmLogOutput, nil}, 78 {"0x00a", feePayerInput, false, Block4, 300, feePayerOutput, nil}, 79 {"0x00b", validateInput, false, Block4, 5000, validateOutput, nil}, 80 // Condition 2. Caller Contract Deploy - before IstanbulCompatible, Call - after istanbulCompatible 81 {"0x009", vmLogInput, false, Block5, 200, vmLogOutput, nil}, 82 {"0x00a", feePayerInput, false, Block5, 300, feePayerOutput, nil}, 83 {"0x00b", validateInput, false, Block5, 5000, validateOutput, nil}, 84 // Condition 3. Caller Contract Deploy - after IstanbulCompatible, Call - after istanbulCompatible 85 {"0x3fd", vmLogInput, true, Block5, 200, vmLogOutput, nil}, 86 {"0x3fe", feePayerInput, true, Block5, 300, feePayerOutput, nil}, 87 {"0x3ff", validateInput, true, Block5, 5000, validateOutput, nil}, 88 89 // Expect Error Behavior 90 // Condition 1. Caller Contract Deploy - before IstanbulCompatible, Call - before istanbulCompatible 91 {"0x3fd", vmLogInput, false, Block4, 0, "", kerrors.ErrPrecompiledContractAddress}, 92 {"0x3fe", feePayerInput, false, Block4, 0, "", kerrors.ErrPrecompiledContractAddress}, 93 {"0x3ff", validateInput, false, Block4, 0, "", kerrors.ErrPrecompiledContractAddress}, 94 // Condition 2. Caller Contract Deploy - before IstanbulCompatible, Call - after istanbulCompatible 95 {"0x3fd", vmLogInput, false, Block5, 0, "", kerrors.ErrPrecompiledContractAddress}, 96 {"0x3fe", feePayerInput, false, Block5, 0, "", kerrors.ErrPrecompiledContractAddress}, 97 {"0x3ff", validateInput, false, Block5, 0, "", kerrors.ErrPrecompiledContractAddress}, 98 // Condition 3. Caller Contract Deploy - after IstanbulCompatible, Call - after istanbulCompatible 99 {"0x009", vmLogInput, true, Block5, math.MaxUint64, "", errors.New("invalid input length")}, 100 {"0x00a", feePayerInput, true, Block5, 0, "", kerrors.ErrPrecompiledContractAddress}, 101 {"0x00b", validateInput, true, Block5, 0, "", kerrors.ErrPrecompiledContractAddress}, 102 }) 103 } 104 105 func TestBn256GasCost(t *testing.T) { 106 var ( 107 // Test Input 108 bn256AddInput = common.Hex2Bytes("18b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f3726607c2b7f58a84bd6145f00c9c2bc0bb1a187f20ff2c92963a88019e7c6a014eed06614e20c147e940f2d70da3f74c9a17df361706a4485c742bd6788478fa17d7") 109 bn256ScalarMulInput = common.Hex2Bytes("2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb721611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb20400000000000000000000000000000000000000000000000011138ce750fa15c2") 110 bn256PairingInput = common.Hex2Bytes("1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f593034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf704bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a416782bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa") 111 // Expected Output 112 bn256AddOutput = "2243525c5efd4b9c3d3c45ac0ca3fe4dd85e830a4ce6b65fa1eeaee202839703301d1d33be6da8e509df21cc35964723180eed7532537db9ae5e7d48f195c915" 113 bn256ScalarMulOutput = "070a8d6a982153cae4be29d434e8faef8a47b274a053f5a4ee2a6c9c13c31e5c031b8ce914eba3a9ffb989f9cdd5b0f01943074bf4f0f315690ec3cec6981afc" 114 bn256PairingOutput = "0000000000000000000000000000000000000000000000000000000000000001" 115 // Test ChainConfig 116 config = ¶ms.ChainConfig{IstanbulCompatibleBlock: Block5} 117 ) 118 119 runPrecompiledContractTestWithHFCondition(t, config, []TestData{ 120 // Test whether appropriate gas cost is returned 121 // Condition 1. Caller Contract Deploy - before IstanbulCompatible, Call - before istanbulCompatible 122 {"0x006", bn256AddInput, false, Block4, params.Bn256AddGasByzantium, bn256AddOutput, nil}, 123 {"0x007", bn256ScalarMulInput, false, Block4, params.Bn256ScalarMulGasByzantium, bn256ScalarMulOutput, nil}, 124 {"0x008", bn256PairingInput, false, Block4, params.Bn256PairingBaseGasByzantium + params.Bn256PairingPerPointGasByzantium*uint64(len(bn256PairingInput)/192), bn256PairingOutput, nil}, 125 // Condition 2. Caller Contract Deploy - before IstanbulCompatible, Call - after istanbulCompatible 126 {"0x006", bn256AddInput, false, Block5, params.Bn256AddGasByzantium, bn256AddOutput, nil}, 127 {"0x007", bn256ScalarMulInput, false, Block5, params.Bn256ScalarMulGasByzantium, bn256ScalarMulOutput, nil}, 128 {"0x008", bn256PairingInput, false, Block5, params.Bn256PairingBaseGasByzantium + params.Bn256PairingPerPointGasByzantium*uint64(len(bn256PairingInput)/192), bn256PairingOutput, nil}, 129 // Condition 3. Caller Contract Deploy - after IstanbulCompatible, Call - after istanbulCompatible 130 {"0x006", bn256AddInput, true, Block5, params.Bn256AddGasIstanbul, bn256AddOutput, nil}, 131 {"0x007", bn256ScalarMulInput, true, Block5, params.Bn256ScalarMulGasIstanbul, bn256ScalarMulOutput, nil}, 132 {"0x008", bn256PairingInput, true, Block5, params.Bn256PairingBaseGasIstanbul + params.Bn256PairingPerPointGasIstanbul*uint64(len(bn256PairingInput)/192), bn256PairingOutput, nil}, 133 }) 134 }