github.com/ethereum-optimism/optimism/l2geth@v0.0.0-20230612200230-50b04ade19e3/accounts/abi/bind/backends/simulated_test.go (about) 1 // Copyright 2019 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package backends 18 19 import ( 20 "bytes" 21 "context" 22 "math/big" 23 "strings" 24 "testing" 25 "time" 26 27 ethereum "github.com/ethereum-optimism/optimism/l2geth" 28 "github.com/ethereum-optimism/optimism/l2geth/accounts/abi" 29 "github.com/ethereum-optimism/optimism/l2geth/accounts/abi/bind" 30 "github.com/ethereum-optimism/optimism/l2geth/common" 31 "github.com/ethereum-optimism/optimism/l2geth/core" 32 "github.com/ethereum-optimism/optimism/l2geth/core/types" 33 "github.com/ethereum-optimism/optimism/l2geth/crypto" 34 "github.com/ethereum-optimism/optimism/l2geth/params" 35 ) 36 37 func TestSimulatedBackend(t *testing.T) { 38 var gasLimit uint64 = 8000029 39 key, _ := crypto.GenerateKey() // nolint: gosec 40 auth := bind.NewKeyedTransactor(key) 41 genAlloc := make(core.GenesisAlloc) 42 genAlloc[auth.From] = core.GenesisAccount{Balance: big.NewInt(9223372036854775807)} 43 44 sim := NewSimulatedBackend(genAlloc, gasLimit) 45 defer sim.Close() 46 47 // should return an error if the tx is not found 48 txHash := common.HexToHash("2") 49 _, isPending, err := sim.TransactionByHash(context.Background(), txHash) 50 51 if isPending { 52 t.Fatal("transaction should not be pending") 53 } 54 if err != ethereum.NotFound { 55 t.Fatalf("err should be `ethereum.NotFound` but received %v", err) 56 } 57 58 // generate a transaction and confirm you can retrieve it 59 code := `6060604052600a8060106000396000f360606040526008565b00` 60 var gas uint64 = 3000000 61 tx := types.NewContractCreation(0, big.NewInt(0), gas, big.NewInt(1), common.FromHex(code)) 62 tx, _ = types.SignTx(tx, types.HomesteadSigner{}, key) 63 64 err = sim.SendTransaction(context.Background(), tx) 65 if err != nil { 66 t.Fatal("error sending transaction") 67 } 68 69 txHash = tx.Hash() 70 _, isPending, err = sim.TransactionByHash(context.Background(), txHash) 71 if err != nil { 72 t.Fatalf("error getting transaction with hash: %v", txHash.String()) 73 } 74 if !isPending { 75 t.Fatal("transaction should have pending status") 76 } 77 78 sim.Commit() 79 _, isPending, err = sim.TransactionByHash(context.Background(), txHash) 80 if err != nil { 81 t.Fatalf("error getting transaction with hash: %v", txHash.String()) 82 } 83 if isPending { 84 t.Fatal("transaction should not have pending status") 85 } 86 } 87 88 var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 89 90 // the following is based on this contract: 91 // contract T { 92 // event received(address sender, uint amount, bytes memo); 93 // event receivedAddr(address sender); 94 // 95 // function receive(bytes calldata memo) external payable returns (string memory res) { 96 // emit received(msg.sender, msg.value, memo); 97 // emit receivedAddr(msg.sender); 98 // return "hello world"; 99 // } 100 // } 101 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" } ]` 102 const abiBin = `0x608060405234801561001057600080fd5b506102a0806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029` 103 const deployedCode = `60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029` 104 105 // expected return value contains "hello world" 106 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} 107 108 func TestNewSimulatedBackend(t *testing.T) { 109 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 110 expectedBal := big.NewInt(10000000000) 111 sim := NewSimulatedBackend( 112 core.GenesisAlloc{ 113 testAddr: {Balance: expectedBal}, 114 }, 10000000, 115 ) 116 defer sim.Close() 117 118 if sim.config != params.AllEthashProtocolChanges { 119 t.Errorf("expected sim config to equal params.AllEthashProtocolChanges, got %v", sim.config) 120 } 121 122 if sim.blockchain.Config() != params.AllEthashProtocolChanges { 123 t.Errorf("expected sim blockchain config to equal params.AllEthashProtocolChanges, got %v", sim.config) 124 } 125 126 statedb, _ := sim.blockchain.State() 127 bal := statedb.GetBalance(testAddr) 128 if bal.Cmp(expectedBal) != 0 { 129 t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) 130 } 131 } 132 133 func TestSimulatedBackend_AdjustTime(t *testing.T) { 134 sim := NewSimulatedBackend( 135 core.GenesisAlloc{}, 10000000, 136 ) 137 defer sim.Close() 138 139 prevTime := sim.pendingBlock.Time() 140 err := sim.AdjustTime(time.Second) 141 if err != nil { 142 t.Error(err) 143 } 144 newTime := sim.pendingBlock.Time() 145 146 if newTime-prevTime != uint64(time.Second.Seconds()) { 147 t.Errorf("adjusted time not equal to a second. prev: %v, new: %v", prevTime, newTime) 148 } 149 } 150 151 func TestSimulatedBackend_BalanceAt(t *testing.T) { 152 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 153 expectedBal := big.NewInt(10000000000) 154 sim := NewSimulatedBackend( 155 core.GenesisAlloc{ 156 testAddr: {Balance: expectedBal}, 157 }, 10000000, 158 ) 159 defer sim.Close() 160 bgCtx := context.Background() 161 162 bal, err := sim.BalanceAt(bgCtx, testAddr, nil) 163 if err != nil { 164 t.Error(err) 165 } 166 167 if bal.Cmp(expectedBal) != 0 { 168 t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) 169 } 170 } 171 172 func TestSimulatedBackend_BlockByHash(t *testing.T) { 173 sim := NewSimulatedBackend( 174 core.GenesisAlloc{}, 10000000, 175 ) 176 defer sim.Close() 177 bgCtx := context.Background() 178 179 block, err := sim.BlockByNumber(bgCtx, nil) 180 if err != nil { 181 t.Errorf("could not get recent block: %v", err) 182 } 183 blockByHash, err := sim.BlockByHash(bgCtx, block.Hash()) 184 if err != nil { 185 t.Errorf("could not get recent block: %v", err) 186 } 187 188 if block.Hash() != blockByHash.Hash() { 189 t.Errorf("did not get expected block") 190 } 191 } 192 193 func TestSimulatedBackend_BlockByNumber(t *testing.T) { 194 sim := NewSimulatedBackend( 195 core.GenesisAlloc{}, 10000000, 196 ) 197 defer sim.Close() 198 bgCtx := context.Background() 199 200 block, err := sim.BlockByNumber(bgCtx, nil) 201 if err != nil { 202 t.Errorf("could not get recent block: %v", err) 203 } 204 if block.NumberU64() != 0 { 205 t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64()) 206 } 207 208 // create one block 209 sim.Commit() 210 211 block, err = sim.BlockByNumber(bgCtx, nil) 212 if err != nil { 213 t.Errorf("could not get recent block: %v", err) 214 } 215 if block.NumberU64() != 1 { 216 t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64()) 217 } 218 219 blockByNumber, err := sim.BlockByNumber(bgCtx, big.NewInt(1)) 220 if err != nil { 221 t.Errorf("could not get block by number: %v", err) 222 } 223 if blockByNumber.Hash() != block.Hash() { 224 t.Errorf("did not get the same block with height of 1 as before") 225 } 226 } 227 228 func TestSimulatedBackend_NonceAt(t *testing.T) { 229 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 230 231 sim := NewSimulatedBackend( 232 core.GenesisAlloc{ 233 testAddr: {Balance: big.NewInt(10000000000)}, 234 }, 10000000, 235 ) 236 defer sim.Close() 237 bgCtx := context.Background() 238 239 nonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(0)) 240 if err != nil { 241 t.Errorf("could not get nonce for test addr: %v", err) 242 } 243 244 if nonce != uint64(0) { 245 t.Errorf("received incorrect nonce. expected 0, got %v", nonce) 246 } 247 248 // create a signed transaction to send 249 tx := types.NewTransaction(nonce, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 250 signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) 251 if err != nil { 252 t.Errorf("could not sign tx: %v", err) 253 } 254 255 // send tx to simulated backend 256 err = sim.SendTransaction(bgCtx, signedTx) 257 if err != nil { 258 t.Errorf("could not add tx to pending block: %v", err) 259 } 260 sim.Commit() 261 262 newNonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(1)) 263 if err != nil { 264 t.Errorf("could not get nonce for test addr: %v", err) 265 } 266 267 if newNonce != nonce+uint64(1) { 268 t.Errorf("received incorrect nonce. expected 1, got %v", nonce) 269 } 270 } 271 272 func TestSimulatedBackend_SendTransaction(t *testing.T) { 273 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 274 275 sim := NewSimulatedBackend( 276 core.GenesisAlloc{ 277 testAddr: {Balance: big.NewInt(10000000000)}, 278 }, 10000000, 279 ) 280 defer sim.Close() 281 bgCtx := context.Background() 282 283 // create a signed transaction to send 284 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 285 signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) 286 if err != nil { 287 t.Errorf("could not sign tx: %v", err) 288 } 289 290 // send tx to simulated backend 291 err = sim.SendTransaction(bgCtx, signedTx) 292 if err != nil { 293 t.Errorf("could not add tx to pending block: %v", err) 294 } 295 sim.Commit() 296 297 block, err := sim.BlockByNumber(bgCtx, big.NewInt(1)) 298 if err != nil { 299 t.Errorf("could not get block at height 1: %v", err) 300 } 301 302 if signedTx.Hash() != block.Transactions()[0].Hash() { 303 t.Errorf("did not commit sent transaction. expected hash %v got hash %v", block.Transactions()[0].Hash(), signedTx.Hash()) 304 } 305 } 306 307 func TestSimulatedBackend_TransactionByHash(t *testing.T) { 308 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 309 310 sim := NewSimulatedBackend( 311 core.GenesisAlloc{ 312 testAddr: {Balance: big.NewInt(10000000000)}, 313 }, 10000000, 314 ) 315 defer sim.Close() 316 bgCtx := context.Background() 317 318 // create a signed transaction to send 319 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 320 signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) 321 if err != nil { 322 t.Errorf("could not sign tx: %v", err) 323 } 324 325 // send tx to simulated backend 326 err = sim.SendTransaction(bgCtx, signedTx) 327 if err != nil { 328 t.Errorf("could not add tx to pending block: %v", err) 329 } 330 331 // ensure tx is committed pending 332 receivedTx, pending, err := sim.TransactionByHash(bgCtx, signedTx.Hash()) 333 if err != nil { 334 t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err) 335 } 336 if !pending { 337 t.Errorf("expected transaction to be in pending state") 338 } 339 if receivedTx.Hash() != signedTx.Hash() { 340 t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash()) 341 } 342 343 sim.Commit() 344 345 // ensure tx is not and committed pending 346 receivedTx, pending, err = sim.TransactionByHash(bgCtx, signedTx.Hash()) 347 if err != nil { 348 t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err) 349 } 350 if pending { 351 t.Errorf("expected transaction to not be in pending state") 352 } 353 if receivedTx.Hash() != signedTx.Hash() { 354 t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash()) 355 } 356 } 357 358 func TestSimulatedBackend_EstimateGas(t *testing.T) { 359 t.Skip("OVM breaks this because gas consumption is not yet standardized") 360 361 sim := NewSimulatedBackend( 362 core.GenesisAlloc{}, 10000000, 363 ) 364 defer sim.Close() 365 bgCtx := context.Background() 366 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 367 368 gas, err := sim.EstimateGas(bgCtx, ethereum.CallMsg{ 369 From: testAddr, 370 To: &testAddr, 371 Value: big.NewInt(1000), 372 Data: []byte{}, 373 }) 374 if err != nil { 375 t.Errorf("could not estimate gas: %v", err) 376 } 377 378 if gas != params.TxGas { 379 t.Errorf("expected 21000 gas cost for a transaction got %v", gas) 380 } 381 } 382 383 func TestSimulatedBackend_HeaderByHash(t *testing.T) { 384 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 385 386 sim := NewSimulatedBackend( 387 core.GenesisAlloc{ 388 testAddr: {Balance: big.NewInt(10000000000)}, 389 }, 10000000, 390 ) 391 defer sim.Close() 392 bgCtx := context.Background() 393 394 header, err := sim.HeaderByNumber(bgCtx, nil) 395 if err != nil { 396 t.Errorf("could not get recent block: %v", err) 397 } 398 headerByHash, err := sim.HeaderByHash(bgCtx, header.Hash()) 399 if err != nil { 400 t.Errorf("could not get recent block: %v", err) 401 } 402 403 if header.Hash() != headerByHash.Hash() { 404 t.Errorf("did not get expected block") 405 } 406 } 407 408 func TestSimulatedBackend_HeaderByNumber(t *testing.T) { 409 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 410 411 sim := NewSimulatedBackend( 412 core.GenesisAlloc{ 413 testAddr: {Balance: big.NewInt(10000000000)}, 414 }, 10000000, 415 ) 416 defer sim.Close() 417 bgCtx := context.Background() 418 419 latestBlockHeader, err := sim.HeaderByNumber(bgCtx, nil) 420 if err != nil { 421 t.Errorf("could not get header for tip of chain: %v", err) 422 } 423 if latestBlockHeader == nil { 424 t.Errorf("received a nil block header") 425 } 426 if latestBlockHeader.Number.Uint64() != uint64(0) { 427 t.Errorf("expected block header number 0, instead got %v", latestBlockHeader.Number.Uint64()) 428 } 429 430 sim.Commit() 431 432 latestBlockHeader, err = sim.HeaderByNumber(bgCtx, nil) 433 if err != nil { 434 t.Errorf("could not get header for blockheight of 1: %v", err) 435 } 436 437 blockHeader, err := sim.HeaderByNumber(bgCtx, big.NewInt(1)) 438 if err != nil { 439 t.Errorf("could not get header for blockheight of 1: %v", err) 440 } 441 442 if blockHeader.Hash() != latestBlockHeader.Hash() { 443 t.Errorf("block header and latest block header are not the same") 444 } 445 if blockHeader.Number.Int64() != int64(1) { 446 t.Errorf("did not get blockheader for block 1. instead got block %v", blockHeader.Number.Int64()) 447 } 448 449 block, err := sim.BlockByNumber(bgCtx, big.NewInt(1)) 450 if err != nil { 451 t.Errorf("could not get block for blockheight of 1: %v", err) 452 } 453 454 if block.Hash() != blockHeader.Hash() { 455 t.Errorf("block hash and block header hash do not match. expected %v, got %v", block.Hash(), blockHeader.Hash()) 456 } 457 } 458 459 func TestSimulatedBackend_TransactionCount(t *testing.T) { 460 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 461 462 sim := NewSimulatedBackend( 463 core.GenesisAlloc{ 464 testAddr: {Balance: big.NewInt(10000000000)}, 465 }, 10000000, 466 ) 467 defer sim.Close() 468 bgCtx := context.Background() 469 currentBlock, err := sim.BlockByNumber(bgCtx, nil) 470 if err != nil || currentBlock == nil { 471 t.Error("could not get current block") 472 } 473 474 count, err := sim.TransactionCount(bgCtx, currentBlock.Hash()) 475 if err != nil { 476 t.Error("could not get current block's transaction count") 477 } 478 479 if count != 0 { 480 t.Errorf("expected transaction count of %v does not match actual count of %v", 0, count) 481 } 482 483 // create a signed transaction to send 484 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 485 signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) 486 if err != nil { 487 t.Errorf("could not sign tx: %v", err) 488 } 489 490 // send tx to simulated backend 491 err = sim.SendTransaction(bgCtx, signedTx) 492 if err != nil { 493 t.Errorf("could not add tx to pending block: %v", err) 494 } 495 496 sim.Commit() 497 498 lastBlock, err := sim.BlockByNumber(bgCtx, nil) 499 if err != nil { 500 t.Errorf("could not get header for tip of chain: %v", err) 501 } 502 503 count, err = sim.TransactionCount(bgCtx, lastBlock.Hash()) 504 if err != nil { 505 t.Error("could not get current block's transaction count") 506 } 507 508 if count != 1 { 509 t.Errorf("expected transaction count of %v does not match actual count of %v", 1, count) 510 } 511 } 512 513 func TestSimulatedBackend_TransactionInBlock(t *testing.T) { 514 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 515 516 sim := NewSimulatedBackend( 517 core.GenesisAlloc{ 518 testAddr: {Balance: big.NewInt(10000000000)}, 519 }, 10000000, 520 ) 521 defer sim.Close() 522 bgCtx := context.Background() 523 524 transaction, err := sim.TransactionInBlock(bgCtx, sim.pendingBlock.Hash(), uint(0)) 525 if err == nil && err != errTransactionDoesNotExist { 526 t.Errorf("expected a transaction does not exist error to be received but received %v", err) 527 } 528 if transaction != nil { 529 t.Errorf("expected transaction to be nil but received %v", transaction) 530 } 531 532 // expect pending nonce to be 0 since account has not been used 533 pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr) 534 if err != nil { 535 t.Errorf("did not get the pending nonce: %v", err) 536 } 537 538 if pendingNonce != uint64(0) { 539 t.Errorf("expected pending nonce of 0 got %v", pendingNonce) 540 } 541 542 // create a signed transaction to send 543 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 544 signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) 545 if err != nil { 546 t.Errorf("could not sign tx: %v", err) 547 } 548 549 // send tx to simulated backend 550 err = sim.SendTransaction(bgCtx, signedTx) 551 if err != nil { 552 t.Errorf("could not add tx to pending block: %v", err) 553 } 554 555 sim.Commit() 556 557 lastBlock, err := sim.BlockByNumber(bgCtx, nil) 558 if err != nil { 559 t.Errorf("could not get header for tip of chain: %v", err) 560 } 561 562 transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(1)) 563 if err == nil && err != errTransactionDoesNotExist { 564 t.Errorf("expected a transaction does not exist error to be received but received %v", err) 565 } 566 if transaction != nil { 567 t.Errorf("expected transaction to be nil but received %v", transaction) 568 } 569 570 transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(0)) 571 if err != nil { 572 t.Errorf("could not get transaction in the lastest block with hash %v: %v", lastBlock.Hash().String(), err) 573 } 574 575 if signedTx.Hash().String() != transaction.Hash().String() { 576 t.Errorf("received transaction that did not match the sent transaction. expected hash %v, got hash %v", signedTx.Hash().String(), transaction.Hash().String()) 577 } 578 } 579 580 func TestSimulatedBackend_PendingNonceAt(t *testing.T) { 581 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 582 583 sim := NewSimulatedBackend( 584 core.GenesisAlloc{ 585 testAddr: {Balance: big.NewInt(10000000000)}, 586 }, 10000000, 587 ) 588 defer sim.Close() 589 bgCtx := context.Background() 590 591 // expect pending nonce to be 0 since account has not been used 592 pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr) 593 if err != nil { 594 t.Errorf("did not get the pending nonce: %v", err) 595 } 596 597 if pendingNonce != uint64(0) { 598 t.Errorf("expected pending nonce of 0 got %v", pendingNonce) 599 } 600 601 // create a signed transaction to send 602 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 603 signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) 604 if err != nil { 605 t.Errorf("could not sign tx: %v", err) 606 } 607 608 // send tx to simulated backend 609 err = sim.SendTransaction(bgCtx, signedTx) 610 if err != nil { 611 t.Errorf("could not add tx to pending block: %v", err) 612 } 613 614 // expect pending nonce to be 1 since account has submitted one transaction 615 pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr) 616 if err != nil { 617 t.Errorf("did not get the pending nonce: %v", err) 618 } 619 620 if pendingNonce != uint64(1) { 621 t.Errorf("expected pending nonce of 1 got %v", pendingNonce) 622 } 623 624 // make a new transaction with a nonce of 1 625 tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 626 signedTx, err = types.SignTx(tx, types.HomesteadSigner{}, testKey) 627 if err != nil { 628 t.Errorf("could not sign tx: %v", err) 629 } 630 err = sim.SendTransaction(bgCtx, signedTx) 631 if err != nil { 632 t.Errorf("could not send tx: %v", err) 633 } 634 635 // expect pending nonce to be 2 since account now has two transactions 636 pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr) 637 if err != nil { 638 t.Errorf("did not get the pending nonce: %v", err) 639 } 640 641 if pendingNonce != uint64(2) { 642 t.Errorf("expected pending nonce of 2 got %v", pendingNonce) 643 } 644 } 645 646 func TestSimulatedBackend_TransactionReceipt(t *testing.T) { 647 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 648 649 sim := NewSimulatedBackend( 650 core.GenesisAlloc{ 651 testAddr: {Balance: big.NewInt(10000000000)}, 652 }, 10000000, 653 ) 654 defer sim.Close() 655 bgCtx := context.Background() 656 657 // create a signed transaction to send 658 tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) 659 signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) 660 if err != nil { 661 t.Errorf("could not sign tx: %v", err) 662 } 663 664 // send tx to simulated backend 665 err = sim.SendTransaction(bgCtx, signedTx) 666 if err != nil { 667 t.Errorf("could not add tx to pending block: %v", err) 668 } 669 sim.Commit() 670 671 receipt, err := sim.TransactionReceipt(bgCtx, signedTx.Hash()) 672 if err != nil { 673 t.Errorf("could not get transaction receipt: %v", err) 674 } 675 676 if receipt.ContractAddress != testAddr && receipt.TxHash != signedTx.Hash() { 677 t.Errorf("received receipt is not correct: %v", receipt) 678 } 679 } 680 681 func TestSimulatedBackend_SuggestGasPrice(t *testing.T) { 682 sim := NewSimulatedBackend( 683 core.GenesisAlloc{}, 684 10000000, 685 ) 686 defer sim.Close() 687 bgCtx := context.Background() 688 gasPrice, err := sim.SuggestGasPrice(bgCtx) 689 if err != nil { 690 t.Errorf("could not get gas price: %v", err) 691 } 692 if gasPrice.Uint64() != uint64(1) { 693 t.Errorf("gas price was not expected value of 1. actual: %v", gasPrice.Uint64()) 694 } 695 } 696 697 func TestSimulatedBackend_PendingCodeAt(t *testing.T) { 698 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 699 sim := NewSimulatedBackend( 700 core.GenesisAlloc{ 701 testAddr: {Balance: big.NewInt(10000000000)}, 702 }, 703 10000000, 704 ) 705 defer sim.Close() 706 bgCtx := context.Background() 707 code, err := sim.CodeAt(bgCtx, testAddr, nil) 708 if err != nil { 709 t.Errorf("could not get code at test addr: %v", err) 710 } 711 if len(code) != 0 { 712 t.Errorf("got code for account that does not have contract code") 713 } 714 715 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 716 if err != nil { 717 t.Errorf("could not get code at test addr: %v", err) 718 } 719 auth := bind.NewKeyedTransactor(testKey) 720 contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) 721 if err != nil { 722 t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) 723 } 724 725 code, err = sim.PendingCodeAt(bgCtx, contractAddr) 726 if err != nil { 727 t.Errorf("could not get code at test addr: %v", err) 728 } 729 if len(code) == 0 { 730 t.Errorf("did not get code for account that has contract code") 731 } 732 // ensure code received equals code deployed 733 if !bytes.Equal(code, common.FromHex(deployedCode)) { 734 t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code) 735 } 736 } 737 738 func TestSimulatedBackend_CodeAt(t *testing.T) { 739 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 740 sim := NewSimulatedBackend( 741 core.GenesisAlloc{ 742 testAddr: {Balance: big.NewInt(10000000000)}, 743 }, 744 10000000, 745 ) 746 defer sim.Close() 747 bgCtx := context.Background() 748 code, err := sim.CodeAt(bgCtx, testAddr, nil) 749 if err != nil { 750 t.Errorf("could not get code at test addr: %v", err) 751 } 752 if len(code) != 0 { 753 t.Errorf("got code for account that does not have contract code") 754 } 755 756 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 757 if err != nil { 758 t.Errorf("could not get code at test addr: %v", err) 759 } 760 auth := bind.NewKeyedTransactor(testKey) 761 contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) 762 if err != nil { 763 t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) 764 } 765 766 sim.Commit() 767 code, err = sim.CodeAt(bgCtx, contractAddr, nil) 768 if err != nil { 769 t.Errorf("could not get code at test addr: %v", err) 770 } 771 if len(code) == 0 { 772 t.Errorf("did not get code for account that has contract code") 773 } 774 // ensure code received equals code deployed 775 if !bytes.Equal(code, common.FromHex(deployedCode)) { 776 t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code) 777 } 778 } 779 780 // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt: 781 // receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} 782 func TestSimulatedBackend_PendingAndCallContract(t *testing.T) { 783 testAddr := crypto.PubkeyToAddress(testKey.PublicKey) 784 sim := NewSimulatedBackend( 785 core.GenesisAlloc{ 786 testAddr: {Balance: big.NewInt(10000000000)}, 787 }, 788 10000000, 789 ) 790 defer sim.Close() 791 bgCtx := context.Background() 792 793 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 794 if err != nil { 795 t.Errorf("could not get code at test addr: %v", err) 796 } 797 contractAuth := bind.NewKeyedTransactor(testKey) 798 addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(abiBin), sim) 799 if err != nil { 800 t.Errorf("could not deploy contract: %v", err) 801 } 802 803 input, err := parsed.Pack("receive", []byte("X")) 804 if err != nil { 805 t.Errorf("could pack receive function on contract: %v", err) 806 } 807 808 // make sure you can call the contract in pending state 809 res, err := sim.PendingCallContract(bgCtx, ethereum.CallMsg{ 810 From: testAddr, 811 To: &addr, 812 Data: input, 813 }) 814 if err != nil { 815 t.Errorf("could not call receive method on contract: %v", err) 816 } 817 if len(res) == 0 { 818 t.Errorf("result of contract call was empty: %v", res) 819 } 820 821 // while comparing against the byte array is more exact, also compare against the human readable string for readability 822 if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") { 823 t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) 824 } 825 826 sim.Commit() 827 828 // make sure you can call the contract 829 res, err = sim.CallContract(bgCtx, ethereum.CallMsg{ 830 From: testAddr, 831 To: &addr, 832 Data: input, 833 }, nil) 834 if err != nil { 835 t.Errorf("could not call receive method on contract: %v", err) 836 } 837 if len(res) == 0 { 838 t.Errorf("result of contract call was empty: %v", res) 839 } 840 841 if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") { 842 t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) 843 } 844 }