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