github.com/ava-labs/subnet-evm@v0.6.4/accounts/abi/bind/backends/simulated_test.go (about) 1 // (c) 2019-2020, Ava Labs, Inc. 2 // 3 // This file is a derived work, based on the go-ethereum library whose original 4 // notices appear below. 5 // 6 // It is distributed under a license compatible with the licensing terms of the 7 // original code from which it is derived. 8 // 9 // Much love to the original authors for their work. 10 // ********** 11 // Copyright 2019 The go-ethereum Authors 12 // This file is part of the go-ethereum library. 13 // 14 // The go-ethereum library is free software: you can redistribute it and/or modify 15 // it under the terms of the GNU Lesser General Public License as published by 16 // the Free Software Foundation, either version 3 of the License, or 17 // (at your option) any later version. 18 // 19 // The go-ethereum library is distributed in the hope that it will be useful, 20 // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 // GNU Lesser General Public License for more details. 23 // 24 // You should have received a copy of the GNU Lesser General Public License 25 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 26 27 package backends 28 29 import ( 30 "bytes" 31 "context" 32 "errors" 33 "math/big" 34 "math/rand" 35 "reflect" 36 "strings" 37 "testing" 38 "time" 39 40 "github.com/ava-labs/subnet-evm/accounts/abi" 41 "github.com/ava-labs/subnet-evm/accounts/abi/bind" 42 "github.com/ava-labs/subnet-evm/core" 43 "github.com/ava-labs/subnet-evm/core/types" 44 "github.com/ava-labs/subnet-evm/interfaces" 45 "github.com/ava-labs/subnet-evm/params" 46 "github.com/ethereum/go-ethereum/common" 47 "github.com/ethereum/go-ethereum/crypto" 48 ) 49 50 func TestSimulatedBackend(t *testing.T) { 51 var gasLimit uint64 = 8000029 52 key, _ := crypto.GenerateKey() // nolint: gosec 53 auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) 54 genAlloc := make(core.GenesisAlloc) 55 genAlloc[auth.From] = core.GenesisAccount{Balance: big.NewInt(9223372036854775807)} 56 57 sim := NewSimulatedBackend(genAlloc, gasLimit) 58 defer sim.Close() 59 60 // should return an error if the tx is not found 61 txHash := common.HexToHash("2") 62 _, isPending, err := sim.TransactionByHash(context.Background(), txHash) 63 64 if isPending { 65 t.Fatal("transaction should not be pending") 66 } 67 if err != interfaces.NotFound { 68 t.Fatalf("err should be `interfaces.NotFound` but received %v", err) 69 } 70 71 // generate a transaction and confirm you can retrieve it 72 head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough 73 gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) 74 75 code := `6060604052600a8060106000396000f360606040526008565b00` 76 var gas uint64 = 3000000 77 tx := types.NewContractCreation(0, big.NewInt(0), gas, gasPrice, common.FromHex(code)) 78 tx, _ = types.SignTx(tx, types.HomesteadSigner{}, key) 79 80 err = sim.SendTransaction(context.Background(), tx) 81 if err != nil { 82 t.Fatal("error sending transaction") 83 } 84 85 txHash = tx.Hash() 86 _, isPending, err = sim.TransactionByHash(context.Background(), txHash) 87 if err != nil { 88 t.Fatalf("error getting transaction with hash: %v", txHash.String()) 89 } 90 if !isPending { 91 t.Fatal("transaction should have pending status") 92 } 93 94 sim.Commit(true) 95 _, isPending, err = sim.TransactionByHash(context.Background(), txHash) 96 if err != nil { 97 t.Fatalf("error getting transaction with hash: %v", txHash.String()) 98 } 99 if isPending { 100 t.Fatal("transaction should not have pending status") 101 } 102 } 103 104 var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 105 106 // the following is based on this contract: 107 // 108 // contract T { 109 // event received(address sender, uint amount, bytes memo); 110 // event receivedAddr(address sender); 111 // 112 // function receive(bytes calldata memo) external payable returns (string memory res) { 113 // emit received(msg.sender, msg.value, memo); 114 // emit receivedAddr(msg.sender); 115 // return "hello world"; 116 // } 117 // } 118 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" } ]` 119 const abiBin = `0x608060405234801561001057600080fd5b506102a0806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029` 120 const deployedCode = `60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029` 121 122 // expected return value contains "hello world" 123 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} 124 125 func simTestBackend(testAddr common.Address) *SimulatedBackend { 126 return NewSimulatedBackend( 127 core.GenesisAlloc{ 128 testAddr: {Balance: new(big.Int).Mul(big.NewInt(10000000000000000), big.NewInt(1000))}, 129 }, 10000000, 130 ) 131 } 132 133 func TestNewSimulatedBackend(t *testing.T) { 134 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 135 expectedBal := new(big.Int).Mul(big.NewInt(10000000000000000), big.NewInt(1000)) 136 sim := simTestBackend(testAddr) 137 defer sim.Close() 138 139 stateDB, _ := sim.blockchain.State() 140 bal := stateDB.GetBalance(testAddr) 141 if bal.Cmp(expectedBal) != 0 { 142 t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) 143 } 144 } 145 146 func TestAdjustTime(t *testing.T) { 147 sim := NewSimulatedBackend( 148 core.GenesisAlloc{}, 10000000, 149 ) 150 defer sim.Close() 151 152 prevTime := sim.acceptedBlock.Time() 153 if err := sim.AdjustTime(time.Second); err != nil { 154 t.Error(err) 155 } 156 newTime := sim.acceptedBlock.Time() 157 158 if newTime-prevTime != uint64(time.Second.Seconds()) { 159 t.Errorf("adjusted time not equal to a second. prev: %v, new: %v", prevTime, newTime) 160 } 161 } 162 163 func TestNewAdjustTimeFail(t *testing.T) { 164 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 165 sim := simTestBackend(testAddr) 166 defer sim.blockchain.Stop() 167 168 // Create tx and send 169 head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough 170 gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) 171 172 tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) 173 signer := types.NewLondonSigner(big.NewInt(1337)) 174 signedTx, err := types.SignTx(tx, signer, testKey) 175 if err != nil { 176 t.Errorf("could not sign tx: %v", err) 177 } 178 sim.SendTransaction(context.Background(), signedTx) 179 // AdjustTime should fail on non-empty block 180 if err := sim.AdjustTime(time.Second); err == nil { 181 t.Error("Expected adjust time to error on non-empty block") 182 } 183 sim.Commit(false) 184 185 prevTime := sim.acceptedBlock.Time() 186 if err := sim.AdjustTime(time.Minute); err != nil { 187 t.Error(err) 188 } 189 newTime := sim.acceptedBlock.Time() 190 if newTime-prevTime != uint64(time.Minute.Seconds()) { 191 t.Errorf("adjusted time not equal to a minute. prev: %v, new: %v", prevTime, newTime) 192 } 193 // Put a transaction after adjusting time 194 tx2 := types.NewTransaction(1, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) 195 signer = types.NewLondonSigner(big.NewInt(1337)) 196 signedTx2, err := types.SignTx(tx2, signer, testKey) 197 if err != nil { 198 t.Errorf("could not sign tx: %v", err) 199 } 200 sim.SendTransaction(context.Background(), signedTx2) 201 sim.Commit(false) 202 newTime = sim.acceptedBlock.Time() 203 if newTime-prevTime >= uint64(time.Minute.Seconds()) { 204 t.Errorf("time adjusted, but shouldn't be: prev: %v, new: %v", prevTime, newTime) 205 } 206 } 207 208 func TestBalanceAt(t *testing.T) { 209 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 210 expectedBal := new(big.Int).Mul(big.NewInt(10000000000000000), big.NewInt(1000)) 211 sim := simTestBackend(testAddr) 212 defer sim.Close() 213 bgCtx := context.Background() 214 215 bal, err := sim.BalanceAt(bgCtx, testAddr, nil) 216 if err != nil { 217 t.Error(err) 218 } 219 220 if bal.Cmp(expectedBal) != 0 { 221 t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) 222 } 223 } 224 225 func TestBlockByHash(t *testing.T) { 226 sim := NewSimulatedBackend( 227 core.GenesisAlloc{}, 10000000, 228 ) 229 defer sim.Close() 230 bgCtx := context.Background() 231 232 block, err := sim.BlockByNumber(bgCtx, nil) 233 if err != nil { 234 t.Errorf("could not get recent block: %v", err) 235 } 236 blockByHash, err := sim.BlockByHash(bgCtx, block.Hash()) 237 if err != nil { 238 t.Errorf("could not get recent block: %v", err) 239 } 240 241 if block.Hash() != blockByHash.Hash() { 242 t.Errorf("did not get expected block") 243 } 244 } 245 246 func TestBlockByNumber(t *testing.T) { 247 sim := NewSimulatedBackend( 248 core.GenesisAlloc{}, 10000000, 249 ) 250 defer sim.Close() 251 bgCtx := context.Background() 252 253 block, err := sim.BlockByNumber(bgCtx, nil) 254 if err != nil { 255 t.Errorf("could not get recent block: %v", err) 256 } 257 if block.NumberU64() != 0 { 258 t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64()) 259 } 260 261 // create one block 262 sim.Commit(false) 263 264 block, err = sim.BlockByNumber(bgCtx, nil) 265 if err != nil { 266 t.Errorf("could not get recent block: %v", err) 267 } 268 if block.NumberU64() != 1 { 269 t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64()) 270 } 271 272 blockByNumber, err := sim.BlockByNumber(bgCtx, big.NewInt(1)) 273 if err != nil { 274 t.Errorf("could not get block by number: %v", err) 275 } 276 if blockByNumber.Hash() != block.Hash() { 277 t.Errorf("did not get the same block with height of 1 as before") 278 } 279 } 280 281 func TestNonceAt(t *testing.T) { 282 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 283 284 sim := simTestBackend(testAddr) 285 defer sim.Close() 286 bgCtx := context.Background() 287 288 nonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(0)) 289 if err != nil { 290 t.Errorf("could not get nonce for test addr: %v", err) 291 } 292 293 if nonce != uint64(0) { 294 t.Errorf("received incorrect nonce. expected 0, got %v", nonce) 295 } 296 297 // create a signed transaction to send 298 head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough 299 gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) 300 301 tx := types.NewTransaction(nonce, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) 302 signer := types.NewLondonSigner(big.NewInt(1337)) 303 signedTx, err := types.SignTx(tx, signer, testKey) 304 if err != nil { 305 t.Errorf("could not sign tx: %v", err) 306 } 307 308 // send tx to simulated backend 309 err = sim.SendTransaction(bgCtx, signedTx) 310 if err != nil { 311 t.Errorf("could not add tx to pending block: %v", err) 312 } 313 sim.Commit(false) 314 315 newNonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(1)) 316 if err != nil { 317 t.Errorf("could not get nonce for test addr: %v", err) 318 } 319 320 if newNonce != nonce+uint64(1) { 321 t.Errorf("received incorrect nonce. expected 1, got %v", nonce) 322 } 323 // create some more blocks 324 sim.Commit(false) 325 // Check that we can get data for an older block/state 326 newNonce, err = sim.NonceAt(bgCtx, testAddr, big.NewInt(1)) 327 if err != nil { 328 t.Fatalf("could not get nonce for test addr: %v", err) 329 } 330 if newNonce != nonce+uint64(1) { 331 t.Fatalf("received incorrect nonce. expected 1, got %v", nonce) 332 } 333 } 334 335 func TestSendTransaction(t *testing.T) { 336 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 337 338 sim := simTestBackend(testAddr) 339 defer sim.Close() 340 bgCtx := context.Background() 341 342 // create a signed transaction to send 343 head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough 344 gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) 345 346 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) 347 signer := types.NewLondonSigner(big.NewInt(1337)) 348 signedTx, err := types.SignTx(tx, signer, testKey) 349 if err != nil { 350 t.Errorf("could not sign tx: %v", err) 351 } 352 353 // send tx to simulated backend 354 err = sim.SendTransaction(bgCtx, signedTx) 355 if err != nil { 356 t.Errorf("could not add tx to pending block: %v", err) 357 } 358 sim.Commit(false) 359 360 block, err := sim.BlockByNumber(bgCtx, big.NewInt(1)) 361 if err != nil { 362 t.Errorf("could not get block at height 1: %v", err) 363 } 364 365 if signedTx.Hash() != block.Transactions()[0].Hash() { 366 t.Errorf("did not commit sent transaction. expected hash %v got hash %v", block.Transactions()[0].Hash(), signedTx.Hash()) 367 } 368 } 369 370 func TestTransactionByHash(t *testing.T) { 371 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 372 373 sim := NewSimulatedBackend( 374 core.GenesisAlloc{ 375 testAddr: {Balance: new(big.Int).Mul(big.NewInt(10000000000000000), big.NewInt(1000))}, 376 }, 10000000, 377 ) 378 defer sim.Close() 379 bgCtx := context.Background() 380 381 // create a signed transaction to send 382 head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough 383 gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) 384 385 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) 386 signer := types.NewLondonSigner(big.NewInt(1337)) 387 signedTx, err := types.SignTx(tx, signer, testKey) 388 if err != nil { 389 t.Errorf("could not sign tx: %v", err) 390 } 391 392 // send tx to simulated backend 393 err = sim.SendTransaction(bgCtx, signedTx) 394 if err != nil { 395 t.Errorf("could not add tx to pending block: %v", err) 396 } 397 398 // ensure tx is committed pending 399 receivedTx, pending, err := sim.TransactionByHash(bgCtx, signedTx.Hash()) 400 if err != nil { 401 t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err) 402 } 403 if !pending { 404 t.Errorf("expected transaction to be in pending state") 405 } 406 if receivedTx.Hash() != signedTx.Hash() { 407 t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash()) 408 } 409 410 sim.Commit(true) 411 412 // ensure tx is not and committed pending 413 receivedTx, pending, err = sim.TransactionByHash(bgCtx, signedTx.Hash()) 414 if err != nil { 415 t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err) 416 } 417 if pending { 418 t.Errorf("expected transaction to not be in pending state") 419 } 420 if receivedTx.Hash() != signedTx.Hash() { 421 t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash()) 422 } 423 } 424 425 func TestEstimateGas(t *testing.T) { 426 /* 427 pragma solidity ^0.6.4; 428 contract GasEstimation { 429 function PureRevert() public { revert(); } 430 function Revert() public { revert("revert reason");} 431 function OOG() public { for (uint i = 0; ; i++) {}} 432 function Assert() public { assert(false);} 433 function Valid() public {} 434 } 435 */ 436 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\"}]" 437 const contractBin = "0x60806040523480156100115760006000fd5b50610017565b61016e806100266000396000f3fe60806040523480156100115760006000fd5b506004361061005c5760003560e01c806350f6fe3414610062578063aa8b1d301461006c578063b9b046f914610076578063d8b9839114610080578063e09fface1461008a5761005c565b60006000fd5b61006a610094565b005b6100746100ad565b005b61007e6100b5565b005b6100886100c2565b005b610092610135565b005b6000600090505b5b808060010191505061009b565b505b565b60006000fd5b565b600015156100bf57fe5b5b565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f72657665727420726561736f6e0000000000000000000000000000000000000081526020015060200191505060405180910390fd5b565b5b56fea2646970667358221220345bbcbb1a5ecf22b53a78eaebf95f8ee0eceff6d10d4b9643495084d2ec934a64736f6c63430006040033" 438 439 key, _ := crypto.GenerateKey() 440 addr := crypto.PubkeyToAddress(key.PublicKey) 441 opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) 442 443 sim := NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether)}}, 10000000) 444 defer sim.Close() 445 446 parsed, _ := abi.JSON(strings.NewReader(contractAbi)) 447 contractAddr, _, _, _ := bind.DeployContract(opts, parsed, common.FromHex(contractBin), sim) 448 sim.Commit(false) 449 450 var cases = []struct { 451 name string 452 message interfaces.CallMsg 453 expect uint64 454 expectError error 455 expectData interface{} 456 }{ 457 {"plain transfer(valid)", interfaces.CallMsg{ 458 From: addr, 459 To: &addr, 460 Gas: 0, 461 GasPrice: big.NewInt(0), 462 Value: big.NewInt(1), 463 Data: nil, 464 }, params.TxGas, nil, nil}, 465 466 {"plain transfer(invalid)", interfaces.CallMsg{ 467 From: addr, 468 To: &contractAddr, 469 Gas: 0, 470 GasPrice: big.NewInt(0), 471 Value: big.NewInt(1), 472 Data: nil, 473 }, 0, errors.New("execution reverted"), nil}, 474 475 {"Revert", interfaces.CallMsg{ 476 From: addr, 477 To: &contractAddr, 478 Gas: 0, 479 GasPrice: big.NewInt(0), 480 Value: nil, 481 Data: common.Hex2Bytes("d8b98391"), 482 }, 0, errors.New("execution reverted: revert reason"), "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d72657665727420726561736f6e00000000000000000000000000000000000000"}, 483 484 {"PureRevert", interfaces.CallMsg{ 485 From: addr, 486 To: &contractAddr, 487 Gas: 0, 488 GasPrice: big.NewInt(0), 489 Value: nil, 490 Data: common.Hex2Bytes("aa8b1d30"), 491 }, 0, errors.New("execution reverted"), nil}, 492 493 {"OOG", interfaces.CallMsg{ 494 From: addr, 495 To: &contractAddr, 496 Gas: 100000, 497 GasPrice: big.NewInt(0), 498 Value: nil, 499 Data: common.Hex2Bytes("50f6fe34"), 500 }, 0, errors.New("gas required exceeds allowance (100000)"), nil}, 501 502 {"Assert", interfaces.CallMsg{ 503 From: addr, 504 To: &contractAddr, 505 Gas: 100000, 506 GasPrice: big.NewInt(0), 507 Value: nil, 508 Data: common.Hex2Bytes("b9b046f9"), 509 }, 0, errors.New("invalid opcode: INVALID"), nil}, 510 511 {"Valid", interfaces.CallMsg{ 512 From: addr, 513 To: &contractAddr, 514 Gas: 100000, 515 GasPrice: big.NewInt(0), 516 Value: nil, 517 Data: common.Hex2Bytes("e09fface"), 518 }, 21275, nil, nil}, 519 } 520 for _, c := range cases { 521 got, err := sim.EstimateGas(context.Background(), c.message) 522 if c.expectError != nil { 523 if err == nil { 524 t.Fatalf("Expect error, got nil") 525 } 526 if c.expectError.Error() != err.Error() { 527 t.Fatalf("Expect error, want %v, got %v", c.expectError, err) 528 } 529 if c.expectData != nil { 530 if err, ok := err.(*revertError); !ok { 531 t.Fatalf("Expect revert error, got %T", err) 532 } else if !reflect.DeepEqual(err.ErrorData(), c.expectData) { 533 t.Fatalf("Error data mismatch, want %v, got %v", c.expectData, err.ErrorData()) 534 } 535 } 536 continue 537 } 538 if got != c.expect { 539 t.Fatalf("Gas estimation mismatch, want %d, got %d", c.expect, got) 540 } 541 } 542 } 543 544 func TestEstimateGasWithPrice(t *testing.T) { 545 key, _ := crypto.GenerateKey() 546 addr := crypto.PubkeyToAddress(key.PublicKey) 547 548 sim := NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether*2 + 2e17)}}, 10000000) 549 defer sim.Close() 550 551 recipient := common.HexToAddress("deadbeef") 552 var cases = []struct { 553 name string 554 message interfaces.CallMsg 555 expect uint64 556 expectError error 557 }{ 558 {"EstimateWithoutPrice", interfaces.CallMsg{ 559 From: addr, 560 To: &recipient, 561 Gas: 0, 562 GasPrice: big.NewInt(0), 563 Value: big.NewInt(100000000000), 564 Data: nil, 565 }, 21000, nil}, 566 567 {"EstimateWithPrice", interfaces.CallMsg{ 568 From: addr, 569 To: &recipient, 570 Gas: 0, 571 GasPrice: big.NewInt(225000000000), 572 Value: big.NewInt(100000000000), 573 Data: nil, 574 }, 21000, nil}, 575 576 {"EstimateWithVeryHighPrice", interfaces.CallMsg{ 577 From: addr, 578 To: &recipient, 579 Gas: 0, 580 GasPrice: big.NewInt(1e14), // gascost = 2.1ether 581 Value: big.NewInt(1e17), // the remaining balance for fee is 2.1ether 582 Data: nil, 583 }, 21000, nil}, 584 585 {"EstimateWithSuperhighPrice", interfaces.CallMsg{ 586 From: addr, 587 To: &recipient, 588 Gas: 0, 589 GasPrice: big.NewInt(2e14), // gascost = 4.2ether 590 Value: big.NewInt(100000000000), 591 Data: nil, 592 }, 21000, errors.New("gas required exceeds allowance (10999)")}, // 10999=(2.2ether-1000wei)/(2e14) 593 594 {"EstimateEIP1559WithHighFees", interfaces.CallMsg{ 595 From: addr, 596 To: &addr, 597 Gas: 0, 598 GasFeeCap: big.NewInt(1e14), // maxgascost = 2.1ether 599 GasTipCap: big.NewInt(1), 600 Value: big.NewInt(1e17), // the remaining balance for fee is 2.1ether 601 Data: nil, 602 }, params.TxGas, nil}, 603 604 {"EstimateEIP1559WithSuperHighFees", interfaces.CallMsg{ 605 From: addr, 606 To: &addr, 607 Gas: 0, 608 GasFeeCap: big.NewInt(1e14), // maxgascost = 2.1ether 609 GasTipCap: big.NewInt(1), 610 Value: big.NewInt(1e17 + 1), // the remaining balance for fee is 2.1ether 611 Data: nil, 612 }, params.TxGas, errors.New("gas required exceeds allowance (20999)")}, // 20999=(2.2ether-0.1ether-1wei)/(1e14) 613 } 614 for i, c := range cases { 615 got, err := sim.EstimateGas(context.Background(), c.message) 616 if c.expectError != nil { 617 if err == nil { 618 t.Fatalf("test %d: expect error, got nil", i) 619 } 620 if c.expectError.Error() != err.Error() { 621 t.Fatalf("test %d: expect error, want %v, got %v", i, c.expectError, err) 622 } 623 continue 624 } 625 if c.expectError == nil && err != nil { 626 t.Fatalf("test %d: didn't expect error, got %v", i, err) 627 } 628 if got != c.expect { 629 t.Fatalf("test %d: gas estimation mismatch, want %d, got %d", i, c.expect, got) 630 } 631 } 632 } 633 634 func TestHeaderByHash(t *testing.T) { 635 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 636 637 sim := simTestBackend(testAddr) 638 defer sim.Close() 639 bgCtx := context.Background() 640 641 header, err := sim.HeaderByNumber(bgCtx, nil) 642 if err != nil { 643 t.Errorf("could not get recent block: %v", err) 644 } 645 headerByHash, err := sim.HeaderByHash(bgCtx, header.Hash()) 646 if err != nil { 647 t.Errorf("could not get recent block: %v", err) 648 } 649 650 if header.Hash() != headerByHash.Hash() { 651 t.Errorf("did not get expected block") 652 } 653 } 654 655 func TestHeaderByNumber(t *testing.T) { 656 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 657 658 sim := simTestBackend(testAddr) 659 defer sim.Close() 660 bgCtx := context.Background() 661 662 latestBlockHeader, err := sim.HeaderByNumber(bgCtx, nil) 663 if err != nil { 664 t.Errorf("could not get header for tip of chain: %v", err) 665 } 666 if latestBlockHeader == nil { 667 t.Errorf("received a nil block header") 668 } else if latestBlockHeader.Number.Uint64() != uint64(0) { 669 t.Errorf("expected block header number 0, instead got %v", latestBlockHeader.Number.Uint64()) 670 } 671 672 sim.Commit(false) 673 674 latestBlockHeader, err = sim.HeaderByNumber(bgCtx, nil) 675 if err != nil { 676 t.Errorf("could not get header for blockheight of 1: %v", err) 677 } 678 679 blockHeader, err := sim.HeaderByNumber(bgCtx, big.NewInt(1)) 680 if err != nil { 681 t.Errorf("could not get header for blockheight of 1: %v", err) 682 } 683 684 if blockHeader.Hash() != latestBlockHeader.Hash() { 685 t.Errorf("block header and latest block header are not the same") 686 } 687 if blockHeader.Number.Int64() != int64(1) { 688 t.Errorf("did not get blockheader for block 1. instead got block %v", blockHeader.Number.Int64()) 689 } 690 691 block, err := sim.BlockByNumber(bgCtx, big.NewInt(1)) 692 if err != nil { 693 t.Errorf("could not get block for blockheight of 1: %v", err) 694 } 695 696 if block.Hash() != blockHeader.Hash() { 697 t.Errorf("block hash and block header hash do not match. expected %v, got %v", block.Hash(), blockHeader.Hash()) 698 } 699 } 700 701 func TestTransactionCount(t *testing.T) { 702 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 703 704 sim := simTestBackend(testAddr) 705 defer sim.Close() 706 bgCtx := context.Background() 707 currentBlock, err := sim.BlockByNumber(bgCtx, nil) 708 if err != nil || currentBlock == nil { 709 t.Error("could not get current block") 710 } 711 712 count, err := sim.TransactionCount(bgCtx, currentBlock.Hash()) 713 if err != nil { 714 t.Error("could not get current block's transaction count") 715 } 716 717 if count != 0 { 718 t.Errorf("expected transaction count of %v does not match actual count of %v", 0, count) 719 } 720 // create a signed transaction to send 721 head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough 722 gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) 723 724 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) 725 signer := types.NewLondonSigner(big.NewInt(1337)) 726 signedTx, err := types.SignTx(tx, signer, testKey) 727 if err != nil { 728 t.Errorf("could not sign tx: %v", err) 729 } 730 731 // send tx to simulated backend 732 err = sim.SendTransaction(bgCtx, signedTx) 733 if err != nil { 734 t.Errorf("could not add tx to pending block: %v", err) 735 } 736 737 sim.Commit(false) 738 739 lastBlock, err := sim.BlockByNumber(bgCtx, nil) 740 if err != nil { 741 t.Errorf("could not get header for tip of chain: %v", err) 742 } 743 744 count, err = sim.TransactionCount(bgCtx, lastBlock.Hash()) 745 if err != nil { 746 t.Error("could not get current block's transaction count") 747 } 748 749 if count != 1 { 750 t.Errorf("expected transaction count of %v does not match actual count of %v", 1, count) 751 } 752 } 753 754 func TestTransactionInBlock(t *testing.T) { 755 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 756 757 sim := simTestBackend(testAddr) 758 defer sim.Close() 759 bgCtx := context.Background() 760 761 transaction, err := sim.TransactionInBlock(bgCtx, sim.acceptedBlock.Hash(), uint(0)) 762 if err == nil && err != errTransactionDoesNotExist { 763 t.Errorf("expected a transaction does not exist error to be received but received %v", err) 764 } 765 if transaction != nil { 766 t.Errorf("expected transaction to be nil but received %v", transaction) 767 } 768 769 // expect accepted nonce to be 0 since account has not been used 770 acceptedNonce, err := sim.AcceptedNonceAt(bgCtx, testAddr) 771 if err != nil { 772 t.Errorf("did not get the pending nonce: %v", err) 773 } 774 775 if acceptedNonce != uint64(0) { 776 t.Errorf("expected pending nonce of 0 got %v", acceptedNonce) 777 } 778 // create a signed transaction to send 779 head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough 780 gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) 781 782 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) 783 signer := types.NewLondonSigner(big.NewInt(1337)) 784 signedTx, err := types.SignTx(tx, signer, testKey) 785 if err != nil { 786 t.Errorf("could not sign tx: %v", err) 787 } 788 789 // send tx to simulated backend 790 err = sim.SendTransaction(bgCtx, signedTx) 791 if err != nil { 792 t.Errorf("could not add tx to pending block: %v", err) 793 } 794 795 sim.Commit(false) 796 797 lastBlock, err := sim.BlockByNumber(bgCtx, nil) 798 if err != nil { 799 t.Errorf("could not get header for tip of chain: %v", err) 800 } 801 802 transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(1)) 803 if err == nil && err != errTransactionDoesNotExist { 804 t.Errorf("expected a transaction does not exist error to be received but received %v", err) 805 } 806 if transaction != nil { 807 t.Errorf("expected transaction to be nil but received %v", transaction) 808 } 809 810 transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(0)) 811 if err != nil { 812 t.Errorf("could not get transaction in the lastest block with hash %v: %v", lastBlock.Hash().String(), err) 813 } 814 815 if signedTx.Hash().String() != transaction.Hash().String() { 816 t.Errorf("received transaction that did not match the sent transaction. expected hash %v, got hash %v", signedTx.Hash().String(), transaction.Hash().String()) 817 } 818 } 819 820 func TestAcceptedNonceAt(t *testing.T) { 821 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 822 823 sim := simTestBackend(testAddr) 824 defer sim.Close() 825 bgCtx := context.Background() 826 827 // expect accepted nonce to be 0 since account has not been used 828 acceptedNonce, err := sim.AcceptedNonceAt(bgCtx, testAddr) 829 if err != nil { 830 t.Errorf("did not get the accepted nonce: %v", err) 831 } 832 833 if acceptedNonce != uint64(0) { 834 t.Errorf("expected accepted nonce of 0 got %v", acceptedNonce) 835 } 836 837 // create a signed transaction to send 838 head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough 839 gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) 840 841 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) 842 signer := types.NewLondonSigner(big.NewInt(1337)) 843 signedTx, err := types.SignTx(tx, signer, testKey) 844 if err != nil { 845 t.Errorf("could not sign tx: %v", err) 846 } 847 848 // send tx to simulated backend 849 err = sim.SendTransaction(bgCtx, signedTx) 850 if err != nil { 851 t.Errorf("could not add tx to pending block: %v", err) 852 } 853 854 // expect accepted nonce to be 1 since account has submitted one transaction 855 acceptedNonce, err = sim.AcceptedNonceAt(bgCtx, testAddr) 856 if err != nil { 857 t.Errorf("did not get the accepted nonce: %v", err) 858 } 859 860 if acceptedNonce != uint64(1) { 861 t.Errorf("expected accepted nonce of 1 got %v", acceptedNonce) 862 } 863 864 // make a new transaction with a nonce of 1 865 tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) 866 signer = types.NewLondonSigner(big.NewInt(1337)) 867 signedTx, err = types.SignTx(tx, signer, testKey) 868 if err != nil { 869 t.Errorf("could not sign tx: %v", err) 870 } 871 err = sim.SendTransaction(bgCtx, signedTx) 872 if err != nil { 873 t.Errorf("could not send tx: %v", err) 874 } 875 876 // expect accepted nonce to be 2 since account now has two transactions 877 acceptedNonce, err = sim.AcceptedNonceAt(bgCtx, testAddr) 878 if err != nil { 879 t.Errorf("did not get the accepted nonce: %v", err) 880 } 881 882 if acceptedNonce != uint64(2) { 883 t.Errorf("expected accepted nonce of 2 got %v", acceptedNonce) 884 } 885 } 886 887 func TestTransactionReceipt(t *testing.T) { 888 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 889 890 sim := simTestBackend(testAddr) 891 defer sim.Close() 892 bgCtx := context.Background() 893 894 // create a signed transaction to send 895 head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough 896 gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) 897 898 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) 899 signer := types.NewLondonSigner(big.NewInt(1337)) 900 signedTx, err := types.SignTx(tx, signer, testKey) 901 if err != nil { 902 t.Errorf("could not sign tx: %v", err) 903 } 904 905 // send tx to simulated backend 906 err = sim.SendTransaction(bgCtx, signedTx) 907 if err != nil { 908 t.Errorf("could not add tx to pending block: %v", err) 909 } 910 sim.Commit(true) 911 912 receipt, err := sim.TransactionReceipt(bgCtx, signedTx.Hash()) 913 if err != nil { 914 t.Errorf("could not get transaction receipt: %v", err) 915 } 916 917 if receipt.ContractAddress != testAddr && receipt.TxHash != signedTx.Hash() { 918 t.Errorf("received receipt is not correct: %v", receipt) 919 } 920 } 921 922 func TestSuggestGasPrice(t *testing.T) { 923 sim := NewSimulatedBackend( 924 core.GenesisAlloc{}, 925 10000000, 926 ) 927 defer sim.Close() 928 bgCtx := context.Background() 929 gasPrice, err := sim.SuggestGasPrice(bgCtx) 930 if err != nil { 931 t.Errorf("could not get gas price: %v", err) 932 } 933 if gasPrice.Uint64() != sim.acceptedBlock.Header().BaseFee.Uint64() { 934 t.Errorf("gas price was not expected value of %v. actual: %v", sim.acceptedBlock.Header().BaseFee.Uint64(), gasPrice.Uint64()) 935 } 936 } 937 938 func TestAcceptedCodeAt(t *testing.T) { 939 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 940 sim := simTestBackend(testAddr) 941 defer sim.Close() 942 bgCtx := context.Background() 943 code, err := sim.CodeAt(bgCtx, testAddr, nil) 944 if err != nil { 945 t.Errorf("could not get code at test addr: %v", err) 946 } 947 if len(code) != 0 { 948 t.Errorf("got code for account that does not have contract code") 949 } 950 951 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 952 if err != nil { 953 t.Errorf("could not get code at test addr: %v", err) 954 } 955 auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337)) 956 contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) 957 if err != nil { 958 t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) 959 } 960 961 code, err = sim.AcceptedCodeAt(bgCtx, contractAddr) 962 if err != nil { 963 t.Errorf("could not get code at test addr: %v", err) 964 } 965 if len(code) == 0 { 966 t.Errorf("did not get code for account that has contract code") 967 } 968 // ensure code received equals code deployed 969 if !bytes.Equal(code, common.FromHex(deployedCode)) { 970 t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code) 971 } 972 } 973 974 func TestCodeAt(t *testing.T) { 975 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 976 sim := simTestBackend(testAddr) 977 defer sim.Close() 978 bgCtx := context.Background() 979 code, err := sim.CodeAt(bgCtx, testAddr, nil) 980 if err != nil { 981 t.Errorf("could not get code at test addr: %v", err) 982 } 983 if len(code) != 0 { 984 t.Errorf("got code for account that does not have contract code") 985 } 986 987 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 988 if err != nil { 989 t.Errorf("could not get code at test addr: %v", err) 990 } 991 auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337)) 992 contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) 993 if err != nil { 994 t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) 995 } 996 997 sim.Commit(false) 998 code, err = sim.CodeAt(bgCtx, contractAddr, nil) 999 if err != nil { 1000 t.Errorf("could not get code at test addr: %v", err) 1001 } 1002 if len(code) == 0 { 1003 t.Errorf("did not get code for account that has contract code") 1004 } 1005 // ensure code received equals code deployed 1006 if !bytes.Equal(code, common.FromHex(deployedCode)) { 1007 t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code) 1008 } 1009 } 1010 1011 // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt: 1012 // 1013 // receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} 1014 func TestPendingAndCallContract(t *testing.T) { 1015 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 1016 sim := simTestBackend(testAddr) 1017 defer sim.Close() 1018 bgCtx := context.Background() 1019 1020 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 1021 if err != nil { 1022 t.Errorf("could not get code at test addr: %v", err) 1023 } 1024 contractAuth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337)) 1025 addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(abiBin), sim) 1026 if err != nil { 1027 t.Errorf("could not deploy contract: %v", err) 1028 } 1029 1030 input, err := parsed.Pack("receive", []byte("X")) 1031 if err != nil { 1032 t.Errorf("could not pack receive function on contract: %v", err) 1033 } 1034 1035 // make sure you can call the contract in accepted state 1036 res, err := sim.AcceptedCallContract(bgCtx, interfaces.CallMsg{ 1037 From: testAddr, 1038 To: &addr, 1039 Data: input, 1040 }) 1041 if err != nil { 1042 t.Errorf("could not call receive method on contract: %v", err) 1043 } 1044 if len(res) == 0 { 1045 t.Errorf("result of contract call was empty: %v", res) 1046 } 1047 1048 // while comparing against the byte array is more exact, also compare against the human readable string for readability 1049 if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") { 1050 t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) 1051 } 1052 1053 sim.Commit(false) 1054 1055 // make sure you can call the contract 1056 res, err = sim.CallContract(bgCtx, interfaces.CallMsg{ 1057 From: testAddr, 1058 To: &addr, 1059 Data: input, 1060 }, nil) 1061 if err != nil { 1062 t.Errorf("could not call receive method on contract: %v", err) 1063 } 1064 if len(res) == 0 { 1065 t.Errorf("result of contract call was empty: %v", res) 1066 } 1067 1068 if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") { 1069 t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) 1070 } 1071 } 1072 1073 // This test is based on the following contract: 1074 /* 1075 contract Reverter { 1076 function revertString() public pure{ 1077 require(false, "some error"); 1078 } 1079 function revertNoString() public pure { 1080 require(false, ""); 1081 } 1082 function revertASM() public pure { 1083 assembly { 1084 revert(0x0, 0x0) 1085 } 1086 } 1087 function noRevert() public pure { 1088 assembly { 1089 // Assembles something that looks like require(false, "some error") but is not reverted 1090 mstore(0x0, 0x08c379a000000000000000000000000000000000000000000000000000000000) 1091 mstore(0x4, 0x0000000000000000000000000000000000000000000000000000000000000020) 1092 mstore(0x24, 0x000000000000000000000000000000000000000000000000000000000000000a) 1093 mstore(0x44, 0x736f6d65206572726f7200000000000000000000000000000000000000000000) 1094 return(0x0, 0x64) 1095 } 1096 } 1097 }*/ 1098 func TestCallContractRevert(t *testing.T) { 1099 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 1100 sim := simTestBackend(testAddr) 1101 defer sim.Close() 1102 bgCtx := context.Background() 1103 1104 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"}]` 1105 reverterBin := "608060405234801561001057600080fd5b506101d3806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80634b409e01146100515780639b340e361461005b5780639bd6103714610065578063b7246fc11461006f575b600080fd5b610059610079565b005b6100636100ca565b005b61006d6100cf565b005b610077610145565b005b60006100c8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526000815260200160200191505060405180910390fd5b565b600080fd5b6000610143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f736f6d65206572726f720000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b7f08c379a0000000000000000000000000000000000000000000000000000000006000526020600452600a6024527f736f6d65206572726f720000000000000000000000000000000000000000000060445260646000f3fea2646970667358221220cdd8af0609ec4996b7360c7c780bad5c735740c64b1fffc3445aa12d37f07cb164736f6c63430006070033" 1106 1107 parsed, err := abi.JSON(strings.NewReader(reverterABI)) 1108 if err != nil { 1109 t.Errorf("could not get code at test addr: %v", err) 1110 } 1111 contractAuth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337)) 1112 addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(reverterBin), sim) 1113 if err != nil { 1114 t.Errorf("could not deploy contract: %v", err) 1115 } 1116 1117 inputs := make(map[string]interface{}, 3) 1118 inputs["revertASM"] = nil 1119 inputs["revertNoString"] = "" 1120 inputs["revertString"] = "some error" 1121 1122 call := make([]func([]byte) ([]byte, error), 2) 1123 call[0] = func(input []byte) ([]byte, error) { 1124 return sim.AcceptedCallContract(bgCtx, interfaces.CallMsg{ 1125 From: testAddr, 1126 To: &addr, 1127 Data: input, 1128 }) 1129 } 1130 call[1] = func(input []byte) ([]byte, error) { 1131 return sim.CallContract(bgCtx, interfaces.CallMsg{ 1132 From: testAddr, 1133 To: &addr, 1134 Data: input, 1135 }, nil) 1136 } 1137 1138 // Run pending calls then commit 1139 for _, cl := range call { 1140 for key, val := range inputs { 1141 input, err := parsed.Pack(key) 1142 if err != nil { 1143 t.Errorf("could not pack %v function on contract: %v", key, err) 1144 } 1145 1146 res, err := cl(input) 1147 if err == nil { 1148 t.Errorf("call to %v was not reverted", key) 1149 } 1150 if res != nil { 1151 t.Errorf("result from %v was not nil: %v", key, res) 1152 } 1153 if val != nil { 1154 rerr, ok := err.(*revertError) 1155 if !ok { 1156 t.Errorf("expect revert error") 1157 } 1158 if rerr.Error() != "execution reverted: "+val.(string) { 1159 t.Errorf("error was malformed: got %v want %v", rerr.Error(), val) 1160 } 1161 } else { 1162 // revert(0x0,0x0) 1163 if err.Error() != "execution reverted" { 1164 t.Errorf("error was malformed: got %v want %v", err, "execution reverted") 1165 } 1166 } 1167 } 1168 input, err := parsed.Pack("noRevert") 1169 if err != nil { 1170 t.Errorf("could not pack noRevert function on contract: %v", err) 1171 } 1172 res, err := cl(input) 1173 if err != nil { 1174 t.Error("call to noRevert was reverted") 1175 } 1176 if res == nil { 1177 t.Errorf("result from noRevert was nil") 1178 } 1179 sim.Commit(false) 1180 } 1181 } 1182 1183 // TestFork check that the chain length after a reorg is correct. 1184 // Steps: 1185 // 1. Save the current block which will serve as parent for the fork. 1186 // 2. Mine n blocks with n ∈ [0, 20]. 1187 // 3. Assert that the chain length is n. 1188 // 4. Fork by using the parent block as ancestor. 1189 // 5. Mine n+1 blocks which should trigger a reorg. 1190 // 6. Assert that the chain length is n+1. 1191 // Since Commit() was called 2n+1 times in total, 1192 // having a chain length of just n+1 means that a reorg occurred. 1193 func TestFork(t *testing.T) { 1194 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 1195 sim := simTestBackend(testAddr) 1196 defer sim.Close() 1197 // 1. 1198 parent := sim.blockchain.CurrentBlock() 1199 // 2. 1200 n := int(rand.Int31n(21)) 1201 for i := 0; i < n; i++ { 1202 sim.Commit(false) 1203 } 1204 // 3. 1205 if sim.blockchain.CurrentBlock().Number.Uint64() != uint64(n) { 1206 t.Error("wrong chain length") 1207 } 1208 // 4. 1209 sim.Fork(context.Background(), parent.Hash()) 1210 // 5. 1211 for i := 0; i < n+1; i++ { 1212 sim.Commit(false) 1213 } 1214 // 6. 1215 if sim.blockchain.CurrentBlock().Number.Uint64() != uint64(n+1) { 1216 t.Error("wrong chain length") 1217 } 1218 } 1219 1220 /* 1221 Example contract to test event emission: 1222 1223 pragma solidity >=0.7.0 <0.9.0; 1224 contract Callable { 1225 event Called(); 1226 function Call() public { emit Called(); } 1227 } 1228 */ 1229 // The fork tests are commented out because transactions are not indexed in subnet-evm until they are marked 1230 // as accepted, which breaks the logic of these tests. 1231 // const callableAbi = "[{\"anonymous\":false,\"inputs\":[],\"name\":\"Called\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"Call\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" 1232 1233 // const callableBin = "6080604052348015600f57600080fd5b5060998061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806334e2292114602d575b600080fd5b60336035565b005b7f81fab7a4a0aa961db47eefc81f143a5220e8c8495260dd65b1356f1d19d3c7b860405160405180910390a156fea2646970667358221220029436d24f3ac598ceca41d4d712e13ced6d70727f4cdc580667de66d2f51d8b64736f6c63430008010033" 1234 1235 // // TestForkLogsReborn check that the simulated reorgs 1236 // // correctly remove and reborn logs. 1237 // // Steps: 1238 // // 1. Deploy the Callable contract. 1239 // // 2. Set up an event subscription. 1240 // // 3. Save the current block which will serve as parent for the fork. 1241 // // 4. Send a transaction. 1242 // // 5. Check that the event was included. 1243 // // 6. Fork by using the parent block as ancestor. 1244 // // 7. Mine two blocks to trigger a reorg. 1245 // // 8. Check that the event was removed. 1246 // // 9. Re-send the transaction and mine a block. 1247 // // 10. Check that the event was reborn. 1248 // func TestForkLogsReborn(t *testing.T) { 1249 // testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 1250 // sim := simTestBackend(testAddr) 1251 // defer sim.Close() 1252 // // 1. 1253 // parsed, _ := abi.JSON(strings.NewReader(callableAbi)) 1254 // auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337)) 1255 // _, _, contract, err := bind.DeployContract(auth, parsed, common.FromHex(callableBin), sim) 1256 // if err != nil { 1257 // t.Errorf("deploying contract: %v", err) 1258 // } 1259 // sim.Commit(false) 1260 // // 2. 1261 // logs, sub, err := contract.WatchLogs(nil, "Called") 1262 // if err != nil { 1263 // t.Errorf("watching logs: %v", err) 1264 // } 1265 // defer sub.Unsubscribe() 1266 // // 3. 1267 // parent := sim.blockchain.CurrentBlock() 1268 // // 4. 1269 // tx, err := contract.Transact(auth, "Call") 1270 // if err != nil { 1271 // t.Errorf("transacting: %v", err) 1272 // } 1273 // sim.Commit(false) 1274 // // 5. 1275 // log := <-logs 1276 // if log.TxHash != tx.Hash() { 1277 // t.Error("wrong event tx hash") 1278 // } 1279 // if log.Removed { 1280 // t.Error("Event should be included") 1281 // } 1282 // // 6. 1283 // if err := sim.Fork(context.Background(), parent.Hash()); err != nil { 1284 // t.Errorf("forking: %v", err) 1285 // } 1286 // // 7. 1287 // sim.Commit(false) 1288 // sim.Commit(false) 1289 // // 8. 1290 // log = <-logs 1291 // if log.TxHash != tx.Hash() { 1292 // t.Error("wrong event tx hash") 1293 // } 1294 // if !log.Removed { 1295 // t.Error("Event should be removed") 1296 // } 1297 // // 9. 1298 // if err := sim.SendTransaction(context.Background(), tx); err != nil { 1299 // t.Errorf("sending transaction: %v", err) 1300 // } 1301 // sim.Commit(false) 1302 // // 10. 1303 // log = <-logs 1304 // if log.TxHash != tx.Hash() { 1305 // t.Error("wrong event tx hash") 1306 // } 1307 // if log.Removed { 1308 // t.Error("Event should be included") 1309 // } 1310 // } 1311 1312 // // TestForkResendTx checks that re-sending a TX after a fork 1313 // // is possible and does not cause a "nonce mismatch" panic. 1314 // // Steps: 1315 // // 1. Save the current block which will serve as parent for the fork. 1316 // // 2. Send a transaction. 1317 // // 3. Check that the TX is included in block 1. 1318 // // 4. Fork by using the parent block as ancestor. 1319 // // 5. Mine a block, Re-send the transaction and mine another one. 1320 // // 6. Check that the TX is now included in block 2. 1321 // func TestForkResendTx(t *testing.T) { 1322 // testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 1323 // sim := simTestBackend(testAddr) 1324 // defer sim.Close() 1325 // // 1. 1326 // parent := sim.blockchain.CurrentBlock() 1327 // // 2. 1328 // head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough 1329 // gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) 1330 1331 // _tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) 1332 // signer := types.NewLondonSigner(big.NewInt(1337)) 1333 // tx, _ := types.SignTx(_tx, signer, testKey) 1334 // sim.SendTransaction(context.Background(), tx) 1335 // sim.Commit(false) 1336 // // 3. 1337 // receipt, _ := sim.TransactionReceipt(context.Background(), tx.Hash()) 1338 // if h := receipt.BlockNumber.Uint64(); h != 1 { 1339 // t.Errorf("TX included in wrong block: %d", h) 1340 // } 1341 // // 4. 1342 // if err := sim.Fork(context.Background(), parent.Hash()); err != nil { 1343 // t.Errorf("forking: %v", err) 1344 // } 1345 // // 5. 1346 // sim.Commit(false) 1347 // if err := sim.SendTransaction(context.Background(), tx); err != nil { 1348 // t.Errorf("sending transaction: %v", err) 1349 // } 1350 // sim.Commit(false) 1351 // // 6. 1352 // receipt, _ = sim.TransactionReceipt(context.Background(), tx.Hash()) 1353 // if h := receipt.BlockNumber.Uint64(); h != 2 { 1354 // t.Errorf("TX included in wrong block: %d", h) 1355 // } 1356 // } 1357 1358 func TestCommitReturnValue(t *testing.T) { 1359 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 1360 sim := simTestBackend(testAddr) 1361 defer sim.Close() 1362 1363 startBlockHeight := sim.blockchain.CurrentBlock().Number.Uint64() 1364 1365 // Test if Commit returns the correct block hash 1366 h1 := sim.Commit(true) 1367 if h1 != sim.blockchain.CurrentBlock().Hash() { 1368 t.Error("Commit did not return the hash of the last block.") 1369 } 1370 1371 // Create a block in the original chain (containing a transaction to force different block hashes) 1372 head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough 1373 gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) 1374 _tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) 1375 tx, _ := types.SignTx(_tx, types.HomesteadSigner{}, testKey) 1376 sim.SendTransaction(context.Background(), tx) 1377 h2 := sim.Commit(false) 1378 1379 // Create another block in the original chain 1380 sim.Commit(false) 1381 1382 // Fork at the first bock 1383 if err := sim.Fork(context.Background(), h1); err != nil { 1384 t.Errorf("forking: %v", err) 1385 } 1386 1387 // Test if Commit returns the correct block hash after the reorg 1388 h2fork := sim.Commit(false) 1389 if h2 == h2fork { 1390 t.Error("The block in the fork and the original block are the same block!") 1391 } 1392 if sim.blockchain.GetHeader(h2fork, startBlockHeight+2) == nil { 1393 t.Error("Could not retrieve the just created block (side-chain)") 1394 } 1395 } 1396 1397 // TestAdjustTimeAfterFork ensures that after a fork, AdjustTime uses the pending fork 1398 // block's parent rather than the canonical head's parent. 1399 func TestAdjustTimeAfterFork(t *testing.T) { 1400 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 1401 sim := simTestBackend(testAddr) 1402 defer sim.Close() 1403 1404 sim.Commit(false) // h1 1405 h1 := sim.blockchain.CurrentHeader().Hash() 1406 sim.Commit(false) // h2 1407 sim.Fork(context.Background(), h1) 1408 sim.AdjustTime(1 * time.Second) 1409 sim.Commit(false) 1410 1411 head := sim.blockchain.CurrentHeader() 1412 if head.Number == common.Big2 && head.ParentHash != h1 { 1413 t.Errorf("failed to build block on fork") 1414 } 1415 }