api_test.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  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, preferDisk 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 TestTraceTransaction(t *testing.T) {
  289. t.Parallel()
  290. // Initialize test accounts
  291. accounts := newAccounts(2)
  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. }}
  296. target := common.Hash{}
  297. signer := types.HomesteadSigner{}
  298. api := NewAPI(newTestBackend(t, 1, genesis, func(i int, b *core.BlockGen) {
  299. // Transfer from account[0] to account[1]
  300. // value: 1000 wei
  301. // fee: 0 wei
  302. tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, big.NewInt(0), nil), signer, accounts[0].key)
  303. b.AddTx(tx)
  304. target = tx.Hash()
  305. }))
  306. result, err := api.TraceTransaction(context.Background(), target, nil)
  307. if err != nil {
  308. t.Errorf("Failed to trace transaction %v", err)
  309. }
  310. if !reflect.DeepEqual(result, &ethapi.ExecutionResult{
  311. Gas: params.TxGas,
  312. Failed: false,
  313. ReturnValue: "",
  314. StructLogs: []ethapi.StructLogRes{},
  315. }) {
  316. t.Error("Transaction tracing result is different")
  317. }
  318. }
  319. func TestTraceBlock(t *testing.T) {
  320. t.Parallel()
  321. // Initialize test accounts
  322. accounts := newAccounts(3)
  323. genesis := &core.Genesis{Alloc: core.GenesisAlloc{
  324. accounts[0].addr: {Balance: big.NewInt(params.Ether)},
  325. accounts[1].addr: {Balance: big.NewInt(params.Ether)},
  326. accounts[2].addr: {Balance: big.NewInt(params.Ether)},
  327. }}
  328. genBlocks := 10
  329. signer := types.HomesteadSigner{}
  330. api := NewAPI(newTestBackend(t, genBlocks, genesis, func(i int, b *core.BlockGen) {
  331. // Transfer from account[0] to account[1]
  332. // value: 1000 wei
  333. // fee: 0 wei
  334. tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, big.NewInt(0), nil), signer, accounts[0].key)
  335. b.AddTx(tx)
  336. }))
  337. var testSuite = []struct {
  338. blockNumber rpc.BlockNumber
  339. config *TraceConfig
  340. want string
  341. expectErr error
  342. }{
  343. // Trace genesis block, expect error
  344. {
  345. blockNumber: rpc.BlockNumber(0),
  346. expectErr: errors.New("genesis is not traceable"),
  347. },
  348. // Trace head block
  349. {
  350. blockNumber: rpc.BlockNumber(genBlocks),
  351. want: `[{"result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}]`,
  352. },
  353. // Trace non-existent block
  354. {
  355. blockNumber: rpc.BlockNumber(genBlocks + 1),
  356. expectErr: fmt.Errorf("block #%d not found", genBlocks+1),
  357. },
  358. // Trace latest block
  359. {
  360. blockNumber: rpc.LatestBlockNumber,
  361. want: `[{"result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}]`,
  362. },
  363. // Trace pending block
  364. {
  365. blockNumber: rpc.PendingBlockNumber,
  366. want: `[{"result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}]`,
  367. },
  368. }
  369. for i, tc := range testSuite {
  370. result, err := api.TraceBlockByNumber(context.Background(), tc.blockNumber, tc.config)
  371. if tc.expectErr != nil {
  372. if err == nil {
  373. t.Errorf("test %d, want error %v", i, tc.expectErr)
  374. continue
  375. }
  376. if !reflect.DeepEqual(err, tc.expectErr) {
  377. t.Errorf("test %d: error mismatch, want %v, get %v", i, tc.expectErr, err)
  378. }
  379. continue
  380. }
  381. if err != nil {
  382. t.Errorf("test %d, want no error, have %v", i, err)
  383. continue
  384. }
  385. have, _ := json.Marshal(result)
  386. want := tc.want
  387. if string(have) != want {
  388. t.Errorf("test %d, result mismatch, have\n%v\n, want\n%v\n", i, string(have), want)
  389. }
  390. }
  391. }
  392. func TestTracingWithOverrides(t *testing.T) {
  393. t.Parallel()
  394. // Initialize test accounts
  395. accounts := newAccounts(3)
  396. genesis := &core.Genesis{Alloc: core.GenesisAlloc{
  397. accounts[0].addr: {Balance: big.NewInt(params.Ether)},
  398. accounts[1].addr: {Balance: big.NewInt(params.Ether)},
  399. accounts[2].addr: {Balance: big.NewInt(params.Ether)},
  400. }}
  401. genBlocks := 10
  402. signer := types.HomesteadSigner{}
  403. api := NewAPI(newTestBackend(t, genBlocks, genesis, func(i int, b *core.BlockGen) {
  404. // Transfer from account[0] to account[1]
  405. // value: 1000 wei
  406. // fee: 0 wei
  407. tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, big.NewInt(1000), params.TxGas, big.NewInt(0), nil), signer, accounts[0].key)
  408. b.AddTx(tx)
  409. }))
  410. randomAccounts := newAccounts(3)
  411. type res struct {
  412. Gas int
  413. Failed bool
  414. returnValue string
  415. }
  416. var testSuite = []struct {
  417. blockNumber rpc.BlockNumber
  418. call ethapi.CallArgs
  419. config *TraceCallConfig
  420. expectErr error
  421. want string
  422. }{
  423. // Call which can only succeed if state is state overridden
  424. {
  425. blockNumber: rpc.PendingBlockNumber,
  426. call: ethapi.CallArgs{
  427. From: &randomAccounts[0].addr,
  428. To: &randomAccounts[1].addr,
  429. Value: (*hexutil.Big)(big.NewInt(1000)),
  430. },
  431. config: &TraceCallConfig{
  432. StateOverrides: &ethapi.StateOverride{
  433. randomAccounts[0].addr: ethapi.OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))},
  434. },
  435. },
  436. want: `{"gas":21000,"failed":false,"returnValue":""}`,
  437. },
  438. // Invalid call without state overriding
  439. {
  440. blockNumber: rpc.PendingBlockNumber,
  441. call: ethapi.CallArgs{
  442. From: &randomAccounts[0].addr,
  443. To: &randomAccounts[1].addr,
  444. Value: (*hexutil.Big)(big.NewInt(1000)),
  445. },
  446. config: &TraceCallConfig{},
  447. expectErr: core.ErrInsufficientFundsForTransfer,
  448. },
  449. // Successful simple contract call
  450. //
  451. // // SPDX-License-Identifier: GPL-3.0
  452. //
  453. // pragma solidity >=0.7.0 <0.8.0;
  454. //
  455. // /**
  456. // * @title Storage
  457. // * @dev Store & retrieve value in a variable
  458. // */
  459. // contract Storage {
  460. // uint256 public number;
  461. // constructor() {
  462. // number = block.number;
  463. // }
  464. // }
  465. {
  466. blockNumber: rpc.PendingBlockNumber,
  467. call: ethapi.CallArgs{
  468. From: &randomAccounts[0].addr,
  469. To: &randomAccounts[2].addr,
  470. Data: newRPCBytes(common.Hex2Bytes("8381f58a")), // call number()
  471. },
  472. config: &TraceCallConfig{
  473. //Tracer: &tracer,
  474. StateOverrides: &ethapi.StateOverride{
  475. randomAccounts[2].addr: ethapi.OverrideAccount{
  476. Code: newRPCBytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c80638381f58a14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000548156fea2646970667358221220eab35ffa6ab2adfe380772a48b8ba78e82a1b820a18fcb6f59aa4efb20a5f60064736f6c63430007040033")),
  477. StateDiff: newStates([]common.Hash{{}}, []common.Hash{common.BigToHash(big.NewInt(123))}),
  478. },
  479. },
  480. },
  481. want: `{"gas":23347,"failed":false,"returnValue":"000000000000000000000000000000000000000000000000000000000000007b"}`,
  482. },
  483. }
  484. for i, tc := range testSuite {
  485. result, err := api.TraceCall(context.Background(), tc.call, rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, tc.config)
  486. if tc.expectErr != nil {
  487. if err == nil {
  488. t.Errorf("test %d: want error %v, have nothing", i, tc.expectErr)
  489. continue
  490. }
  491. if !errors.Is(err, tc.expectErr) {
  492. t.Errorf("test %d: error mismatch, want %v, have %v", i, tc.expectErr, err)
  493. }
  494. continue
  495. }
  496. if err != nil {
  497. t.Errorf("test %d: want no error, have %v", i, err)
  498. continue
  499. }
  500. // Turn result into res-struct
  501. var (
  502. have res
  503. want res
  504. )
  505. resBytes, _ := json.Marshal(result)
  506. json.Unmarshal(resBytes, &have)
  507. json.Unmarshal([]byte(tc.want), &want)
  508. if !reflect.DeepEqual(have, want) {
  509. t.Errorf("test %d, result mismatch, have\n%v\n, want\n%v\n", i, string(resBytes), want)
  510. }
  511. }
  512. }
  513. type Account struct {
  514. key *ecdsa.PrivateKey
  515. addr common.Address
  516. }
  517. type Accounts []Account
  518. func (a Accounts) Len() int { return len(a) }
  519. func (a Accounts) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
  520. func (a Accounts) Less(i, j int) bool { return bytes.Compare(a[i].addr.Bytes(), a[j].addr.Bytes()) < 0 }
  521. func newAccounts(n int) (accounts Accounts) {
  522. for i := 0; i < n; i++ {
  523. key, _ := crypto.GenerateKey()
  524. addr := crypto.PubkeyToAddress(key.PublicKey)
  525. accounts = append(accounts, Account{key: key, addr: addr})
  526. }
  527. sort.Sort(accounts)
  528. return accounts
  529. }
  530. func newRPCBalance(balance *big.Int) **hexutil.Big {
  531. rpcBalance := (*hexutil.Big)(balance)
  532. return &rpcBalance
  533. }
  534. func newRPCBytes(bytes []byte) *hexutil.Bytes {
  535. rpcBytes := hexutil.Bytes(bytes)
  536. return &rpcBytes
  537. }
  538. func newStates(keys []common.Hash, vals []common.Hash) *map[common.Hash]common.Hash {
  539. if len(keys) != len(vals) {
  540. panic("invalid input")
  541. }
  542. m := make(map[common.Hash]common.Hash)
  543. for i := 0; i < len(keys); i++ {
  544. m[keys[i]] = vals[i]
  545. }
  546. return &m
  547. }