api_test.go 20 KB

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