ethclient_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. // Copyright 2016 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 ethclient
  17. import (
  18. "bytes"
  19. "context"
  20. "errors"
  21. "fmt"
  22. "math/big"
  23. "reflect"
  24. "testing"
  25. "time"
  26. "github.com/ethereum/go-ethereum"
  27. "github.com/ethereum/go-ethereum/common"
  28. "github.com/ethereum/go-ethereum/consensus/ethash"
  29. "github.com/ethereum/go-ethereum/core"
  30. "github.com/ethereum/go-ethereum/core/rawdb"
  31. "github.com/ethereum/go-ethereum/core/types"
  32. "github.com/ethereum/go-ethereum/crypto"
  33. "github.com/ethereum/go-ethereum/eth"
  34. "github.com/ethereum/go-ethereum/eth/ethconfig"
  35. "github.com/ethereum/go-ethereum/node"
  36. "github.com/ethereum/go-ethereum/params"
  37. "github.com/ethereum/go-ethereum/rpc"
  38. )
  39. // Verify that Client implements the ethereum interfaces.
  40. var (
  41. _ = ethereum.ChainReader(&Client{})
  42. _ = ethereum.TransactionReader(&Client{})
  43. _ = ethereum.ChainStateReader(&Client{})
  44. _ = ethereum.ChainSyncReader(&Client{})
  45. _ = ethereum.ContractCaller(&Client{})
  46. _ = ethereum.GasEstimator(&Client{})
  47. _ = ethereum.GasPricer(&Client{})
  48. _ = ethereum.LogFilterer(&Client{})
  49. _ = ethereum.PendingStateReader(&Client{})
  50. // _ = ethereum.PendingStateEventer(&Client{})
  51. _ = ethereum.PendingContractCaller(&Client{})
  52. )
  53. func TestToFilterArg(t *testing.T) {
  54. blockHashErr := fmt.Errorf("cannot specify both BlockHash and FromBlock/ToBlock")
  55. addresses := []common.Address{
  56. common.HexToAddress("0xD36722ADeC3EdCB29c8e7b5a47f352D701393462"),
  57. }
  58. blockHash := common.HexToHash(
  59. "0xeb94bb7d78b73657a9d7a99792413f50c0a45c51fc62bdcb08a53f18e9a2b4eb",
  60. )
  61. for _, testCase := range []struct {
  62. name string
  63. input ethereum.FilterQuery
  64. output interface{}
  65. err error
  66. }{
  67. {
  68. "without BlockHash",
  69. ethereum.FilterQuery{
  70. Addresses: addresses,
  71. FromBlock: big.NewInt(1),
  72. ToBlock: big.NewInt(2),
  73. Topics: [][]common.Hash{},
  74. },
  75. map[string]interface{}{
  76. "address": addresses,
  77. "fromBlock": "0x1",
  78. "toBlock": "0x2",
  79. "topics": [][]common.Hash{},
  80. },
  81. nil,
  82. },
  83. {
  84. "with nil fromBlock and nil toBlock",
  85. ethereum.FilterQuery{
  86. Addresses: addresses,
  87. Topics: [][]common.Hash{},
  88. },
  89. map[string]interface{}{
  90. "address": addresses,
  91. "fromBlock": "0x0",
  92. "toBlock": "latest",
  93. "topics": [][]common.Hash{},
  94. },
  95. nil,
  96. },
  97. {
  98. "with negative fromBlock and negative toBlock",
  99. ethereum.FilterQuery{
  100. Addresses: addresses,
  101. FromBlock: big.NewInt(-1),
  102. ToBlock: big.NewInt(-1),
  103. Topics: [][]common.Hash{},
  104. },
  105. map[string]interface{}{
  106. "address": addresses,
  107. "fromBlock": "pending",
  108. "toBlock": "pending",
  109. "topics": [][]common.Hash{},
  110. },
  111. nil,
  112. },
  113. {
  114. "with blockhash",
  115. ethereum.FilterQuery{
  116. Addresses: addresses,
  117. BlockHash: &blockHash,
  118. Topics: [][]common.Hash{},
  119. },
  120. map[string]interface{}{
  121. "address": addresses,
  122. "blockHash": blockHash,
  123. "topics": [][]common.Hash{},
  124. },
  125. nil,
  126. },
  127. {
  128. "with blockhash and from block",
  129. ethereum.FilterQuery{
  130. Addresses: addresses,
  131. BlockHash: &blockHash,
  132. FromBlock: big.NewInt(1),
  133. Topics: [][]common.Hash{},
  134. },
  135. nil,
  136. blockHashErr,
  137. },
  138. {
  139. "with blockhash and to block",
  140. ethereum.FilterQuery{
  141. Addresses: addresses,
  142. BlockHash: &blockHash,
  143. ToBlock: big.NewInt(1),
  144. Topics: [][]common.Hash{},
  145. },
  146. nil,
  147. blockHashErr,
  148. },
  149. {
  150. "with blockhash and both from / to block",
  151. ethereum.FilterQuery{
  152. Addresses: addresses,
  153. BlockHash: &blockHash,
  154. FromBlock: big.NewInt(1),
  155. ToBlock: big.NewInt(2),
  156. Topics: [][]common.Hash{},
  157. },
  158. nil,
  159. blockHashErr,
  160. },
  161. } {
  162. t.Run(testCase.name, func(t *testing.T) {
  163. output, err := toFilterArg(testCase.input)
  164. if (testCase.err == nil) != (err == nil) {
  165. t.Fatalf("expected error %v but got %v", testCase.err, err)
  166. }
  167. if testCase.err != nil {
  168. if testCase.err.Error() != err.Error() {
  169. t.Fatalf("expected error %v but got %v", testCase.err, err)
  170. }
  171. } else if !reflect.DeepEqual(testCase.output, output) {
  172. t.Fatalf("expected filter arg %v but got %v", testCase.output, output)
  173. }
  174. })
  175. }
  176. }
  177. var (
  178. testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  179. testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
  180. testBalance = big.NewInt(2e15)
  181. )
  182. var genesis = &core.Genesis{
  183. Config: params.AllEthashProtocolChanges,
  184. Alloc: core.GenesisAlloc{testAddr: {Balance: testBalance}},
  185. ExtraData: []byte("test genesis"),
  186. Timestamp: 9000,
  187. BaseFee: big.NewInt(params.InitialBaseFee),
  188. }
  189. var testTx1 = types.MustSignNewTx(testKey, types.LatestSigner(genesis.Config), &types.LegacyTx{
  190. Nonce: 0,
  191. Value: big.NewInt(12),
  192. GasPrice: big.NewInt(params.InitialBaseFee),
  193. Gas: params.TxGas,
  194. To: &common.Address{2},
  195. })
  196. var testTx2 = types.MustSignNewTx(testKey, types.LatestSigner(genesis.Config), &types.LegacyTx{
  197. Nonce: 1,
  198. Value: big.NewInt(8),
  199. GasPrice: big.NewInt(params.InitialBaseFee),
  200. Gas: params.TxGas,
  201. To: &common.Address{2},
  202. })
  203. func newTestBackend(t *testing.T) (*node.Node, []*types.Block) {
  204. // Generate test chain.
  205. blocks := generateTestChain()
  206. // Create node
  207. n, err := node.New(&node.Config{})
  208. if err != nil {
  209. t.Fatalf("can't create new node: %v", err)
  210. }
  211. // Create Ethereum Service
  212. config := &ethconfig.Config{Genesis: genesis, RPCGasCap: 50000000}
  213. config.Ethash.PowMode = ethash.ModeFake
  214. ethservice, err := eth.New(n, config)
  215. if err != nil {
  216. t.Fatalf("can't create new ethereum service: %v", err)
  217. }
  218. // Import the test chain.
  219. if err := n.Start(); err != nil {
  220. t.Fatalf("can't start test node: %v", err)
  221. }
  222. if _, err := ethservice.BlockChain().InsertChain(blocks[1:]); err != nil {
  223. t.Fatalf("can't import test blocks: %v", err)
  224. }
  225. return n, blocks
  226. }
  227. func generateTestChain() []*types.Block {
  228. db := rawdb.NewMemoryDatabase()
  229. generate := func(i int, g *core.BlockGen) {
  230. g.OffsetTime(5)
  231. g.SetExtra([]byte("test"))
  232. if i == 1 {
  233. // Test transactions are included in block #2.
  234. g.AddTx(testTx1)
  235. g.AddTx(testTx2)
  236. }
  237. }
  238. gblock := genesis.MustCommit(db)
  239. engine := ethash.NewFaker()
  240. blocks, _ := core.GenerateChain(genesis.Config, gblock, engine, db, 2, generate)
  241. blocks = append([]*types.Block{gblock}, blocks...)
  242. return blocks
  243. }
  244. func TestEthClient(t *testing.T) {
  245. backend, chain := newTestBackend(t)
  246. client, _ := backend.Attach()
  247. defer backend.Close()
  248. defer client.Close()
  249. tests := map[string]struct {
  250. test func(t *testing.T)
  251. }{
  252. "Header": {
  253. func(t *testing.T) { testHeader(t, chain, client) },
  254. },
  255. "BalanceAt": {
  256. func(t *testing.T) { testBalanceAt(t, client) },
  257. },
  258. "TxInBlockInterrupted": {
  259. func(t *testing.T) { testTransactionInBlockInterrupted(t, client) },
  260. },
  261. "ChainID": {
  262. func(t *testing.T) { testChainID(t, client) },
  263. },
  264. "GetBlock": {
  265. func(t *testing.T) { testGetBlock(t, client) },
  266. },
  267. "StatusFunctions": {
  268. func(t *testing.T) { testStatusFunctions(t, client) },
  269. },
  270. "CallContract": {
  271. func(t *testing.T) { testCallContract(t, client) },
  272. },
  273. "CallContractAtHash": {
  274. func(t *testing.T) { testCallContractAtHash(t, client) },
  275. },
  276. "AtFunctions": {
  277. func(t *testing.T) { testAtFunctions(t, client) },
  278. },
  279. "TransactionSender": {
  280. func(t *testing.T) { testTransactionSender(t, client) },
  281. },
  282. }
  283. t.Parallel()
  284. for name, tt := range tests {
  285. t.Run(name, tt.test)
  286. }
  287. }
  288. func testHeader(t *testing.T, chain []*types.Block, client *rpc.Client) {
  289. tests := map[string]struct {
  290. block *big.Int
  291. want *types.Header
  292. wantErr error
  293. }{
  294. "genesis": {
  295. block: big.NewInt(0),
  296. want: chain[0].Header(),
  297. },
  298. "first_block": {
  299. block: big.NewInt(1),
  300. want: chain[1].Header(),
  301. },
  302. "future_block": {
  303. block: big.NewInt(1000000000),
  304. want: nil,
  305. wantErr: ethereum.NotFound,
  306. },
  307. }
  308. for name, tt := range tests {
  309. t.Run(name, func(t *testing.T) {
  310. ec := NewClient(client)
  311. ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
  312. defer cancel()
  313. got, err := ec.HeaderByNumber(ctx, tt.block)
  314. if !errors.Is(err, tt.wantErr) {
  315. t.Fatalf("HeaderByNumber(%v) error = %q, want %q", tt.block, err, tt.wantErr)
  316. }
  317. if got != nil && got.Number != nil && got.Number.Sign() == 0 {
  318. got.Number = big.NewInt(0) // hack to make DeepEqual work
  319. }
  320. if !reflect.DeepEqual(got, tt.want) {
  321. t.Fatalf("HeaderByNumber(%v)\n = %v\nwant %v", tt.block, got, tt.want)
  322. }
  323. })
  324. }
  325. }
  326. func testBalanceAt(t *testing.T, client *rpc.Client) {
  327. tests := map[string]struct {
  328. account common.Address
  329. block *big.Int
  330. want *big.Int
  331. wantErr error
  332. }{
  333. "valid_account_genesis": {
  334. account: testAddr,
  335. block: big.NewInt(0),
  336. want: testBalance,
  337. },
  338. "valid_account": {
  339. account: testAddr,
  340. block: big.NewInt(1),
  341. want: testBalance,
  342. },
  343. "non_existent_account": {
  344. account: common.Address{1},
  345. block: big.NewInt(1),
  346. want: big.NewInt(0),
  347. },
  348. "future_block": {
  349. account: testAddr,
  350. block: big.NewInt(1000000000),
  351. want: big.NewInt(0),
  352. wantErr: errors.New("header not found"),
  353. },
  354. }
  355. for name, tt := range tests {
  356. t.Run(name, func(t *testing.T) {
  357. ec := NewClient(client)
  358. ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
  359. defer cancel()
  360. got, err := ec.BalanceAt(ctx, tt.account, tt.block)
  361. if tt.wantErr != nil && (err == nil || err.Error() != tt.wantErr.Error()) {
  362. t.Fatalf("BalanceAt(%x, %v) error = %q, want %q", tt.account, tt.block, err, tt.wantErr)
  363. }
  364. if got.Cmp(tt.want) != 0 {
  365. t.Fatalf("BalanceAt(%x, %v) = %v, want %v", tt.account, tt.block, got, tt.want)
  366. }
  367. })
  368. }
  369. }
  370. func testTransactionInBlockInterrupted(t *testing.T, client *rpc.Client) {
  371. ec := NewClient(client)
  372. // Get current block by number.
  373. block, err := ec.BlockByNumber(context.Background(), nil)
  374. if err != nil {
  375. t.Fatalf("unexpected error: %v", err)
  376. }
  377. // Test tx in block interupted.
  378. ctx, cancel := context.WithCancel(context.Background())
  379. cancel()
  380. tx, err := ec.TransactionInBlock(ctx, block.Hash(), 0)
  381. if tx != nil {
  382. t.Fatal("transaction should be nil")
  383. }
  384. if err == nil || err == ethereum.NotFound {
  385. t.Fatal("error should not be nil/notfound")
  386. }
  387. // Test tx in block not found.
  388. if _, err := ec.TransactionInBlock(context.Background(), block.Hash(), 20); err != ethereum.NotFound {
  389. t.Fatal("error should be ethereum.NotFound")
  390. }
  391. }
  392. func testChainID(t *testing.T, client *rpc.Client) {
  393. ec := NewClient(client)
  394. id, err := ec.ChainID(context.Background())
  395. if err != nil {
  396. t.Fatalf("unexpected error: %v", err)
  397. }
  398. if id == nil || id.Cmp(params.AllEthashProtocolChanges.ChainID) != 0 {
  399. t.Fatalf("ChainID returned wrong number: %+v", id)
  400. }
  401. }
  402. func testGetBlock(t *testing.T, client *rpc.Client) {
  403. ec := NewClient(client)
  404. // Get current block number
  405. blockNumber, err := ec.BlockNumber(context.Background())
  406. if err != nil {
  407. t.Fatalf("unexpected error: %v", err)
  408. }
  409. if blockNumber != 2 {
  410. t.Fatalf("BlockNumber returned wrong number: %d", blockNumber)
  411. }
  412. // Get current block by number
  413. block, err := ec.BlockByNumber(context.Background(), new(big.Int).SetUint64(blockNumber))
  414. if err != nil {
  415. t.Fatalf("unexpected error: %v", err)
  416. }
  417. if block.NumberU64() != blockNumber {
  418. t.Fatalf("BlockByNumber returned wrong block: want %d got %d", blockNumber, block.NumberU64())
  419. }
  420. // Get current block by hash
  421. blockH, err := ec.BlockByHash(context.Background(), block.Hash())
  422. if err != nil {
  423. t.Fatalf("unexpected error: %v", err)
  424. }
  425. if block.Hash() != blockH.Hash() {
  426. t.Fatalf("BlockByHash returned wrong block: want %v got %v", block.Hash().Hex(), blockH.Hash().Hex())
  427. }
  428. // Get header by number
  429. header, err := ec.HeaderByNumber(context.Background(), new(big.Int).SetUint64(blockNumber))
  430. if err != nil {
  431. t.Fatalf("unexpected error: %v", err)
  432. }
  433. if block.Header().Hash() != header.Hash() {
  434. t.Fatalf("HeaderByNumber returned wrong header: want %v got %v", block.Header().Hash().Hex(), header.Hash().Hex())
  435. }
  436. // Get header by hash
  437. headerH, err := ec.HeaderByHash(context.Background(), block.Hash())
  438. if err != nil {
  439. t.Fatalf("unexpected error: %v", err)
  440. }
  441. if block.Header().Hash() != headerH.Hash() {
  442. t.Fatalf("HeaderByHash returned wrong header: want %v got %v", block.Header().Hash().Hex(), headerH.Hash().Hex())
  443. }
  444. }
  445. func testStatusFunctions(t *testing.T, client *rpc.Client) {
  446. ec := NewClient(client)
  447. // Sync progress
  448. progress, err := ec.SyncProgress(context.Background())
  449. if err != nil {
  450. t.Fatalf("unexpected error: %v", err)
  451. }
  452. if progress != nil {
  453. t.Fatalf("unexpected progress: %v", progress)
  454. }
  455. // NetworkID
  456. networkID, err := ec.NetworkID(context.Background())
  457. if err != nil {
  458. t.Fatalf("unexpected error: %v", err)
  459. }
  460. if networkID.Cmp(big.NewInt(0)) != 0 {
  461. t.Fatalf("unexpected networkID: %v", networkID)
  462. }
  463. // SuggestGasPrice
  464. gasPrice, err := ec.SuggestGasPrice(context.Background())
  465. if err != nil {
  466. t.Fatalf("unexpected error: %v", err)
  467. }
  468. if gasPrice.Cmp(big.NewInt(1000000000)) != 0 {
  469. t.Fatalf("unexpected gas price: %v", gasPrice)
  470. }
  471. // SuggestGasTipCap
  472. gasTipCap, err := ec.SuggestGasTipCap(context.Background())
  473. if err != nil {
  474. t.Fatalf("unexpected error: %v", err)
  475. }
  476. if gasTipCap.Cmp(big.NewInt(234375000)) != 0 {
  477. t.Fatalf("unexpected gas tip cap: %v", gasTipCap)
  478. }
  479. // FeeHistory
  480. history, err := ec.FeeHistory(context.Background(), 1, big.NewInt(2), []float64{95, 99})
  481. if err != nil {
  482. t.Fatalf("unexpected error: %v", err)
  483. }
  484. want := &ethereum.FeeHistory{
  485. OldestBlock: big.NewInt(2),
  486. Reward: [][]*big.Int{
  487. {
  488. big.NewInt(234375000),
  489. big.NewInt(234375000),
  490. },
  491. },
  492. BaseFee: []*big.Int{
  493. big.NewInt(765625000),
  494. big.NewInt(671627818),
  495. },
  496. GasUsedRatio: []float64{0.008912678667376286},
  497. }
  498. if !reflect.DeepEqual(history, want) {
  499. t.Fatalf("FeeHistory result doesn't match expected: (got: %v, want: %v)", history, want)
  500. }
  501. }
  502. func testCallContractAtHash(t *testing.T, client *rpc.Client) {
  503. ec := NewClient(client)
  504. // EstimateGas
  505. msg := ethereum.CallMsg{
  506. From: testAddr,
  507. To: &common.Address{},
  508. Gas: 21000,
  509. Value: big.NewInt(1),
  510. }
  511. gas, err := ec.EstimateGas(context.Background(), msg)
  512. if err != nil {
  513. t.Fatalf("unexpected error: %v", err)
  514. }
  515. if gas != 21000 {
  516. t.Fatalf("unexpected gas price: %v", gas)
  517. }
  518. block, err := ec.HeaderByNumber(context.Background(), big.NewInt(1))
  519. if err != nil {
  520. t.Fatalf("BlockByNumber error: %v", err)
  521. }
  522. // CallContract
  523. if _, err := ec.CallContractAtHash(context.Background(), msg, block.Hash()); err != nil {
  524. t.Fatalf("unexpected error: %v", err)
  525. }
  526. }
  527. func testCallContract(t *testing.T, client *rpc.Client) {
  528. ec := NewClient(client)
  529. // EstimateGas
  530. msg := ethereum.CallMsg{
  531. From: testAddr,
  532. To: &common.Address{},
  533. Gas: 21000,
  534. Value: big.NewInt(1),
  535. }
  536. gas, err := ec.EstimateGas(context.Background(), msg)
  537. if err != nil {
  538. t.Fatalf("unexpected error: %v", err)
  539. }
  540. if gas != 21000 {
  541. t.Fatalf("unexpected gas price: %v", gas)
  542. }
  543. // CallContract
  544. if _, err := ec.CallContract(context.Background(), msg, big.NewInt(1)); err != nil {
  545. t.Fatalf("unexpected error: %v", err)
  546. }
  547. // PendingCallContract
  548. if _, err := ec.PendingCallContract(context.Background(), msg); err != nil {
  549. t.Fatalf("unexpected error: %v", err)
  550. }
  551. }
  552. func testAtFunctions(t *testing.T, client *rpc.Client) {
  553. ec := NewClient(client)
  554. // send a transaction for some interesting pending status
  555. sendTransaction(ec)
  556. time.Sleep(100 * time.Millisecond)
  557. // Check pending transaction count
  558. pending, err := ec.PendingTransactionCount(context.Background())
  559. if err != nil {
  560. t.Fatalf("unexpected error: %v", err)
  561. }
  562. if pending != 1 {
  563. t.Fatalf("unexpected pending, wanted 1 got: %v", pending)
  564. }
  565. // Query balance
  566. balance, err := ec.BalanceAt(context.Background(), testAddr, nil)
  567. if err != nil {
  568. t.Fatalf("unexpected error: %v", err)
  569. }
  570. penBalance, err := ec.PendingBalanceAt(context.Background(), testAddr)
  571. if err != nil {
  572. t.Fatalf("unexpected error: %v", err)
  573. }
  574. if balance.Cmp(penBalance) == 0 {
  575. t.Fatalf("unexpected balance: %v %v", balance, penBalance)
  576. }
  577. // NonceAt
  578. nonce, err := ec.NonceAt(context.Background(), testAddr, nil)
  579. if err != nil {
  580. t.Fatalf("unexpected error: %v", err)
  581. }
  582. penNonce, err := ec.PendingNonceAt(context.Background(), testAddr)
  583. if err != nil {
  584. t.Fatalf("unexpected error: %v", err)
  585. }
  586. if penNonce != nonce+1 {
  587. t.Fatalf("unexpected nonce: %v %v", nonce, penNonce)
  588. }
  589. // StorageAt
  590. storage, err := ec.StorageAt(context.Background(), testAddr, common.Hash{}, nil)
  591. if err != nil {
  592. t.Fatalf("unexpected error: %v", err)
  593. }
  594. penStorage, err := ec.PendingStorageAt(context.Background(), testAddr, common.Hash{})
  595. if err != nil {
  596. t.Fatalf("unexpected error: %v", err)
  597. }
  598. if !bytes.Equal(storage, penStorage) {
  599. t.Fatalf("unexpected storage: %v %v", storage, penStorage)
  600. }
  601. // CodeAt
  602. code, err := ec.CodeAt(context.Background(), testAddr, nil)
  603. if err != nil {
  604. t.Fatalf("unexpected error: %v", err)
  605. }
  606. penCode, err := ec.PendingCodeAt(context.Background(), testAddr)
  607. if err != nil {
  608. t.Fatalf("unexpected error: %v", err)
  609. }
  610. if !bytes.Equal(code, penCode) {
  611. t.Fatalf("unexpected code: %v %v", code, penCode)
  612. }
  613. }
  614. func testTransactionSender(t *testing.T, client *rpc.Client) {
  615. ec := NewClient(client)
  616. ctx := context.Background()
  617. // Retrieve testTx1 via RPC.
  618. block2, err := ec.HeaderByNumber(ctx, big.NewInt(2))
  619. if err != nil {
  620. t.Fatal("can't get block 1:", err)
  621. }
  622. tx1, err := ec.TransactionInBlock(ctx, block2.Hash(), 0)
  623. if err != nil {
  624. t.Fatal("can't get tx:", err)
  625. }
  626. if tx1.Hash() != testTx1.Hash() {
  627. t.Fatalf("wrong tx hash %v, want %v", tx1.Hash(), testTx1.Hash())
  628. }
  629. // The sender address is cached in tx1, so no additional RPC should be required in
  630. // TransactionSender. Ensure the server is not asked by canceling the context here.
  631. canceledCtx, cancel := context.WithCancel(context.Background())
  632. cancel()
  633. sender1, err := ec.TransactionSender(canceledCtx, tx1, block2.Hash(), 0)
  634. if err != nil {
  635. t.Fatal(err)
  636. }
  637. if sender1 != testAddr {
  638. t.Fatal("wrong sender:", sender1)
  639. }
  640. // Now try to get the sender of testTx2, which was not fetched through RPC.
  641. // TransactionSender should query the server here.
  642. sender2, err := ec.TransactionSender(ctx, testTx2, block2.Hash(), 1)
  643. if err != nil {
  644. t.Fatal(err)
  645. }
  646. if sender2 != testAddr {
  647. t.Fatal("wrong sender:", sender2)
  648. }
  649. }
  650. func sendTransaction(ec *Client) error {
  651. chainID, err := ec.ChainID(context.Background())
  652. if err != nil {
  653. return err
  654. }
  655. nonce, err := ec.PendingNonceAt(context.Background(), testAddr)
  656. if err != nil {
  657. return err
  658. }
  659. signer := types.LatestSignerForChainID(chainID)
  660. tx, err := types.SignNewTx(testKey, signer, &types.LegacyTx{
  661. Nonce: nonce,
  662. To: &common.Address{2},
  663. Value: big.NewInt(1),
  664. Gas: 22000,
  665. GasPrice: big.NewInt(params.InitialBaseFee),
  666. })
  667. if err != nil {
  668. return err
  669. }
  670. return ec.SendTransaction(context.Background(), tx)
  671. }