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