github.com/klaytn/klaytn@v1.12.1/api/api_ethereum_test.go (about) 1 package api 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 "errors" 8 "fmt" 9 "math/big" 10 "reflect" 11 "testing" 12 "time" 13 14 "github.com/golang/mock/gomock" 15 "github.com/klaytn/klaytn/accounts" 16 mock_accounts "github.com/klaytn/klaytn/accounts/mocks" 17 mock_api "github.com/klaytn/klaytn/api/mocks" 18 "github.com/klaytn/klaytn/blockchain" 19 "github.com/klaytn/klaytn/blockchain/state" 20 "github.com/klaytn/klaytn/blockchain/types" 21 "github.com/klaytn/klaytn/blockchain/types/accountkey" 22 "github.com/klaytn/klaytn/blockchain/vm" 23 "github.com/klaytn/klaytn/common" 24 "github.com/klaytn/klaytn/common/hexutil" 25 "github.com/klaytn/klaytn/consensus" 26 "github.com/klaytn/klaytn/consensus/gxhash" 27 "github.com/klaytn/klaytn/consensus/mocks" 28 "github.com/klaytn/klaytn/crypto" 29 "github.com/klaytn/klaytn/governance" 30 "github.com/klaytn/klaytn/networks/rpc" 31 "github.com/klaytn/klaytn/params" 32 "github.com/klaytn/klaytn/rlp" 33 "github.com/klaytn/klaytn/storage/database" 34 "github.com/stretchr/testify/assert" 35 "github.com/stretchr/testify/require" 36 ) 37 38 var dummyChainConfigForEthereumAPITest = ¶ms.ChainConfig{ 39 ChainID: new(big.Int).SetUint64(111111), 40 IstanbulCompatibleBlock: new(big.Int).SetUint64(0), 41 LondonCompatibleBlock: new(big.Int).SetUint64(0), 42 EthTxTypeCompatibleBlock: new(big.Int).SetUint64(0), 43 UnitPrice: 25000000000, // 25 ston 44 } 45 46 var ( 47 testLondonConfig = ¶ms.ChainConfig{ 48 ChainID: new(big.Int).SetUint64(111111), 49 IstanbulCompatibleBlock: common.Big0, 50 LondonCompatibleBlock: common.Big0, 51 UnitPrice: 25000000000, 52 } 53 testEthTxTypeConfig = ¶ms.ChainConfig{ 54 ChainID: new(big.Int).SetUint64(111111), 55 IstanbulCompatibleBlock: common.Big0, 56 LondonCompatibleBlock: common.Big0, 57 EthTxTypeCompatibleBlock: common.Big0, 58 UnitPrice: 25000000000, // 25 ston 59 } 60 testRandaoConfig = ¶ms.ChainConfig{ 61 ChainID: new(big.Int).SetUint64(111111), 62 IstanbulCompatibleBlock: common.Big0, 63 LondonCompatibleBlock: common.Big0, 64 EthTxTypeCompatibleBlock: common.Big0, 65 MagmaCompatibleBlock: common.Big0, 66 KoreCompatibleBlock: common.Big0, 67 ShanghaiCompatibleBlock: common.Big0, 68 CancunCompatibleBlock: common.Big0, 69 RandaoCompatibleBlock: common.Big0, 70 UnitPrice: 25000000000, // 25 ston 71 } 72 ) 73 74 // TestEthereumAPI_Etherbase tests Etherbase. 75 func TestEthereumAPI_Etherbase(t *testing.T) { 76 testNodeAddress(t, "Etherbase") 77 } 78 79 // TestEthereumAPI_Coinbase tests Coinbase. 80 func TestEthereumAPI_Coinbase(t *testing.T) { 81 testNodeAddress(t, "Coinbase") 82 } 83 84 // testNodeAddress generates nodeAddress and tests Etherbase and Coinbase. 85 func testNodeAddress(t *testing.T, testAPIName string) { 86 gov := governance.NewMixedEngineNoInit( 87 dummyChainConfigForEthereumAPITest, 88 database.NewMemoryDBManager(), 89 ) 90 key, _ := crypto.GenerateKey() 91 nodeAddress := crypto.PubkeyToAddress(key.PublicKey) 92 gov.SetNodeAddress(nodeAddress) 93 94 api := EthereumAPI{governanceAPI: governance.NewGovernanceAPI(gov)} 95 results := reflect.ValueOf(&api).MethodByName(testAPIName).Call([]reflect.Value{}) 96 result, ok := results[0].Interface().(common.Address) 97 assert.True(t, ok) 98 assert.Equal(t, nodeAddress, result) 99 } 100 101 // TestEthereumAPI_Hashrate tests Hasharate. 102 func TestEthereumAPI_Hashrate(t *testing.T) { 103 api := &EthereumAPI{} 104 assert.Equal(t, hexutil.Uint64(ZeroHashrate), api.Hashrate()) 105 } 106 107 // TestEthereumAPI_Mining tests Mining. 108 func TestEthereumAPI_Mining(t *testing.T) { 109 api := &EthereumAPI{} 110 assert.Equal(t, false, api.Mining()) 111 } 112 113 // TestEthereumAPI_GetWork tests GetWork. 114 func TestEthereumAPI_GetWork(t *testing.T) { 115 api := &EthereumAPI{} 116 _, err := api.GetWork() 117 assert.Equal(t, errNoMiningWork, err) 118 } 119 120 // TestEthereumAPI_SubmitWork tests SubmitWork. 121 func TestEthereumAPI_SubmitWork(t *testing.T) { 122 api := &EthereumAPI{} 123 assert.Equal(t, false, api.SubmitWork(BlockNonce{}, common.Hash{}, common.Hash{})) 124 } 125 126 // TestEthereumAPI_SubmitHashrate tests SubmitHashrate. 127 func TestEthereumAPI_SubmitHashrate(t *testing.T) { 128 api := &EthereumAPI{} 129 assert.Equal(t, false, api.SubmitHashrate(hexutil.Uint64(0), common.Hash{})) 130 } 131 132 // TestEthereumAPI_GetHashrate tests GetHashrate. 133 func TestEthereumAPI_GetHashrate(t *testing.T) { 134 api := &EthereumAPI{} 135 assert.Equal(t, ZeroHashrate, api.GetHashrate()) 136 } 137 138 // TestEthereumAPI_GetUncleByBlockNumberAndIndex tests GetUncleByBlockNumberAndIndex. 139 func TestEthereumAPI_GetUncleByBlockNumberAndIndex(t *testing.T) { 140 api := &EthereumAPI{} 141 uncleBlock, err := api.GetUncleByBlockNumberAndIndex(context.Background(), rpc.BlockNumber(0), hexutil.Uint(0)) 142 assert.NoError(t, err) 143 assert.Nil(t, uncleBlock) 144 } 145 146 // TestEthereumAPI_GetUncleByBlockHashAndIndex tests GetUncleByBlockHashAndIndex. 147 func TestEthereumAPI_GetUncleByBlockHashAndIndex(t *testing.T) { 148 api := &EthereumAPI{} 149 uncleBlock, err := api.GetUncleByBlockHashAndIndex(context.Background(), common.Hash{}, hexutil.Uint(0)) 150 assert.NoError(t, err) 151 assert.Nil(t, uncleBlock) 152 } 153 154 // TestTestEthereumAPI_GetUncleCountByBlockNumber tests GetUncleCountByBlockNumber. 155 func TestTestEthereumAPI_GetUncleCountByBlockNumber(t *testing.T) { 156 mockCtrl, mockBackend, api := testInitForEthApi(t) 157 block, _, _, _, _ := createTestData(t, nil) 158 159 // For existing block number, it must return 0. 160 mockBackend.EXPECT().BlockByNumber(gomock.Any(), gomock.Any()).Return(block, nil) 161 existingBlockNumber := rpc.BlockNumber(block.Number().Int64()) 162 assert.Equal(t, hexutil.Uint(ZeroUncleCount), *api.GetUncleCountByBlockNumber(context.Background(), existingBlockNumber)) 163 164 // For non-existing block number, it must return nil. 165 mockBackend.EXPECT().BlockByNumber(gomock.Any(), gomock.Any()).Return(nil, nil) 166 nonExistingBlockNumber := rpc.BlockNumber(5) 167 uncleCount := api.GetUncleCountByBlockNumber(context.Background(), nonExistingBlockNumber) 168 uintNil := hexutil.Uint(uint(0)) 169 expectedResult := &uintNil 170 expectedResult = nil 171 assert.Equal(t, expectedResult, uncleCount) 172 173 mockCtrl.Finish() 174 } 175 176 // TestTestEthereumAPI_GetUncleCountByBlockHash tests GetUncleCountByBlockHash. 177 func TestTestEthereumAPI_GetUncleCountByBlockHash(t *testing.T) { 178 mockCtrl, mockBackend, api := testInitForEthApi(t) 179 block, _, _, _, _ := createTestData(t, nil) 180 181 // For existing block hash, it must return 0. 182 mockBackend.EXPECT().BlockByHash(gomock.Any(), gomock.Any()).Return(block, nil) 183 existingHash := block.Hash() 184 assert.Equal(t, hexutil.Uint(ZeroUncleCount), *api.GetUncleCountByBlockHash(context.Background(), existingHash)) 185 186 // For non-existing block hash, it must return nil. 187 mockBackend.EXPECT().BlockByHash(gomock.Any(), gomock.Any()).Return(nil, nil) 188 nonExistingHash := block.Hash() 189 uncleCount := api.GetUncleCountByBlockHash(context.Background(), nonExistingHash) 190 uintNil := hexutil.Uint(uint(0)) 191 expectedResult := &uintNil 192 expectedResult = nil 193 assert.Equal(t, expectedResult, uncleCount) 194 195 mockCtrl.Finish() 196 } 197 198 // TestEthereumAPI_GetHeaderByNumber tests GetHeaderByNumber. 199 func TestEthereumAPI_GetHeaderByNumber(t *testing.T) { 200 testGetHeader(t, "GetHeaderByNumber", testLondonConfig) 201 testGetHeader(t, "GetHeaderByNumber", testEthTxTypeConfig) 202 testGetHeader(t, "GetHeaderByNumber", testRandaoConfig) 203 } 204 205 // TestEthereumAPI_GetHeaderByHash tests GetHeaderByNumber. 206 func TestEthereumAPI_GetHeaderByHash(t *testing.T) { 207 testGetHeader(t, "GetHeaderByHash", testLondonConfig) 208 testGetHeader(t, "GetHeaderByHash", testEthTxTypeConfig) 209 testGetHeader(t, "GetHeaderByHash", testRandaoConfig) 210 } 211 212 // testGetHeader generates data to test GetHeader related functions in EthereumAPI 213 // and actually tests the API function passed as a parameter. 214 func testGetHeader(t *testing.T, testAPIName string, config *params.ChainConfig) { 215 mockCtrl, mockBackend, api := testInitForEthApi(t) 216 217 // Creates a MockEngine. 218 mockEngine := mocks.NewMockEngine(mockCtrl) 219 // GetHeader APIs calls internally below methods. 220 mockBackend.EXPECT().Engine().Return(mockEngine) 221 mockBackend.EXPECT().ChainConfig().Return(config).AnyTimes() 222 223 // Author is called when calculates miner field of Header. 224 dummyMiner := common.HexToAddress("0x9712f943b296758aaae79944ec975884188d3a96") 225 mockEngine.EXPECT().Author(gomock.Any()).Return(dummyMiner, nil) 226 var dummyTotalDifficulty uint64 = 5 227 mockBackend.EXPECT().GetTd(gomock.Any()).Return(new(big.Int).SetUint64(dummyTotalDifficulty)) 228 229 // Create dummy header 230 header := types.CopyHeader(&types.Header{ 231 ParentHash: common.HexToHash("0xc8036293065bacdfce87debec0094a71dbbe40345b078d21dcc47adb4513f348"), 232 Rewardbase: common.Address{}, 233 TxHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"), 234 Root: common.HexToHash("0xad31c32942fa033166e4ef588ab973dbe26657c594de4ba98192108becf0fec9"), 235 ReceiptHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"), 236 Bloom: types.Bloom{}, 237 BlockScore: new(big.Int).SetUint64(1), 238 Number: new(big.Int).SetUint64(4), 239 GasUsed: uint64(10000), 240 Time: new(big.Int).SetUint64(1641363540), 241 TimeFoS: uint8(85), 242 Extra: common.Hex2Bytes("0xd983010701846b6c617988676f312e31362e338664617277696e000000000000f89ed5949712f943b296758aaae79944ec975884188d3a96b8415a0614be7fd5ea40f11ce558e02993bd55f11ae72a3cfbc861875a57483ec5ec3adda3e5845fd7ab271d670c755480f9ef5b8dd731f4e1f032fff5d165b763ac01f843b8418867d3733167a0c737fa5b62dcc59ec3b0af5748bcc894e7990a0b5a642da4546713c9127b3358cdfe7894df1ca1db5a97560599986d7f1399003cd63660b98200"), 243 Governance: []byte{}, 244 Vote: []byte{}, 245 }) 246 if config.IsRandaoForkEnabled(common.Big0) { 247 header.RandomReveal = hexutil.MustDecode("0x94516a8bc695b5bf43aa077cd682d9475a3a6bed39a633395b78ed8f276e7c5bb00bb26a77825013c6718579f1b3ee2275b158801705ea77989e3acc849ee9c524bd1822bde3cba7be2aae04347f0d91508b7b7ce2f11ec36cbf763173421ae7") 248 header.MixHash = hexutil.MustDecode("0xdf117d1245dceaae0a47f05371b23cd0d0db963ff9d5c8ba768dc989f4c31883") 249 } 250 251 var blockParam interface{} 252 switch testAPIName { 253 case "GetHeaderByNumber": 254 blockParam = rpc.BlockNumber(header.Number.Uint64()) 255 mockBackend.EXPECT().HeaderByNumber(gomock.Any(), gomock.Any()).Return(header, nil) 256 case "GetHeaderByHash": 257 blockParam = header.Hash() 258 mockBackend.EXPECT().HeaderByHash(gomock.Any(), gomock.Any()).Return(header, nil) 259 } 260 261 results := reflect.ValueOf(&api).MethodByName(testAPIName).Call( 262 []reflect.Value{ 263 reflect.ValueOf(context.Background()), 264 reflect.ValueOf(blockParam), 265 }, 266 ) 267 ethHeader, ok := results[0].Interface().(map[string]interface{}) 268 assert.Equal(t, true, ok) 269 assert.NotEqual(t, ethHeader, nil) 270 271 // We can get a real mashaled data by using real backend instance, not mock 272 // Mock just return a header instance, not rlp decoded json data 273 expected := make(map[string]interface{}) 274 assert.NoError(t, json.Unmarshal([]byte(` 275 { 276 "difficulty": "0x1", 277 "extraData": "0x", 278 "gasLimit": "0xe8d4a50fff", 279 "gasUsed": "0x2710", 280 "hash": "0xd6d5d8295f612bc824762f1945f4271c73aee9306bcf91e151d269369526ba60", 281 "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 282 "miner": "0x9712f943b296758aaae79944ec975884188d3a96", 283 "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", 284 "nonce": "0x0000000000000000", 285 "number": "0x4", 286 "parentHash": "0xc8036293065bacdfce87debec0094a71dbbe40345b078d21dcc47adb4513f348", 287 "receiptsRoot": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", 288 "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", 289 "size": "0x244", 290 "stateRoot": "0xad31c32942fa033166e4ef588ab973dbe26657c594de4ba98192108becf0fec9", 291 "timestamp": "0x61d53854", 292 "totalDifficulty": "0x5", 293 "transactionsRoot": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" 294 }`), &expected)) 295 296 if config.IsEthTxTypeForkEnabled(common.Big0) { 297 expected["baseFeePerGas"] = "0x0" 298 } 299 if config.IsRandaoForkEnabled(common.Big0) { 300 expected["randomReveal"] = "0x94516a8bc695b5bf43aa077cd682d9475a3a6bed39a633395b78ed8f276e7c5bb00bb26a77825013c6718579f1b3ee2275b158801705ea77989e3acc849ee9c524bd1822bde3cba7be2aae04347f0d91508b7b7ce2f11ec36cbf763173421ae7" 301 expected["mixHash"] = "0xdf117d1245dceaae0a47f05371b23cd0d0db963ff9d5c8ba768dc989f4c31883" 302 expected["hash"] = "0x4179dd7e323cde164e287045857cbc930892f92479d8c375d5d622ddde59f912" 303 expected["size"] = "0x2c4" 304 } 305 assert.Equal(t, stringifyMap(expected), stringifyMap(ethHeader)) 306 } 307 308 // TestEthereumAPI_GetBlockByNumber tests GetBlockByNumber. 309 func TestEthereumAPI_GetBlockByNumber(t *testing.T) { 310 testGetBlock(t, "GetBlockByNumber", false) 311 testGetBlock(t, "GetBlockByNumber", true) 312 } 313 314 // TestEthereumAPI_GetBlockByHash tests GetBlockByHash. 315 func TestEthereumAPI_GetBlockByHash(t *testing.T) { 316 testGetBlock(t, "GetBlockByHash", false) 317 testGetBlock(t, "GetBlockByHash", true) 318 } 319 320 // testGetBlock generates data to test GetBlock related functions in EthereumAPI 321 // and actually tests the API function passed as a parameter. 322 func testGetBlock(t *testing.T, testAPIName string, fullTxs bool) { 323 mockCtrl, mockBackend, api := testInitForEthApi(t) 324 325 // Creates a MockEngine. 326 mockEngine := mocks.NewMockEngine(mockCtrl) 327 // GetHeader APIs calls internally below methods. 328 mockBackend.EXPECT().Engine().Return(mockEngine) 329 mockBackend.EXPECT().ChainConfig().Return(dummyChainConfigForEthereumAPITest).AnyTimes() 330 // Author is called when calculates miner field of Header. 331 dummyMiner := common.HexToAddress("0x9712f943b296758aaae79944ec975884188d3a96") 332 mockEngine.EXPECT().Author(gomock.Any()).Return(dummyMiner, nil) 333 var dummyTotalDifficulty uint64 = 5 334 mockBackend.EXPECT().GetTd(gomock.Any()).Return(new(big.Int).SetUint64(dummyTotalDifficulty)) 335 336 // Create dummy header 337 header := types.CopyHeader(&types.Header{ 338 ParentHash: common.HexToHash("0xc8036293065bacdfce87debec0094a71dbbe40345b078d21dcc47adb4513f348"), Rewardbase: common.Address{}, TxHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"), 339 Root: common.HexToHash("0xad31c32942fa033166e4ef588ab973dbe26657c594de4ba98192108becf0fec9"), 340 ReceiptHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"), 341 Bloom: types.Bloom{}, 342 BlockScore: new(big.Int).SetUint64(1), 343 Number: new(big.Int).SetUint64(4), 344 GasUsed: uint64(10000), 345 Time: new(big.Int).SetUint64(1641363540), 346 TimeFoS: uint8(85), 347 Extra: common.Hex2Bytes("0xd983010701846b6c617988676f312e31362e338664617277696e000000000000f89ed5949712f943b296758aaae79944ec975884188d3a96b8415a0614be7fd5ea40f11ce558e02993bd55f11ae72a3cfbc861875a57483ec5ec3adda3e5845fd7ab271d670c755480f9ef5b8dd731f4e1f032fff5d165b763ac01f843b8418867d3733167a0c737fa5b62dcc59ec3b0af5748bcc894e7990a0b5a642da4546713c9127b3358cdfe7894df1ca1db5a97560599986d7f1399003cd63660b98200"), 348 Governance: []byte{}, 349 Vote: []byte{}, 350 }) 351 block, _, _, _, _ := createTestData(t, header) 352 var blockParam interface{} 353 switch testAPIName { 354 case "GetBlockByNumber": 355 blockParam = rpc.BlockNumber(block.NumberU64()) 356 mockBackend.EXPECT().BlockByNumber(gomock.Any(), gomock.Any()).Return(block, nil) 357 case "GetBlockByHash": 358 blockParam = block.Hash() 359 mockBackend.EXPECT().BlockByHash(gomock.Any(), gomock.Any()).Return(block, nil) 360 } 361 362 results := reflect.ValueOf(&api).MethodByName(testAPIName).Call( 363 []reflect.Value{ 364 reflect.ValueOf(context.Background()), 365 reflect.ValueOf(blockParam), 366 reflect.ValueOf(fullTxs), 367 }, 368 ) 369 ethBlock, ok := results[0].Interface().(map[string]interface{}) 370 assert.Equal(t, true, ok) 371 assert.NotEqual(t, ethBlock, nil) 372 373 expected := make(map[string]interface{}) 374 if fullTxs { 375 assert.NoError(t, json.Unmarshal([]byte(` 376 { 377 "baseFeePerGas": "0x0", 378 "difficulty": "0x1", 379 "extraData": "0x", 380 "gasLimit": "0xe8d4a50fff", 381 "gasUsed": "0x2710", 382 "hash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 383 "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 384 "miner": "0x9712f943b296758aaae79944ec975884188d3a96", 385 "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", 386 "nonce": "0x0000000000000000", 387 "number": "0x4", 388 "parentHash": "0xc8036293065bacdfce87debec0094a71dbbe40345b078d21dcc47adb4513f348", 389 "receiptsRoot": "0xf6278dd71ffc1637f78dc2ee54f6f9e64d4b1633c1179dfdbc8c3b482efbdbec", 390 "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", 391 "size": "0xe44", 392 "stateRoot": "0xad31c32942fa033166e4ef588ab973dbe26657c594de4ba98192108becf0fec9", 393 "timestamp": "0x61d53854", 394 "totalDifficulty": "0x5", 395 "transactions": [ 396 { 397 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 398 "blockNumber": "0x4", 399 "from": "0x0000000000000000000000000000000000000000", 400 "gas": "0x1c9c380", 401 "gasPrice": "0x5d21dba00", 402 "hash": "0x6231f24f79d28bb5b8425ce577b3b77cd9c1ab766fcfc5233358a2b1c2f4ff70", 403 "input": "0x3078653331393765386630303030303030303030303030303030303030303030303065306265663939623461323232383665323736333062343835643036633561313437636565393331303030303030303030303030303030303030303030303030313538626566663863386364656264363436353461646435663661316439393337653733353336633030303030303030303030303030303030303030303030303030303030303030303030303030303030303030323962623565376662366265616533326366383030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030306530303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303138303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030316236306662343631346132326530303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303031303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030343030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303031353862656666386338636465626436343635346164643566366131643939333765373335333663303030303030303030303030303030303030303030303030373462613033313938666564326231356135316166323432623963363366616633633866346433343030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303033303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030", 404 "nonce": "0x0", 405 "to": "0x3736346135356338333362313038373730343930", 406 "transactionIndex": "0x0", 407 "value": "0x0", 408 "type": "0x0", 409 "v": "0x1", 410 "r": "0x2", 411 "s": "0x3" 412 }, 413 { 414 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 415 "blockNumber": "0x4", 416 "from": "0x3036656164333031646165616636376537376538", 417 "gas": "0x989680", 418 "gasPrice": "0x5d21dba00", 419 "hash": "0xf146858415c060eae65a389cbeea8aeadc79461038fbee331ffd97b41279dd63", 420 "input": "0x", 421 "nonce": "0x1", 422 "to": "0x3364613566326466626334613262333837316462", 423 "transactionIndex": "0x1", 424 "value": "0x5", 425 "type": "0x0", 426 "v": "0x1", 427 "r": "0x2", 428 "s": "0x3" 429 }, 430 { 431 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 432 "blockNumber": "0x4", 433 "from": "0x3730323366383135666136613633663761613063", 434 "gas": "0x1312d00", 435 "gasPrice": "0x5d21dba00", 436 "hash": "0x0a01fc67bb4c15c32fa43563c0fcf05cd5bf2fdcd4ec78122b5d0295993bca24", 437 "input": "0x68656c6c6f", 438 "nonce": "0x2", 439 "to": "0x3336623562313539333066323466653862616538", 440 "transactionIndex": "0x2", 441 "value": "0x3", 442 "type": "0x0", 443 "v": "0x1", 444 "r": "0x2", 445 "s": "0x3" 446 }, 447 { 448 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 449 "blockNumber": "0x4", 450 "from": "0x3936663364636533666637396132333733653330", 451 "gas": "0x1312d00", 452 "gasPrice": "0x5d21dba00", 453 "hash": "0x486f7561375c38f1627264f8676f92ec0dd1c4a7c52002ba8714e61fcc6bb649", 454 "input": "0x", 455 "nonce": "0x3", 456 "to": "0x3936663364636533666637396132333733653330", 457 "transactionIndex": "0x3", 458 "value": "0x0", 459 "type": "0x0", 460 "v": "0x1", 461 "r": "0x2", 462 "s": "0x3" 463 }, 464 { 465 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 466 "blockNumber": "0x4", 467 "from": "0x3936663364636533666637396132333733653330", 468 "gas": "0x5f5e100", 469 "gasPrice": "0x5d21dba00", 470 "hash": "0xbd3e57cd31dd3d6679326f7a949f0de312e9ae53bec5ef3c23b43a5319c220a4", 471 "input": "0x", 472 "nonce": "0x4", 473 "to": null, 474 "transactionIndex": "0x4", 475 "value": "0x0", 476 "type": "0x0", 477 "v": "0x1", 478 "r": "0x2", 479 "s": "0x3" 480 }, 481 { 482 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 483 "blockNumber": "0x4", 484 "from": "0x3936663364636533666637396132333733653330", 485 "gas": "0x2faf080", 486 "gasPrice": "0x5d21dba00", 487 "hash": "0xff666129a0c7227b17681d668ecdef5d6681fc93dbd58856eea1374880c598b0", 488 "input": "0x", 489 "nonce": "0x5", 490 "to": "0x3632323232656162393565396564323963346266", 491 "transactionIndex": "0x5", 492 "value": "0x0", 493 "type": "0x0", 494 "v": "0x1", 495 "r": "0x2", 496 "s": "0x3" 497 }, 498 { 499 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 500 "blockNumber": "0x4", 501 "from": "0x3936663364636533666637396132333733653330", 502 "gas": "0x2faf080", 503 "gasPrice": "0x5d21dba00", 504 "hash": "0xa8ad4f295f2acff9ef56b476b1c52ecb74fb3fd95a789d768c2edb3376dbeacf", 505 "input": "0x", 506 "nonce": "0x6", 507 "to": "0x3936663364636533666637396132333733653330", 508 "transactionIndex": "0x6", 509 "value": "0x0", 510 "type": "0x0", 511 "v": "0x1", 512 "r": "0x2", 513 "s": "0x3" 514 }, 515 { 516 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 517 "blockNumber": "0x4", 518 "from": "0x3936663364636533666637396132333733653330", 519 "gas": "0x2faf080", 520 "gasPrice": "0x5d21dba00", 521 "hash": "0x47dbfd201fc1dd4188fd2003c6328a09bf49414be607867ca3a5d63573aede93", 522 "input": "0xf8ad80b8aaf8a8a0072409b14b96f9d7dbf4788dbc68c5d30bd5fac1431c299e0ab55c92e70a28a4a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a00000000000000000000000000000000000000000000000000000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a00000000000000000000000000000000000000000000000000000000000000000808080", 523 "nonce": "0x7", 524 "to": "0x3936663364636533666637396132333733653330", 525 "transactionIndex": "0x7", 526 "value": "0x0", 527 "type": "0x0", 528 "v": "0x1", 529 "r": "0x2", 530 "s": "0x3" 531 }, 532 { 533 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 534 "blockNumber": "0x4", 535 "from": "0x3036656164333031646165616636376537376538", 536 "gas": "0x989680", 537 "gasPrice": "0x5d21dba00", 538 "hash": "0x2283294e89b41df2df4dd37c375a3f51c3ad11877aa0a4b59d0f68cf5cfd865a", 539 "input": "0x", 540 "nonce": "0x8", 541 "to": "0x3364613566326466626334613262333837316462", 542 "transactionIndex": "0x8", 543 "value": "0x5", 544 "type": "0x0", 545 "v": "0x1", 546 "r": "0x2", 547 "s": "0x3" 548 }, 549 { 550 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 551 "blockNumber": "0x4", 552 "from": "0x3730323366383135666136613633663761613063", 553 "gas": "0x1312d00", 554 "gasPrice": "0x5d21dba00", 555 "hash": "0x80e05750d02d22d73926179a0611b431ae7658846406f836e903d76191423716", 556 "input": "0x68656c6c6f", 557 "nonce": "0x9", 558 "to": "0x3336623562313539333066323466653862616538", 559 "transactionIndex": "0x9", 560 "value": "0x3", 561 "type": "0x0", 562 "v": "0x1", 563 "r": "0x2", 564 "s": "0x3" 565 }, 566 { 567 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 568 "blockNumber": "0x4", 569 "from": "0x3936663364636533666637396132333733653330", 570 "gas": "0x1312d00", 571 "gasPrice": "0x5d21dba00", 572 "hash": "0xe8abdee5e8fef72fe4d98f7dbef36000407e97874e8c880df4d85646958dd2c1", 573 "input": "0x", 574 "nonce": "0xa", 575 "to": "0x3936663364636533666637396132333733653330", 576 "transactionIndex": "0xa", 577 "value": "0x0", 578 "type": "0x0", 579 "v": "0x1", 580 "r": "0x2", 581 "s": "0x3" 582 }, 583 { 584 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 585 "blockNumber": "0x4", 586 "from": "0x3936663364636533666637396132333733653330", 587 "gas": "0x5f5e100", 588 "gasPrice": "0x5d21dba00", 589 "hash": "0x4c970be1815e58e6f69321202ce38b2e5c5e5ecb70205634848afdbc57224811", 590 "input": "0x", 591 "nonce": "0xb", 592 "to": null, 593 "transactionIndex": "0xb", 594 "value": "0x0", 595 "type": "0x0", 596 "v": "0x1", 597 "r": "0x2", 598 "s": "0x3" 599 }, 600 { 601 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 602 "blockNumber": "0x4", 603 "from": "0x3936663364636533666637396132333733653330", 604 "gas": "0x2faf080", 605 "gasPrice": "0x5d21dba00", 606 "hash": "0x7ff0a809387d0a4cab77624d467f4d65ffc1ac95f4cc46c2246daab0407a7d83", 607 "input": "0x", 608 "nonce": "0xc", 609 "to": "0x3632323232656162393565396564323963346266", 610 "transactionIndex": "0xc", 611 "value": "0x0", 612 "type": "0x0", 613 "v": "0x1", 614 "r": "0x2", 615 "s": "0x3" 616 }, 617 { 618 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 619 "blockNumber": "0x4", 620 "from": "0x3936663364636533666637396132333733653330", 621 "gas": "0x2faf080", 622 "gasPrice": "0x5d21dba00", 623 "hash": "0xb510b11415b39d18a972a00e3b43adae1e0f583ea0481a4296e169561ff4d916", 624 "input": "0x", 625 "nonce": "0xd", 626 "to": "0x3936663364636533666637396132333733653330", 627 "transactionIndex": "0xd", 628 "value": "0x0", 629 "type": "0x0", 630 "v": "0x1", 631 "r": "0x2", 632 "s": "0x3" 633 }, 634 { 635 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 636 "blockNumber": "0x4", 637 "from": "0x3936663364636533666637396132333733653330", 638 "gas": "0x2faf080", 639 "gasPrice": "0x5d21dba00", 640 "hash": "0xab466145fb71a2d24d6f6af3bddf3bcfa43c20a5937905dd01963eaf9fc5e382", 641 "input": "0xf8ad80b8aaf8a8a0072409b14b96f9d7dbf4788dbc68c5d30bd5fac1431c299e0ab55c92e70a28a4a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a00000000000000000000000000000000000000000000000000000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a00000000000000000000000000000000000000000000000000000000000000000808080", 642 "nonce": "0xe", 643 "to": "0x3936663364636533666637396132333733653330", 644 "transactionIndex": "0xe", 645 "value": "0x0", 646 "type": "0x0", 647 "v": "0x1", 648 "r": "0x2", 649 "s": "0x3" 650 }, 651 { 652 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 653 "blockNumber": "0x4", 654 "from": "0x3036656164333031646165616636376537376538", 655 "gas": "0x989680", 656 "gasPrice": "0x5d21dba00", 657 "hash": "0xec714ab0875768f482daeabf7eb7be804e3c94bc1f1b687359da506c7f3a66b2", 658 "input": "0x", 659 "nonce": "0xf", 660 "to": "0x3364613566326466626334613262333837316462", 661 "transactionIndex": "0xf", 662 "value": "0x5", 663 "type": "0x0", 664 "v": "0x1", 665 "r": "0x2", 666 "s": "0x3" 667 }, 668 { 669 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 670 "blockNumber": "0x4", 671 "from": "0x3730323366383135666136613633663761613063", 672 "gas": "0x1312d00", 673 "gasPrice": "0x5d21dba00", 674 "hash": "0x069af125fe88784e46f90ace9960a09e5d23e6ace20350062be75964a7ece8e6", 675 "input": "0x68656c6c6f", 676 "nonce": "0x10", 677 "to": "0x3336623562313539333066323466653862616538", 678 "transactionIndex": "0x10", 679 "value": "0x3", 680 "type": "0x0", 681 "v": "0x1", 682 "r": "0x2", 683 "s": "0x3" 684 }, 685 { 686 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 687 "blockNumber": "0x4", 688 "from": "0x3936663364636533666637396132333733653330", 689 "gas": "0x1312d00", 690 "gasPrice": "0x5d21dba00", 691 "hash": "0x4a6bb7b2cd68265eb6a693aa270daffa3cc297765267f92be293b12e64948c82", 692 "input": "0x", 693 "nonce": "0x11", 694 "to": "0x3936663364636533666637396132333733653330", 695 "transactionIndex": "0x11", 696 "value": "0x0", 697 "type": "0x0", 698 "v": "0x1", 699 "r": "0x2", 700 "s": "0x3" 701 }, 702 { 703 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 704 "blockNumber": "0x4", 705 "from": "0x3936663364636533666637396132333733653330", 706 "gas": "0x5f5e100", 707 "gasPrice": "0x5d21dba00", 708 "hash": "0xa354fe3fdde6292e85545e6327c314827a20e0d7a1525398b38526fe28fd36e1", 709 "input": "0x", 710 "nonce": "0x12", 711 "to": null, 712 "transactionIndex": "0x12", 713 "value": "0x0", 714 "type": "0x0", 715 "v": "0x1", 716 "r": "0x2", 717 "s": "0x3" 718 }, 719 { 720 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 721 "blockNumber": "0x4", 722 "from": "0x3936663364636533666637396132333733653330", 723 "gas": "0x2faf080", 724 "gasPrice": "0x5d21dba00", 725 "hash": "0x5bb64e885f196f7b515e62e3b90496864d960e2f5e0d7ad88550fa1c875ca691", 726 "input": "0x", 727 "nonce": "0x13", 728 "to": "0x3632323232656162393565396564323963346266", 729 "transactionIndex": "0x13", 730 "value": "0x0", 731 "type": "0x0", 732 "v": "0x1", 733 "r": "0x2", 734 "s": "0x3" 735 }, 736 { 737 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 738 "blockNumber": "0x4", 739 "from": "0x3936663364636533666637396132333733653330", 740 "gas": "0x2faf080", 741 "gasPrice": "0x5d21dba00", 742 "hash": "0x6f4308b3c98db2db215d02c0df24472a215df7aa283261fcb06a6c9f796df9af", 743 "input": "0x", 744 "nonce": "0x14", 745 "to": "0x3936663364636533666637396132333733653330", 746 "transactionIndex": "0x14", 747 "value": "0x0", 748 "type": "0x0", 749 "v": "0x1", 750 "r": "0x2", 751 "s": "0x3" 752 }, 753 { 754 "blockHash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 755 "blockNumber": "0x4", 756 "from": "0x3936663364636533666637396132333733653330", 757 "gas": "0x2faf080", 758 "gasPrice": "0x5d21dba00", 759 "hash": "0x1df88d113f0c5833c1f7264687cd6ac43888c232600ffba8d3a7d89bb5013e71", 760 "input": "0xf8ad80b8aaf8a8a0072409b14b96f9d7dbf4788dbc68c5d30bd5fac1431c299e0ab55c92e70a28a4a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a00000000000000000000000000000000000000000000000000000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a00000000000000000000000000000000000000000000000000000000000000000808080", 761 "nonce": "0x15", 762 "to": "0x3936663364636533666637396132333733653330", 763 "transactionIndex": "0x15", 764 "value": "0x0", 765 "type": "0x0", 766 "v": "0x1", 767 "r": "0x2", 768 "s": "0x3" 769 } 770 ], 771 "transactionsRoot": "0x0a83e34ab7302f42f4a9203e8295f545517645989da6555d8cbdc1e9599df85b", 772 "uncles": [] 773 } 774 `, 775 ), &expected)) 776 } else { 777 assert.NoError(t, json.Unmarshal([]byte(` 778 { 779 "baseFeePerGas": "0x0", 780 "difficulty": "0x1", 781 "extraData": "0x", 782 "gasLimit": "0xe8d4a50fff", 783 "gasUsed": "0x2710", 784 "hash": "0xc74d8c04d4d2f2e4ed9cd1731387248367cea7f149731b7a015371b220ffa0fb", 785 "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 786 "miner": "0x9712f943b296758aaae79944ec975884188d3a96", 787 "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", 788 "nonce": "0x0000000000000000", 789 "number": "0x4", 790 "parentHash": "0xc8036293065bacdfce87debec0094a71dbbe40345b078d21dcc47adb4513f348", 791 "receiptsRoot": "0xf6278dd71ffc1637f78dc2ee54f6f9e64d4b1633c1179dfdbc8c3b482efbdbec", 792 "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", 793 "size": "0xe44", 794 "stateRoot": "0xad31c32942fa033166e4ef588ab973dbe26657c594de4ba98192108becf0fec9", 795 "timestamp": "0x61d53854", 796 "totalDifficulty": "0x5", 797 "transactions": [ 798 "0x6231f24f79d28bb5b8425ce577b3b77cd9c1ab766fcfc5233358a2b1c2f4ff70", 799 "0xf146858415c060eae65a389cbeea8aeadc79461038fbee331ffd97b41279dd63", 800 "0x0a01fc67bb4c15c32fa43563c0fcf05cd5bf2fdcd4ec78122b5d0295993bca24", 801 "0x486f7561375c38f1627264f8676f92ec0dd1c4a7c52002ba8714e61fcc6bb649", 802 "0xbd3e57cd31dd3d6679326f7a949f0de312e9ae53bec5ef3c23b43a5319c220a4", 803 "0xff666129a0c7227b17681d668ecdef5d6681fc93dbd58856eea1374880c598b0", 804 "0xa8ad4f295f2acff9ef56b476b1c52ecb74fb3fd95a789d768c2edb3376dbeacf", 805 "0x47dbfd201fc1dd4188fd2003c6328a09bf49414be607867ca3a5d63573aede93", 806 "0x2283294e89b41df2df4dd37c375a3f51c3ad11877aa0a4b59d0f68cf5cfd865a", 807 "0x80e05750d02d22d73926179a0611b431ae7658846406f836e903d76191423716", 808 "0xe8abdee5e8fef72fe4d98f7dbef36000407e97874e8c880df4d85646958dd2c1", 809 "0x4c970be1815e58e6f69321202ce38b2e5c5e5ecb70205634848afdbc57224811", 810 "0x7ff0a809387d0a4cab77624d467f4d65ffc1ac95f4cc46c2246daab0407a7d83", 811 "0xb510b11415b39d18a972a00e3b43adae1e0f583ea0481a4296e169561ff4d916", 812 "0xab466145fb71a2d24d6f6af3bddf3bcfa43c20a5937905dd01963eaf9fc5e382", 813 "0xec714ab0875768f482daeabf7eb7be804e3c94bc1f1b687359da506c7f3a66b2", 814 "0x069af125fe88784e46f90ace9960a09e5d23e6ace20350062be75964a7ece8e6", 815 "0x4a6bb7b2cd68265eb6a693aa270daffa3cc297765267f92be293b12e64948c82", 816 "0xa354fe3fdde6292e85545e6327c314827a20e0d7a1525398b38526fe28fd36e1", 817 "0x5bb64e885f196f7b515e62e3b90496864d960e2f5e0d7ad88550fa1c875ca691", 818 "0x6f4308b3c98db2db215d02c0df24472a215df7aa283261fcb06a6c9f796df9af", 819 "0x1df88d113f0c5833c1f7264687cd6ac43888c232600ffba8d3a7d89bb5013e71" 820 ], 821 "transactionsRoot": "0x0a83e34ab7302f42f4a9203e8295f545517645989da6555d8cbdc1e9599df85b", 822 "uncles": [] 823 } 824 `, 825 ), &expected)) 826 } 827 assert.Equal(t, stringifyMap(expected), stringifyMap(ethBlock)) 828 } 829 830 // marshal and unmarshal to stringify map fields. 831 func stringifyMap(m map[string]interface{}) map[string]interface{} { 832 marshaled, _ := json.Marshal(m) 833 var unmarshaled map[string]interface{} 834 json.Unmarshal(marshaled, &unmarshaled) 835 return unmarshaled 836 } 837 838 // TestEthereumAPI_GetTransactionByBlockNumberAndIndex tests GetTransactionByBlockNumberAndIndex. 839 func TestEthereumAPI_GetTransactionByBlockNumberAndIndex(t *testing.T) { 840 mockCtrl, mockBackend, api := testInitForEthApi(t) 841 block, txs, _, _, _ := createTestData(t, nil) 842 843 // Mock Backend functions. 844 mockBackend.EXPECT().BlockByNumber(gomock.Any(), gomock.Any()).Return(block, nil).Times(txs.Len()) 845 846 // Get transaction by block number and index for each transaction types. 847 for i := 0; i < txs.Len(); i++ { 848 ethTx := api.GetTransactionByBlockNumberAndIndex(context.Background(), rpc.BlockNumber(block.NumberU64()), hexutil.Uint(i)) 849 checkEthRPCTransactionFormat(t, block, ethTx, txs[i], hexutil.Uint64(i)) 850 } 851 852 mockCtrl.Finish() 853 } 854 855 // TestEthereumAPI_GetTransactionByBlockHashAndIndex tests GetTransactionByBlockHashAndIndex. 856 func TestEthereumAPI_GetTransactionByBlockHashAndIndex(t *testing.T) { 857 mockCtrl, mockBackend, api := testInitForEthApi(t) 858 block, txs, _, _, _ := createTestData(t, nil) 859 860 // Mock Backend functions. 861 mockBackend.EXPECT().BlockByHash(gomock.Any(), gomock.Any()).Return(block, nil).Times(txs.Len()) 862 863 // Get transaction by block hash and index for each transaction types. 864 for i := 0; i < txs.Len(); i++ { 865 ethTx := api.GetTransactionByBlockHashAndIndex(context.Background(), block.Hash(), hexutil.Uint(i)) 866 checkEthRPCTransactionFormat(t, block, ethTx, txs[i], hexutil.Uint64(i)) 867 } 868 869 mockCtrl.Finish() 870 } 871 872 // TestEthereumAPI_GetTransactionByHash tests GetTransactionByHash. 873 func TestEthereumAPI_GetTransactionByHash(t *testing.T) { 874 mockCtrl, mockBackend, api := testInitForEthApi(t) 875 block, txs, txHashMap, _, _ := createTestData(t, nil) 876 877 // Define queryFromPool for ReadTxAndLookupInfo function return tx from hash map. 878 // MockDatabaseManager will initiate data with txHashMap, block and queryFromPool. 879 // If queryFromPool is true, MockDatabaseManager will return nil to query transactions from transaction pool, 880 // otherwise return a transaction from txHashMap. 881 mockDBManager := &MockDatabaseManager{txHashMap: txHashMap, blockData: block, queryFromPool: false} 882 883 // Mock Backend functions. 884 mockBackend.EXPECT().ChainDB().Return(mockDBManager).Times(txs.Len()) 885 mockBackend.EXPECT().BlockByHash(gomock.Any(), block.Hash()).Return(block, nil).Times(txs.Len()) 886 887 // Get transaction by hash for each transaction types. 888 for i := 0; i < txs.Len(); i++ { 889 ethTx, err := api.GetTransactionByHash(context.Background(), txs[i].Hash()) 890 if err != nil { 891 t.Fatal(err) 892 } 893 checkEthRPCTransactionFormat(t, block, ethTx, txs[i], hexutil.Uint64(i)) 894 } 895 896 mockCtrl.Finish() 897 } 898 899 // TestEthereumAPI_GetTransactionByHash tests GetTransactionByHash from transaction pool. 900 func TestEthereumAPI_GetTransactionByHashFromPool(t *testing.T) { 901 mockCtrl, mockBackend, api := testInitForEthApi(t) 902 block, txs, txHashMap, _, _ := createTestData(t, nil) 903 904 // Define queryFromPool for ReadTxAndLookupInfo function return nil. 905 // MockDatabaseManager will initiate data with txHashMap, block and queryFromPool. 906 // If queryFromPool is true, MockDatabaseManager will return nil to query transactions from transaction pool, 907 // otherwise return a transaction from txHashMap. 908 mockDBManager := &MockDatabaseManager{txHashMap: txHashMap, blockData: block, queryFromPool: true} 909 910 // Mock Backend functions. 911 mockBackend.EXPECT().ChainDB().Return(mockDBManager).Times(txs.Len()) 912 mockBackend.EXPECT().GetPoolTransaction(gomock.Any()).DoAndReturn( 913 func(hash common.Hash) *types.Transaction { 914 return txHashMap[hash] 915 }, 916 ).Times(txs.Len()) 917 918 // Get transaction by hash from the transaction pool for each transaction types. 919 for i := 0; i < txs.Len(); i++ { 920 ethTx, err := api.GetTransactionByHash(context.Background(), txs[i].Hash()) 921 if err != nil { 922 t.Fatal(err) 923 } 924 checkEthRPCTransactionFormat(t, nil, ethTx, txs[i], 0) 925 } 926 927 mockCtrl.Finish() 928 } 929 930 // TestEthereumAPI_PendingTransactionstests PendingTransactions. 931 func TestEthereumAPI_PendingTransactions(t *testing.T) { 932 mockCtrl, mockBackend, api := testInitForEthApi(t) 933 _, txs, txHashMap, _, _ := createTestData(t, nil) 934 935 mockAccountManager := mock_accounts.NewMockAccountManager(mockCtrl) 936 mockBackend.EXPECT().AccountManager().Return(mockAccountManager) 937 938 mockBackend.EXPECT().GetPoolTransactions().Return(txs, nil) 939 940 wallets := make([]accounts.Wallet, 1) 941 wallets[0] = NewMockWallet(txs) 942 mockAccountManager.EXPECT().Wallets().Return(wallets) 943 944 pendingTxs, err := api.PendingTransactions() 945 if err != nil { 946 t.Fatal(err) 947 } 948 949 for _, pt := range pendingTxs { 950 checkEthRPCTransactionFormat(t, nil, pt, txHashMap[pt.Hash], 0) 951 } 952 953 mockCtrl.Finish() 954 } 955 956 // TestEthereumAPI_GetTransactionReceipt tests GetTransactionReceipt. 957 func TestEthereumAPI_GetTransactionReceipt(t *testing.T) { 958 mockCtrl, mockBackend, api := testInitForEthApi(t) 959 block, txs, txHashMap, receiptMap, receipts := createTestData(t, nil) 960 961 // Mock Backend functions. 962 mockBackend.EXPECT().GetTxLookupInfoAndReceipt(gomock.Any(), gomock.Any()).DoAndReturn( 963 func(ctx context.Context, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, *types.Receipt) { 964 txLookupInfo := txHashMap[hash] 965 idx := txLookupInfo.Nonce() // Assume idx of the transaction is nonce 966 return txLookupInfo, block.Hash(), block.NumberU64(), idx, receiptMap[hash] 967 }, 968 ).Times(txs.Len()) 969 mockBackend.EXPECT().GetBlockReceipts(gomock.Any(), gomock.Any()).Return(receipts).Times(txs.Len()) 970 mockBackend.EXPECT().HeaderByHash(gomock.Any(), block.Hash()).Return(block.Header(), nil).Times(txs.Len()) 971 972 // Get receipt for each transaction types. 973 for i := 0; i < txs.Len(); i++ { 974 receipt, err := api.GetTransactionReceipt(context.Background(), txs[i].Hash()) 975 if err != nil { 976 t.Fatal(err) 977 } 978 txIdx := uint64(i) 979 checkEthTransactionReceiptFormat(t, block, receipts, receipt, RpcOutputReceipt(block.Header(), txs[i], block.Hash(), block.NumberU64(), txIdx, receiptMap[txs[i].Hash()]), txIdx) 980 } 981 982 mockCtrl.Finish() 983 } 984 985 func testInitForEthApi(t *testing.T) (*gomock.Controller, *mock_api.MockBackend, EthereumAPI) { 986 mockCtrl := gomock.NewController(t) 987 mockBackend := mock_api.NewMockBackend(mockCtrl) 988 989 blockchain.InitDeriveSha(dummyChainConfigForEthereumAPITest) 990 991 api := EthereumAPI{ 992 publicTransactionPoolAPI: NewPublicTransactionPoolAPI(mockBackend, new(AddrLocker)), 993 publicKlayAPI: NewPublicKlayAPI(mockBackend), 994 publicBlockChainAPI: NewPublicBlockChainAPI(mockBackend), 995 } 996 return mockCtrl, mockBackend, api 997 } 998 999 func checkEthRPCTransactionFormat(t *testing.T, block *types.Block, ethTx *EthRPCTransaction, tx *types.Transaction, expectedIndex hexutil.Uint64) { 1000 // All Klaytn transaction types must be returned as TxTypeLegacyTransaction types. 1001 assert.Equal(t, types.TxType(ethTx.Type), types.TxTypeLegacyTransaction) 1002 1003 // Check the data of common fields of the transaction. 1004 from := getFrom(tx) 1005 assert.Equal(t, from, ethTx.From) 1006 assert.Equal(t, hexutil.Uint64(tx.Gas()), ethTx.Gas) 1007 assert.Equal(t, tx.GasPrice(), ethTx.GasPrice.ToInt()) 1008 assert.Equal(t, tx.Hash(), ethTx.Hash) 1009 assert.Equal(t, tx.GetTxInternalData().RawSignatureValues()[0].V, ethTx.V.ToInt()) 1010 assert.Equal(t, tx.GetTxInternalData().RawSignatureValues()[0].R, ethTx.R.ToInt()) 1011 assert.Equal(t, tx.GetTxInternalData().RawSignatureValues()[0].S, ethTx.S.ToInt()) 1012 assert.Equal(t, hexutil.Uint64(tx.Nonce()), ethTx.Nonce) 1013 1014 // Check the optional field of Klaytn transactions. 1015 assert.Equal(t, 0, bytes.Compare(ethTx.Input, tx.Data())) 1016 1017 to := tx.To() 1018 switch tx.Type() { 1019 case types.TxTypeAccountUpdate, types.TxTypeFeeDelegatedAccountUpdate, types.TxTypeFeeDelegatedAccountUpdateWithRatio, 1020 types.TxTypeCancel, types.TxTypeFeeDelegatedCancel, types.TxTypeFeeDelegatedCancelWithRatio, 1021 types.TxTypeChainDataAnchoring, types.TxTypeFeeDelegatedChainDataAnchoring, types.TxTypeFeeDelegatedChainDataAnchoringWithRatio: 1022 assert.Equal(t, &from, ethTx.To) 1023 default: 1024 assert.Equal(t, to, ethTx.To) 1025 } 1026 value := tx.Value() 1027 assert.Equal(t, value, ethTx.Value.ToInt()) 1028 1029 // If it is not a pending transaction and has already been processed and added into a block, 1030 // the following fields should be returned. 1031 if block != nil { 1032 assert.Equal(t, block.Hash().String(), ethTx.BlockHash.String()) 1033 assert.Equal(t, block.NumberU64(), ethTx.BlockNumber.ToInt().Uint64()) 1034 assert.Equal(t, expectedIndex, *ethTx.TransactionIndex) 1035 } 1036 1037 // Fields additionally used for Ethereum transaction types are not used 1038 // when returning Klaytn transactions. 1039 assert.Equal(t, true, reflect.ValueOf(ethTx.Accesses).IsNil()) 1040 assert.Equal(t, true, reflect.ValueOf(ethTx.ChainID).IsNil()) 1041 assert.Equal(t, true, reflect.ValueOf(ethTx.GasFeeCap).IsNil()) 1042 assert.Equal(t, true, reflect.ValueOf(ethTx.GasTipCap).IsNil()) 1043 } 1044 1045 func checkEthTransactionReceiptFormat(t *testing.T, block *types.Block, receipts []*types.Receipt, ethReceipt map[string]interface{}, kReceipt map[string]interface{}, idx uint64) { 1046 tx := block.Transactions()[idx] 1047 1048 // Check the common receipt fields. 1049 blockHash, ok := ethReceipt["blockHash"] 1050 if !ok { 1051 t.Fatal("blockHash is not defined in Ethereum transaction receipt format.") 1052 } 1053 assert.Equal(t, blockHash, kReceipt["blockHash"]) 1054 1055 blockNumber, ok := ethReceipt["blockNumber"] 1056 if !ok { 1057 t.Fatal("blockNumber is not defined in Ethereum transaction receipt format.") 1058 } 1059 assert.Equal(t, blockNumber.(hexutil.Uint64), hexutil.Uint64(kReceipt["blockNumber"].(*hexutil.Big).ToInt().Uint64())) 1060 1061 transactionHash, ok := ethReceipt["transactionHash"] 1062 if !ok { 1063 t.Fatal("transactionHash is not defined in Ethereum transaction receipt format.") 1064 } 1065 assert.Equal(t, transactionHash, kReceipt["transactionHash"]) 1066 1067 transactionIndex, ok := ethReceipt["transactionIndex"] 1068 if !ok { 1069 t.Fatal("transactionIndex is not defined in Ethereum transaction receipt format.") 1070 } 1071 assert.Equal(t, transactionIndex, hexutil.Uint64(kReceipt["transactionIndex"].(hexutil.Uint))) 1072 1073 from, ok := ethReceipt["from"] 1074 if !ok { 1075 t.Fatal("from is not defined in Ethereum transaction receipt format.") 1076 } 1077 assert.Equal(t, from, kReceipt["from"]) 1078 1079 // Klaytn transactions that do not use the 'To' field 1080 // fill in 'To' with from during converting format. 1081 toInTx := tx.To() 1082 fromAddress := getFrom(tx) 1083 to, ok := ethReceipt["to"] 1084 if !ok { 1085 t.Fatal("to is not defined in Ethereum transaction receipt format.") 1086 } 1087 switch tx.Type() { 1088 case types.TxTypeAccountUpdate, types.TxTypeFeeDelegatedAccountUpdate, types.TxTypeFeeDelegatedAccountUpdateWithRatio, 1089 types.TxTypeCancel, types.TxTypeFeeDelegatedCancel, types.TxTypeFeeDelegatedCancelWithRatio, 1090 types.TxTypeChainDataAnchoring, types.TxTypeFeeDelegatedChainDataAnchoring, types.TxTypeFeeDelegatedChainDataAnchoringWithRatio: 1091 assert.Equal(t, &fromAddress, to) 1092 default: 1093 assert.Equal(t, toInTx, to) 1094 } 1095 1096 gasUsed, ok := ethReceipt["gasUsed"] 1097 if !ok { 1098 t.Fatal("gasUsed is not defined in Ethereum transaction receipt format.") 1099 } 1100 assert.Equal(t, gasUsed, kReceipt["gasUsed"]) 1101 1102 // Compare with the calculated cumulative gas used value 1103 // to check whether the cumulativeGasUsed value is calculated properly. 1104 cumulativeGasUsed, ok := ethReceipt["cumulativeGasUsed"] 1105 if !ok { 1106 t.Fatal("cumulativeGasUsed is not defined in Ethereum transaction receipt format.") 1107 } 1108 calculatedCumulativeGas := uint64(0) 1109 for i := 0; i <= int(idx); i++ { 1110 calculatedCumulativeGas += receipts[i].GasUsed 1111 } 1112 assert.Equal(t, cumulativeGasUsed, hexutil.Uint64(calculatedCumulativeGas)) 1113 1114 contractAddress, ok := ethReceipt["contractAddress"] 1115 if !ok { 1116 t.Fatal("contractAddress is not defined in Ethereum transaction receipt format.") 1117 } 1118 assert.Equal(t, contractAddress, kReceipt["contractAddress"]) 1119 1120 logs, ok := ethReceipt["logs"] 1121 if !ok { 1122 t.Fatal("logs is not defined in Ethereum transaction receipt format.") 1123 } 1124 assert.Equal(t, logs, kReceipt["logs"]) 1125 1126 logsBloom, ok := ethReceipt["logsBloom"] 1127 if !ok { 1128 t.Fatal("logsBloom is not defined in Ethereum transaction receipt format.") 1129 } 1130 assert.Equal(t, logsBloom, kReceipt["logsBloom"]) 1131 1132 typeInt, ok := ethReceipt["type"] 1133 if !ok { 1134 t.Fatal("type is not defined in Ethereum transaction receipt format.") 1135 } 1136 assert.Equal(t, types.TxType(typeInt.(hexutil.Uint)), types.TxTypeLegacyTransaction) 1137 1138 effectiveGasPrice, ok := ethReceipt["effectiveGasPrice"] 1139 if !ok { 1140 t.Fatal("effectiveGasPrice is not defined in Ethereum transaction receipt format.") 1141 } 1142 assert.Equal(t, effectiveGasPrice, hexutil.Uint64(kReceipt["gasPrice"].(*hexutil.Big).ToInt().Uint64())) 1143 1144 status, ok := ethReceipt["status"] 1145 if !ok { 1146 t.Fatal("status is not defined in Ethereum transaction receipt format.") 1147 } 1148 assert.Equal(t, status, kReceipt["status"]) 1149 1150 // Check the receipt fields that should be removed. 1151 var shouldNotExisted []string 1152 shouldNotExisted = append(shouldNotExisted, "gas", "gasPrice", "senderTxHash", "signatures", "txError", "typeInt", "feePayer", "feePayerSignatures", "feeRatio", "input", "value", "codeFormat", "humanReadable", "key", "inputJSON") 1153 for i := 0; i < len(shouldNotExisted); i++ { 1154 k := shouldNotExisted[i] 1155 _, ok = ethReceipt[k] 1156 if ok { 1157 t.Fatal(k, " should not be defined in the Ethereum transaction receipt format.") 1158 } 1159 } 1160 } 1161 1162 func createTestData(t *testing.T, header *types.Header) (*types.Block, types.Transactions, map[common.Hash]*types.Transaction, map[common.Hash]*types.Receipt, []*types.Receipt) { 1163 var txs types.Transactions 1164 1165 gasPrice := big.NewInt(25 * params.Ston) 1166 deployData := "0x60806040526000805534801561001457600080fd5b506101ea806100246000396000f30060806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306661abd1461007257806342cbb15c1461009d578063767800de146100c8578063b22636271461011f578063d14e62b814610150575b600080fd5b34801561007e57600080fd5b5061008761017d565b6040518082815260200191505060405180910390f35b3480156100a957600080fd5b506100b2610183565b6040518082815260200191505060405180910390f35b3480156100d457600080fd5b506100dd61018b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561012b57600080fd5b5061014e60048036038101908080356000191690602001909291905050506101b1565b005b34801561015c57600080fd5b5061017b600480360381019080803590602001909291905050506101b4565b005b60005481565b600043905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b50565b80600081905550505600a165627a7a7230582053c65686a3571c517e2cf4f741d842e5ee6aa665c96ce70f46f9a594794f11eb0029" 1167 executeData := "0xa9059cbb0000000000000000000000008a4c9c443bb0645df646a2d5bb55def0ed1e885a0000000000000000000000000000000000000000000000000000000000003039" 1168 var anchorData []byte 1169 1170 txHashMap := make(map[common.Hash]*types.Transaction) 1171 receiptMap := make(map[common.Hash]*types.Receipt) 1172 var receipts []*types.Receipt 1173 1174 // Create test data for chainDataAnchoring tx 1175 { 1176 dummyBlock := types.NewBlock(&types.Header{}, nil, nil) 1177 scData, err := types.NewAnchoringDataType0(dummyBlock, 0, uint64(dummyBlock.Transactions().Len())) 1178 if err != nil { 1179 t.Fatal(err) 1180 } 1181 anchorData, _ = rlp.EncodeToBytes(scData) 1182 } 1183 1184 // Make test transactions data 1185 { 1186 // TxTypeLegacyTransaction 1187 values := map[types.TxValueKeyType]interface{}{ 1188 // Simply set the nonce to txs.Len() to have a different nonce for each transaction type. 1189 types.TxValueKeyNonce: uint64(txs.Len()), 1190 types.TxValueKeyTo: common.StringToAddress("0xe0680cfce04f80a386f1764a55c833b108770490"), 1191 types.TxValueKeyAmount: big.NewInt(0), 1192 types.TxValueKeyGasLimit: uint64(30000000), 1193 types.TxValueKeyGasPrice: gasPrice, 1194 types.TxValueKeyData: []byte("0xe3197e8f000000000000000000000000e0bef99b4a22286e27630b485d06c5a147cee931000000000000000000000000158beff8c8cdebd64654add5f6a1d9937e73536c0000000000000000000000000000000000000000000029bb5e7fb6beae32cf8000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000001b60fb4614a22e000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000158beff8c8cdebd64654add5f6a1d9937e73536c00000000000000000000000074ba03198fed2b15a51af242b9c63faf3c8f4d3400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), 1195 } 1196 tx, err := types.NewTransactionWithMap(types.TxTypeLegacyTransaction, values) 1197 assert.Equal(t, nil, err) 1198 1199 signatures := types.TxSignatures{ 1200 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1201 } 1202 tx.SetSignature(signatures) 1203 1204 txs = append(txs, tx) 1205 txHashMap[tx.Hash()] = tx 1206 // For testing, set GasUsed with tx.Gas() 1207 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1208 receipts = append(receipts, receiptMap[tx.Hash()]) 1209 1210 } 1211 { 1212 // TxTypeValueTransfer 1213 values := map[types.TxValueKeyType]interface{}{ 1214 types.TxValueKeyNonce: uint64(txs.Len()), 1215 types.TxValueKeyFrom: common.StringToAddress("0x520af902892196a3449b06ead301daeaf67e77e8"), 1216 types.TxValueKeyTo: common.StringToAddress("0xa06fa690d92788cac4953da5f2dfbc4a2b3871db"), 1217 types.TxValueKeyAmount: big.NewInt(5), 1218 types.TxValueKeyGasLimit: uint64(10000000), 1219 types.TxValueKeyGasPrice: gasPrice, 1220 } 1221 tx, err := types.NewTransactionWithMap(types.TxTypeValueTransfer, values) 1222 assert.Equal(t, nil, err) 1223 1224 signatures := types.TxSignatures{ 1225 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1226 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1227 } 1228 tx.SetSignature(signatures) 1229 1230 txs = append(txs, tx) 1231 txHashMap[tx.Hash()] = tx 1232 // For testing, set GasUsed with tx.Gas() 1233 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1234 receipts = append(receipts, receiptMap[tx.Hash()]) 1235 } 1236 { 1237 // TxTypeValueTransferMemo 1238 values := map[types.TxValueKeyType]interface{}{ 1239 types.TxValueKeyNonce: uint64(txs.Len()), 1240 types.TxValueKeyFrom: common.StringToAddress("0xc05e11f9075d453b4fc87023f815fa6a63f7aa0c"), 1241 types.TxValueKeyTo: common.StringToAddress("0xb5a2d79e9228f3d278cb36b5b15930f24fe8bae8"), 1242 types.TxValueKeyAmount: big.NewInt(3), 1243 types.TxValueKeyGasLimit: uint64(20000000), 1244 types.TxValueKeyGasPrice: gasPrice, 1245 types.TxValueKeyData: []byte(string("hello")), 1246 } 1247 tx, err := types.NewTransactionWithMap(types.TxTypeValueTransferMemo, values) 1248 assert.Equal(t, nil, err) 1249 1250 signatures := types.TxSignatures{ 1251 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1252 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1253 } 1254 tx.SetSignature(signatures) 1255 1256 txs = append(txs, tx) 1257 txHashMap[tx.Hash()] = tx 1258 // For testing, set GasUsed with tx.Gas() 1259 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1260 receipts = append(receipts, receiptMap[tx.Hash()]) 1261 } 1262 { 1263 // TxTypeAccountUpdate 1264 values := map[types.TxValueKeyType]interface{}{ 1265 types.TxValueKeyNonce: uint64(txs.Len()), 1266 types.TxValueKeyFrom: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1267 types.TxValueKeyGasLimit: uint64(20000000), 1268 types.TxValueKeyGasPrice: gasPrice, 1269 types.TxValueKeyAccountKey: accountkey.NewAccountKeyLegacy(), 1270 } 1271 tx, err := types.NewTransactionWithMap(types.TxTypeAccountUpdate, values) 1272 assert.Equal(t, nil, err) 1273 1274 signatures := types.TxSignatures{ 1275 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1276 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1277 } 1278 tx.SetSignature(signatures) 1279 1280 txs = append(txs, tx) 1281 txHashMap[tx.Hash()] = tx 1282 // For testing, set GasUsed with tx.Gas() 1283 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1284 receipts = append(receipts, receiptMap[tx.Hash()]) 1285 } 1286 { 1287 // TxTypeSmartContractDeploy 1288 values := map[types.TxValueKeyType]interface{}{ 1289 types.TxValueKeyNonce: uint64(txs.Len()), 1290 types.TxValueKeyFrom: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1291 types.TxValueKeyTo: (*common.Address)(nil), 1292 types.TxValueKeyAmount: big.NewInt(0), 1293 types.TxValueKeyGasLimit: uint64(100000000), 1294 types.TxValueKeyGasPrice: gasPrice, 1295 types.TxValueKeyData: common.Hex2Bytes(deployData), 1296 types.TxValueKeyHumanReadable: false, 1297 types.TxValueKeyCodeFormat: params.CodeFormatEVM, 1298 } 1299 tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractDeploy, values) 1300 assert.Equal(t, nil, err) 1301 1302 signatures := types.TxSignatures{ 1303 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1304 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1305 } 1306 tx.SetSignature(signatures) 1307 1308 txs = append(txs, tx) 1309 txHashMap[tx.Hash()] = tx 1310 // For testing, set GasUsed with tx.Gas() 1311 r := createReceipt(t, tx, tx.Gas()) 1312 fromAddress, err := tx.From() 1313 if err != nil { 1314 t.Fatal(err) 1315 } 1316 tx.FillContractAddress(fromAddress, r) 1317 receiptMap[tx.Hash()] = r 1318 receipts = append(receipts, receiptMap[tx.Hash()]) 1319 } 1320 { 1321 // TxTypeSmartContractExecution 1322 values := map[types.TxValueKeyType]interface{}{ 1323 types.TxValueKeyNonce: uint64(txs.Len()), 1324 types.TxValueKeyFrom: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1325 types.TxValueKeyTo: common.StringToAddress("0x00ca1eee49a4d2b04e6562222eab95e9ed29c4bf"), 1326 types.TxValueKeyAmount: big.NewInt(0), 1327 types.TxValueKeyGasLimit: uint64(50000000), 1328 types.TxValueKeyGasPrice: gasPrice, 1329 types.TxValueKeyData: common.Hex2Bytes(executeData), 1330 } 1331 tx, err := types.NewTransactionWithMap(types.TxTypeSmartContractExecution, values) 1332 assert.Equal(t, nil, err) 1333 1334 signatures := types.TxSignatures{ 1335 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1336 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1337 } 1338 tx.SetSignature(signatures) 1339 1340 txs = append(txs, tx) 1341 txHashMap[tx.Hash()] = tx 1342 // For testing, set GasUsed with tx.Gas() 1343 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1344 receipts = append(receipts, receiptMap[tx.Hash()]) 1345 } 1346 { 1347 // TxTypeCancel 1348 values := map[types.TxValueKeyType]interface{}{ 1349 types.TxValueKeyNonce: uint64(txs.Len()), 1350 types.TxValueKeyFrom: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1351 types.TxValueKeyGasLimit: uint64(50000000), 1352 types.TxValueKeyGasPrice: gasPrice, 1353 } 1354 tx, err := types.NewTransactionWithMap(types.TxTypeCancel, values) 1355 assert.Equal(t, nil, err) 1356 1357 signatures := types.TxSignatures{ 1358 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1359 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1360 } 1361 tx.SetSignature(signatures) 1362 1363 txs = append(txs, tx) 1364 txHashMap[tx.Hash()] = tx 1365 // For testing, set GasUsed with tx.Gas() 1366 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1367 receipts = append(receipts, receiptMap[tx.Hash()]) 1368 } 1369 { 1370 // TxTypeChainDataAnchoring 1371 values := map[types.TxValueKeyType]interface{}{ 1372 types.TxValueKeyNonce: uint64(txs.Len()), 1373 types.TxValueKeyFrom: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1374 types.TxValueKeyGasLimit: uint64(50000000), 1375 types.TxValueKeyGasPrice: gasPrice, 1376 types.TxValueKeyAnchoredData: anchorData, 1377 } 1378 tx, err := types.NewTransactionWithMap(types.TxTypeChainDataAnchoring, values) 1379 assert.Equal(t, nil, err) 1380 1381 signatures := types.TxSignatures{ 1382 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1383 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1384 } 1385 tx.SetSignature(signatures) 1386 1387 txs = append(txs, tx) 1388 txHashMap[tx.Hash()] = tx 1389 // For testing, set GasUsed with tx.Gas() 1390 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1391 receipts = append(receipts, receiptMap[tx.Hash()]) 1392 } 1393 { 1394 // TxTypeFeeDelegatedValueTransfer 1395 values := map[types.TxValueKeyType]interface{}{ 1396 types.TxValueKeyNonce: uint64(txs.Len()), 1397 types.TxValueKeyFrom: common.StringToAddress("0x520af902892196a3449b06ead301daeaf67e77e8"), 1398 types.TxValueKeyTo: common.StringToAddress("0xa06fa690d92788cac4953da5f2dfbc4a2b3871db"), 1399 types.TxValueKeyAmount: big.NewInt(5), 1400 types.TxValueKeyGasLimit: uint64(10000000), 1401 types.TxValueKeyGasPrice: gasPrice, 1402 types.TxValueKeyFeePayer: common.StringToAddress("0xa142f7b24a618778165c9b06e15a61f100c51400"), 1403 } 1404 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedValueTransfer, values) 1405 assert.Equal(t, nil, err) 1406 1407 signatures := types.TxSignatures{ 1408 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1409 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1410 } 1411 tx.SetSignature(signatures) 1412 1413 feePayerSignatures := types.TxSignatures{ 1414 &types.TxSignature{V: big.NewInt(3), R: big.NewInt(4), S: big.NewInt(5)}, 1415 &types.TxSignature{V: big.NewInt(4), R: big.NewInt(5), S: big.NewInt(6)}, 1416 } 1417 tx.SetFeePayerSignatures(feePayerSignatures) 1418 1419 txs = append(txs, tx) 1420 txHashMap[tx.Hash()] = tx 1421 // For testing, set GasUsed with tx.Gas() 1422 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1423 receipts = append(receipts, receiptMap[tx.Hash()]) 1424 } 1425 { 1426 // TxTypeFeeDelegatedValueTransferMemo 1427 values := map[types.TxValueKeyType]interface{}{ 1428 types.TxValueKeyNonce: uint64(txs.Len()), 1429 types.TxValueKeyFrom: common.StringToAddress("0xc05e11f9075d453b4fc87023f815fa6a63f7aa0c"), 1430 types.TxValueKeyTo: common.StringToAddress("0xb5a2d79e9228f3d278cb36b5b15930f24fe8bae8"), 1431 types.TxValueKeyAmount: big.NewInt(3), 1432 types.TxValueKeyGasLimit: uint64(20000000), 1433 types.TxValueKeyGasPrice: gasPrice, 1434 types.TxValueKeyData: []byte(string("hello")), 1435 types.TxValueKeyFeePayer: common.StringToAddress("0xa142f7b24a618778165c9b06e15a61f100c51400"), 1436 } 1437 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedValueTransferMemo, values) 1438 assert.Equal(t, nil, err) 1439 1440 signatures := types.TxSignatures{ 1441 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1442 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1443 } 1444 tx.SetSignature(signatures) 1445 1446 feePayerSignatures := types.TxSignatures{ 1447 &types.TxSignature{V: big.NewInt(3), R: big.NewInt(4), S: big.NewInt(5)}, 1448 &types.TxSignature{V: big.NewInt(4), R: big.NewInt(5), S: big.NewInt(6)}, 1449 } 1450 tx.SetFeePayerSignatures(feePayerSignatures) 1451 1452 txs = append(txs, tx) 1453 txHashMap[tx.Hash()] = tx 1454 1455 // For testing, set GasUsed with tx.Gas() 1456 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1457 receipts = append(receipts, receiptMap[tx.Hash()]) 1458 } 1459 { 1460 // TxTypeFeeDelegatedAccountUpdate 1461 values := map[types.TxValueKeyType]interface{}{ 1462 types.TxValueKeyNonce: uint64(txs.Len()), 1463 types.TxValueKeyFrom: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1464 types.TxValueKeyGasLimit: uint64(20000000), 1465 types.TxValueKeyGasPrice: gasPrice, 1466 types.TxValueKeyAccountKey: accountkey.NewAccountKeyLegacy(), 1467 types.TxValueKeyFeePayer: common.StringToAddress("0xa142f7b24a618778165c9b06e15a61f100c51400"), 1468 } 1469 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedAccountUpdate, values) 1470 assert.Equal(t, nil, err) 1471 1472 signatures := types.TxSignatures{ 1473 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1474 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1475 } 1476 tx.SetSignature(signatures) 1477 1478 feePayerSignatures := types.TxSignatures{ 1479 &types.TxSignature{V: big.NewInt(3), R: big.NewInt(4), S: big.NewInt(5)}, 1480 &types.TxSignature{V: big.NewInt(4), R: big.NewInt(5), S: big.NewInt(6)}, 1481 } 1482 tx.SetFeePayerSignatures(feePayerSignatures) 1483 1484 txs = append(txs, tx) 1485 txHashMap[tx.Hash()] = tx 1486 // For testing, set GasUsed with tx.Gas() 1487 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1488 receipts = append(receipts, receiptMap[tx.Hash()]) 1489 } 1490 { 1491 // TxTypeFeeDelegatedSmartContractDeploy 1492 values := map[types.TxValueKeyType]interface{}{ 1493 types.TxValueKeyNonce: uint64(txs.Len()), 1494 types.TxValueKeyFrom: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1495 types.TxValueKeyTo: (*common.Address)(nil), 1496 types.TxValueKeyAmount: big.NewInt(0), 1497 types.TxValueKeyGasLimit: uint64(100000000), 1498 types.TxValueKeyGasPrice: gasPrice, 1499 types.TxValueKeyData: common.Hex2Bytes(deployData), 1500 types.TxValueKeyHumanReadable: false, 1501 types.TxValueKeyCodeFormat: params.CodeFormatEVM, 1502 types.TxValueKeyFeePayer: common.StringToAddress("0xa142f7b24a618778165c9b06e15a61f100c51400"), 1503 } 1504 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedSmartContractDeploy, values) 1505 assert.Equal(t, nil, err) 1506 1507 signatures := types.TxSignatures{ 1508 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1509 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1510 } 1511 tx.SetSignature(signatures) 1512 1513 feePayerSignatures := types.TxSignatures{ 1514 &types.TxSignature{V: big.NewInt(3), R: big.NewInt(4), S: big.NewInt(5)}, 1515 &types.TxSignature{V: big.NewInt(4), R: big.NewInt(5), S: big.NewInt(6)}, 1516 } 1517 tx.SetFeePayerSignatures(feePayerSignatures) 1518 1519 txs = append(txs, tx) 1520 txHashMap[tx.Hash()] = tx 1521 // For testing, set GasUsed with tx.Gas() 1522 r := createReceipt(t, tx, tx.Gas()) 1523 fromAddress, err := tx.From() 1524 if err != nil { 1525 t.Fatal(err) 1526 } 1527 tx.FillContractAddress(fromAddress, r) 1528 receiptMap[tx.Hash()] = r 1529 receipts = append(receipts, receiptMap[tx.Hash()]) 1530 } 1531 { 1532 // TxTypeFeeDelegatedSmartContractExecution 1533 values := map[types.TxValueKeyType]interface{}{ 1534 types.TxValueKeyNonce: uint64(txs.Len()), 1535 types.TxValueKeyFrom: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1536 types.TxValueKeyTo: common.StringToAddress("0x00ca1eee49a4d2b04e6562222eab95e9ed29c4bf"), 1537 types.TxValueKeyAmount: big.NewInt(0), 1538 types.TxValueKeyGasLimit: uint64(50000000), 1539 types.TxValueKeyGasPrice: gasPrice, 1540 types.TxValueKeyData: common.Hex2Bytes(executeData), 1541 types.TxValueKeyFeePayer: common.StringToAddress("0xa142f7b24a618778165c9b06e15a61f100c51400"), 1542 } 1543 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedSmartContractExecution, values) 1544 assert.Equal(t, nil, err) 1545 1546 signatures := types.TxSignatures{ 1547 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1548 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1549 } 1550 tx.SetSignature(signatures) 1551 1552 feePayerSignatures := types.TxSignatures{ 1553 &types.TxSignature{V: big.NewInt(3), R: big.NewInt(4), S: big.NewInt(5)}, 1554 &types.TxSignature{V: big.NewInt(4), R: big.NewInt(5), S: big.NewInt(6)}, 1555 } 1556 tx.SetFeePayerSignatures(feePayerSignatures) 1557 1558 txs = append(txs, tx) 1559 txHashMap[tx.Hash()] = tx 1560 // For testing, set GasUsed with tx.Gas() 1561 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1562 receipts = append(receipts, receiptMap[tx.Hash()]) 1563 } 1564 { 1565 // TxTypeFeeDelegatedCancel 1566 values := map[types.TxValueKeyType]interface{}{ 1567 types.TxValueKeyNonce: uint64(txs.Len()), 1568 types.TxValueKeyFrom: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1569 types.TxValueKeyGasLimit: uint64(50000000), 1570 types.TxValueKeyGasPrice: gasPrice, 1571 types.TxValueKeyFeePayer: common.StringToAddress("0xa142f7b24a618778165c9b06e15a61f100c51400"), 1572 } 1573 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedCancel, values) 1574 assert.Equal(t, nil, err) 1575 1576 signatures := types.TxSignatures{ 1577 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1578 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1579 } 1580 tx.SetSignature(signatures) 1581 1582 feePayerSignatures := types.TxSignatures{ 1583 &types.TxSignature{V: big.NewInt(3), R: big.NewInt(4), S: big.NewInt(5)}, 1584 &types.TxSignature{V: big.NewInt(4), R: big.NewInt(5), S: big.NewInt(6)}, 1585 } 1586 tx.SetFeePayerSignatures(feePayerSignatures) 1587 1588 txs = append(txs, tx) 1589 txHashMap[tx.Hash()] = tx 1590 // For testing, set GasUsed with tx.Gas() 1591 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1592 receipts = append(receipts, receiptMap[tx.Hash()]) 1593 } 1594 { 1595 // TxTypeFeeDelegatedChainDataAnchoring 1596 values := map[types.TxValueKeyType]interface{}{ 1597 types.TxValueKeyNonce: uint64(txs.Len()), 1598 types.TxValueKeyFrom: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1599 types.TxValueKeyGasLimit: uint64(50000000), 1600 types.TxValueKeyGasPrice: gasPrice, 1601 types.TxValueKeyAnchoredData: anchorData, 1602 types.TxValueKeyFeePayer: common.StringToAddress("0xa142f7b24a618778165c9b06e15a61f100c51400"), 1603 } 1604 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedChainDataAnchoring, values) 1605 assert.Equal(t, nil, err) 1606 1607 signatures := types.TxSignatures{ 1608 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1609 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1610 } 1611 tx.SetSignature(signatures) 1612 1613 feePayerSignatures := types.TxSignatures{ 1614 &types.TxSignature{V: big.NewInt(3), R: big.NewInt(4), S: big.NewInt(5)}, 1615 &types.TxSignature{V: big.NewInt(4), R: big.NewInt(5), S: big.NewInt(6)}, 1616 } 1617 tx.SetFeePayerSignatures(feePayerSignatures) 1618 1619 txs = append(txs, tx) 1620 txHashMap[tx.Hash()] = tx 1621 1622 // For testing, set GasUsed with tx.Gas() 1623 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1624 receipts = append(receipts, receiptMap[tx.Hash()]) 1625 } 1626 { 1627 // TxTypeFeeDelegatedValueTransferWithRatio 1628 values := map[types.TxValueKeyType]interface{}{ 1629 types.TxValueKeyNonce: uint64(txs.Len()), 1630 types.TxValueKeyFrom: common.StringToAddress("0x520af902892196a3449b06ead301daeaf67e77e8"), 1631 types.TxValueKeyTo: common.StringToAddress("0xa06fa690d92788cac4953da5f2dfbc4a2b3871db"), 1632 types.TxValueKeyAmount: big.NewInt(5), 1633 types.TxValueKeyGasLimit: uint64(10000000), 1634 types.TxValueKeyGasPrice: gasPrice, 1635 types.TxValueKeyFeePayer: common.StringToAddress("0xa142f7b24a618778165c9b06e15a61f100c51400"), 1636 types.TxValueKeyFeeRatioOfFeePayer: types.FeeRatio(20), 1637 } 1638 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedValueTransferWithRatio, values) 1639 assert.Equal(t, nil, err) 1640 1641 signatures := types.TxSignatures{ 1642 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1643 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1644 } 1645 tx.SetSignature(signatures) 1646 1647 feePayerSignatures := types.TxSignatures{ 1648 &types.TxSignature{V: big.NewInt(3), R: big.NewInt(4), S: big.NewInt(5)}, 1649 &types.TxSignature{V: big.NewInt(4), R: big.NewInt(5), S: big.NewInt(6)}, 1650 } 1651 tx.SetFeePayerSignatures(feePayerSignatures) 1652 1653 txs = append(txs, tx) 1654 txHashMap[tx.Hash()] = tx 1655 // For testing, set GasUsed with tx.Gas() 1656 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1657 receipts = append(receipts, receiptMap[tx.Hash()]) 1658 } 1659 { 1660 // TxTypeFeeDelegatedValueTransferMemoWithRatio 1661 values := map[types.TxValueKeyType]interface{}{ 1662 types.TxValueKeyNonce: uint64(txs.Len()), 1663 types.TxValueKeyFrom: common.StringToAddress("0xc05e11f9075d453b4fc87023f815fa6a63f7aa0c"), 1664 types.TxValueKeyTo: common.StringToAddress("0xb5a2d79e9228f3d278cb36b5b15930f24fe8bae8"), 1665 types.TxValueKeyAmount: big.NewInt(3), 1666 types.TxValueKeyGasLimit: uint64(20000000), 1667 types.TxValueKeyGasPrice: gasPrice, 1668 types.TxValueKeyData: []byte(string("hello")), 1669 types.TxValueKeyFeePayer: common.StringToAddress("0xa142f7b24a618778165c9b06e15a61f100c51400"), 1670 types.TxValueKeyFeeRatioOfFeePayer: types.FeeRatio(20), 1671 } 1672 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedValueTransferMemoWithRatio, values) 1673 assert.Equal(t, nil, err) 1674 1675 signatures := types.TxSignatures{ 1676 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1677 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1678 } 1679 tx.SetSignature(signatures) 1680 1681 feePayerSignatures := types.TxSignatures{ 1682 &types.TxSignature{V: big.NewInt(3), R: big.NewInt(4), S: big.NewInt(5)}, 1683 &types.TxSignature{V: big.NewInt(4), R: big.NewInt(5), S: big.NewInt(6)}, 1684 } 1685 tx.SetFeePayerSignatures(feePayerSignatures) 1686 1687 txs = append(txs, tx) 1688 txHashMap[tx.Hash()] = tx 1689 // For testing, set GasUsed with tx.Gas() 1690 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1691 receipts = append(receipts, receiptMap[tx.Hash()]) 1692 } 1693 { 1694 // TxTypeFeeDelegatedAccountUpdateWithRatio 1695 values := map[types.TxValueKeyType]interface{}{ 1696 types.TxValueKeyNonce: uint64(txs.Len()), 1697 types.TxValueKeyFrom: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1698 types.TxValueKeyGasLimit: uint64(20000000), 1699 types.TxValueKeyGasPrice: gasPrice, 1700 types.TxValueKeyAccountKey: accountkey.NewAccountKeyLegacy(), 1701 types.TxValueKeyFeePayer: common.StringToAddress("0xa142f7b24a618778165c9b06e15a61f100c51400"), 1702 types.TxValueKeyFeeRatioOfFeePayer: types.FeeRatio(20), 1703 } 1704 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedAccountUpdateWithRatio, values) 1705 assert.Equal(t, nil, err) 1706 1707 signatures := types.TxSignatures{ 1708 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1709 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1710 } 1711 tx.SetSignature(signatures) 1712 1713 feePayerSignatures := types.TxSignatures{ 1714 &types.TxSignature{V: big.NewInt(3), R: big.NewInt(4), S: big.NewInt(5)}, 1715 &types.TxSignature{V: big.NewInt(4), R: big.NewInt(5), S: big.NewInt(6)}, 1716 } 1717 tx.SetFeePayerSignatures(feePayerSignatures) 1718 1719 txs = append(txs, tx) 1720 txHashMap[tx.Hash()] = tx 1721 // For testing, set GasUsed with tx.Gas() 1722 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1723 receipts = append(receipts, receiptMap[tx.Hash()]) 1724 } 1725 { 1726 // TxTypeFeeDelegatedSmartContractDeployWithRatio 1727 values := map[types.TxValueKeyType]interface{}{ 1728 types.TxValueKeyNonce: uint64(txs.Len()), 1729 types.TxValueKeyFrom: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1730 types.TxValueKeyTo: (*common.Address)(nil), 1731 types.TxValueKeyAmount: big.NewInt(0), 1732 types.TxValueKeyGasLimit: uint64(100000000), 1733 types.TxValueKeyGasPrice: gasPrice, 1734 types.TxValueKeyData: common.Hex2Bytes(deployData), 1735 types.TxValueKeyHumanReadable: false, 1736 types.TxValueKeyCodeFormat: params.CodeFormatEVM, 1737 types.TxValueKeyFeePayer: common.StringToAddress("0xa142f7b24a618778165c9b06e15a61f100c51400"), 1738 types.TxValueKeyFeeRatioOfFeePayer: types.FeeRatio(20), 1739 } 1740 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedSmartContractDeployWithRatio, values) 1741 assert.Equal(t, nil, err) 1742 1743 signatures := types.TxSignatures{ 1744 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1745 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1746 } 1747 tx.SetSignature(signatures) 1748 1749 feePayerSignatures := types.TxSignatures{ 1750 &types.TxSignature{V: big.NewInt(3), R: big.NewInt(4), S: big.NewInt(5)}, 1751 &types.TxSignature{V: big.NewInt(4), R: big.NewInt(5), S: big.NewInt(6)}, 1752 } 1753 tx.SetFeePayerSignatures(feePayerSignatures) 1754 1755 txs = append(txs, tx) 1756 txHashMap[tx.Hash()] = tx 1757 // For testing, set GasUsed with tx.Gas() 1758 r := createReceipt(t, tx, tx.Gas()) 1759 fromAddress, err := tx.From() 1760 if err != nil { 1761 t.Fatal(err) 1762 } 1763 tx.FillContractAddress(fromAddress, r) 1764 receiptMap[tx.Hash()] = r 1765 receipts = append(receipts, receiptMap[tx.Hash()]) 1766 } 1767 { 1768 // TxTypeFeeDelegatedSmartContractExecutionWithRatio 1769 values := map[types.TxValueKeyType]interface{}{ 1770 types.TxValueKeyNonce: uint64(txs.Len()), 1771 types.TxValueKeyFrom: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1772 types.TxValueKeyTo: common.StringToAddress("0x00ca1eee49a4d2b04e6562222eab95e9ed29c4bf"), 1773 types.TxValueKeyAmount: big.NewInt(0), 1774 types.TxValueKeyGasLimit: uint64(50000000), 1775 types.TxValueKeyGasPrice: gasPrice, 1776 types.TxValueKeyData: common.Hex2Bytes(executeData), 1777 types.TxValueKeyFeePayer: common.StringToAddress("0xa142f7b24a618778165c9b06e15a61f100c51400"), 1778 types.TxValueKeyFeeRatioOfFeePayer: types.FeeRatio(20), 1779 } 1780 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedSmartContractExecutionWithRatio, values) 1781 assert.Equal(t, nil, err) 1782 1783 signatures := types.TxSignatures{ 1784 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1785 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1786 } 1787 tx.SetSignature(signatures) 1788 1789 feePayerSignatures := types.TxSignatures{ 1790 &types.TxSignature{V: big.NewInt(3), R: big.NewInt(4), S: big.NewInt(5)}, 1791 &types.TxSignature{V: big.NewInt(4), R: big.NewInt(5), S: big.NewInt(6)}, 1792 } 1793 tx.SetFeePayerSignatures(feePayerSignatures) 1794 1795 txs = append(txs, tx) 1796 txHashMap[tx.Hash()] = tx 1797 // For testing, set GasUsed with tx.Gas() 1798 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1799 receipts = append(receipts, receiptMap[tx.Hash()]) 1800 } 1801 { 1802 // TxTypeFeeDelegatedCancelWithRatio 1803 values := map[types.TxValueKeyType]interface{}{ 1804 types.TxValueKeyNonce: uint64(txs.Len()), 1805 types.TxValueKeyFrom: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1806 types.TxValueKeyGasLimit: uint64(50000000), 1807 types.TxValueKeyGasPrice: gasPrice, 1808 types.TxValueKeyFeePayer: common.StringToAddress("0xa142f7b24a618778165c9b06e15a61f100c51400"), 1809 types.TxValueKeyFeeRatioOfFeePayer: types.FeeRatio(20), 1810 } 1811 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedCancelWithRatio, values) 1812 assert.Equal(t, nil, err) 1813 1814 signatures := types.TxSignatures{ 1815 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1816 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1817 } 1818 tx.SetSignature(signatures) 1819 1820 feePayerSignatures := types.TxSignatures{ 1821 &types.TxSignature{V: big.NewInt(3), R: big.NewInt(4), S: big.NewInt(5)}, 1822 &types.TxSignature{V: big.NewInt(4), R: big.NewInt(5), S: big.NewInt(6)}, 1823 } 1824 tx.SetFeePayerSignatures(feePayerSignatures) 1825 1826 txs = append(txs, tx) 1827 txHashMap[tx.Hash()] = tx 1828 // For testing, set GasUsed with tx.Gas() 1829 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1830 receipts = append(receipts, receiptMap[tx.Hash()]) 1831 } 1832 { 1833 // TxTypeFeeDelegatedChainDataAnchoringWithRatio 1834 values := map[types.TxValueKeyType]interface{}{ 1835 types.TxValueKeyNonce: uint64(txs.Len()), 1836 types.TxValueKeyFrom: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1837 types.TxValueKeyGasLimit: uint64(50000000), 1838 types.TxValueKeyGasPrice: gasPrice, 1839 types.TxValueKeyAnchoredData: anchorData, 1840 types.TxValueKeyFeePayer: common.StringToAddress("0xa142f7b24a618778165c9b06e15a61f100c51400"), 1841 types.TxValueKeyFeeRatioOfFeePayer: types.FeeRatio(20), 1842 } 1843 tx, err := types.NewTransactionWithMap(types.TxTypeFeeDelegatedChainDataAnchoringWithRatio, values) 1844 assert.Equal(t, nil, err) 1845 1846 signatures := types.TxSignatures{ 1847 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1848 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1849 } 1850 tx.SetSignature(signatures) 1851 1852 feePayerSignatures := types.TxSignatures{ 1853 &types.TxSignature{V: big.NewInt(3), R: big.NewInt(4), S: big.NewInt(5)}, 1854 &types.TxSignature{V: big.NewInt(4), R: big.NewInt(5), S: big.NewInt(6)}, 1855 } 1856 tx.SetFeePayerSignatures(feePayerSignatures) 1857 1858 txs = append(txs, tx) 1859 txHashMap[tx.Hash()] = tx 1860 // For testing, set GasUsed with tx.Gas() 1861 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1862 receipts = append(receipts, receiptMap[tx.Hash()]) 1863 } 1864 1865 // Create a block which includes all transaction data. 1866 var block *types.Block 1867 if header != nil { 1868 block = types.NewBlock(header, txs, receipts) 1869 } else { 1870 block = types.NewBlock(&types.Header{Number: big.NewInt(1)}, txs, nil) 1871 } 1872 1873 return block, txs, txHashMap, receiptMap, receipts 1874 } 1875 1876 func createEthereumTypedTestData(t *testing.T, header *types.Header) (*types.Block, types.Transactions, map[common.Hash]*types.Transaction, map[common.Hash]*types.Receipt, []*types.Receipt) { 1877 var txs types.Transactions 1878 1879 gasPrice := big.NewInt(25 * params.Ston) 1880 deployData := "0x60806040526000805534801561001457600080fd5b506101ea806100246000396000f30060806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306661abd1461007257806342cbb15c1461009d578063767800de146100c8578063b22636271461011f578063d14e62b814610150575b600080fd5b34801561007e57600080fd5b5061008761017d565b6040518082815260200191505060405180910390f35b3480156100a957600080fd5b506100b2610183565b6040518082815260200191505060405180910390f35b3480156100d457600080fd5b506100dd61018b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561012b57600080fd5b5061014e60048036038101908080356000191690602001909291905050506101b1565b005b34801561015c57600080fd5b5061017b600480360381019080803590602001909291905050506101b4565b005b60005481565b600043905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b50565b80600081905550505600a165627a7a7230582053c65686a3571c517e2cf4f741d842e5ee6aa665c96ce70f46f9a594794f11eb0029" 1881 accessList := types.AccessList{ 1882 types.AccessTuple{ 1883 Address: common.StringToAddress("0x23a519a88e79fbc0bab796f3dce3ff79a2373e30"), 1884 StorageKeys: []common.Hash{ 1885 common.HexToHash("0xa145cd642157a5df01f5bc3837a1bb59b3dcefbbfad5ec435919780aebeaba2b"), 1886 common.HexToHash("0x12e2c26dca2fb2b8879f54a5ea1604924edf0e37965c2be8aa6133b75818da40"), 1887 }, 1888 }, 1889 } 1890 chainId := new(big.Int).SetUint64(2019) 1891 1892 txHashMap := make(map[common.Hash]*types.Transaction) 1893 receiptMap := make(map[common.Hash]*types.Receipt) 1894 var receipts []*types.Receipt 1895 1896 // Make test transactions data 1897 { 1898 // TxTypeEthereumAccessList 1899 to := common.StringToAddress("0xb5a2d79e9228f3d278cb36b5b15930f24fe8bae8") 1900 values := map[types.TxValueKeyType]interface{}{ 1901 types.TxValueKeyNonce: uint64(txs.Len()), 1902 types.TxValueKeyTo: &to, 1903 types.TxValueKeyAmount: big.NewInt(10), 1904 types.TxValueKeyGasLimit: uint64(50000000), 1905 types.TxValueKeyData: common.Hex2Bytes(deployData), 1906 types.TxValueKeyGasPrice: gasPrice, 1907 types.TxValueKeyAccessList: accessList, 1908 types.TxValueKeyChainID: chainId, 1909 } 1910 tx, err := types.NewTransactionWithMap(types.TxTypeEthereumAccessList, values) 1911 assert.Equal(t, nil, err) 1912 1913 signatures := types.TxSignatures{ 1914 &types.TxSignature{V: big.NewInt(1), R: big.NewInt(2), S: big.NewInt(3)}, 1915 } 1916 tx.SetSignature(signatures) 1917 1918 txs = append(txs, tx) 1919 txHashMap[tx.Hash()] = tx 1920 // For testing, set GasUsed with tx.Gas() 1921 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1922 receipts = append(receipts, receiptMap[tx.Hash()]) 1923 } 1924 { 1925 // TxTypeEthereumDynamicFee 1926 to := common.StringToAddress("0xb5a2d79e9228f3d278cb36b5b15930f24fe8bae8") 1927 values := map[types.TxValueKeyType]interface{}{ 1928 types.TxValueKeyNonce: uint64(txs.Len()), 1929 types.TxValueKeyTo: &to, 1930 types.TxValueKeyAmount: big.NewInt(3), 1931 types.TxValueKeyGasLimit: uint64(50000000), 1932 types.TxValueKeyData: common.Hex2Bytes(deployData), 1933 types.TxValueKeyGasTipCap: gasPrice, 1934 types.TxValueKeyGasFeeCap: gasPrice, 1935 types.TxValueKeyAccessList: accessList, 1936 types.TxValueKeyChainID: chainId, 1937 } 1938 tx, err := types.NewTransactionWithMap(types.TxTypeEthereumDynamicFee, values) 1939 assert.Equal(t, nil, err) 1940 1941 signatures := types.TxSignatures{ 1942 &types.TxSignature{V: big.NewInt(2), R: big.NewInt(3), S: big.NewInt(4)}, 1943 } 1944 tx.SetSignature(signatures) 1945 1946 txs = append(txs, tx) 1947 txHashMap[tx.Hash()] = tx 1948 // For testing, set GasUsed with tx.Gas() 1949 receiptMap[tx.Hash()] = createReceipt(t, tx, tx.Gas()) 1950 receipts = append(receipts, receiptMap[tx.Hash()]) 1951 } 1952 1953 // Create a block which includes all transaction data. 1954 var block *types.Block 1955 if header != nil { 1956 block = types.NewBlock(header, txs, receipts) 1957 } else { 1958 block = types.NewBlock(&types.Header{Number: big.NewInt(1)}, txs, nil) 1959 } 1960 1961 return block, txs, txHashMap, receiptMap, receipts 1962 } 1963 1964 func createReceipt(t *testing.T, tx *types.Transaction, gasUsed uint64) *types.Receipt { 1965 rct := types.NewReceipt(uint(0), tx.Hash(), gasUsed) 1966 rct.Logs = []*types.Log{} 1967 rct.Bloom = types.Bloom{} 1968 return rct 1969 } 1970 1971 // MockDatabaseManager is a mock of database.DBManager interface for overriding the ReadTxAndLookupInfo function. 1972 type MockDatabaseManager struct { 1973 database.DBManager 1974 1975 txHashMap map[common.Hash]*types.Transaction 1976 blockData *types.Block 1977 queryFromPool bool 1978 } 1979 1980 // GetTxLookupInfoAndReceipt retrieves a tx and lookup info and receipt for a given transaction hash. 1981 func (dbm *MockDatabaseManager) ReadTxAndLookupInfo(hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) { 1982 // If queryFromPool, return nil to query from pool after this function 1983 if dbm.queryFromPool { 1984 return nil, common.Hash{}, 0, 0 1985 } 1986 1987 txFromHashMap := dbm.txHashMap[hash] 1988 if txFromHashMap == nil { 1989 return nil, common.Hash{}, 0, 0 1990 } 1991 return txFromHashMap, dbm.blockData.Hash(), dbm.blockData.NumberU64(), txFromHashMap.Nonce() 1992 } 1993 1994 // MockWallet is a mock of accounts.Wallet interface for overriding the Accounts function. 1995 type MockWallet struct { 1996 accounts.Wallet 1997 1998 accounts []accounts.Account 1999 } 2000 2001 // NewMockWallet prepares accounts based on tx from. 2002 func NewMockWallet(txs types.Transactions) *MockWallet { 2003 mw := &MockWallet{} 2004 2005 for _, t := range txs { 2006 mw.accounts = append(mw.accounts, accounts.Account{Address: getFrom(t)}) 2007 } 2008 return mw 2009 } 2010 2011 // Accounts implements accounts.Wallet, returning an account list. 2012 func (mw *MockWallet) Accounts() []accounts.Account { 2013 return mw.accounts 2014 } 2015 2016 // TestEthTransactionArgs_setDefaults tests setDefaults method of EthTransactionArgs. 2017 func TestEthTransactionArgs_setDefaults(t *testing.T) { 2018 _, mockBackend, _ := testInitForEthApi(t) 2019 // To clarify the exact scope of this test, it is assumed that the user must fill in the gas. 2020 // Because when user does not specify gas, it calls estimateGas internally and it requires 2021 // many backend calls which are not directly related with this test. 2022 gas := hexutil.Uint64(1000000) 2023 from := common.HexToAddress("0x2eaad2bf70a070aaa2e007beee99c6148f47718e") 2024 poolNonce := uint64(1) 2025 accountNonce := uint64(5) 2026 to := common.HexToAddress("0x9712f943b296758aaae79944ec975884188d3a96") 2027 byteCode := common.Hex2Bytes("6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632e64cec114604e5780636057361d146076575b600080fd5b348015605957600080fd5b50606060a0565b6040518082815260200191505060405180910390f35b348015608157600080fd5b50609e6004803603810190808035906020019092919050505060a9565b005b60008054905090565b80600081905550505600a165627a7a723058207783dba41884f73679e167576362b7277f88458815141651f48ca38c25b498f80029") 2028 unitPrice := new(big.Int).SetUint64(dummyChainConfigForEthereumAPITest.UnitPrice) 2029 value := new(big.Int).SetUint64(500) 2030 testSet := []struct { 2031 txArgs EthTransactionArgs 2032 expectedResult EthTransactionArgs 2033 dynamicFeeParamsSet bool 2034 nonceSet bool 2035 chainIdSet bool 2036 expectedError error 2037 }{ 2038 { 2039 txArgs: EthTransactionArgs{ 2040 From: nil, 2041 To: nil, 2042 Gas: &gas, 2043 GasPrice: nil, 2044 MaxFeePerGas: nil, 2045 MaxPriorityFeePerGas: nil, 2046 Value: nil, 2047 Nonce: nil, 2048 Data: (*hexutil.Bytes)(&byteCode), 2049 Input: nil, 2050 AccessList: nil, 2051 ChainID: nil, 2052 }, 2053 expectedResult: EthTransactionArgs{ 2054 From: nil, 2055 To: nil, 2056 Gas: &gas, 2057 GasPrice: nil, 2058 MaxFeePerGas: (*hexutil.Big)(unitPrice), 2059 MaxPriorityFeePerGas: (*hexutil.Big)(unitPrice), 2060 Value: (*hexutil.Big)(new(big.Int)), 2061 Nonce: (*hexutil.Uint64)(&poolNonce), 2062 Data: (*hexutil.Bytes)(&byteCode), 2063 Input: nil, 2064 AccessList: nil, 2065 ChainID: (*hexutil.Big)(dummyChainConfigForEthereumAPITest.ChainID), 2066 }, 2067 dynamicFeeParamsSet: false, 2068 nonceSet: false, 2069 chainIdSet: false, 2070 expectedError: nil, 2071 }, 2072 { 2073 txArgs: EthTransactionArgs{ 2074 From: &from, 2075 To: &to, 2076 Gas: &gas, 2077 GasPrice: (*hexutil.Big)(unitPrice), 2078 MaxFeePerGas: nil, 2079 MaxPriorityFeePerGas: nil, 2080 Value: (*hexutil.Big)(value), 2081 Nonce: nil, 2082 Data: (*hexutil.Bytes)(&byteCode), 2083 Input: nil, 2084 AccessList: nil, 2085 ChainID: nil, 2086 }, 2087 expectedResult: EthTransactionArgs{ 2088 From: &from, 2089 To: &to, 2090 Gas: &gas, 2091 GasPrice: (*hexutil.Big)(unitPrice), 2092 MaxFeePerGas: nil, 2093 MaxPriorityFeePerGas: nil, 2094 Value: (*hexutil.Big)(value), 2095 Nonce: (*hexutil.Uint64)(&poolNonce), 2096 Data: (*hexutil.Bytes)(&byteCode), 2097 Input: nil, 2098 AccessList: nil, 2099 ChainID: (*hexutil.Big)(dummyChainConfigForEthereumAPITest.ChainID), 2100 }, 2101 dynamicFeeParamsSet: false, 2102 nonceSet: false, 2103 chainIdSet: false, 2104 expectedError: nil, 2105 }, 2106 { 2107 txArgs: EthTransactionArgs{ 2108 From: &from, 2109 To: &to, 2110 Gas: &gas, 2111 GasPrice: nil, 2112 MaxFeePerGas: (*hexutil.Big)(new(big.Int).SetUint64(1)), 2113 MaxPriorityFeePerGas: nil, 2114 Value: (*hexutil.Big)(value), 2115 Nonce: nil, 2116 Data: nil, 2117 Input: nil, 2118 AccessList: nil, 2119 ChainID: nil, 2120 }, 2121 expectedResult: EthTransactionArgs{}, 2122 dynamicFeeParamsSet: false, 2123 nonceSet: false, 2124 chainIdSet: false, 2125 expectedError: fmt.Errorf("only %s is allowed to be used as maxFeePerGas and maxPriorityPerGas", unitPrice.Text(16)), 2126 }, 2127 { 2128 txArgs: EthTransactionArgs{ 2129 From: &from, 2130 To: &to, 2131 Gas: &gas, 2132 GasPrice: nil, 2133 MaxFeePerGas: nil, 2134 MaxPriorityFeePerGas: (*hexutil.Big)(unitPrice), 2135 Value: (*hexutil.Big)(value), 2136 Nonce: nil, 2137 Data: nil, 2138 Input: nil, 2139 AccessList: nil, 2140 ChainID: nil, 2141 }, 2142 expectedResult: EthTransactionArgs{ 2143 From: &from, 2144 To: &to, 2145 Gas: &gas, 2146 GasPrice: nil, 2147 MaxFeePerGas: (*hexutil.Big)(unitPrice), 2148 MaxPriorityFeePerGas: (*hexutil.Big)(unitPrice), 2149 Value: (*hexutil.Big)(value), 2150 Nonce: (*hexutil.Uint64)(&poolNonce), 2151 Data: nil, 2152 Input: nil, 2153 AccessList: nil, 2154 ChainID: (*hexutil.Big)(dummyChainConfigForEthereumAPITest.ChainID), 2155 }, 2156 dynamicFeeParamsSet: false, 2157 nonceSet: false, 2158 chainIdSet: false, 2159 expectedError: nil, 2160 }, 2161 { 2162 txArgs: EthTransactionArgs{ 2163 From: &from, 2164 To: &to, 2165 Gas: &gas, 2166 GasPrice: nil, 2167 MaxFeePerGas: nil, 2168 MaxPriorityFeePerGas: (*hexutil.Big)(new(big.Int).SetUint64(1)), 2169 Value: (*hexutil.Big)(value), 2170 Nonce: nil, 2171 Data: nil, 2172 Input: nil, 2173 AccessList: nil, 2174 ChainID: nil, 2175 }, 2176 expectedResult: EthTransactionArgs{}, 2177 dynamicFeeParamsSet: false, 2178 nonceSet: false, 2179 chainIdSet: false, 2180 expectedError: fmt.Errorf("only %s is allowed to be used as maxFeePerGas and maxPriorityPerGas", unitPrice.Text(16)), 2181 }, 2182 { 2183 txArgs: EthTransactionArgs{ 2184 From: &from, 2185 To: &to, 2186 Gas: &gas, 2187 GasPrice: (*hexutil.Big)(unitPrice), 2188 MaxFeePerGas: (*hexutil.Big)(unitPrice), 2189 MaxPriorityFeePerGas: (*hexutil.Big)(unitPrice), 2190 Value: (*hexutil.Big)(value), 2191 Nonce: nil, 2192 Data: nil, 2193 Input: nil, 2194 AccessList: nil, 2195 ChainID: nil, 2196 }, 2197 expectedResult: EthTransactionArgs{}, 2198 dynamicFeeParamsSet: false, 2199 nonceSet: false, 2200 chainIdSet: false, 2201 expectedError: errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified"), 2202 }, 2203 { 2204 txArgs: EthTransactionArgs{ 2205 From: &from, 2206 To: &to, 2207 Gas: &gas, 2208 GasPrice: nil, 2209 MaxFeePerGas: (*hexutil.Big)(unitPrice), 2210 MaxPriorityFeePerGas: (*hexutil.Big)(unitPrice), 2211 Value: (*hexutil.Big)(value), 2212 Nonce: nil, 2213 Data: nil, 2214 Input: nil, 2215 AccessList: nil, 2216 ChainID: nil, 2217 }, 2218 expectedResult: EthTransactionArgs{ 2219 From: &from, 2220 To: &to, 2221 Gas: &gas, 2222 GasPrice: nil, 2223 MaxFeePerGas: (*hexutil.Big)(unitPrice), 2224 MaxPriorityFeePerGas: (*hexutil.Big)(unitPrice), 2225 Value: (*hexutil.Big)(value), 2226 Nonce: (*hexutil.Uint64)(&poolNonce), 2227 Data: nil, 2228 Input: nil, 2229 AccessList: nil, 2230 ChainID: (*hexutil.Big)(dummyChainConfigForEthereumAPITest.ChainID), 2231 }, 2232 dynamicFeeParamsSet: true, 2233 nonceSet: false, 2234 chainIdSet: false, 2235 expectedError: nil, 2236 }, 2237 { 2238 txArgs: EthTransactionArgs{ 2239 From: &from, 2240 To: &to, 2241 Gas: &gas, 2242 GasPrice: nil, 2243 MaxFeePerGas: nil, 2244 MaxPriorityFeePerGas: nil, 2245 Value: (*hexutil.Big)(value), 2246 Nonce: (*hexutil.Uint64)(&accountNonce), 2247 Data: (*hexutil.Bytes)(&byteCode), 2248 Input: nil, 2249 AccessList: nil, 2250 ChainID: nil, 2251 }, 2252 expectedResult: EthTransactionArgs{ 2253 From: &from, 2254 To: &to, 2255 Gas: &gas, 2256 GasPrice: nil, 2257 MaxFeePerGas: (*hexutil.Big)(unitPrice), 2258 MaxPriorityFeePerGas: (*hexutil.Big)(unitPrice), 2259 Value: (*hexutil.Big)(value), 2260 Nonce: (*hexutil.Uint64)(&accountNonce), 2261 Data: (*hexutil.Bytes)(&byteCode), 2262 Input: nil, 2263 AccessList: nil, 2264 ChainID: (*hexutil.Big)(dummyChainConfigForEthereumAPITest.ChainID), 2265 }, 2266 dynamicFeeParamsSet: false, 2267 nonceSet: true, 2268 chainIdSet: false, 2269 expectedError: nil, 2270 }, 2271 { 2272 txArgs: EthTransactionArgs{ 2273 From: &from, 2274 To: &to, 2275 Gas: &gas, 2276 GasPrice: nil, 2277 MaxFeePerGas: (*hexutil.Big)(unitPrice), 2278 MaxPriorityFeePerGas: (*hexutil.Big)(unitPrice), 2279 Value: (*hexutil.Big)(value), 2280 Nonce: (*hexutil.Uint64)(&accountNonce), 2281 Data: (*hexutil.Bytes)(&byteCode), 2282 Input: nil, 2283 AccessList: nil, 2284 ChainID: nil, 2285 }, 2286 expectedResult: EthTransactionArgs{ 2287 From: &from, 2288 To: &to, 2289 Gas: &gas, 2290 GasPrice: nil, 2291 MaxFeePerGas: (*hexutil.Big)(unitPrice), 2292 MaxPriorityFeePerGas: (*hexutil.Big)(unitPrice), 2293 Value: (*hexutil.Big)(value), 2294 Nonce: (*hexutil.Uint64)(&accountNonce), 2295 Data: (*hexutil.Bytes)(&byteCode), 2296 Input: nil, 2297 AccessList: nil, 2298 ChainID: (*hexutil.Big)(dummyChainConfigForEthereumAPITest.ChainID), 2299 }, 2300 dynamicFeeParamsSet: true, 2301 nonceSet: true, 2302 chainIdSet: false, 2303 expectedError: nil, 2304 }, 2305 { 2306 txArgs: EthTransactionArgs{ 2307 From: &from, 2308 To: &to, 2309 Gas: &gas, 2310 GasPrice: nil, 2311 MaxFeePerGas: (*hexutil.Big)(unitPrice), 2312 MaxPriorityFeePerGas: (*hexutil.Big)(unitPrice), 2313 Value: (*hexutil.Big)(value), 2314 Nonce: (*hexutil.Uint64)(&accountNonce), 2315 Data: (*hexutil.Bytes)(&byteCode), 2316 Input: nil, 2317 AccessList: nil, 2318 ChainID: (*hexutil.Big)(new(big.Int).SetUint64(1234)), 2319 }, 2320 expectedResult: EthTransactionArgs{ 2321 From: &from, 2322 To: &to, 2323 Gas: &gas, 2324 GasPrice: nil, 2325 MaxFeePerGas: (*hexutil.Big)(unitPrice), 2326 MaxPriorityFeePerGas: (*hexutil.Big)(unitPrice), 2327 Value: (*hexutil.Big)(value), 2328 Nonce: (*hexutil.Uint64)(&accountNonce), 2329 Data: (*hexutil.Bytes)(&byteCode), 2330 Input: nil, 2331 AccessList: nil, 2332 ChainID: (*hexutil.Big)(new(big.Int).SetUint64(1234)), 2333 }, 2334 dynamicFeeParamsSet: true, 2335 nonceSet: true, 2336 chainIdSet: true, 2337 expectedError: nil, 2338 }, 2339 { 2340 txArgs: EthTransactionArgs{ 2341 From: &from, 2342 To: &to, 2343 Gas: &gas, 2344 GasPrice: nil, 2345 MaxFeePerGas: (*hexutil.Big)(unitPrice), 2346 MaxPriorityFeePerGas: (*hexutil.Big)(unitPrice), 2347 Value: (*hexutil.Big)(value), 2348 Nonce: (*hexutil.Uint64)(&accountNonce), 2349 Data: (*hexutil.Bytes)(&byteCode), 2350 Input: (*hexutil.Bytes)(&[]byte{0x1}), 2351 AccessList: nil, 2352 ChainID: (*hexutil.Big)(new(big.Int).SetUint64(1234)), 2353 }, 2354 expectedResult: EthTransactionArgs{}, 2355 dynamicFeeParamsSet: true, 2356 nonceSet: true, 2357 chainIdSet: true, 2358 expectedError: errors.New(`both "data" and "input" are set and not equal. Please use "input" to pass transaction call data`), 2359 }, 2360 } 2361 for _, test := range testSet { 2362 mockBackend.EXPECT().CurrentBlock().Return( 2363 types.NewBlockWithHeader(&types.Header{Number: new(big.Int).SetUint64(0)}), 2364 ) 2365 mockBackend.EXPECT().SuggestPrice(gomock.Any()).Return(unitPrice, nil) 2366 if !test.dynamicFeeParamsSet { 2367 mockBackend.EXPECT().ChainConfig().Return(dummyChainConfigForEthereumAPITest) 2368 } 2369 if !test.nonceSet { 2370 mockBackend.EXPECT().GetPoolNonce(context.Background(), gomock.Any()).Return(poolNonce) 2371 } 2372 if !test.chainIdSet { 2373 mockBackend.EXPECT().ChainConfig().Return(dummyChainConfigForEthereumAPITest) 2374 } 2375 mockBackend.EXPECT().RPCGasCap().Return(nil) 2376 txArgs := test.txArgs 2377 err := txArgs.setDefaults(context.Background(), mockBackend) 2378 require.Equal(t, test.expectedError, err) 2379 if err == nil { 2380 require.Equal(t, test.expectedResult, txArgs) 2381 } 2382 } 2383 } 2384 2385 func TestEthereumAPI_GetRawTransactionByHash(t *testing.T) { 2386 mockCtrl, mockBackend, api := testInitForEthApi(t) 2387 block, txs, txHashMap, _, _ := createEthereumTypedTestData(t, nil) 2388 2389 // Define queryFromPool for ReadTxAndLookupInfo function return tx from hash map. 2390 // MockDatabaseManager will initiate data with txHashMap, block and queryFromPool. 2391 // If queryFromPool is true, MockDatabaseManager will return nil to query transactions from transaction pool, 2392 // otherwise return a transaction from txHashMap. 2393 mockDBManager := &MockDatabaseManager{txHashMap: txHashMap, blockData: block, queryFromPool: false} 2394 2395 // Mock Backend functions. 2396 mockBackend.EXPECT().ChainDB().Return(mockDBManager).Times(txs.Len()) 2397 2398 for i := 0; i < txs.Len(); i++ { 2399 rawTx, err := api.GetRawTransactionByHash(context.Background(), txs[i].Hash()) 2400 if err != nil { 2401 t.Fatal(err) 2402 } 2403 prefix := types.TxType(rawTx[0]) 2404 // When get raw transaction by eth namespace API, EthereumTxTypeEnvelope must not be included. 2405 require.NotEqual(t, types.EthereumTxTypeEnvelope, prefix) 2406 } 2407 2408 mockCtrl.Finish() 2409 } 2410 2411 func TestEthereumAPI_GetRawTransactionByBlockNumberAndIndex(t *testing.T) { 2412 mockCtrl, mockBackend, api := testInitForEthApi(t) 2413 block, txs, _, _, _ := createEthereumTypedTestData(t, nil) 2414 2415 // Mock Backend functions. 2416 mockBackend.EXPECT().BlockByNumber(gomock.Any(), gomock.Any()).Return(block, nil).Times(txs.Len()) 2417 2418 for i := 0; i < txs.Len(); i++ { 2419 rawTx := api.GetRawTransactionByBlockNumberAndIndex(context.Background(), rpc.BlockNumber(block.NumberU64()), hexutil.Uint(i)) 2420 prefix := types.TxType(rawTx[0]) 2421 // When get raw transaction by eth namespace API, EthereumTxTypeEnvelope must not be included. 2422 require.NotEqual(t, types.EthereumTxTypeEnvelope, prefix) 2423 } 2424 2425 mockCtrl.Finish() 2426 } 2427 2428 type testChainContext struct { 2429 header *types.Header 2430 } 2431 2432 func (mc *testChainContext) Engine() consensus.Engine { 2433 return gxhash.NewFaker() 2434 } 2435 2436 func (mc *testChainContext) GetHeader(common.Hash, uint64) *types.Header { 2437 return mc.header 2438 } 2439 2440 // Contract C { constructor() { revert("hello"); } } 2441 var codeRevertHello = "0x6080604052348015600f57600080fd5b5060405162461bcd60e51b815260206004820152600560248201526468656c6c6f60d81b604482015260640160405180910390fdfe" 2442 2443 func testEstimateGas(t *testing.T, mockBackend *mock_api.MockBackend, fnEstimateGas func(EthTransactionArgs) (hexutil.Uint64, error)) { 2444 chainConfig := ¶ms.ChainConfig{} 2445 chainConfig.IstanbulCompatibleBlock = common.Big0 2446 chainConfig.LondonCompatibleBlock = common.Big0 2447 chainConfig.EthTxTypeCompatibleBlock = common.Big0 2448 chainConfig.MagmaCompatibleBlock = common.Big0 2449 var ( 2450 // genesis 2451 account1 = common.HexToAddress("0xaaaa") 2452 account2 = common.HexToAddress("0xbbbb") 2453 account3 = common.HexToAddress("0xcccc") 2454 gspec = &blockchain.Genesis{Alloc: blockchain.GenesisAlloc{ 2455 account1: {Balance: big.NewInt(params.KLAY * 2)}, 2456 account2: {Balance: common.Big0}, 2457 account3: {Balance: common.Big0, Code: hexutil.MustDecode(codeRevertHello)}, 2458 }, Config: chainConfig} 2459 2460 // blockchain 2461 dbm = database.NewMemoryDBManager() 2462 db = state.NewDatabase(dbm) 2463 block = gspec.MustCommit(dbm) 2464 header = block.Header() 2465 chain = &testChainContext{header: header} 2466 2467 // tx arguments 2468 KLAY = hexutil.Big(*big.NewInt(params.KLAY)) 2469 mKLAY = hexutil.Big(*big.NewInt(params.KLAY / 1000)) 2470 KLAY2_1 = hexutil.Big(*big.NewInt(params.KLAY*2 + 1)) 2471 gas1000 = hexutil.Uint64(1000) 2472 gas40000 = hexutil.Uint64(40000) 2473 baddata = hexutil.Bytes(hexutil.MustDecode("0xdeadbeef")) 2474 ) 2475 2476 any := gomock.Any() 2477 getStateAndHeader := func(...interface{}) (*state.StateDB, *types.Header, error) { 2478 // Return a new state for each call because the state is modified by EstimateGas. 2479 state, err := state.New(block.Root(), db, nil, nil) 2480 return state, header, err 2481 } 2482 getEVM := func(_ context.Context, msg blockchain.Message, state *state.StateDB, header *types.Header, vmConfig vm.Config) (*vm.EVM, func() error, error) { 2483 // Taken from node/cn/api_backend.go 2484 vmError := func() error { return nil } 2485 txContext := blockchain.NewEVMTxContext(msg, header) 2486 blockContext := blockchain.NewEVMBlockContext(header, chain, nil) 2487 return vm.NewEVM(blockContext, txContext, state, chainConfig, &vmConfig), vmError, nil 2488 } 2489 mockBackend.EXPECT().ChainConfig().Return(chainConfig).AnyTimes() 2490 mockBackend.EXPECT().RPCGasCap().Return(common.Big0).AnyTimes() 2491 mockBackend.EXPECT().RPCEVMTimeout().Return(5 * time.Second).AnyTimes() 2492 mockBackend.EXPECT().StateAndHeaderByNumber(any, any).DoAndReturn(getStateAndHeader).AnyTimes() 2493 mockBackend.EXPECT().StateAndHeaderByNumberOrHash(any, any).DoAndReturn(getStateAndHeader).AnyTimes() 2494 mockBackend.EXPECT().GetEVM(any, any, any, any, any).DoAndReturn(getEVM).AnyTimes() 2495 2496 testcases := []struct { 2497 args EthTransactionArgs 2498 expectErr string 2499 expectGas uint64 2500 }{ 2501 { // simple transfer 2502 args: EthTransactionArgs{ 2503 From: &account1, 2504 To: &account2, 2505 Value: &KLAY, 2506 }, 2507 expectGas: 21000, 2508 }, 2509 { // simple transfer with insufficient funds with zero gasPrice 2510 args: EthTransactionArgs{ 2511 From: &account2, // sender has 0 KLAY 2512 To: &account1, 2513 Value: &KLAY, // transfer 1 KLAY 2514 }, 2515 expectErr: "insufficient balance for transfer", 2516 }, 2517 { // simple transfer with slightly insufficient funds with zero gasPrice 2518 // this testcase is to check whether the gas prefunded in EthDoCall is not too much 2519 args: EthTransactionArgs{ 2520 From: &account1, // sender has 2 KLAY 2521 To: &account2, 2522 Value: &KLAY2_1, // transfer 2.0000...1 KLAY 2523 }, 2524 expectErr: "insufficient balance for transfer", 2525 }, 2526 { // simple transfer with insufficient funds with nonzero gasPrice 2527 args: EthTransactionArgs{ 2528 From: &account2, // sender has 0 KLAY 2529 To: &account1, 2530 Value: &KLAY, // transfer 1 KLAY 2531 GasPrice: &mKLAY, 2532 }, 2533 expectErr: "insufficient funds for transfer", 2534 }, 2535 { // simple transfer too high gasPrice 2536 args: EthTransactionArgs{ 2537 From: &account1, // sender has 2 KLAY 2538 To: &account2, 2539 Value: &KLAY, // transfer 1 KLAY 2540 GasPrice: &mKLAY, // allowance = (2 - 1) / 0.001 = 1000 gas 2541 }, 2542 expectErr: "gas required exceeds allowance", 2543 }, 2544 { // empty create 2545 args: EthTransactionArgs{}, 2546 expectGas: 53000, 2547 }, 2548 { // ignore too small gasLimit 2549 args: EthTransactionArgs{ 2550 Gas: &gas1000, 2551 }, 2552 expectGas: 53000, 2553 }, 2554 { // capped by gasLimit 2555 args: EthTransactionArgs{ 2556 Gas: &gas40000, 2557 }, 2558 expectErr: "gas required exceeds allowance", 2559 }, 2560 { // fails with VM error 2561 args: EthTransactionArgs{ 2562 From: &account1, 2563 Data: &baddata, 2564 }, 2565 expectErr: "VM error occurs while running smart contract", 2566 }, 2567 { // fails with contract revert 2568 args: EthTransactionArgs{ 2569 From: &account1, 2570 To: &account3, 2571 }, 2572 expectErr: "execution reverted: hello", 2573 }, 2574 } 2575 2576 for i, tc := range testcases { 2577 gas, err := fnEstimateGas(tc.args) 2578 t.Logf("tc[%02d] = %d %v", i, gas, err) 2579 if len(tc.expectErr) > 0 { 2580 require.NotNil(t, err) 2581 assert.Contains(t, err.Error(), tc.expectErr, i) 2582 } else { 2583 assert.Nil(t, err) 2584 assert.Equal(t, tc.expectGas, uint64(gas), i) 2585 } 2586 } 2587 } 2588 2589 func TestEthereumAPI_EstimateGas(t *testing.T) { 2590 mockCtrl, mockBackend, api := testInitForEthApi(t) 2591 defer mockCtrl.Finish() 2592 2593 testEstimateGas(t, mockBackend, func(args EthTransactionArgs) (hexutil.Uint64, error) { 2594 return api.EstimateGas(context.Background(), args, nil) 2595 }) 2596 }