simulated_test.go 41 KB

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