simulated_test.go 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997
  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_EstimateGasWithPrice(t *testing.T) {
  405. key, _ := crypto.GenerateKey()
  406. addr := crypto.PubkeyToAddress(key.PublicKey)
  407. sim := NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether*2 + 2e17)}}, 10000000)
  408. defer sim.Close()
  409. receipant := common.HexToAddress("deadbeef")
  410. var cases = []struct {
  411. name string
  412. message ethereum.CallMsg
  413. expect uint64
  414. expectError error
  415. }{
  416. {"EstimateWithoutPrice", ethereum.CallMsg{
  417. From: addr,
  418. To: &receipant,
  419. Gas: 0,
  420. GasPrice: big.NewInt(0),
  421. Value: big.NewInt(1000),
  422. Data: nil,
  423. }, 21000, nil},
  424. {"EstimateWithPrice", ethereum.CallMsg{
  425. From: addr,
  426. To: &receipant,
  427. Gas: 0,
  428. GasPrice: big.NewInt(1000),
  429. Value: big.NewInt(1000),
  430. Data: nil,
  431. }, 21000, nil},
  432. {"EstimateWithVeryHighPrice", ethereum.CallMsg{
  433. From: addr,
  434. To: &receipant,
  435. Gas: 0,
  436. GasPrice: big.NewInt(1e14), // gascost = 2.1ether
  437. Value: big.NewInt(1e17), // the remaining balance for fee is 2.1ether
  438. Data: nil,
  439. }, 21000, nil},
  440. {"EstimateWithSuperhighPrice", ethereum.CallMsg{
  441. From: addr,
  442. To: &receipant,
  443. Gas: 0,
  444. GasPrice: big.NewInt(2e14), // gascost = 4.2ether
  445. Value: big.NewInt(1000),
  446. Data: nil,
  447. }, 21000, errors.New("gas required exceeds allowance (10999)")}, // 10999=(2.2ether-1000wei)/(2e14)
  448. }
  449. for _, c := range cases {
  450. got, err := sim.EstimateGas(context.Background(), c.message)
  451. if c.expectError != nil {
  452. if err == nil {
  453. t.Fatalf("Expect error, got nil")
  454. }
  455. if c.expectError.Error() != err.Error() {
  456. t.Fatalf("Expect error, want %v, got %v", c.expectError, err)
  457. }
  458. continue
  459. }
  460. if got != c.expect {
  461. t.Fatalf("Gas estimation mismatch, want %d, got %d", c.expect, got)
  462. }
  463. }
  464. }
  465. func TestSimulatedBackend_HeaderByHash(t *testing.T) {
  466. testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
  467. sim := NewSimulatedBackend(
  468. core.GenesisAlloc{
  469. testAddr: {Balance: big.NewInt(10000000000)},
  470. }, 10000000,
  471. )
  472. defer sim.Close()
  473. bgCtx := context.Background()
  474. header, err := sim.HeaderByNumber(bgCtx, nil)
  475. if err != nil {
  476. t.Errorf("could not get recent block: %v", err)
  477. }
  478. headerByHash, err := sim.HeaderByHash(bgCtx, header.Hash())
  479. if err != nil {
  480. t.Errorf("could not get recent block: %v", err)
  481. }
  482. if header.Hash() != headerByHash.Hash() {
  483. t.Errorf("did not get expected block")
  484. }
  485. }
  486. func TestSimulatedBackend_HeaderByNumber(t *testing.T) {
  487. testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
  488. sim := NewSimulatedBackend(
  489. core.GenesisAlloc{
  490. testAddr: {Balance: big.NewInt(10000000000)},
  491. }, 10000000,
  492. )
  493. defer sim.Close()
  494. bgCtx := context.Background()
  495. latestBlockHeader, err := sim.HeaderByNumber(bgCtx, nil)
  496. if err != nil {
  497. t.Errorf("could not get header for tip of chain: %v", err)
  498. }
  499. if latestBlockHeader == nil {
  500. t.Errorf("received a nil block header")
  501. }
  502. if latestBlockHeader.Number.Uint64() != uint64(0) {
  503. t.Errorf("expected block header number 0, instead got %v", latestBlockHeader.Number.Uint64())
  504. }
  505. sim.Commit()
  506. latestBlockHeader, err = sim.HeaderByNumber(bgCtx, nil)
  507. if err != nil {
  508. t.Errorf("could not get header for blockheight of 1: %v", err)
  509. }
  510. blockHeader, err := sim.HeaderByNumber(bgCtx, big.NewInt(1))
  511. if err != nil {
  512. t.Errorf("could not get header for blockheight of 1: %v", err)
  513. }
  514. if blockHeader.Hash() != latestBlockHeader.Hash() {
  515. t.Errorf("block header and latest block header are not the same")
  516. }
  517. if blockHeader.Number.Int64() != int64(1) {
  518. t.Errorf("did not get blockheader for block 1. instead got block %v", blockHeader.Number.Int64())
  519. }
  520. block, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
  521. if err != nil {
  522. t.Errorf("could not get block for blockheight of 1: %v", err)
  523. }
  524. if block.Hash() != blockHeader.Hash() {
  525. t.Errorf("block hash and block header hash do not match. expected %v, got %v", block.Hash(), blockHeader.Hash())
  526. }
  527. }
  528. func TestSimulatedBackend_TransactionCount(t *testing.T) {
  529. testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
  530. sim := NewSimulatedBackend(
  531. core.GenesisAlloc{
  532. testAddr: {Balance: big.NewInt(10000000000)},
  533. }, 10000000,
  534. )
  535. defer sim.Close()
  536. bgCtx := context.Background()
  537. currentBlock, err := sim.BlockByNumber(bgCtx, nil)
  538. if err != nil || currentBlock == nil {
  539. t.Error("could not get current block")
  540. }
  541. count, err := sim.TransactionCount(bgCtx, currentBlock.Hash())
  542. if err != nil {
  543. t.Error("could not get current block's transaction count")
  544. }
  545. if count != 0 {
  546. t.Errorf("expected transaction count of %v does not match actual count of %v", 0, count)
  547. }
  548. // create a signed transaction to send
  549. tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
  550. signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
  551. if err != nil {
  552. t.Errorf("could not sign tx: %v", err)
  553. }
  554. // send tx to simulated backend
  555. err = sim.SendTransaction(bgCtx, signedTx)
  556. if err != nil {
  557. t.Errorf("could not add tx to pending block: %v", err)
  558. }
  559. sim.Commit()
  560. lastBlock, err := sim.BlockByNumber(bgCtx, nil)
  561. if err != nil {
  562. t.Errorf("could not get header for tip of chain: %v", err)
  563. }
  564. count, err = sim.TransactionCount(bgCtx, lastBlock.Hash())
  565. if err != nil {
  566. t.Error("could not get current block's transaction count")
  567. }
  568. if count != 1 {
  569. t.Errorf("expected transaction count of %v does not match actual count of %v", 1, count)
  570. }
  571. }
  572. func TestSimulatedBackend_TransactionInBlock(t *testing.T) {
  573. testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
  574. sim := NewSimulatedBackend(
  575. core.GenesisAlloc{
  576. testAddr: {Balance: big.NewInt(10000000000)},
  577. }, 10000000,
  578. )
  579. defer sim.Close()
  580. bgCtx := context.Background()
  581. transaction, err := sim.TransactionInBlock(bgCtx, sim.pendingBlock.Hash(), uint(0))
  582. if err == nil && err != errTransactionDoesNotExist {
  583. t.Errorf("expected a transaction does not exist error to be received but received %v", err)
  584. }
  585. if transaction != nil {
  586. t.Errorf("expected transaction to be nil but received %v", transaction)
  587. }
  588. // expect pending nonce to be 0 since account has not been used
  589. pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr)
  590. if err != nil {
  591. t.Errorf("did not get the pending nonce: %v", err)
  592. }
  593. if pendingNonce != uint64(0) {
  594. t.Errorf("expected pending nonce of 0 got %v", pendingNonce)
  595. }
  596. // create a signed transaction to send
  597. tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
  598. signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
  599. if err != nil {
  600. t.Errorf("could not sign tx: %v", err)
  601. }
  602. // send tx to simulated backend
  603. err = sim.SendTransaction(bgCtx, signedTx)
  604. if err != nil {
  605. t.Errorf("could not add tx to pending block: %v", err)
  606. }
  607. sim.Commit()
  608. lastBlock, err := sim.BlockByNumber(bgCtx, nil)
  609. if err != nil {
  610. t.Errorf("could not get header for tip of chain: %v", err)
  611. }
  612. transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(1))
  613. if err == nil && err != errTransactionDoesNotExist {
  614. t.Errorf("expected a transaction does not exist error to be received but received %v", err)
  615. }
  616. if transaction != nil {
  617. t.Errorf("expected transaction to be nil but received %v", transaction)
  618. }
  619. transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(0))
  620. if err != nil {
  621. t.Errorf("could not get transaction in the lastest block with hash %v: %v", lastBlock.Hash().String(), err)
  622. }
  623. if signedTx.Hash().String() != transaction.Hash().String() {
  624. t.Errorf("received transaction that did not match the sent transaction. expected hash %v, got hash %v", signedTx.Hash().String(), transaction.Hash().String())
  625. }
  626. }
  627. func TestSimulatedBackend_PendingNonceAt(t *testing.T) {
  628. testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
  629. sim := NewSimulatedBackend(
  630. core.GenesisAlloc{
  631. testAddr: {Balance: big.NewInt(10000000000)},
  632. }, 10000000,
  633. )
  634. defer sim.Close()
  635. bgCtx := context.Background()
  636. // expect pending nonce to be 0 since account has not been used
  637. pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr)
  638. if err != nil {
  639. t.Errorf("did not get the pending nonce: %v", err)
  640. }
  641. if pendingNonce != uint64(0) {
  642. t.Errorf("expected pending nonce of 0 got %v", pendingNonce)
  643. }
  644. // create a signed transaction to send
  645. tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
  646. signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
  647. if err != nil {
  648. t.Errorf("could not sign tx: %v", err)
  649. }
  650. // send tx to simulated backend
  651. err = sim.SendTransaction(bgCtx, signedTx)
  652. if err != nil {
  653. t.Errorf("could not add tx to pending block: %v", err)
  654. }
  655. // expect pending nonce to be 1 since account has submitted one transaction
  656. pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr)
  657. if err != nil {
  658. t.Errorf("did not get the pending nonce: %v", err)
  659. }
  660. if pendingNonce != uint64(1) {
  661. t.Errorf("expected pending nonce of 1 got %v", pendingNonce)
  662. }
  663. // make a new transaction with a nonce of 1
  664. tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
  665. signedTx, err = types.SignTx(tx, types.HomesteadSigner{}, testKey)
  666. if err != nil {
  667. t.Errorf("could not sign tx: %v", err)
  668. }
  669. err = sim.SendTransaction(bgCtx, signedTx)
  670. if err != nil {
  671. t.Errorf("could not send tx: %v", err)
  672. }
  673. // expect pending nonce to be 2 since account now has two transactions
  674. pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr)
  675. if err != nil {
  676. t.Errorf("did not get the pending nonce: %v", err)
  677. }
  678. if pendingNonce != uint64(2) {
  679. t.Errorf("expected pending nonce of 2 got %v", pendingNonce)
  680. }
  681. }
  682. func TestSimulatedBackend_TransactionReceipt(t *testing.T) {
  683. testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
  684. sim := NewSimulatedBackend(
  685. core.GenesisAlloc{
  686. testAddr: {Balance: big.NewInt(10000000000)},
  687. }, 10000000,
  688. )
  689. defer sim.Close()
  690. bgCtx := context.Background()
  691. // create a signed transaction to send
  692. tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
  693. signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey)
  694. if err != nil {
  695. t.Errorf("could not sign tx: %v", err)
  696. }
  697. // send tx to simulated backend
  698. err = sim.SendTransaction(bgCtx, signedTx)
  699. if err != nil {
  700. t.Errorf("could not add tx to pending block: %v", err)
  701. }
  702. sim.Commit()
  703. receipt, err := sim.TransactionReceipt(bgCtx, signedTx.Hash())
  704. if err != nil {
  705. t.Errorf("could not get transaction receipt: %v", err)
  706. }
  707. if receipt.ContractAddress != testAddr && receipt.TxHash != signedTx.Hash() {
  708. t.Errorf("received receipt is not correct: %v", receipt)
  709. }
  710. }
  711. func TestSimulatedBackend_SuggestGasPrice(t *testing.T) {
  712. sim := NewSimulatedBackend(
  713. core.GenesisAlloc{},
  714. 10000000,
  715. )
  716. defer sim.Close()
  717. bgCtx := context.Background()
  718. gasPrice, err := sim.SuggestGasPrice(bgCtx)
  719. if err != nil {
  720. t.Errorf("could not get gas price: %v", err)
  721. }
  722. if gasPrice.Uint64() != uint64(1) {
  723. t.Errorf("gas price was not expected value of 1. actual: %v", gasPrice.Uint64())
  724. }
  725. }
  726. func TestSimulatedBackend_PendingCodeAt(t *testing.T) {
  727. testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
  728. sim := NewSimulatedBackend(
  729. core.GenesisAlloc{
  730. testAddr: {Balance: big.NewInt(10000000000)},
  731. },
  732. 10000000,
  733. )
  734. defer sim.Close()
  735. bgCtx := context.Background()
  736. code, err := sim.CodeAt(bgCtx, testAddr, nil)
  737. if err != nil {
  738. t.Errorf("could not get code at test addr: %v", err)
  739. }
  740. if len(code) != 0 {
  741. t.Errorf("got code for account that does not have contract code")
  742. }
  743. parsed, err := abi.JSON(strings.NewReader(abiJSON))
  744. if err != nil {
  745. t.Errorf("could not get code at test addr: %v", err)
  746. }
  747. auth := bind.NewKeyedTransactor(testKey)
  748. contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
  749. if err != nil {
  750. t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
  751. }
  752. code, err = sim.PendingCodeAt(bgCtx, contractAddr)
  753. if err != nil {
  754. t.Errorf("could not get code at test addr: %v", err)
  755. }
  756. if len(code) == 0 {
  757. t.Errorf("did not get code for account that has contract code")
  758. }
  759. // ensure code received equals code deployed
  760. if !bytes.Equal(code, common.FromHex(deployedCode)) {
  761. t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code)
  762. }
  763. }
  764. func TestSimulatedBackend_CodeAt(t *testing.T) {
  765. testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
  766. sim := NewSimulatedBackend(
  767. core.GenesisAlloc{
  768. testAddr: {Balance: big.NewInt(10000000000)},
  769. },
  770. 10000000,
  771. )
  772. defer sim.Close()
  773. bgCtx := context.Background()
  774. code, err := sim.CodeAt(bgCtx, testAddr, nil)
  775. if err != nil {
  776. t.Errorf("could not get code at test addr: %v", err)
  777. }
  778. if len(code) != 0 {
  779. t.Errorf("got code for account that does not have contract code")
  780. }
  781. parsed, err := abi.JSON(strings.NewReader(abiJSON))
  782. if err != nil {
  783. t.Errorf("could not get code at test addr: %v", err)
  784. }
  785. auth := bind.NewKeyedTransactor(testKey)
  786. contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
  787. if err != nil {
  788. t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
  789. }
  790. sim.Commit()
  791. code, err = sim.CodeAt(bgCtx, contractAddr, nil)
  792. if err != nil {
  793. t.Errorf("could not get code at test addr: %v", err)
  794. }
  795. if len(code) == 0 {
  796. t.Errorf("did not get code for account that has contract code")
  797. }
  798. // ensure code received equals code deployed
  799. if !bytes.Equal(code, common.FromHex(deployedCode)) {
  800. t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code)
  801. }
  802. }
  803. // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt:
  804. // receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]}
  805. func TestSimulatedBackend_PendingAndCallContract(t *testing.T) {
  806. testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
  807. sim := NewSimulatedBackend(
  808. core.GenesisAlloc{
  809. testAddr: {Balance: big.NewInt(10000000000)},
  810. },
  811. 10000000,
  812. )
  813. defer sim.Close()
  814. bgCtx := context.Background()
  815. parsed, err := abi.JSON(strings.NewReader(abiJSON))
  816. if err != nil {
  817. t.Errorf("could not get code at test addr: %v", err)
  818. }
  819. contractAuth := bind.NewKeyedTransactor(testKey)
  820. addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(abiBin), sim)
  821. if err != nil {
  822. t.Errorf("could not deploy contract: %v", err)
  823. }
  824. input, err := parsed.Pack("receive", []byte("X"))
  825. if err != nil {
  826. t.Errorf("could pack receive function on contract: %v", err)
  827. }
  828. // make sure you can call the contract in pending state
  829. res, err := sim.PendingCallContract(bgCtx, ethereum.CallMsg{
  830. From: testAddr,
  831. To: &addr,
  832. Data: input,
  833. })
  834. if err != nil {
  835. t.Errorf("could not call receive method on contract: %v", err)
  836. }
  837. if len(res) == 0 {
  838. t.Errorf("result of contract call was empty: %v", res)
  839. }
  840. // while comparing against the byte array is more exact, also compare against the human readable string for readability
  841. if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") {
  842. t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res))
  843. }
  844. sim.Commit()
  845. // make sure you can call the contract
  846. res, err = sim.CallContract(bgCtx, ethereum.CallMsg{
  847. From: testAddr,
  848. To: &addr,
  849. Data: input,
  850. }, nil)
  851. if err != nil {
  852. t.Errorf("could not call receive method on contract: %v", err)
  853. }
  854. if len(res) == 0 {
  855. t.Errorf("result of contract call was empty: %v", res)
  856. }
  857. if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") {
  858. t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res))
  859. }
  860. }