api_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. // Copyright 2021 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 tracers
  17. import (
  18. "bytes"
  19. "context"
  20. "crypto/ecdsa"
  21. "encoding/json"
  22. "errors"
  23. "fmt"
  24. "math/big"
  25. "reflect"
  26. "sort"
  27. "testing"
  28. "time"
  29. "github.com/ethereum/go-ethereum/common"
  30. "github.com/ethereum/go-ethereum/common/hexutil"
  31. "github.com/ethereum/go-ethereum/consensus"
  32. "github.com/ethereum/go-ethereum/consensus/ethash"
  33. "github.com/ethereum/go-ethereum/core"
  34. "github.com/ethereum/go-ethereum/core/rawdb"
  35. "github.com/ethereum/go-ethereum/core/state"
  36. "github.com/ethereum/go-ethereum/core/types"
  37. "github.com/ethereum/go-ethereum/core/vm"
  38. "github.com/ethereum/go-ethereum/crypto"
  39. "github.com/ethereum/go-ethereum/ethdb"
  40. "github.com/ethereum/go-ethereum/internal/ethapi"
  41. "github.com/ethereum/go-ethereum/params"
  42. "github.com/ethereum/go-ethereum/rpc"
  43. )
  44. var (
  45. errStateNotFound = errors.New("state not found")
  46. errBlockNotFound = errors.New("block not found")
  47. errTransactionNotFound = errors.New("transaction not found")
  48. )
  49. type testBackend struct {
  50. chainConfig *params.ChainConfig
  51. engine consensus.Engine
  52. chaindb ethdb.Database
  53. chain *core.BlockChain
  54. }
  55. func newTestBackend(t *testing.T, n int, gspec *core.Genesis, generator func(i int, b *core.BlockGen)) *testBackend {
  56. backend := &testBackend{
  57. chainConfig: params.TestChainConfig,
  58. engine: ethash.NewFaker(),
  59. chaindb: rawdb.NewMemoryDatabase(),
  60. }
  61. // Generate blocks for testing
  62. gspec.Config = backend.chainConfig
  63. var (
  64. gendb = rawdb.NewMemoryDatabase()
  65. genesis = gspec.MustCommit(gendb)
  66. )
  67. blocks, _ := core.GenerateChain(backend.chainConfig, genesis, backend.engine, gendb, n, generator)
  68. // Import the canonical chain
  69. gspec.MustCommit(backend.chaindb)
  70. cacheConfig := &core.CacheConfig{
  71. TrieCleanLimit: 256,
  72. TrieDirtyLimit: 256,
  73. TrieTimeLimit: 5 * time.Minute,
  74. SnapshotLimit: 0,
  75. TriesInMemory: 128,
  76. TrieDirtyDisabled: true, // Archive mode
  77. }
  78. chain, err := core.NewBlockChain(backend.chaindb, cacheConfig, backend.chainConfig, backend.engine, vm.Config{}, nil, nil)
  79. if err != nil {
  80. t.Fatalf("failed to create tester chain: %v", err)
  81. }
  82. if n, err := chain.InsertChain(blocks); err != nil {
  83. t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  84. }
  85. backend.chain = chain
  86. return backend
  87. }
  88. func (b *testBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
  89. return b.chain.GetHeaderByHash(hash), nil
  90. }
  91. func (b *testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
  92. if number == rpc.PendingBlockNumber || number == rpc.LatestBlockNumber {
  93. return b.chain.CurrentHeader(), nil
  94. }
  95. return b.chain.GetHeaderByNumber(uint64(number)), nil
  96. }
  97. func (b *testBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
  98. return b.chain.GetBlockByHash(hash), nil
  99. }
  100. func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
  101. if number == rpc.PendingBlockNumber || number == rpc.LatestBlockNumber {
  102. return b.chain.CurrentBlock(), nil
  103. }
  104. return b.chain.GetBlockByNumber(uint64(number)), nil
  105. }
  106. func (b *testBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
  107. tx, hash, blockNumber, index := rawdb.ReadTransaction(b.chaindb, txHash)
  108. if tx == nil {
  109. return nil, common.Hash{}, 0, 0, errTransactionNotFound
  110. }
  111. return tx, hash, blockNumber, index, nil
  112. }
  113. func (b *testBackend) RPCGasCap() uint64 {
  114. return 25000000
  115. }
  116. func (b *testBackend) ChainConfig() *params.ChainConfig {
  117. return b.chainConfig
  118. }
  119. func (b *testBackend) Engine() consensus.Engine {
  120. return b.engine
  121. }
  122. func (b *testBackend) ChainDb() ethdb.Database {
  123. return b.chaindb
  124. }
  125. func (b *testBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, checkLive bool) (*state.StateDB, error) {
  126. statedb, err := b.chain.StateAt(block.Root())
  127. if err != nil {
  128. return nil, errStateNotFound
  129. }
  130. return statedb, nil
  131. }
  132. func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, error) {
  133. parent := b.chain.GetBlock(block.ParentHash(), block.NumberU64()-1)
  134. if parent == nil {
  135. return nil, vm.BlockContext{}, nil, errBlockNotFound
  136. }
  137. statedb, err := b.chain.StateAt(parent.Root())
  138. if err != nil {
  139. return nil, vm.BlockContext{}, nil, errStateNotFound
  140. }
  141. if txIndex == 0 && len(block.Transactions()) == 0 {
  142. return nil, vm.BlockContext{}, statedb, nil
  143. }
  144. // Recompute transactions up to the target index.
  145. signer := types.MakeSigner(b.chainConfig, block.Number())
  146. for idx, tx := range block.Transactions() {
  147. msg, _ := tx.AsMessage(signer)
  148. txContext := core.NewEVMTxContext(msg)
  149. context := core.NewEVMBlockContext(block.Header(), b.chain, nil)
  150. if idx == txIndex {
  151. return msg, context, statedb, nil
  152. }
  153. vmenv := vm.NewEVM(context, txContext, statedb, b.chainConfig, vm.Config{})
  154. if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
  155. return nil, vm.BlockContext{}, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
  156. }
  157. statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
  158. }
  159. return nil, vm.BlockContext{}, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
  160. }
  161. func TestTraceCall(t *testing.T) {
  162. t.Parallel()
  163. // Initialize test accounts
  164. accounts := newAccounts(3)
  165. genesis := &core.Genesis{Alloc: core.GenesisAlloc{
  166. accounts[0].addr: {Balance: big.NewInt(params.Ether)},
  167. accounts[1].addr: {Balance: big.NewInt(params.Ether)},
  168. accounts[2].addr: {Balance: big.NewInt(params.Ether)},
  169. }}
  170. genBlocks := 10
  171. signer := types.HomesteadSigner{}
  172. api := NewAPI(newTestBackend(t, genBlocks, genesis, func(i int, b *core.BlockGen) {
  173. // Transfer from account[0] to account[1]
  174. // value: 1000 wei
  175. // fee: 0 wei
  176. tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, big.NewInt(0), nil), signer, accounts[0].key)
  177. b.AddTx(tx)
  178. }))
  179. var testSuite = []struct {
  180. blockNumber rpc.BlockNumber
  181. call ethapi.CallArgs
  182. config *TraceCallConfig
  183. expectErr error
  184. expect interface{}
  185. }{
  186. // Standard JSON trace upon the genesis, plain transfer.
  187. {
  188. blockNumber: rpc.BlockNumber(0),
  189. call: ethapi.CallArgs{
  190. From: &accounts[0].addr,
  191. To: &accounts[1].addr,
  192. Value: (*hexutil.Big)(big.NewInt(1000)),
  193. },
  194. config: nil,
  195. expectErr: nil,
  196. expect: &ethapi.ExecutionResult{
  197. Gas: params.TxGas,
  198. Failed: false,
  199. ReturnValue: "",
  200. StructLogs: []ethapi.StructLogRes{},
  201. },
  202. },
  203. // Standard JSON trace upon the head, plain transfer.
  204. {
  205. blockNumber: rpc.BlockNumber(genBlocks),
  206. call: ethapi.CallArgs{
  207. From: &accounts[0].addr,
  208. To: &accounts[1].addr,
  209. Value: (*hexutil.Big)(big.NewInt(1000)),
  210. },
  211. config: nil,
  212. expectErr: nil,
  213. expect: &ethapi.ExecutionResult{
  214. Gas: params.TxGas,
  215. Failed: false,
  216. ReturnValue: "",
  217. StructLogs: []ethapi.StructLogRes{},
  218. },
  219. },
  220. // Standard JSON trace upon the non-existent block, error expects
  221. {
  222. blockNumber: rpc.BlockNumber(genBlocks + 1),
  223. call: ethapi.CallArgs{
  224. From: &accounts[0].addr,
  225. To: &accounts[1].addr,
  226. Value: (*hexutil.Big)(big.NewInt(1000)),
  227. },
  228. config: nil,
  229. expectErr: fmt.Errorf("block #%d not found", genBlocks+1),
  230. expect: nil,
  231. },
  232. // Standard JSON trace upon the latest block
  233. {
  234. blockNumber: rpc.LatestBlockNumber,
  235. call: ethapi.CallArgs{
  236. From: &accounts[0].addr,
  237. To: &accounts[1].addr,
  238. Value: (*hexutil.Big)(big.NewInt(1000)),
  239. },
  240. config: nil,
  241. expectErr: nil,
  242. expect: &ethapi.ExecutionResult{
  243. Gas: params.TxGas,
  244. Failed: false,
  245. ReturnValue: "",
  246. StructLogs: []ethapi.StructLogRes{},
  247. },
  248. },
  249. // Standard JSON trace upon the pending block
  250. {
  251. blockNumber: rpc.PendingBlockNumber,
  252. call: ethapi.CallArgs{
  253. From: &accounts[0].addr,
  254. To: &accounts[1].addr,
  255. Value: (*hexutil.Big)(big.NewInt(1000)),
  256. },
  257. config: nil,
  258. expectErr: nil,
  259. expect: &ethapi.ExecutionResult{
  260. Gas: params.TxGas,
  261. Failed: false,
  262. ReturnValue: "",
  263. StructLogs: []ethapi.StructLogRes{},
  264. },
  265. },
  266. }
  267. for _, testspec := range testSuite {
  268. result, err := api.TraceCall(context.Background(), testspec.call, rpc.BlockNumberOrHash{BlockNumber: &testspec.blockNumber}, testspec.config)
  269. if testspec.expectErr != nil {
  270. if err == nil {
  271. t.Errorf("Expect error %v, get nothing", testspec.expectErr)
  272. continue
  273. }
  274. if !reflect.DeepEqual(err, testspec.expectErr) {
  275. t.Errorf("Error mismatch, want %v, get %v", testspec.expectErr, err)
  276. }
  277. } else {
  278. if err != nil {
  279. t.Errorf("Expect no error, get %v", err)
  280. continue
  281. }
  282. if !reflect.DeepEqual(result, testspec.expect) {
  283. t.Errorf("Result mismatch, want %v, get %v", testspec.expect, result)
  284. }
  285. }
  286. }
  287. }
  288. func TestOverridenTraceCall(t *testing.T) {
  289. t.Parallel()
  290. // Initialize test accounts
  291. accounts := newAccounts(3)
  292. genesis := &core.Genesis{Alloc: core.GenesisAlloc{
  293. accounts[0].addr: {Balance: big.NewInt(params.Ether)},
  294. accounts[1].addr: {Balance: big.NewInt(params.Ether)},
  295. accounts[2].addr: {Balance: big.NewInt(params.Ether)},
  296. }}
  297. genBlocks := 10
  298. signer := types.HomesteadSigner{}
  299. api := NewAPI(newTestBackend(t, genBlocks, genesis, func(i int, b *core.BlockGen) {
  300. // Transfer from account[0] to account[1]
  301. // value: 1000 wei
  302. // fee: 0 wei
  303. tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, big.NewInt(0), nil), signer, accounts[0].key)
  304. b.AddTx(tx)
  305. }))
  306. randomAccounts, tracer := newAccounts(3), "callTracer"
  307. var testSuite = []struct {
  308. blockNumber rpc.BlockNumber
  309. call ethapi.CallArgs
  310. config *TraceCallConfig
  311. expectErr error
  312. expect *callTrace
  313. }{
  314. // Succcessful call with state overriding
  315. {
  316. blockNumber: rpc.PendingBlockNumber,
  317. call: ethapi.CallArgs{
  318. From: &randomAccounts[0].addr,
  319. To: &randomAccounts[1].addr,
  320. Value: (*hexutil.Big)(big.NewInt(1000)),
  321. },
  322. config: &TraceCallConfig{
  323. Tracer: &tracer,
  324. StateOverrides: &ethapi.StateOverride{
  325. randomAccounts[0].addr: ethapi.OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))},
  326. },
  327. },
  328. expectErr: nil,
  329. expect: &callTrace{
  330. Type: "CALL",
  331. From: randomAccounts[0].addr,
  332. To: randomAccounts[1].addr,
  333. Gas: newRPCUint64(24979000),
  334. GasUsed: newRPCUint64(0),
  335. Value: (*hexutil.Big)(big.NewInt(1000)),
  336. },
  337. },
  338. // Invalid call without state overriding
  339. {
  340. blockNumber: rpc.PendingBlockNumber,
  341. call: ethapi.CallArgs{
  342. From: &randomAccounts[0].addr,
  343. To: &randomAccounts[1].addr,
  344. Value: (*hexutil.Big)(big.NewInt(1000)),
  345. },
  346. config: &TraceCallConfig{
  347. Tracer: &tracer,
  348. },
  349. expectErr: core.ErrInsufficientFundsForTransfer,
  350. expect: nil,
  351. },
  352. // Successful simple contract call
  353. //
  354. // // SPDX-License-Identifier: GPL-3.0
  355. //
  356. // pragma solidity >=0.7.0 <0.8.0;
  357. //
  358. // /**
  359. // * @title Storage
  360. // * @dev Store & retrieve value in a variable
  361. // */
  362. // contract Storage {
  363. // uint256 public number;
  364. // constructor() {
  365. // number = block.number;
  366. // }
  367. // }
  368. {
  369. blockNumber: rpc.PendingBlockNumber,
  370. call: ethapi.CallArgs{
  371. From: &randomAccounts[0].addr,
  372. To: &randomAccounts[2].addr,
  373. Data: newRPCBytes(common.Hex2Bytes("8381f58a")), // call number()
  374. },
  375. config: &TraceCallConfig{
  376. Tracer: &tracer,
  377. StateOverrides: &ethapi.StateOverride{
  378. randomAccounts[2].addr: ethapi.OverrideAccount{
  379. Code: newRPCBytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c80638381f58a14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000548156fea2646970667358221220eab35ffa6ab2adfe380772a48b8ba78e82a1b820a18fcb6f59aa4efb20a5f60064736f6c63430007040033")),
  380. StateDiff: newStates([]common.Hash{{}}, []common.Hash{common.BigToHash(big.NewInt(123))}),
  381. },
  382. },
  383. },
  384. expectErr: nil,
  385. expect: &callTrace{
  386. Type: "CALL",
  387. From: randomAccounts[0].addr,
  388. To: randomAccounts[2].addr,
  389. Input: hexutil.Bytes(common.Hex2Bytes("8381f58a")),
  390. Output: hexutil.Bytes(common.BigToHash(big.NewInt(123)).Bytes()),
  391. Gas: newRPCUint64(24978936),
  392. GasUsed: newRPCUint64(2283),
  393. Value: (*hexutil.Big)(big.NewInt(0)),
  394. },
  395. },
  396. }
  397. for _, testspec := range testSuite {
  398. result, err := api.TraceCall(context.Background(), testspec.call, rpc.BlockNumberOrHash{BlockNumber: &testspec.blockNumber}, testspec.config)
  399. if testspec.expectErr != nil {
  400. if err == nil {
  401. t.Errorf("Expect error %v, get nothing", testspec.expectErr)
  402. continue
  403. }
  404. if !errors.Is(err, testspec.expectErr) {
  405. t.Errorf("Error mismatch, want %v, get %v", testspec.expectErr, err)
  406. }
  407. } else {
  408. if err != nil {
  409. t.Errorf("Expect no error, get %v", err)
  410. continue
  411. }
  412. ret := new(callTrace)
  413. if err := json.Unmarshal(result.(json.RawMessage), ret); err != nil {
  414. t.Fatalf("failed to unmarshal trace result: %v", err)
  415. }
  416. if !jsonEqual(ret, testspec.expect) {
  417. // uncomment this for easier debugging
  418. //have, _ := json.MarshalIndent(ret, "", " ")
  419. //want, _ := json.MarshalIndent(testspec.expect, "", " ")
  420. //t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", string(have), string(want))
  421. t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, testspec.expect)
  422. }
  423. }
  424. }
  425. }
  426. func TestTraceTransaction(t *testing.T) {
  427. t.Parallel()
  428. // Initialize test accounts
  429. accounts := newAccounts(2)
  430. genesis := &core.Genesis{Alloc: core.GenesisAlloc{
  431. accounts[0].addr: {Balance: big.NewInt(params.Ether)},
  432. accounts[1].addr: {Balance: big.NewInt(params.Ether)},
  433. }}
  434. target := common.Hash{}
  435. signer := types.HomesteadSigner{}
  436. api := NewAPI(newTestBackend(t, 1, genesis, func(i int, b *core.BlockGen) {
  437. // Transfer from account[0] to account[1]
  438. // value: 1000 wei
  439. // fee: 0 wei
  440. tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, big.NewInt(0), nil), signer, accounts[0].key)
  441. b.AddTx(tx)
  442. target = tx.Hash()
  443. }))
  444. result, err := api.TraceTransaction(context.Background(), target, nil)
  445. if err != nil {
  446. t.Errorf("Failed to trace transaction %v", err)
  447. }
  448. if !reflect.DeepEqual(result, &ethapi.ExecutionResult{
  449. Gas: params.TxGas,
  450. Failed: false,
  451. ReturnValue: "",
  452. StructLogs: []ethapi.StructLogRes{},
  453. }) {
  454. t.Error("Transaction tracing result is different")
  455. }
  456. }
  457. func TestTraceBlock(t *testing.T) {
  458. t.Parallel()
  459. // Initialize test accounts
  460. accounts := newAccounts(3)
  461. genesis := &core.Genesis{Alloc: core.GenesisAlloc{
  462. accounts[0].addr: {Balance: big.NewInt(params.Ether)},
  463. accounts[1].addr: {Balance: big.NewInt(params.Ether)},
  464. accounts[2].addr: {Balance: big.NewInt(params.Ether)},
  465. }}
  466. genBlocks := 10
  467. signer := types.HomesteadSigner{}
  468. api := NewAPI(newTestBackend(t, genBlocks, genesis, func(i int, b *core.BlockGen) {
  469. // Transfer from account[0] to account[1]
  470. // value: 1000 wei
  471. // fee: 0 wei
  472. tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, big.NewInt(0), nil), signer, accounts[0].key)
  473. b.AddTx(tx)
  474. }))
  475. var testSuite = []struct {
  476. blockNumber rpc.BlockNumber
  477. config *TraceConfig
  478. expect interface{}
  479. expectErr error
  480. }{
  481. // Trace genesis block, expect error
  482. {
  483. blockNumber: rpc.BlockNumber(0),
  484. config: nil,
  485. expect: nil,
  486. expectErr: errors.New("genesis is not traceable"),
  487. },
  488. // Trace head block
  489. {
  490. blockNumber: rpc.BlockNumber(genBlocks),
  491. config: nil,
  492. expectErr: nil,
  493. expect: []*txTraceResult{
  494. {
  495. Result: &ethapi.ExecutionResult{
  496. Gas: params.TxGas,
  497. Failed: false,
  498. ReturnValue: "",
  499. StructLogs: []ethapi.StructLogRes{},
  500. },
  501. },
  502. },
  503. },
  504. // Trace non-existent block
  505. {
  506. blockNumber: rpc.BlockNumber(genBlocks + 1),
  507. config: nil,
  508. expectErr: fmt.Errorf("block #%d not found", genBlocks+1),
  509. expect: nil,
  510. },
  511. // Trace latest block
  512. {
  513. blockNumber: rpc.LatestBlockNumber,
  514. config: nil,
  515. expectErr: nil,
  516. expect: []*txTraceResult{
  517. {
  518. Result: &ethapi.ExecutionResult{
  519. Gas: params.TxGas,
  520. Failed: false,
  521. ReturnValue: "",
  522. StructLogs: []ethapi.StructLogRes{},
  523. },
  524. },
  525. },
  526. },
  527. // Trace pending block
  528. {
  529. blockNumber: rpc.PendingBlockNumber,
  530. config: nil,
  531. expectErr: nil,
  532. expect: []*txTraceResult{
  533. {
  534. Result: &ethapi.ExecutionResult{
  535. Gas: params.TxGas,
  536. Failed: false,
  537. ReturnValue: "",
  538. StructLogs: []ethapi.StructLogRes{},
  539. },
  540. },
  541. },
  542. },
  543. }
  544. for _, testspec := range testSuite {
  545. result, err := api.TraceBlockByNumber(context.Background(), testspec.blockNumber, testspec.config)
  546. if testspec.expectErr != nil {
  547. if err == nil {
  548. t.Errorf("Expect error %v, get nothing", testspec.expectErr)
  549. continue
  550. }
  551. if !reflect.DeepEqual(err, testspec.expectErr) {
  552. t.Errorf("Error mismatch, want %v, get %v", testspec.expectErr, err)
  553. }
  554. } else {
  555. if err != nil {
  556. t.Errorf("Expect no error, get %v", err)
  557. continue
  558. }
  559. if !reflect.DeepEqual(result, testspec.expect) {
  560. t.Errorf("Result mismatch, want %v, get %v", testspec.expect, result)
  561. }
  562. }
  563. }
  564. }
  565. type Account struct {
  566. key *ecdsa.PrivateKey
  567. addr common.Address
  568. }
  569. type Accounts []Account
  570. func (a Accounts) Len() int { return len(a) }
  571. func (a Accounts) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
  572. func (a Accounts) Less(i, j int) bool { return bytes.Compare(a[i].addr.Bytes(), a[j].addr.Bytes()) < 0 }
  573. func newAccounts(n int) (accounts Accounts) {
  574. for i := 0; i < n; i++ {
  575. key, _ := crypto.GenerateKey()
  576. addr := crypto.PubkeyToAddress(key.PublicKey)
  577. accounts = append(accounts, Account{key: key, addr: addr})
  578. }
  579. sort.Sort(accounts)
  580. return accounts
  581. }
  582. func newRPCBalance(balance *big.Int) **hexutil.Big {
  583. rpcBalance := (*hexutil.Big)(balance)
  584. return &rpcBalance
  585. }
  586. func newRPCUint64(number uint64) *hexutil.Uint64 {
  587. rpcUint64 := hexutil.Uint64(number)
  588. return &rpcUint64
  589. }
  590. func newRPCBytes(bytes []byte) *hexutil.Bytes {
  591. rpcBytes := hexutil.Bytes(bytes)
  592. return &rpcBytes
  593. }
  594. func newStates(keys []common.Hash, vals []common.Hash) *map[common.Hash]common.Hash {
  595. if len(keys) != len(vals) {
  596. panic("invalid input")
  597. }
  598. m := make(map[common.Hash]common.Hash)
  599. for i := 0; i < len(keys); i++ {
  600. m[keys[i]] = vals[i]
  601. }
  602. return &m
  603. }