github.com/klaytn/klaytn@v1.12.1/accounts/abi/bind/backends/simulated_test.go (about) 1 // Modifications Copyright 2020 The klaytn Authors 2 // Copyright 2019 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from accounts/abi/bind/backends/simulated_test.go(2020/11/24). 19 // Modified and improved for the klaytn development. 20 21 package backends 22 23 import ( 24 "bytes" 25 "context" 26 "errors" 27 "math/big" 28 "reflect" 29 "strings" 30 "testing" 31 "time" 32 33 "github.com/klaytn/klaytn" 34 "github.com/klaytn/klaytn/accounts/abi" 35 "github.com/klaytn/klaytn/accounts/abi/bind" 36 "github.com/klaytn/klaytn/blockchain" 37 "github.com/klaytn/klaytn/blockchain/types" 38 "github.com/klaytn/klaytn/common" 39 "github.com/klaytn/klaytn/crypto" 40 "github.com/klaytn/klaytn/params" 41 ) 42 43 func TestSimulatedBackend(t *testing.T) { 44 key, _ := crypto.GenerateKey() // nolint: gosec 45 auth := bind.NewKeyedTransactor(key) 46 genAlloc := make(blockchain.GenesisAlloc) 47 genAlloc[auth.From] = blockchain.GenesisAccount{Balance: big.NewInt(9223372036854775807)} 48 49 sim := NewSimulatedBackend(genAlloc) 50 defer sim.Close() 51 52 // should return an error if the tx is not found 53 txHash := common.HexToHash("2") 54 _, isPending, err := sim.TransactionByHash(context.Background(), txHash) 55 56 if isPending { 57 t.Fatal("transaction should not be pending") 58 } 59 if err != klaytn.NotFound { 60 t.Fatalf("err should be `klaytn.NotFound` but received %v", err) 61 } 62 63 // generate a transaction and confirm you can retrieve it 64 code := `6060604052600a8060106000396000f360606040526008565b00` 65 var gas uint64 = 3000000 66 tx := types.NewContractCreation(0, big.NewInt(0), gas, big.NewInt(1), common.FromHex(code)) 67 tx, _ = types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), key) 68 69 err = sim.SendTransaction(context.Background(), tx) 70 if err != nil { 71 t.Fatal("error sending transaction") 72 } 73 74 txHash = tx.Hash() 75 _, isPending, err = sim.TransactionByHash(context.Background(), txHash) 76 if err != nil { 77 t.Fatalf("error getting transaction with hash: %v", txHash.String()) 78 } 79 if !isPending { 80 t.Fatal("transaction should have pending status") 81 } 82 83 sim.Commit() 84 _, isPending, err = sim.TransactionByHash(context.Background(), txHash) 85 if err != nil { 86 t.Fatalf("error getting transaction with hash: %v", txHash.String()) 87 } 88 if isPending { 89 t.Fatal("transaction should not have pending status") 90 } 91 } 92 93 var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 94 95 // the following is based on this contract: 96 // contract T { 97 // event received(address sender, uint amount, bytes memo); 98 // event receivedAddr(address sender); 99 // 100 // function receive(bytes calldata memo) external payable returns (string memory res) { 101 // emit received(msg.sender, msg.value, memo); 102 // emit receivedAddr(msg.sender); 103 // return "hello world"; 104 // } 105 // } 106 const abiJSON = `[ { "constant": false, "inputs": [ { "name": "memo", "type": "bytes" } ], "name": "receive", "outputs": [ { "name": "res", "type": "string" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" }, { "indexed": false, "name": "memo", "type": "bytes" } ], "name": "received", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" } ], "name": "receivedAddr", "type": "event" } ]` 107 108 const ( 109 abiBin = `0x608060405234801561001057600080fd5b506102a0806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029` 110 deployedCode = `60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029` 111 ) 112 113 // expected return value contains "hello world" 114 var expectedReturn = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 115 116 func simTestBackend(testAddr common.Address) *SimulatedBackend { 117 return NewSimulatedBackend( 118 blockchain.GenesisAlloc{ 119 testAddr: {Balance: big.NewInt(10000000000)}, 120 }, 121 ) 122 } 123 124 func TestNewSimulatedBackend(t *testing.T) { 125 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 126 expectedBal := big.NewInt(10000000000) 127 sim := simTestBackend(testAddr) 128 defer sim.Close() 129 130 if sim.config != params.AllGxhashProtocolChanges { 131 t.Errorf("expected sim config to equal params.AllGxhashProtocolChanges, got %v", sim.config) 132 } 133 134 if sim.blockchain.Config() != params.AllGxhashProtocolChanges { 135 t.Errorf("expected sim blockchain config to equal params.AllGxhashProtocolChanges, got %v", sim.config) 136 } 137 138 stateDB, _ := sim.blockchain.State() 139 bal := stateDB.GetBalance(testAddr) 140 if bal.Cmp(expectedBal) != 0 { 141 t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) 142 } 143 } 144 145 func TestSimulatedBackend_AdjustTime(t *testing.T) { 146 sim := NewSimulatedBackend( 147 blockchain.GenesisAlloc{}, 148 ) 149 defer sim.Close() 150 151 prevTime := sim.pendingBlock.Time() 152 if err := sim.AdjustTime(time.Second); err != nil { 153 t.Error(err) 154 } 155 newTime := sim.pendingBlock.Time() 156 157 if newTime.Uint64()-prevTime.Uint64() != uint64(time.Second.Seconds()) { 158 t.Errorf("adjusted time not equal to a second. prev: %v, new: %v", prevTime, newTime) 159 } 160 } 161 162 func TestNewSimulatedBackend_AdjustTimeFail(t *testing.T) { 163 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 164 sim := simTestBackend(testAddr) 165 // Create tx and send 166 tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 167 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 168 if err != nil { 169 t.Errorf("could not sign tx: %v", err) 170 } 171 sim.SendTransaction(context.Background(), signedTx) 172 // AdjustTime should fail on non-empty block 173 if err := sim.AdjustTime(time.Second); err == nil { 174 t.Error("Expected adjust time to error on non-empty block") 175 } 176 sim.Commit() 177 178 prevTime := sim.pendingBlock.Time() 179 if err := sim.AdjustTime(time.Minute); err != nil { 180 t.Error(err) 181 } 182 newTime := sim.pendingBlock.Time() 183 if newTime.Uint64()-prevTime.Uint64() != uint64(time.Minute.Seconds()) { 184 t.Errorf("adjusted time not equal to a minute. prev: %v, new: %v", prevTime, newTime) 185 } 186 // Put a transaction after adjusting time 187 tx2 := types.NewTransaction(1, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 188 signedTx2, err := types.SignTx(tx2, types.LatestSignerForChainID(sim.config.ChainID), testKey) 189 if err != nil { 190 t.Errorf("could not sign tx: %v", err) 191 } 192 sim.SendTransaction(context.Background(), signedTx2) 193 sim.Commit() 194 newTime = sim.pendingBlock.Time() 195 if newTime.Uint64()-prevTime.Uint64() >= uint64(time.Minute.Seconds()) { 196 t.Errorf("time adjusted, but shouldn't be: prev: %v, new: %v", prevTime, newTime) 197 } 198 } 199 200 func TestSimulatedBackend_BalanceAt(t *testing.T) { 201 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 202 expectedBal := big.NewInt(10000000000) 203 sim := simTestBackend(testAddr) 204 defer sim.Close() 205 bgCtx := context.Background() 206 207 bal, err := sim.BalanceAt(bgCtx, testAddr, nil) 208 if err != nil { 209 t.Error(err) 210 } 211 212 if bal.Cmp(expectedBal) != 0 { 213 t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) 214 } 215 } 216 217 func TestSimulatedBackend_BlockByHash(t *testing.T) { 218 sim := NewSimulatedBackend( 219 blockchain.GenesisAlloc{}, 220 ) 221 defer sim.Close() 222 bgCtx := context.Background() 223 224 block, err := sim.BlockByNumber(bgCtx, nil) 225 if err != nil { 226 t.Errorf("could not get recent block: %v", err) 227 } 228 blockByHash, err := sim.BlockByHash(bgCtx, block.Hash()) 229 if err != nil { 230 t.Errorf("could not get recent block: %v", err) 231 } 232 233 if block.Hash() != blockByHash.Hash() { 234 t.Errorf("did not get expected block") 235 } 236 } 237 238 func TestSimulatedBackend_BlockByNumber(t *testing.T) { 239 sim := NewSimulatedBackend( 240 blockchain.GenesisAlloc{}, 241 ) 242 defer sim.Close() 243 bgCtx := context.Background() 244 245 block, err := sim.BlockByNumber(bgCtx, nil) 246 if err != nil { 247 t.Errorf("could not get recent block: %v", err) 248 } 249 if block.NumberU64() != 0 { 250 t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64()) 251 } 252 253 // create one block 254 sim.Commit() 255 256 block, err = sim.BlockByNumber(bgCtx, nil) 257 if err != nil { 258 t.Errorf("could not get recent block: %v", err) 259 } 260 if block.NumberU64() != 1 { 261 t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64()) 262 } 263 264 blockByNumber, err := sim.BlockByNumber(bgCtx, big.NewInt(1)) 265 if err != nil { 266 t.Errorf("could not get block by number: %v", err) 267 } 268 if blockByNumber.Hash() != block.Hash() { 269 t.Errorf("did not get the same block with height of 1 as before") 270 } 271 } 272 273 func TestSimulatedBackend_NonceAt(t *testing.T) { 274 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 275 276 sim := simTestBackend(testAddr) 277 defer sim.Close() 278 bgCtx := context.Background() 279 280 nonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(0)) 281 if err != nil { 282 t.Errorf("could not get nonce for test addr: %v", err) 283 } 284 285 if nonce != uint64(0) { 286 t.Errorf("received incorrect nonce. expected 0, got %v", nonce) 287 } 288 289 // create a signed transaction to send 290 tx := types.NewTransaction(nonce, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 291 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 292 if err != nil { 293 t.Errorf("could not sign tx: %v", err) 294 } 295 296 // send tx to simulated backend 297 err = sim.SendTransaction(bgCtx, signedTx) 298 if err != nil { 299 t.Errorf("could not add tx to pending block: %v", err) 300 } 301 sim.Commit() 302 303 newNonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(1)) 304 if err != nil { 305 t.Errorf("could not get nonce for test addr: %v", err) 306 } 307 308 if newNonce != nonce+uint64(1) { 309 t.Errorf("received incorrect nonce. expected 1, got %v", nonce) 310 } 311 // create some more blocks 312 sim.Commit() 313 // Check that we can get data for an older block/state 314 newNonce, err = sim.NonceAt(bgCtx, testAddr, big.NewInt(1)) 315 if err != nil { 316 t.Fatalf("could not get nonce for test addr: %v", err) 317 } 318 if newNonce != nonce+uint64(1) { 319 t.Fatalf("received incorrect nonce. expected 1, got %v", nonce) 320 } 321 } 322 323 func TestSimulatedBackend_SendTransaction(t *testing.T) { 324 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 325 326 sim := simTestBackend(testAddr) 327 defer sim.Close() 328 bgCtx := context.Background() 329 330 // create a signed transaction to send 331 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 332 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 333 if err != nil { 334 t.Errorf("could not sign tx: %v", err) 335 } 336 337 // send tx to simulated backend 338 err = sim.SendTransaction(bgCtx, signedTx) 339 if err != nil { 340 t.Errorf("could not add tx to pending block: %v", err) 341 } 342 sim.Commit() 343 344 block, err := sim.BlockByNumber(bgCtx, big.NewInt(1)) 345 if err != nil { 346 t.Errorf("could not get block at height 1: %v", err) 347 } 348 349 if signedTx.Hash() != block.Transactions()[0].Hash() { 350 t.Errorf("did not commit sent transaction. expected hash %v got hash %v", block.Transactions()[0].Hash(), signedTx.Hash()) 351 } 352 } 353 354 func TestSimulatedBackend_TransactionByHash(t *testing.T) { 355 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 356 357 sim := simTestBackend(testAddr) 358 defer sim.Close() 359 bgCtx := context.Background() 360 361 // create a signed transaction to send 362 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 363 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 364 if err != nil { 365 t.Errorf("could not sign tx: %v", err) 366 } 367 368 // send tx to simulated backend 369 err = sim.SendTransaction(bgCtx, signedTx) 370 if err != nil { 371 t.Errorf("could not add tx to pending block: %v", err) 372 } 373 374 // ensure tx is committed pending 375 receivedTx, pending, err := sim.TransactionByHash(bgCtx, signedTx.Hash()) 376 if err != nil { 377 t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err) 378 } 379 if !pending { 380 t.Errorf("expected transaction to be in pending state") 381 } 382 if receivedTx.Hash() != signedTx.Hash() { 383 t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash()) 384 } 385 386 sim.Commit() 387 388 // ensure tx is not and committed pending 389 receivedTx, pending, err = sim.TransactionByHash(bgCtx, signedTx.Hash()) 390 if err != nil { 391 t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err) 392 } 393 if pending { 394 t.Errorf("expected transaction to not be in pending state") 395 } 396 if receivedTx.Hash() != signedTx.Hash() { 397 t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash()) 398 } 399 } 400 401 func TestSimulatedBackend_EstimateGas(t *testing.T) { 402 /* 403 pragma solidity ^0.6.4; 404 contract GasEstimation { 405 function PureRevert() public { revert(); } 406 function Revert() public { revert("revert reason");} 407 function OOG() public { for (uint i = 0; ; i++) {}} 408 function Assert() public { assert(false);} 409 function Valid() public {} 410 }*/ 411 const contractAbi = "[{\"inputs\":[],\"name\":\"Assert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OOG\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PureRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Revert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Valid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" 412 const contractBin = "0x60806040523480156100115760006000fd5b50610017565b61016e806100266000396000f3fe60806040523480156100115760006000fd5b506004361061005c5760003560e01c806350f6fe3414610062578063aa8b1d301461006c578063b9b046f914610076578063d8b9839114610080578063e09fface1461008a5761005c565b60006000fd5b61006a610094565b005b6100746100ad565b005b61007e6100b5565b005b6100886100c2565b005b610092610135565b005b6000600090505b5b808060010191505061009b565b505b565b60006000fd5b565b600015156100bf57fe5b5b565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f72657665727420726561736f6e0000000000000000000000000000000000000081526020015060200191505060405180910390fd5b565b5b56fea2646970667358221220345bbcbb1a5ecf22b53a78eaebf95f8ee0eceff6d10d4b9643495084d2ec934a64736f6c63430006040033" 413 414 key, _ := crypto.GenerateKey() 415 addr := crypto.PubkeyToAddress(key.PublicKey) 416 opts := bind.NewKeyedTransactor(key) 417 418 sim := simTestBackend(addr) 419 defer sim.Close() 420 421 parsed, _ := abi.JSON(strings.NewReader(contractAbi)) 422 contractAddr, _, _, _ := bind.DeployContract(opts, parsed, common.FromHex(contractBin), sim) 423 sim.Commit() 424 425 cases := []struct { 426 name string 427 message klaytn.CallMsg 428 expect uint64 429 expectError error 430 expectData interface{} 431 }{ 432 {"plain transfer(valid)", klaytn.CallMsg{ 433 From: addr, 434 To: &addr, 435 Gas: 0, 436 GasPrice: big.NewInt(0), 437 Value: big.NewInt(1), 438 Data: nil, 439 }, params.TxGas, nil, nil}, 440 441 {"plain transfer(invalid)", klaytn.CallMsg{ 442 From: addr, 443 To: &contractAddr, 444 Gas: 0, 445 GasPrice: big.NewInt(0), 446 Value: big.NewInt(1), 447 Data: nil, 448 }, 0, errors.New("evm: execution reverted"), nil}, 449 450 {"Revert", klaytn.CallMsg{ 451 From: addr, 452 To: &contractAddr, 453 Gas: 0, 454 GasPrice: big.NewInt(0), 455 Value: nil, 456 Data: common.Hex2Bytes("d8b98391"), 457 }, 0, errors.New("execution reverted: revert reason"), "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d72657665727420726561736f6e00000000000000000000000000000000000000"}, 458 459 {"PureRevert", klaytn.CallMsg{ 460 From: addr, 461 To: &contractAddr, 462 Gas: 0, 463 GasPrice: big.NewInt(0), 464 Value: nil, 465 Data: common.Hex2Bytes("aa8b1d30"), 466 }, 0, errors.New("evm: execution reverted"), nil}, 467 468 {"OOG", klaytn.CallMsg{ 469 From: addr, 470 To: &contractAddr, 471 Gas: 100000, 472 GasPrice: big.NewInt(0), 473 Value: nil, 474 Data: common.Hex2Bytes("50f6fe34"), 475 }, 0, errors.New("gas required exceeds allowance (100000)"), nil}, 476 477 {"Assert", klaytn.CallMsg{ 478 From: addr, 479 To: &contractAddr, 480 Gas: 100000, 481 GasPrice: big.NewInt(0), 482 Value: nil, 483 Data: common.Hex2Bytes("b9b046f9"), 484 }, 0, errors.New("VM error occurs while running smart contract"), nil}, 485 486 {"Valid", klaytn.CallMsg{ 487 From: addr, 488 To: &contractAddr, 489 Gas: 100000, 490 GasPrice: big.NewInt(0), 491 Value: nil, 492 Data: common.Hex2Bytes("e09fface"), 493 }, 21483, nil, nil}, 494 } 495 for _, c := range cases { 496 got, err := sim.EstimateGas(context.Background(), c.message) 497 if c.expectError != nil { 498 if err == nil { 499 t.Fatalf("Expect error, got nil") 500 } 501 if c.expectError.Error() != err.Error() { 502 t.Fatalf("Expect error, want %v, got %v", c.expectError, err) 503 } 504 if c.expectData != nil { 505 if err, ok := err.(*blockchain.RevertError); !ok { 506 t.Fatalf("Expect revert error, got %T", err) 507 } else if !reflect.DeepEqual(err.ErrorData(), c.expectData) { 508 t.Fatalf("Error data mismatch, want %v, got %v", c.expectData, err.ErrorData()) 509 } 510 } 511 continue 512 } 513 if got != c.expect { 514 t.Fatalf("Gas estimation mismatch, want %d, got %d", c.expect, got) 515 } 516 } 517 } 518 519 func TestSimulatedBackend_HeaderByHash(t *testing.T) { 520 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 521 522 sim := simTestBackend(testAddr) 523 defer sim.Close() 524 bgCtx := context.Background() 525 526 header, err := sim.HeaderByNumber(bgCtx, nil) 527 if err != nil { 528 t.Errorf("could not get recent block: %v", err) 529 } 530 headerByHash, err := sim.HeaderByHash(bgCtx, header.Hash()) 531 if err != nil { 532 t.Errorf("could not get recent block: %v", err) 533 } 534 535 if header.Hash() != headerByHash.Hash() { 536 t.Errorf("did not get expected block") 537 } 538 } 539 540 func TestSimulatedBackend_HeaderByNumber(t *testing.T) { 541 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 542 543 sim := simTestBackend(testAddr) 544 defer sim.Close() 545 bgCtx := context.Background() 546 547 latestBlockHeader, err := sim.HeaderByNumber(bgCtx, nil) 548 if err != nil { 549 t.Errorf("could not get header for tip of chain: %v", err) 550 } 551 if latestBlockHeader == nil { 552 t.Errorf("received a nil block header") 553 } 554 if latestBlockHeader.Number.Uint64() != uint64(0) { 555 t.Errorf("expected block header number 0, instead got %v", latestBlockHeader.Number.Uint64()) 556 } 557 558 sim.Commit() 559 560 latestBlockHeader, err = sim.HeaderByNumber(bgCtx, nil) 561 if err != nil { 562 t.Errorf("could not get header for blockheight of 1: %v", err) 563 } 564 565 blockHeader, err := sim.HeaderByNumber(bgCtx, big.NewInt(1)) 566 if err != nil { 567 t.Errorf("could not get header for blockheight of 1: %v", err) 568 } 569 570 if blockHeader.Hash() != latestBlockHeader.Hash() { 571 t.Errorf("block header and latest block header are not the same") 572 } 573 if blockHeader.Number.Int64() != int64(1) { 574 t.Errorf("did not get blockheader for block 1. instead got block %v", blockHeader.Number.Int64()) 575 } 576 577 block, err := sim.BlockByNumber(bgCtx, big.NewInt(1)) 578 if err != nil { 579 t.Errorf("could not get block for blockheight of 1: %v", err) 580 } 581 582 if block.Hash() != blockHeader.Hash() { 583 t.Errorf("block hash and block header hash do not match. expected %v, got %v", block.Hash(), blockHeader.Hash()) 584 } 585 } 586 587 func TestSimulatedBackend_TransactionCount(t *testing.T) { 588 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 589 590 sim := simTestBackend(testAddr) 591 defer sim.Close() 592 bgCtx := context.Background() 593 currentBlock, err := sim.BlockByNumber(bgCtx, nil) 594 if err != nil || currentBlock == nil { 595 t.Error("could not get current block") 596 } 597 598 count, err := sim.TransactionCount(bgCtx, currentBlock.Hash()) 599 if err != nil { 600 t.Error("could not get current block's transaction count") 601 } 602 603 if count != 0 { 604 t.Errorf("expected transaction count of %v does not match actual count of %v", 0, count) 605 } 606 607 // create a signed transaction to send 608 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 609 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 610 if err != nil { 611 t.Errorf("could not sign tx: %v", err) 612 } 613 614 // send tx to simulated backend 615 err = sim.SendTransaction(bgCtx, signedTx) 616 if err != nil { 617 t.Errorf("could not add tx to pending block: %v", err) 618 } 619 620 sim.Commit() 621 622 lastBlock, err := sim.BlockByNumber(bgCtx, nil) 623 if err != nil { 624 t.Errorf("could not get header for tip of chain: %v", err) 625 } 626 627 count, err = sim.TransactionCount(bgCtx, lastBlock.Hash()) 628 if err != nil { 629 t.Error("could not get current block's transaction count") 630 } 631 632 if count != 1 { 633 t.Errorf("expected transaction count of %v does not match actual count of %v", 1, count) 634 } 635 } 636 637 func TestSimulatedBackend_TransactionInBlock(t *testing.T) { 638 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 639 640 sim := simTestBackend(testAddr) 641 defer sim.Close() 642 bgCtx := context.Background() 643 644 transaction, err := sim.TransactionInBlock(bgCtx, sim.pendingBlock.Hash(), uint(0)) 645 if err == nil && err != errTransactionDoesNotExist { 646 t.Errorf("expected a transaction does not exist error to be received but received %v", err) 647 } 648 if transaction != nil { 649 t.Errorf("expected transaction to be nil but received %v", transaction) 650 } 651 652 // expect pending nonce to be 0 since account has not been used 653 pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr) 654 if err != nil { 655 t.Errorf("did not get the pending nonce: %v", err) 656 } 657 658 if pendingNonce != uint64(0) { 659 t.Errorf("expected pending nonce of 0 got %v", pendingNonce) 660 } 661 662 // create a signed transaction to send 663 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 664 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 665 if err != nil { 666 t.Errorf("could not sign tx: %v", err) 667 } 668 669 // send tx to simulated backend 670 err = sim.SendTransaction(bgCtx, signedTx) 671 if err != nil { 672 t.Errorf("could not add tx to pending block: %v", err) 673 } 674 675 sim.Commit() 676 677 lastBlock, err := sim.BlockByNumber(bgCtx, nil) 678 if err != nil { 679 t.Errorf("could not get header for tip of chain: %v", err) 680 } 681 682 transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(1)) 683 if err == nil && err != errTransactionDoesNotExist { 684 t.Errorf("expected a transaction does not exist error to be received but received %v", err) 685 } 686 if transaction != nil { 687 t.Errorf("expected transaction to be nil but received %v", transaction) 688 } 689 690 transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(0)) 691 if err != nil { 692 t.Errorf("could not get transaction in the lastest block with hash %v: %v", lastBlock.Hash().String(), err) 693 } 694 695 if signedTx.Hash().String() != transaction.Hash().String() { 696 t.Errorf("received transaction that did not match the sent transaction. expected hash %v, got hash %v", signedTx.Hash().String(), transaction.Hash().String()) 697 } 698 } 699 700 func TestSimulatedBackend_PendingNonceAt(t *testing.T) { 701 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 702 703 sim := simTestBackend(testAddr) 704 defer sim.Close() 705 bgCtx := context.Background() 706 707 // expect pending nonce to be 0 since account has not been used 708 pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr) 709 if err != nil { 710 t.Errorf("did not get the pending nonce: %v", err) 711 } 712 713 if pendingNonce != uint64(0) { 714 t.Errorf("expected pending nonce of 0 got %v", pendingNonce) 715 } 716 717 // create a signed transaction to send 718 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 719 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 720 if err != nil { 721 t.Errorf("could not sign tx: %v", err) 722 } 723 724 // send tx to simulated backend 725 err = sim.SendTransaction(bgCtx, signedTx) 726 if err != nil { 727 t.Errorf("could not add tx to pending block: %v", err) 728 } 729 730 // expect pending nonce to be 1 since account has submitted one transaction 731 pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr) 732 if err != nil { 733 t.Errorf("did not get the pending nonce: %v", err) 734 } 735 736 if pendingNonce != uint64(1) { 737 t.Errorf("expected pending nonce of 1 got %v", pendingNonce) 738 } 739 740 // make a new transaction with a nonce of 1 741 tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 742 signedTx, err = types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 743 if err != nil { 744 t.Errorf("could not sign tx: %v", err) 745 } 746 err = sim.SendTransaction(bgCtx, signedTx) 747 if err != nil { 748 t.Errorf("could not send tx: %v", err) 749 } 750 751 // expect pending nonce to be 2 since account now has two transactions 752 pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr) 753 if err != nil { 754 t.Errorf("did not get the pending nonce: %v", err) 755 } 756 757 if pendingNonce != uint64(2) { 758 t.Errorf("expected pending nonce of 2 got %v", pendingNonce) 759 } 760 } 761 762 func TestSimulatedBackend_TransactionReceipt(t *testing.T) { 763 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 764 765 sim := simTestBackend(testAddr) 766 defer sim.Close() 767 bgCtx := context.Background() 768 769 // create a signed transaction to send 770 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 771 signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey) 772 if err != nil { 773 t.Errorf("could not sign tx: %v", err) 774 } 775 776 // send tx to simulated backend 777 err = sim.SendTransaction(bgCtx, signedTx) 778 if err != nil { 779 t.Errorf("could not add tx to pending block: %v", err) 780 } 781 sim.Commit() 782 783 receipt, err := sim.TransactionReceipt(bgCtx, signedTx.Hash()) 784 if err != nil { 785 t.Errorf("could not get transaction receipt: %v", err) 786 } 787 788 if receipt.ContractAddress != testAddr && receipt.TxHash != signedTx.Hash() { 789 t.Errorf("received receipt is not correct: %v", receipt) 790 } 791 } 792 793 func TestSimulatedBackend_SuggestGasPrice(t *testing.T) { 794 sim := NewSimulatedBackend( 795 blockchain.GenesisAlloc{}, 796 ) 797 defer sim.Close() 798 bgCtx := context.Background() 799 gasPrice, err := sim.SuggestGasPrice(bgCtx) 800 if err != nil { 801 t.Errorf("could not get gas price: %v", err) 802 } 803 if gasPrice.Uint64() != uint64(0) { 804 t.Errorf("gas price was not expected value of 0. actual: %v", gasPrice.Uint64()) 805 } 806 } 807 808 func TestSimulatedBackend_PendingCodeAt(t *testing.T) { 809 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 810 sim := simTestBackend(testAddr) 811 defer sim.Close() 812 bgCtx := context.Background() 813 code, err := sim.CodeAt(bgCtx, testAddr, nil) 814 if err != nil { 815 t.Errorf("could not get code at test addr: %v", err) 816 } 817 if len(code) != 0 { 818 t.Errorf("got code for account that does not have contract code") 819 } 820 821 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 822 if err != nil { 823 t.Errorf("could not get code at test addr: %v", err) 824 } 825 auth := bind.NewKeyedTransactor(testKey) 826 contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) 827 if err != nil { 828 t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) 829 } 830 831 code, err = sim.PendingCodeAt(bgCtx, contractAddr) 832 if err != nil { 833 t.Errorf("could not get code at test addr: %v", err) 834 } 835 if len(code) == 0 { 836 t.Errorf("did not get code for account that has contract code") 837 } 838 // ensure code received equals code deployed 839 if !bytes.Equal(code, common.FromHex(deployedCode)) { 840 t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code) 841 } 842 } 843 844 func TestSimulatedBackend_CodeAt(t *testing.T) { 845 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 846 sim := simTestBackend(testAddr) 847 defer sim.Close() 848 bgCtx := context.Background() 849 code, err := sim.CodeAt(bgCtx, testAddr, nil) 850 if err != nil { 851 t.Errorf("could not get code at test addr: %v", err) 852 } 853 if len(code) != 0 { 854 t.Errorf("got code for account that does not have contract code") 855 } 856 857 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 858 if err != nil { 859 t.Errorf("could not get code at test addr: %v", err) 860 } 861 auth := bind.NewKeyedTransactor(testKey) 862 contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) 863 if err != nil { 864 t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) 865 } 866 867 sim.Commit() 868 code, err = sim.CodeAt(bgCtx, contractAddr, nil) 869 if err != nil { 870 t.Errorf("could not get code at test addr: %v", err) 871 } 872 if len(code) == 0 { 873 t.Errorf("did not get code for account that has contract code") 874 } 875 // ensure code received equals code deployed 876 if !bytes.Equal(code, common.FromHex(deployedCode)) { 877 t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code) 878 } 879 } 880 881 // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt: 882 // receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} 883 func TestSimulatedBackend_PendingAndCallContract(t *testing.T) { 884 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 885 sim := simTestBackend(testAddr) 886 defer sim.Close() 887 bgCtx := context.Background() 888 889 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 890 if err != nil { 891 t.Errorf("could not get code at test addr: %v", err) 892 } 893 contractAuth := bind.NewKeyedTransactor(testKey) 894 addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(abiBin), sim) 895 if err != nil { 896 t.Errorf("could not deploy contract: %v", err) 897 } 898 899 input, err := parsed.Pack("receive", []byte("X")) 900 if err != nil { 901 t.Errorf("could not pack receive function on contract: %v", err) 902 } 903 904 // make sure you can call the contract in pending state 905 res, err := sim.PendingCallContract(bgCtx, klaytn.CallMsg{ 906 From: testAddr, 907 To: &addr, 908 Data: input, 909 }) 910 if err != nil { 911 t.Errorf("could not call receive method on contract: %v", err) 912 } 913 if len(res) == 0 { 914 t.Errorf("result of contract call was empty: %v", res) 915 } 916 917 // while comparing against the byte array is more exact, also compare against the human readable string for readability 918 if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") { 919 t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) 920 } 921 922 sim.Commit() 923 924 // make sure you can call the contract 925 res, err = sim.CallContract(bgCtx, klaytn.CallMsg{ 926 From: testAddr, 927 To: &addr, 928 Data: input, 929 }, nil) 930 if err != nil { 931 t.Errorf("could not call receive method on contract: %v", err) 932 } 933 if len(res) == 0 { 934 t.Errorf("result of contract call was empty: %v", res) 935 } 936 937 if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") { 938 t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) 939 } 940 } 941 942 // This test is based on the following contract: 943 /* 944 contract Reverter { 945 function revertString() public pure{ 946 require(false, "some error"); 947 } 948 function revertNoString() public pure { 949 require(false, ""); 950 } 951 function revertASM() public pure { 952 assembly { 953 revert(0x0, 0x0) 954 } 955 } 956 function noRevert() public pure { 957 assembly { 958 // Assembles something that looks like require(false, "some error") but is not reverted 959 mstore(0x0, 0x08c379a000000000000000000000000000000000000000000000000000000000) 960 mstore(0x4, 0x0000000000000000000000000000000000000000000000000000000000000020) 961 mstore(0x24, 0x000000000000000000000000000000000000000000000000000000000000000a) 962 mstore(0x44, 0x736f6d65206572726f7200000000000000000000000000000000000000000000) 963 return(0x0, 0x64) 964 } 965 } 966 }*/ 967 var ( 968 reverterABI = `[{"inputs": [],"name": "noRevert","outputs": [],"stateMutability": "pure","type": "function"},{"inputs": [],"name": "revertASM","outputs": [],"stateMutability": "pure","type": "function"},{"inputs": [],"name": "revertNoString","outputs": [],"stateMutability": "pure","type": "function"},{"inputs": [],"name": "revertString","outputs": [],"stateMutability": "pure","type": "function"}]` 969 reverterBin = "608060405234801561001057600080fd5b506101d3806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80634b409e01146100515780639b340e361461005b5780639bd6103714610065578063b7246fc11461006f575b600080fd5b610059610079565b005b6100636100ca565b005b61006d6100cf565b005b610077610145565b005b60006100c8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526000815260200160200191505060405180910390fd5b565b600080fd5b6000610143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f736f6d65206572726f720000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b7f08c379a0000000000000000000000000000000000000000000000000000000006000526020600452600a6024527f736f6d65206572726f720000000000000000000000000000000000000000000060445260646000f3fea2646970667358221220cdd8af0609ec4996b7360c7c780bad5c735740c64b1fffc3445aa12d37f07cb164736f6c63430006070033" 970 reverterDeployedBin = "608060405234801561001057600080fd5b506004361061004c5760003560e01c80634b409e01146100515780639b340e361461005b5780639bd6103714610065578063b7246fc11461006f575b600080fd5b610059610079565b005b6100636100ca565b005b61006d6100cf565b005b610077610145565b005b60006100c8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526000815260200160200191505060405180910390fd5b565b600080fd5b6000610143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f736f6d65206572726f720000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b7f08c379a0000000000000000000000000000000000000000000000000000000006000526020600452600a6024527f736f6d65206572726f720000000000000000000000000000000000000000000060445260646000f3fea2646970667358221220cdd8af0609ec4996b7360c7c780bad5c735740c64b1fffc3445aa12d37f07cb164736f6c63430006070033" 971 ) 972 973 func TestSimulatedBackend_CallContractRevert(t *testing.T) { 974 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 975 sim := simTestBackend(testAddr) 976 defer sim.Close() 977 bgCtx := context.Background() 978 979 parsed, err := abi.JSON(strings.NewReader(reverterABI)) 980 if err != nil { 981 t.Errorf("could not get code at test addr: %v", err) 982 } 983 contractAuth := bind.NewKeyedTransactor(testKey) 984 addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(reverterBin), sim) 985 if err != nil { 986 t.Errorf("could not deploy contract: %v", err) 987 } 988 989 inputs := make(map[string]interface{}, 3) 990 inputs["revertASM"] = nil 991 inputs["revertNoString"] = "" 992 inputs["revertString"] = "some error" 993 994 call := make([]func([]byte) ([]byte, error), 2) 995 call[0] = func(input []byte) ([]byte, error) { 996 return sim.PendingCallContract(bgCtx, klaytn.CallMsg{ 997 From: testAddr, 998 To: &addr, 999 Data: input, 1000 }) 1001 } 1002 call[1] = func(input []byte) ([]byte, error) { 1003 return sim.CallContract(bgCtx, klaytn.CallMsg{ 1004 From: testAddr, 1005 To: &addr, 1006 Data: input, 1007 }, nil) 1008 } 1009 1010 // Run pending calls then commit 1011 for _, cl := range call { 1012 for key, val := range inputs { 1013 input, err := parsed.Pack(key) 1014 if err != nil { 1015 t.Errorf("could not pack %v function on contract: %v", key, err) 1016 } 1017 1018 res, err := cl(input) 1019 if err == nil { 1020 t.Errorf("call to %v was not reverted", key) 1021 } 1022 if res != nil { 1023 t.Errorf("result from %v was not nil: %v", key, res) 1024 } 1025 if val != nil { 1026 rerr, ok := err.(*blockchain.RevertError) 1027 if !ok { 1028 t.Errorf("expect revert error") 1029 } 1030 if rerr.Error() != "execution reverted: "+val.(string) { 1031 t.Errorf("error was malformed: got %v want %v", rerr.Error(), val) 1032 } 1033 } else { 1034 // revert(0x0,0x0) 1035 if err.Error() != "evm: execution reverted" { 1036 t.Errorf("error was malformed: got %v want %v", err, "evm: execution reverted") 1037 } 1038 } 1039 } 1040 input, err := parsed.Pack("noRevert") 1041 if err != nil { 1042 t.Errorf("could not pack noRevert function on contract: %v", err) 1043 } 1044 res, err := cl(input) 1045 if err != nil { 1046 t.Error("call to noRevert was reverted") 1047 } 1048 if res == nil { 1049 t.Errorf("result from noRevert was nil") 1050 } 1051 sim.Commit() 1052 } 1053 }