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