simulated_test.go 33 KB

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