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