diff --git a/cmd/devp2p/internal/ethtest/suite_test.go b/cmd/devp2p/internal/ethtest/suite_test.go
deleted file mode 100644
index c8479fd3aa..0000000000
--- a/cmd/devp2p/internal/ethtest/suite_test.go
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2021 The go-ethereum Authors
-// This file is part of go-ethereum.
-//
-// go-ethereum is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// go-ethereum is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with go-ethereum. If not, see .
-
-package ethtest // TOFIX
-
-import (
- crand "crypto/rand"
- "fmt"
- "os"
- "path"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/eth/catalyst"
- "github.com/ethereum/go-ethereum/eth/ethconfig"
- "github.com/ethereum/go-ethereum/internal/utesting"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
-)
-
-func makeJWTSecret() (string, [32]byte, error) {
- var secret [32]byte
- if _, err := crand.Read(secret[:]); err != nil {
- return "", secret, fmt.Errorf("failed to create jwt secret: %v", err)
- }
- jwtPath := path.Join(os.TempDir(), "jwt_secret")
- if err := os.WriteFile(jwtPath, []byte(hexutil.Encode(secret[:])), 0600); err != nil {
- return "", secret, fmt.Errorf("failed to prepare jwt secret file: %v", err)
- }
- return jwtPath, secret, nil
-}
-
-func TestEthSuite(t *testing.T) {
- jwtPath, secret, err := makeJWTSecret()
- if err != nil {
- t.Fatalf("could not make jwt secret: %v", err)
- }
- geth, err := runGeth("./testdata", jwtPath)
- if err != nil {
- t.Fatalf("could not run geth: %v", err)
- }
- defer geth.Close()
-
- suite, err := NewSuite(geth.Server().Self(), "./testdata", geth.HTTPAuthEndpoint(), common.Bytes2Hex(secret[:]))
- if err != nil {
- t.Fatalf("could not create new test suite: %v", err)
- }
- for _, test := range suite.EthTests() {
- t.Run(test.Name, func(t *testing.T) {
- if test.Slow && testing.Short() {
- t.Skipf("%s: skipping in -short mode", test.Name)
- }
- result := utesting.RunTests([]utesting.Test{{Name: test.Name, Fn: test.Fn}}, os.Stdout)
- if result[0].Failed {
- t.Fatal()
- }
- })
- }
-}
-
-func TestSnapSuite(t *testing.T) {
- jwtPath, secret, err := makeJWTSecret()
- if err != nil {
- t.Fatalf("could not make jwt secret: %v", err)
- }
- geth, err := runGeth("./testdata", jwtPath)
- if err != nil {
- t.Fatalf("could not run geth: %v", err)
- }
- defer geth.Close()
-
- suite, err := NewSuite(geth.Server().Self(), "./testdata", geth.HTTPAuthEndpoint(), common.Bytes2Hex(secret[:]))
- if err != nil {
- t.Fatalf("could not create new test suite: %v", err)
- }
- for _, test := range suite.SnapTests() {
- t.Run(test.Name, func(t *testing.T) {
- result := utesting.RunTests([]utesting.Test{{Name: test.Name, Fn: test.Fn}}, os.Stdout)
- if result[0].Failed {
- t.Fatal()
- }
- })
- }
-}
-
-// runGeth creates and starts a geth node
-func runGeth(dir string, jwtPath string) (*node.Node, error) {
- stack, err := node.New(&node.Config{
- AuthAddr: "127.0.0.1",
- AuthPort: 0,
- P2P: p2p.Config{
- ListenAddr: "127.0.0.1:0",
- NoDiscovery: true,
- MaxPeers: 10, // in case a test requires multiple connections, can be changed in the future
- MaxPeersPerIP: 10,
- NoDial: true,
- },
- JWTSecret: jwtPath,
- })
- if err != nil {
- return nil, err
- }
-
- err = setupGeth(stack, dir)
- if err != nil {
- stack.Close()
- return nil, err
- }
- if err = stack.Start(); err != nil {
- stack.Close()
- return nil, err
- }
- return stack, nil
-}
-
-func setupGeth(stack *node.Node, dir string) error {
- chain, err := NewChain(dir)
- if err != nil {
- return err
- }
- backend, err := eth.New(stack, ðconfig.Config{
- Genesis: &chain.genesis,
- NetworkId: chain.genesis.Config.ChainID.Uint64(), // 19763
- DatabaseCache: 10,
- TrieCleanCache: 10,
- TrieDirtyCache: 16,
- TrieTimeout: 60 * time.Minute,
- SnapshotCache: 10,
- TriesInMemory: 128,
- })
- if err != nil {
- return err
- }
- if err := catalyst.Register(stack, backend); err != nil {
- return fmt.Errorf("failed to register catalyst service: %v", err)
- }
- _, err = backend.BlockChain().InsertChain(chain.blocks[1:])
- return err
-}
diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go
deleted file mode 100644
index 8764f51fb6..0000000000
--- a/internal/ethapi/api_test.go
+++ /dev/null
@@ -1,2295 +0,0 @@
-// Copyright 2023 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package ethapi
-
-import (
- "bytes"
- "context"
- "crypto/ecdsa"
- "crypto/sha256"
- "encoding/json"
- "errors"
- "fmt"
- "math/big"
- "os"
- "path/filepath"
- "reflect"
- "testing"
- "time"
-
- "github.com/holiman/uint256"
- "github.com/stretchr/testify/require"
- "golang.org/x/exp/slices"
-
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/beacon"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/kzg4844"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/internal/blocktest"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-var emptyBlob = kzg4844.Blob{}
-var emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob)
-var emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit)
-var emptyBlobHash common.Hash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit)
-
-func testTransactionMarshal(t *testing.T, tests []txData, config *params.ChainConfig) {
- t.Parallel()
- var (
- signer = types.LatestSigner(config)
- key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
- )
-
- for i, tt := range tests {
- var tx2 types.Transaction
- tx, err := types.SignNewTx(key, signer, tt.Tx)
- if err != nil {
- t.Fatalf("test %d: signing failed: %v", i, err)
- }
- // Regular transaction
- if data, err := json.Marshal(tx); err != nil {
- t.Fatalf("test %d: marshalling failed; %v", i, err)
- } else if err = tx2.UnmarshalJSON(data); err != nil {
- t.Fatalf("test %d: sunmarshal failed: %v", i, err)
- } else if want, have := tx.Hash(), tx2.Hash(); want != have {
- t.Fatalf("test %d: stx changed, want %x have %x", i, want, have)
- }
-
- // rpcTransaction
- rpcTx := newRPCTransaction(tx, common.Hash{}, 0, 0, 0, nil, config)
- if data, err := json.Marshal(rpcTx); err != nil {
- t.Fatalf("test %d: marshalling failed; %v", i, err)
- } else if err = tx2.UnmarshalJSON(data); err != nil {
- t.Fatalf("test %d: unmarshal failed: %v", i, err)
- } else if want, have := tx.Hash(), tx2.Hash(); want != have {
- t.Fatalf("test %d: tx changed, want %x have %x", i, want, have)
- } else {
- want, have := tt.Want, string(data)
- require.JSONEqf(t, want, have, "test %d: rpc json not match, want %s have %s", i, want, have)
- }
- }
-}
-
-func TestTransaction_RoundTripRpcJSON(t *testing.T) {
- var (
- config = params.AllEthashProtocolChanges
- tests = allTransactionTypes(common.Address{0xde, 0xad}, config)
- )
- testTransactionMarshal(t, tests, config)
-}
-
-func TestTransactionBlobTx(t *testing.T) {
- config := *params.TestChainConfig
- config.ShanghaiTime = new(uint64)
- config.CancunTime = new(uint64)
- tests := allBlobTxs(common.Address{0xde, 0xad}, &config)
-
- testTransactionMarshal(t, tests, &config)
-}
-
-type txData struct {
- Tx types.TxData
- Want string
-}
-
-func allTransactionTypes(addr common.Address, config *params.ChainConfig) []txData {
- return []txData{
- {
- Tx: &types.LegacyTx{
- Nonce: 5,
- GasPrice: big.NewInt(6),
- Gas: 7,
- To: &addr,
- Value: big.NewInt(8),
- Data: []byte{0, 1, 2, 3, 4},
- V: big.NewInt(9),
- R: big.NewInt(10),
- S: big.NewInt(11),
- },
- Want: `{
- "blockHash": null,
- "blockNumber": null,
- "from": "0x71562b71999873db5b286df957af199ec94617f7",
- "gas": "0x7",
- "gasPrice": "0x6",
- "hash": "0x5f3240454cd09a5d8b1c5d651eefae7a339262875bcd2d0e6676f3d989967008",
- "input": "0x0001020304",
- "nonce": "0x5",
- "to": "0xdead000000000000000000000000000000000000",
- "transactionIndex": null,
- "value": "0x8",
- "type": "0x0",
- "chainId": "0x539",
- "v": "0xa96",
- "r": "0xbc85e96592b95f7160825d837abb407f009df9ebe8f1b9158a4b8dd093377f75",
- "s": "0x1b55ea3af5574c536967b039ba6999ef6c89cf22fc04bcb296e0e8b0b9b576f5"
- }`,
- }, {
- Tx: &types.LegacyTx{
- Nonce: 5,
- GasPrice: big.NewInt(6),
- Gas: 7,
- To: nil,
- Value: big.NewInt(8),
- Data: []byte{0, 1, 2, 3, 4},
- V: big.NewInt(32),
- R: big.NewInt(10),
- S: big.NewInt(11),
- },
- Want: `{
- "blockHash": null,
- "blockNumber": null,
- "from": "0x71562b71999873db5b286df957af199ec94617f7",
- "gas": "0x7",
- "gasPrice": "0x6",
- "hash": "0x806e97f9d712b6cb7e781122001380a2837531b0fc1e5f5d78174ad4cb699873",
- "input": "0x0001020304",
- "nonce": "0x5",
- "to": null,
- "transactionIndex": null,
- "value": "0x8",
- "type": "0x0",
- "chainId": "0x539",
- "v": "0xa96",
- "r": "0x9dc28b267b6ad4e4af6fe9289668f9305c2eb7a3241567860699e478af06835a",
- "s": "0xa0b51a071aa9bed2cd70aedea859779dff039e3630ea38497d95202e9b1fec7"
- }`,
- },
- {
- Tx: &types.AccessListTx{
- ChainID: config.ChainID,
- Nonce: 5,
- GasPrice: big.NewInt(6),
- Gas: 7,
- To: &addr,
- Value: big.NewInt(8),
- Data: []byte{0, 1, 2, 3, 4},
- AccessList: types.AccessList{
- types.AccessTuple{
- Address: common.Address{0x2},
- StorageKeys: []common.Hash{types.EmptyRootHash},
- },
- },
- V: big.NewInt(32),
- R: big.NewInt(10),
- S: big.NewInt(11),
- },
- Want: `{
- "blockHash": null,
- "blockNumber": null,
- "from": "0x71562b71999873db5b286df957af199ec94617f7",
- "gas": "0x7",
- "gasPrice": "0x6",
- "hash": "0x121347468ee5fe0a29f02b49b4ffd1c8342bc4255146bb686cd07117f79e7129",
- "input": "0x0001020304",
- "nonce": "0x5",
- "to": "0xdead000000000000000000000000000000000000",
- "transactionIndex": null,
- "value": "0x8",
- "type": "0x1",
- "accessList": [
- {
- "address": "0x0200000000000000000000000000000000000000",
- "storageKeys": [
- "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
- ]
- }
- ],
- "chainId": "0x539",
- "v": "0x0",
- "r": "0xf372ad499239ae11d91d34c559ffc5dab4daffc0069e03afcabdcdf231a0c16b",
- "s": "0x28573161d1f9472fa0fd4752533609e72f06414f7ab5588699a7141f65d2abf",
- "yParity": "0x0"
- }`,
- }, {
- Tx: &types.AccessListTx{
- ChainID: config.ChainID,
- Nonce: 5,
- GasPrice: big.NewInt(6),
- Gas: 7,
- To: nil,
- Value: big.NewInt(8),
- Data: []byte{0, 1, 2, 3, 4},
- AccessList: types.AccessList{
- types.AccessTuple{
- Address: common.Address{0x2},
- StorageKeys: []common.Hash{types.EmptyRootHash},
- },
- },
- V: big.NewInt(32),
- R: big.NewInt(10),
- S: big.NewInt(11),
- },
- Want: `{
- "blockHash": null,
- "blockNumber": null,
- "from": "0x71562b71999873db5b286df957af199ec94617f7",
- "gas": "0x7",
- "gasPrice": "0x6",
- "hash": "0x067c3baebede8027b0f828a9d933be545f7caaec623b00684ac0659726e2055b",
- "input": "0x0001020304",
- "nonce": "0x5",
- "to": null,
- "transactionIndex": null,
- "value": "0x8",
- "type": "0x1",
- "accessList": [
- {
- "address": "0x0200000000000000000000000000000000000000",
- "storageKeys": [
- "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
- ]
- }
- ],
- "chainId": "0x539",
- "v": "0x1",
- "r": "0x542981b5130d4613897fbab144796cb36d3cb3d7807d47d9c7f89ca7745b085c",
- "s": "0x7425b9dd6c5deaa42e4ede35d0c4570c4624f68c28d812c10d806ffdf86ce63",
- "yParity": "0x1"
- }`,
- }, {
- Tx: &types.DynamicFeeTx{
- ChainID: config.ChainID,
- Nonce: 5,
- GasTipCap: big.NewInt(6),
- GasFeeCap: big.NewInt(9),
- Gas: 7,
- To: &addr,
- Value: big.NewInt(8),
- Data: []byte{0, 1, 2, 3, 4},
- AccessList: types.AccessList{
- types.AccessTuple{
- Address: common.Address{0x2},
- StorageKeys: []common.Hash{types.EmptyRootHash},
- },
- },
- V: big.NewInt(32),
- R: big.NewInt(10),
- S: big.NewInt(11),
- },
- Want: `{
- "blockHash": null,
- "blockNumber": null,
- "from": "0x71562b71999873db5b286df957af199ec94617f7",
- "gas": "0x7",
- "gasPrice": "0x9",
- "maxFeePerGas": "0x9",
- "maxPriorityFeePerGas": "0x6",
- "hash": "0xb63e0b146b34c3e9cb7fbabb5b3c081254a7ded6f1b65324b5898cc0545d79ff",
- "input": "0x0001020304",
- "nonce": "0x5",
- "to": "0xdead000000000000000000000000000000000000",
- "transactionIndex": null,
- "value": "0x8",
- "type": "0x2",
- "accessList": [
- {
- "address": "0x0200000000000000000000000000000000000000",
- "storageKeys": [
- "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
- ]
- }
- ],
- "chainId": "0x539",
- "v": "0x1",
- "r": "0x3b167e05418a8932cd53d7578711fe1a76b9b96c48642402bb94978b7a107e80",
- "s": "0x22f98a332d15ea2cc80386c1ebaa31b0afebfa79ebc7d039a1e0074418301fef",
- "yParity": "0x1"
- }`,
- }, {
- Tx: &types.DynamicFeeTx{
- ChainID: config.ChainID,
- Nonce: 5,
- GasTipCap: big.NewInt(6),
- GasFeeCap: big.NewInt(9),
- Gas: 7,
- To: nil,
- Value: big.NewInt(8),
- Data: []byte{0, 1, 2, 3, 4},
- AccessList: types.AccessList{},
- V: big.NewInt(32),
- R: big.NewInt(10),
- S: big.NewInt(11),
- },
- Want: `{
- "blockHash": null,
- "blockNumber": null,
- "from": "0x71562b71999873db5b286df957af199ec94617f7",
- "gas": "0x7",
- "gasPrice": "0x9",
- "maxFeePerGas": "0x9",
- "maxPriorityFeePerGas": "0x6",
- "hash": "0xcbab17ee031a9d5b5a09dff909f0a28aedb9b295ac0635d8710d11c7b806ec68",
- "input": "0x0001020304",
- "nonce": "0x5",
- "to": null,
- "transactionIndex": null,
- "value": "0x8",
- "type": "0x2",
- "accessList": [],
- "chainId": "0x539",
- "v": "0x0",
- "r": "0x6446b8a682db7e619fc6b4f6d1f708f6a17351a41c7fbd63665f469bc78b41b9",
- "s": "0x7626abc15834f391a117c63450047309dbf84c5ce3e8e609b607062641e2de43",
- "yParity": "0x0"
- }`,
- },
- }
-}
-
-func allBlobTxs(addr common.Address, config *params.ChainConfig) []txData {
- return []txData{
- {
- Tx: &types.BlobTx{
- Nonce: 6,
- GasTipCap: uint256.NewInt(1),
- GasFeeCap: uint256.NewInt(5),
- Gas: 6,
- To: addr,
- BlobFeeCap: uint256.NewInt(1),
- BlobHashes: []common.Hash{{1}},
- Value: new(uint256.Int),
- V: uint256.NewInt(32),
- R: uint256.NewInt(10),
- S: uint256.NewInt(11),
- },
- Want: `{
- "blockHash": null,
- "blockNumber": null,
- "from": "0x71562b71999873db5b286df957af199ec94617f7",
- "gas": "0x6",
- "gasPrice": "0x5",
- "maxFeePerGas": "0x5",
- "maxPriorityFeePerGas": "0x1",
- "maxFeePerBlobGas": "0x1",
- "hash": "0x1f2b59a20e61efc615ad0cbe936379d6bbea6f938aafaf35eb1da05d8e7f46a3",
- "input": "0x",
- "nonce": "0x6",
- "to": "0xdead000000000000000000000000000000000000",
- "transactionIndex": null,
- "value": "0x0",
- "type": "0x3",
- "accessList": [],
- "chainId": "0x1",
- "blobVersionedHashes": [
- "0x0100000000000000000000000000000000000000000000000000000000000000"
- ],
- "v": "0x0",
- "r": "0x618be8908e0e5320f8f3b48042a079fe5a335ebd4ed1422a7d2207cd45d872bc",
- "s": "0x27b2bc6c80e849a8e8b764d4549d8c2efac3441e73cf37054eb0a9b9f8e89b27",
- "yParity": "0x0"
- }`,
- },
- }
-}
-
-func newTestAccountManager(t *testing.T) (*accounts.Manager, accounts.Account) {
- var (
- dir = t.TempDir()
- am = accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: true})
- b = keystore.NewKeyStore(dir, 2, 1)
- testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
- )
- acc, err := b.ImportECDSA(testKey, "")
- if err != nil {
- t.Fatalf("failed to create test account: %v", err)
- }
- if err := b.Unlock(acc, ""); err != nil {
- t.Fatalf("failed to unlock account: %v\n", err)
- }
- am.AddBackend(b)
- return am, acc
-}
-
-type testBackend struct {
- db ethdb.Database
- chain *core.BlockChain
- pending *types.Block
- accman *accounts.Manager
- acc accounts.Account
-}
-
-func newTestBackend(t *testing.T, n int, gspec *core.Genesis, engine consensus.Engine, generator func(i int, b *core.BlockGen)) *testBackend {
- var (
- cacheConfig = &core.CacheConfig{
- TrieCleanLimit: 256,
- TrieDirtyLimit: 256,
- TrieTimeLimit: 5 * time.Minute,
- SnapshotLimit: 0,
- TrieDirtyDisabled: true, // Archive mode
- }
- )
- accman, acc := newTestAccountManager(t)
- gspec.Alloc[acc.Address] = types.Account{Balance: big.NewInt(params.Ether)}
- // Generate blocks for testing
- db, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, n, generator)
- txlookupLimit := uint64(0)
- chain, err := core.NewBlockChain(db, cacheConfig, gspec, nil, engine, vm.Config{}, nil, &txlookupLimit)
- if err != nil {
- t.Fatalf("failed to create tester chain: %v", err)
- }
- if n, err := chain.InsertChain(blocks); err != nil {
- t.Fatalf("block %d: failed to insert into chain: %v", n, err)
- }
-
- backend := &testBackend{db: db, chain: chain, accman: accman, acc: acc}
- return backend
-}
-
-// nolint:unused
-func (b *testBackend) setPendingBlock(block *types.Block) {
- b.pending = block
-}
-
-func (b testBackend) SyncProgress() ethereum.SyncProgress { return ethereum.SyncProgress{} }
-func (b testBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
- return big.NewInt(0), nil
-}
-
-func (b testBackend) Chain() *core.BlockChain {
- return b.chain
-}
-
-func (b testBackend) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) {
- return nil, nil, nil, nil, nil
-}
-func (b testBackend) ChainDb() ethdb.Database { return b.db }
-func (b testBackend) AccountManager() *accounts.Manager { return b.accman }
-func (b testBackend) ExtRPCEnabled() bool { return false }
-func (b testBackend) RPCGasCap() uint64 { return 10000000 }
-func (b testBackend) RPCEVMTimeout() time.Duration { return time.Second }
-func (b testBackend) RPCTxFeeCap() float64 { return 0 }
-func (b testBackend) UnprotectedAllowed() bool { return false }
-func (b testBackend) SetHead(number uint64) {}
-func (b testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
- if number == rpc.LatestBlockNumber {
- return b.chain.CurrentBlock(), nil
- }
- if number == rpc.PendingBlockNumber && b.pending != nil {
- return b.pending.Header(), nil
- }
- return b.chain.GetHeaderByNumber(uint64(number)), nil
-}
-func (b testBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
- return b.chain.GetHeaderByHash(hash), nil
-}
-func (b testBackend) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error) {
- if blockNr, ok := blockNrOrHash.Number(); ok {
- return b.HeaderByNumber(ctx, blockNr)
- }
- if blockHash, ok := blockNrOrHash.Hash(); ok {
- return b.HeaderByHash(ctx, blockHash)
- }
- panic("unknown type rpc.BlockNumberOrHash")
-}
-func (b testBackend) CurrentHeader() *types.Header { return b.chain.CurrentBlock() }
-func (b testBackend) CurrentBlock() *types.Header { return b.chain.CurrentBlock() }
-func (b testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
- if number == rpc.LatestBlockNumber {
- head := b.chain.CurrentBlock()
- return b.chain.GetBlock(head.Hash(), head.Number.Uint64()), nil
- }
- if number == rpc.PendingBlockNumber {
- return b.pending, nil
- }
- return b.chain.GetBlockByNumber(uint64(number)), nil
-}
-func (b testBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
- return b.chain.GetBlockByHash(hash), nil
-}
-func (b testBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) {
- if blockNr, ok := blockNrOrHash.Number(); ok {
- return b.BlockByNumber(ctx, blockNr)
- }
- if blockHash, ok := blockNrOrHash.Hash(); ok {
- return b.BlockByHash(ctx, blockHash)
- }
- panic("unknown type rpc.BlockNumberOrHash")
-}
-func (b testBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) {
- return b.chain.GetBlock(hash, uint64(number.Int64())).Body(), nil
-}
-func (b testBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
- if number == rpc.PendingBlockNumber {
- panic("pending state not implemented")
- }
- header, err := b.HeaderByNumber(ctx, number)
- if err != nil {
- return nil, nil, err
- }
- if header == nil {
- return nil, nil, errors.New("header not found")
- }
- stateDb, err := b.chain.StateAt(header.Root)
- return stateDb, header, err
-}
-func (b testBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) {
- if blockNr, ok := blockNrOrHash.Number(); ok {
- return b.StateAndHeaderByNumber(ctx, blockNr)
- }
- panic("only implemented for number")
-}
-func (b testBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) { panic("implement me") }
-func (b testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
- header, err := b.HeaderByHash(ctx, hash)
- if header == nil || err != nil {
- return nil, err
- }
- receipts := rawdb.ReadReceipts(b.db, hash, header.Number.Uint64(), header.Time, b.chain.Config())
- return receipts, nil
-}
-
-func (b testBackend) GetBlobSidecars(ctx context.Context, hash common.Hash) (types.BlobSidecars, error) {
- header, err := b.HeaderByHash(ctx, hash)
- if header == nil || err != nil {
- return nil, err
- }
- blobSidecars := rawdb.ReadBlobSidecars(b.db, hash, header.Number.Uint64())
- return blobSidecars, nil
-}
-func (b testBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int {
- if b.pending != nil && hash == b.pending.Hash() {
- return nil
- }
- return big.NewInt(1)
-}
-func (b testBackend) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockContext *vm.BlockContext) *vm.EVM {
- if vmConfig == nil {
- vmConfig = b.chain.GetVMConfig()
- }
- txContext := core.NewEVMTxContext(msg)
- context := core.NewEVMBlockContext(header, b.chain, nil)
- if blockContext != nil {
- context = *blockContext
- }
- return vm.NewEVM(context, txContext, state, b.chain.Config(), *vmConfig)
-}
-func (b testBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
- panic("implement me")
-}
-func (b testBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription {
- panic("implement me")
-}
-func (b testBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription {
- panic("implement me")
-}
-func (b testBackend) SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription {
- panic("implement me")
-}
-func (b testBackend) SubscribeNewVoteEvent(ch chan<- core.NewVoteEvent) event.Subscription {
- panic("implement me")
-}
-func (b testBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
- panic("implement me")
-}
-func (b testBackend) GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error) {
- tx, blockHash, blockNumber, index := rawdb.ReadTransaction(b.db, txHash)
- return true, tx, blockHash, blockNumber, index, nil
-}
-func (b testBackend) GetPoolTransactions() (types.Transactions, error) { panic("implement me") }
-func (b testBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction { panic("implement me") }
-func (b testBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
- return 0, nil
-}
-func (b testBackend) Stats() (pending int, queued int) { panic("implement me") }
-func (b testBackend) TxPoolContent() (map[common.Address][]*types.Transaction, map[common.Address][]*types.Transaction) {
- panic("implement me")
-}
-func (b testBackend) TxPoolContentFrom(addr common.Address) ([]*types.Transaction, []*types.Transaction) {
- panic("implement me")
-}
-func (b testBackend) SubscribeNewTxsEvent(events chan<- core.NewTxsEvent) event.Subscription {
- panic("implement me")
-}
-func (b testBackend) ChainConfig() *params.ChainConfig { return b.chain.Config() }
-func (b testBackend) Engine() consensus.Engine { return b.chain.Engine() }
-func (b testBackend) GetLogs(ctx context.Context, blockHash common.Hash, number uint64) ([][]*types.Log, error) {
- panic("implement me")
-}
-func (b testBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
- panic("implement me")
-}
-func (b testBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
- panic("implement me")
-}
-func (b testBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription {
- panic("implement me")
-}
-func (b testBackend) BloomStatus() (uint64, uint64) { panic("implement me") }
-func (b testBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) {
- panic("implement me")
-}
-
-func (b *testBackend) MevRunning() bool { return false }
-func (b *testBackend) HasBuilder(builder common.Address) bool { return false }
-func (b *testBackend) MevParams() *types.MevParams {
- return &types.MevParams{}
-}
-func (b *testBackend) StartMev() {}
-func (b *testBackend) StopMev() {}
-func (b *testBackend) AddBuilder(builder common.Address, builderUrl string) error { return nil }
-func (b *testBackend) RemoveBuilder(builder common.Address) error { return nil }
-func (b *testBackend) SendBid(ctx context.Context, bid *types.BidArgs) (common.Hash, error) {
- panic("implement me")
-}
-func (b *testBackend) MinerInTurn() bool { return false }
-func (b *testBackend) BestBidGasFee(parentHash common.Hash) *big.Int {
- //TODO implement me
- panic("implement me")
-}
-
-func TestEstimateGas(t *testing.T) {
- t.Parallel()
- // Initialize test accounts
- var (
- accounts = newAccounts(2)
- genesis = &core.Genesis{
- Config: params.MergedTestChainConfig,
- Alloc: types.GenesisAlloc{
- accounts[0].addr: {Balance: big.NewInt(params.Ether)},
- accounts[1].addr: {Balance: big.NewInt(params.Ether)},
- },
- }
- genBlocks = 10
- signer = types.HomesteadSigner{}
- randomAccounts = newAccounts(2)
- )
- api := NewBlockChainAPI(newTestBackend(t, genBlocks, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
- // Transfer from account[0] to account[1]
- // value: 1000 wei
- // fee: 0 wei
- tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: &accounts[1].addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), Data: nil}), signer, accounts[0].key)
- b.AddTx(tx)
- b.SetPoS()
- }))
- var testSuite = []struct {
- blockNumber rpc.BlockNumber
- call TransactionArgs
- overrides StateOverride
- expectErr error
- want uint64
- }{
- // simple transfer on latest block
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{
- From: &accounts[0].addr,
- To: &accounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- expectErr: nil,
- want: 21000,
- },
- // simple transfer with insufficient funds on latest block
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{
- From: &randomAccounts[0].addr,
- To: &accounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- expectErr: core.ErrInsufficientFunds,
- want: 21000,
- },
- // empty create
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{},
- expectErr: nil,
- want: 53000,
- },
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{},
- overrides: StateOverride{
- randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))},
- },
- expectErr: nil,
- want: 53000,
- },
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{
- From: &randomAccounts[0].addr,
- To: &randomAccounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- overrides: StateOverride{
- randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(big.NewInt(0))},
- },
- expectErr: core.ErrInsufficientFunds,
- },
- // Test for a bug where the gas price was set to zero but the basefee non-zero
- //
- // contract BasefeeChecker {
- // constructor() {
- // require(tx.gasprice >= block.basefee);
- // if (tx.gasprice > 0) {
- // require(block.basefee > 0);
- // }
- // }
- //}
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{
- From: &accounts[0].addr,
- Input: hex2Bytes("6080604052348015600f57600080fd5b50483a1015601c57600080fd5b60003a111560315760004811603057600080fd5b5b603f80603e6000396000f3fe6080604052600080fdfea264697066735822122060729c2cee02b10748fae5200f1c9da4661963354973d9154c13a8e9ce9dee1564736f6c63430008130033"),
- GasPrice: (*hexutil.Big)(big.NewInt(1_000_000_000)), // Legacy as pricing
- },
- expectErr: nil,
- want: 67617,
- },
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{
- From: &accounts[0].addr,
- Input: hex2Bytes("6080604052348015600f57600080fd5b50483a1015601c57600080fd5b60003a111560315760004811603057600080fd5b5b603f80603e6000396000f3fe6080604052600080fdfea264697066735822122060729c2cee02b10748fae5200f1c9da4661963354973d9154c13a8e9ce9dee1564736f6c63430008130033"),
- MaxFeePerGas: (*hexutil.Big)(big.NewInt(1_000_000_000)), // 1559 gas pricing
- },
- expectErr: nil,
- want: 67617,
- },
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{
- From: &accounts[0].addr,
- Input: hex2Bytes("6080604052348015600f57600080fd5b50483a1015601c57600080fd5b60003a111560315760004811603057600080fd5b5b603f80603e6000396000f3fe6080604052600080fdfea264697066735822122060729c2cee02b10748fae5200f1c9da4661963354973d9154c13a8e9ce9dee1564736f6c63430008130033"),
- GasPrice: nil, // No legacy gas pricing
- MaxFeePerGas: nil, // No 1559 gas pricing
- },
- expectErr: nil,
- want: 67595,
- },
- // Blobs should have no effect on gas estimate
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{
- From: &accounts[0].addr,
- To: &accounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1)),
- BlobHashes: []common.Hash{common.Hash{0x01, 0x22}},
- BlobFeeCap: (*hexutil.Big)(big.NewInt(1)),
- },
- want: 21000,
- },
- }
- for i, tc := range testSuite {
- result, err := api.EstimateGas(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides)
- if tc.expectErr != nil {
- if err == nil {
- t.Errorf("test %d: want error %v, have nothing", i, tc.expectErr)
- continue
- }
- if !errors.Is(err, tc.expectErr) {
- t.Errorf("test %d: error mismatch, want %v, have %v", i, tc.expectErr, err)
- }
- continue
- }
- if err != nil {
- t.Errorf("test %d: want no error, have %v", i, err)
- continue
- }
- if float64(result) > float64(tc.want)*(1+estimateGasErrorRatio) {
- t.Errorf("test %d, result mismatch, have\n%v\n, want\n%v\n", i, uint64(result), tc.want)
- }
- }
-}
-
-func TestCall(t *testing.T) {
- t.Parallel()
- // Initialize test accounts
- var (
- accounts = newAccounts(3)
- genesis = &core.Genesis{
- Config: params.MergedTestChainConfig,
- Alloc: types.GenesisAlloc{
- accounts[0].addr: {Balance: big.NewInt(params.Ether)},
- accounts[1].addr: {Balance: big.NewInt(params.Ether)},
- accounts[2].addr: {Balance: big.NewInt(params.Ether)},
- },
- }
- genBlocks = 10
- signer = types.HomesteadSigner{}
- )
- api := NewBlockChainAPI(newTestBackend(t, genBlocks, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
- // Transfer from account[0] to account[1]
- // value: 1000 wei
- // fee: 0 wei
- tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: &accounts[1].addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), Data: nil}), signer, accounts[0].key)
- b.AddTx(tx)
- b.SetPoS()
- }))
- randomAccounts := newAccounts(3)
- var testSuite = []struct {
- blockNumber rpc.BlockNumber
- overrides StateOverride
- call TransactionArgs
- blockOverrides BlockOverrides
- expectErr error
- want string
- }{
- // transfer on genesis
- {
- blockNumber: rpc.BlockNumber(0),
- call: TransactionArgs{
- From: &accounts[0].addr,
- To: &accounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- expectErr: nil,
- want: "0x",
- },
- // transfer on the head
- {
- blockNumber: rpc.BlockNumber(genBlocks),
- call: TransactionArgs{
- From: &accounts[0].addr,
- To: &accounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- expectErr: nil,
- want: "0x",
- },
- // transfer on a non-existent block, error expects
- {
- blockNumber: rpc.BlockNumber(genBlocks + 1),
- call: TransactionArgs{
- From: &accounts[0].addr,
- To: &accounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- expectErr: errors.New("header not found"),
- },
- // transfer on the latest block
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{
- From: &accounts[0].addr,
- To: &accounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- expectErr: nil,
- want: "0x",
- },
- // Call which can only succeed if state is state overridden
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{
- From: &randomAccounts[0].addr,
- To: &randomAccounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- overrides: StateOverride{
- randomAccounts[0].addr: OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))},
- },
- want: "0x",
- },
- // Invalid call without state overriding
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{
- From: &randomAccounts[0].addr,
- To: &randomAccounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- expectErr: core.ErrInsufficientFunds,
- },
- // Successful simple contract call
- //
- // // SPDX-License-Identifier: GPL-3.0
- //
- // pragma solidity >=0.7.0 <0.8.0;
- //
- // /**
- // * @title Storage
- // * @dev Store & retrieve value in a variable
- // */
- // contract Storage {
- // uint256 public number;
- // constructor() {
- // number = block.number;
- // }
- // }
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{
- From: &randomAccounts[0].addr,
- To: &randomAccounts[2].addr,
- Data: hex2Bytes("8381f58a"), // call number()
- },
- overrides: StateOverride{
- randomAccounts[2].addr: OverrideAccount{
- Code: hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c80638381f58a14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000548156fea2646970667358221220eab35ffa6ab2adfe380772a48b8ba78e82a1b820a18fcb6f59aa4efb20a5f60064736f6c63430007040033"),
- StateDiff: &map[common.Hash]common.Hash{{}: common.BigToHash(big.NewInt(123))},
- },
- },
- want: "0x000000000000000000000000000000000000000000000000000000000000007b",
- },
- // Block overrides should work
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{
- From: &accounts[1].addr,
- Input: &hexutil.Bytes{
- 0x43, // NUMBER
- 0x60, 0x00, 0x52, // MSTORE offset 0
- 0x60, 0x20, 0x60, 0x00, 0xf3,
- },
- },
- blockOverrides: BlockOverrides{Number: (*hexutil.Big)(big.NewInt(11))},
- want: "0x000000000000000000000000000000000000000000000000000000000000000b",
- },
- // Invalid blob tx
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{
- From: &accounts[1].addr,
- Input: &hexutil.Bytes{0x00},
- BlobHashes: []common.Hash{},
- },
- expectErr: core.ErrBlobTxCreate,
- },
- // BLOBHASH opcode
- {
- blockNumber: rpc.LatestBlockNumber,
- call: TransactionArgs{
- From: &accounts[1].addr,
- To: &randomAccounts[2].addr,
- BlobHashes: []common.Hash{common.Hash{0x01, 0x22}},
- BlobFeeCap: (*hexutil.Big)(big.NewInt(1)),
- },
- overrides: StateOverride{
- randomAccounts[2].addr: {
- Code: hex2Bytes("60004960005260206000f3"),
- },
- },
- want: "0x0122000000000000000000000000000000000000000000000000000000000000",
- },
- }
- for i, tc := range testSuite {
- result, err := api.Call(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides, &tc.blockOverrides)
- if tc.expectErr != nil {
- if err == nil {
- t.Errorf("test %d: want error %v, have nothing", i, tc.expectErr)
- continue
- }
- if !errors.Is(err, tc.expectErr) {
- // Second try
- if !reflect.DeepEqual(err, tc.expectErr) {
- t.Errorf("test %d: error mismatch, want %v, have %v", i, tc.expectErr, err)
- }
- }
- continue
- }
- if err != nil {
- t.Errorf("test %d: want no error, have %v", i, err)
- continue
- }
- if !reflect.DeepEqual(result.String(), tc.want) {
- t.Errorf("test %d, result mismatch, have\n%v\n, want\n%v\n", i, result.String(), tc.want)
- }
- }
-}
-
-func TestSignTransaction(t *testing.T) {
- t.Parallel()
- // Initialize test accounts
- var (
- key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
- to = crypto.PubkeyToAddress(key.PublicKey)
- genesis = &core.Genesis{
- Config: params.MergedTestChainConfig,
- Alloc: types.GenesisAlloc{},
- }
- )
- b := newTestBackend(t, 1, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
- b.SetPoS()
- })
- api := NewTransactionAPI(b, nil)
- res, err := api.FillTransaction(context.Background(), TransactionArgs{
- From: &b.acc.Address,
- To: &to,
- Value: (*hexutil.Big)(big.NewInt(1)),
- })
- if err != nil {
- t.Fatalf("failed to fill tx defaults: %v\n", err)
- }
-
- res, err = api.SignTransaction(context.Background(), argsFromTransaction(res.Tx, b.acc.Address))
- if err != nil {
- t.Fatalf("failed to sign tx: %v\n", err)
- }
- tx, err := json.Marshal(res.Tx)
- if err != nil {
- t.Fatal(err)
- }
- expect := `{"type":"0x2","chainId":"0x1","nonce":"0x0","to":"0x703c4b2bd70c169f5717101caee543299fc946c7","gas":"0x5208","gasPrice":null,"maxPriorityFeePerGas":"0x0","maxFeePerGas":"0x684ee180","value":"0x1","input":"0x","accessList":[],"v":"0x0","r":"0x8fabeb142d585dd9247f459f7e6fe77e2520c88d50ba5d220da1533cea8b34e1","s":"0x582dd68b21aef36ba23f34e49607329c20d981d30404daf749077f5606785ce7","yParity":"0x0","hash":"0x93927839207cfbec395da84b8a2bc38b7b65d2cb2819e9fef1f091f5b1d4cc8f"}`
- if !bytes.Equal(tx, []byte(expect)) {
- t.Errorf("result mismatch. Have:\n%s\nWant:\n%s\n", tx, expect)
- }
-}
-
-func TestSignBlobTransaction(t *testing.T) {
- t.Parallel()
- // Initialize test accounts
- var (
- key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
- to = crypto.PubkeyToAddress(key.PublicKey)
- genesis = &core.Genesis{
- Config: params.MergedTestChainConfig,
- Alloc: types.GenesisAlloc{},
- }
- )
- b := newTestBackend(t, 1, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
- b.SetPoS()
- })
- api := NewTransactionAPI(b, nil)
- res, err := api.FillTransaction(context.Background(), TransactionArgs{
- From: &b.acc.Address,
- To: &to,
- Value: (*hexutil.Big)(big.NewInt(1)),
- BlobHashes: []common.Hash{{0x01, 0x22}},
- })
- if err != nil {
- t.Fatalf("failed to fill tx defaults: %v\n", err)
- }
-
- _, err = api.SignTransaction(context.Background(), argsFromTransaction(res.Tx, b.acc.Address))
- if err == nil {
- t.Fatalf("should fail on blob transaction")
- }
- if !errors.Is(err, errBlobTxNotSupported) {
- t.Errorf("error mismatch. Have: %v, want: %v", err, errBlobTxNotSupported)
- }
-}
-
-func TestSendBlobTransaction(t *testing.T) {
- t.Parallel()
- // Initialize test accounts
- var (
- key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
- to = crypto.PubkeyToAddress(key.PublicKey)
- genesis = &core.Genesis{
- Config: params.MergedTestChainConfig,
- Alloc: types.GenesisAlloc{},
- }
- )
- b := newTestBackend(t, 1, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
- b.SetPoS()
- })
- api := NewTransactionAPI(b, nil)
- res, err := api.FillTransaction(context.Background(), TransactionArgs{
- From: &b.acc.Address,
- To: &to,
- Value: (*hexutil.Big)(big.NewInt(1)),
- BlobHashes: []common.Hash{common.Hash{0x01, 0x22}},
- })
- if err != nil {
- t.Fatalf("failed to fill tx defaults: %v\n", err)
- }
-
- _, err = api.SendTransaction(context.Background(), argsFromTransaction(res.Tx, b.acc.Address))
- if err == nil {
- t.Errorf("sending tx should have failed")
- } else if !errors.Is(err, errBlobTxNotSupported) {
- t.Errorf("unexpected error. Have %v, want %v\n", err, errBlobTxNotSupported)
- }
-}
-
-func TestFillBlobTransaction(t *testing.T) {
- t.Parallel()
- // Initialize test accounts
- var (
- key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
- to = crypto.PubkeyToAddress(key.PublicKey)
- genesis = &core.Genesis{
- Config: params.MergedTestChainConfig,
- Alloc: types.GenesisAlloc{},
- }
- )
- b := newTestBackend(t, 1, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
- b.SetPoS()
- })
- api := NewTransactionAPI(b, nil)
- type result struct {
- Hashes []common.Hash
- Sidecar *types.BlobTxSidecar
- }
- suite := []struct {
- name string
- args TransactionArgs
- err string
- want *result
- }{
- {
- name: "TestInvalidParamsCombination1",
- args: TransactionArgs{
- From: &b.acc.Address,
- To: &to,
- Value: (*hexutil.Big)(big.NewInt(1)),
- Blobs: []kzg4844.Blob{{}},
- Proofs: []kzg4844.Proof{{}},
- },
- err: `blob proofs provided while commitments were not`,
- },
- {
- name: "TestInvalidParamsCombination2",
- args: TransactionArgs{
- From: &b.acc.Address,
- To: &to,
- Value: (*hexutil.Big)(big.NewInt(1)),
- Blobs: []kzg4844.Blob{{}},
- Commitments: []kzg4844.Commitment{{}},
- },
- err: `blob commitments provided while proofs were not`,
- },
- {
- name: "TestInvalidParamsCount1",
- args: TransactionArgs{
- From: &b.acc.Address,
- To: &to,
- Value: (*hexutil.Big)(big.NewInt(1)),
- Blobs: []kzg4844.Blob{{}},
- Commitments: []kzg4844.Commitment{{}, {}},
- Proofs: []kzg4844.Proof{{}, {}},
- },
- err: `number of blobs and commitments mismatch (have=2, want=1)`,
- },
- {
- name: "TestInvalidParamsCount2",
- args: TransactionArgs{
- From: &b.acc.Address,
- To: &to,
- Value: (*hexutil.Big)(big.NewInt(1)),
- Blobs: []kzg4844.Blob{{}, {}},
- Commitments: []kzg4844.Commitment{{}, {}},
- Proofs: []kzg4844.Proof{{}},
- },
- err: `number of blobs and proofs mismatch (have=1, want=2)`,
- },
- {
- name: "TestInvalidProofVerification",
- args: TransactionArgs{
- From: &b.acc.Address,
- To: &to,
- Value: (*hexutil.Big)(big.NewInt(1)),
- Blobs: []kzg4844.Blob{{}, {}},
- Commitments: []kzg4844.Commitment{{}, {}},
- Proofs: []kzg4844.Proof{{}, {}},
- },
- err: `failed to verify blob proof: short buffer`,
- },
- {
- name: "TestGenerateBlobHashes",
- args: TransactionArgs{
- From: &b.acc.Address,
- To: &to,
- Value: (*hexutil.Big)(big.NewInt(1)),
- Blobs: []kzg4844.Blob{emptyBlob},
- Commitments: []kzg4844.Commitment{emptyBlobCommit},
- Proofs: []kzg4844.Proof{emptyBlobProof},
- },
- want: &result{
- Hashes: []common.Hash{emptyBlobHash},
- Sidecar: &types.BlobTxSidecar{
- Blobs: []kzg4844.Blob{emptyBlob},
- Commitments: []kzg4844.Commitment{emptyBlobCommit},
- Proofs: []kzg4844.Proof{emptyBlobProof},
- },
- },
- },
- {
- name: "TestValidBlobHashes",
- args: TransactionArgs{
- From: &b.acc.Address,
- To: &to,
- Value: (*hexutil.Big)(big.NewInt(1)),
- BlobHashes: []common.Hash{emptyBlobHash},
- Blobs: []kzg4844.Blob{emptyBlob},
- Commitments: []kzg4844.Commitment{emptyBlobCommit},
- Proofs: []kzg4844.Proof{emptyBlobProof},
- },
- want: &result{
- Hashes: []common.Hash{emptyBlobHash},
- Sidecar: &types.BlobTxSidecar{
- Blobs: []kzg4844.Blob{emptyBlob},
- Commitments: []kzg4844.Commitment{emptyBlobCommit},
- Proofs: []kzg4844.Proof{emptyBlobProof},
- },
- },
- },
- {
- name: "TestInvalidBlobHashes",
- args: TransactionArgs{
- From: &b.acc.Address,
- To: &to,
- Value: (*hexutil.Big)(big.NewInt(1)),
- BlobHashes: []common.Hash{{0x01, 0x22}},
- Blobs: []kzg4844.Blob{emptyBlob},
- Commitments: []kzg4844.Commitment{emptyBlobCommit},
- Proofs: []kzg4844.Proof{emptyBlobProof},
- },
- err: fmt.Sprintf("blob hash verification failed (have=%s, want=%s)", common.Hash{0x01, 0x22}, emptyBlobHash),
- },
- {
- name: "TestGenerateBlobProofs",
- args: TransactionArgs{
- From: &b.acc.Address,
- To: &to,
- Value: (*hexutil.Big)(big.NewInt(1)),
- Blobs: []kzg4844.Blob{emptyBlob},
- },
- want: &result{
- Hashes: []common.Hash{emptyBlobHash},
- Sidecar: &types.BlobTxSidecar{
- Blobs: []kzg4844.Blob{emptyBlob},
- Commitments: []kzg4844.Commitment{emptyBlobCommit},
- Proofs: []kzg4844.Proof{emptyBlobProof},
- },
- },
- },
- }
- for _, tc := range suite {
- t.Run(tc.name, func(t *testing.T) {
- res, err := api.FillTransaction(context.Background(), tc.args)
- if len(tc.err) > 0 {
- if err == nil {
- t.Fatalf("missing error. want: %s", tc.err)
- } else if err != nil && err.Error() != tc.err {
- t.Fatalf("error mismatch. want: %s, have: %s", tc.err, err.Error())
- }
- return
- }
- if err != nil && len(tc.err) == 0 {
- t.Fatalf("expected no error. have: %s", err)
- }
- if res == nil {
- t.Fatal("result missing")
- }
- want, err := json.Marshal(tc.want)
- if err != nil {
- t.Fatalf("failed to encode expected: %v", err)
- }
- have, err := json.Marshal(result{Hashes: res.Tx.BlobHashes(), Sidecar: res.Tx.BlobTxSidecar()})
- if err != nil {
- t.Fatalf("failed to encode computed sidecar: %v", err)
- }
- if !bytes.Equal(have, want) {
- t.Errorf("blob sidecar mismatch. Have: %s, want: %s", have, want)
- }
- })
- }
-}
-
-func argsFromTransaction(tx *types.Transaction, from common.Address) TransactionArgs {
- var (
- gas = tx.Gas()
- nonce = tx.Nonce()
- input = tx.Data()
- )
- return TransactionArgs{
- From: &from,
- To: tx.To(),
- Gas: (*hexutil.Uint64)(&gas),
- MaxFeePerGas: (*hexutil.Big)(tx.GasFeeCap()),
- MaxPriorityFeePerGas: (*hexutil.Big)(tx.GasTipCap()),
- Value: (*hexutil.Big)(tx.Value()),
- Nonce: (*hexutil.Uint64)(&nonce),
- Input: (*hexutil.Bytes)(&input),
- ChainID: (*hexutil.Big)(tx.ChainId()),
- // TODO: impl accessList conversion
- //AccessList: tx.AccessList(),
- BlobFeeCap: (*hexutil.Big)(tx.BlobGasFeeCap()),
- BlobHashes: tx.BlobHashes(),
- }
-}
-
-type account struct {
- key *ecdsa.PrivateKey
- addr common.Address
-}
-
-func newAccounts(n int) (accounts []account) {
- for i := 0; i < n; i++ {
- key, _ := crypto.GenerateKey()
- addr := crypto.PubkeyToAddress(key.PublicKey)
- accounts = append(accounts, account{key: key, addr: addr})
- }
- slices.SortFunc(accounts, func(a, b account) int { return a.addr.Cmp(b.addr) })
- return accounts
-}
-
-func newRPCBalance(balance *big.Int) **hexutil.Big {
- rpcBalance := (*hexutil.Big)(balance)
- return &rpcBalance
-}
-
-func hex2Bytes(str string) *hexutil.Bytes {
- rpcBytes := hexutil.Bytes(common.Hex2Bytes(str))
- return &rpcBytes
-}
-
-func TestRPCMarshalBlock(t *testing.T) {
- t.Parallel()
- var (
- txs []*types.Transaction
- to = common.BytesToAddress([]byte{0x11})
- )
- for i := uint64(1); i <= 4; i++ {
- var tx *types.Transaction
- if i%2 == 0 {
- tx = types.NewTx(&types.LegacyTx{
- Nonce: i,
- GasPrice: big.NewInt(11111),
- Gas: 1111,
- To: &to,
- Value: big.NewInt(111),
- Data: []byte{0x11, 0x11, 0x11},
- })
- } else {
- tx = types.NewTx(&types.AccessListTx{
- ChainID: big.NewInt(1337),
- Nonce: i,
- GasPrice: big.NewInt(11111),
- Gas: 1111,
- To: &to,
- Value: big.NewInt(111),
- Data: []byte{0x11, 0x11, 0x11},
- })
- }
- txs = append(txs, tx)
- }
- block := types.NewBlock(&types.Header{Number: big.NewInt(100)}, txs, nil, nil, blocktest.NewHasher())
-
- var testSuite = []struct {
- inclTx bool
- fullTx bool
- want string
- }{
- // without txs
- {
- inclTx: false,
- fullTx: false,
- want: `{
- "difficulty": "0x0",
- "extraData": "0x",
- "gasLimit": "0x0",
- "gasUsed": "0x0",
- "hash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
- "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "miner": "0x0000000000000000000000000000000000000000",
- "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "nonce": "0x0000000000000000",
- "number": "0x64",
- "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
- "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
- "size": "0x296",
- "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "timestamp": "0x0",
- "transactionsRoot": "0x661a9febcfa8f1890af549b874faf9fa274aede26ef489d9db0b25daa569450e",
- "uncles": []
- }`,
- },
- // only tx hashes
- {
- inclTx: true,
- fullTx: false,
- want: `{
- "difficulty": "0x0",
- "extraData": "0x",
- "gasLimit": "0x0",
- "gasUsed": "0x0",
- "hash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
- "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "miner": "0x0000000000000000000000000000000000000000",
- "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "nonce": "0x0000000000000000",
- "number": "0x64",
- "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
- "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
- "size": "0x296",
- "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "timestamp": "0x0",
- "transactions": [
- "0x7d39df979e34172322c64983a9ad48302c2b889e55bda35324afecf043a77605",
- "0x9bba4c34e57c875ff57ac8d172805a26ae912006985395dc1bdf8f44140a7bf4",
- "0x98909ea1ff040da6be56bc4231d484de1414b3c1dac372d69293a4beb9032cb5",
- "0x12e1f81207b40c3bdcc13c0ee18f5f86af6d31754d57a0ea1b0d4cfef21abef1"
- ],
- "transactionsRoot": "0x661a9febcfa8f1890af549b874faf9fa274aede26ef489d9db0b25daa569450e",
- "uncles": []
- }`,
- },
- // full tx details
- {
- inclTx: true,
- fullTx: true,
- want: `{
- "difficulty": "0x0",
- "extraData": "0x",
- "gasLimit": "0x0",
- "gasUsed": "0x0",
- "hash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
- "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "miner": "0x0000000000000000000000000000000000000000",
- "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "nonce": "0x0000000000000000",
- "number": "0x64",
- "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
- "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
- "size": "0x296",
- "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "timestamp": "0x0",
- "transactions": [
- {
- "blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
- "blockNumber": "0x64",
- "from": "0x0000000000000000000000000000000000000000",
- "gas": "0x457",
- "gasPrice": "0x2b67",
- "hash": "0x7d39df979e34172322c64983a9ad48302c2b889e55bda35324afecf043a77605",
- "input": "0x111111",
- "nonce": "0x1",
- "to": "0x0000000000000000000000000000000000000011",
- "transactionIndex": "0x0",
- "value": "0x6f",
- "type": "0x1",
- "accessList": [],
- "chainId": "0x539",
- "v": "0x0",
- "r": "0x0",
- "s": "0x0",
- "yParity": "0x0"
- },
- {
- "blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
- "blockNumber": "0x64",
- "from": "0x0000000000000000000000000000000000000000",
- "gas": "0x457",
- "gasPrice": "0x2b67",
- "hash": "0x9bba4c34e57c875ff57ac8d172805a26ae912006985395dc1bdf8f44140a7bf4",
- "input": "0x111111",
- "nonce": "0x2",
- "to": "0x0000000000000000000000000000000000000011",
- "transactionIndex": "0x1",
- "value": "0x6f",
- "type": "0x0",
- "chainId": "0x7fffffffffffffee",
- "v": "0x0",
- "r": "0x0",
- "s": "0x0"
- },
- {
- "blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
- "blockNumber": "0x64",
- "from": "0x0000000000000000000000000000000000000000",
- "gas": "0x457",
- "gasPrice": "0x2b67",
- "hash": "0x98909ea1ff040da6be56bc4231d484de1414b3c1dac372d69293a4beb9032cb5",
- "input": "0x111111",
- "nonce": "0x3",
- "to": "0x0000000000000000000000000000000000000011",
- "transactionIndex": "0x2",
- "value": "0x6f",
- "type": "0x1",
- "accessList": [],
- "chainId": "0x539",
- "v": "0x0",
- "r": "0x0",
- "s": "0x0",
- "yParity": "0x0"
- },
- {
- "blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee",
- "blockNumber": "0x64",
- "from": "0x0000000000000000000000000000000000000000",
- "gas": "0x457",
- "gasPrice": "0x2b67",
- "hash": "0x12e1f81207b40c3bdcc13c0ee18f5f86af6d31754d57a0ea1b0d4cfef21abef1",
- "input": "0x111111",
- "nonce": "0x4",
- "to": "0x0000000000000000000000000000000000000011",
- "transactionIndex": "0x3",
- "value": "0x6f",
- "type": "0x0",
- "chainId": "0x7fffffffffffffee",
- "v": "0x0",
- "r": "0x0",
- "s": "0x0"
- }
- ],
- "transactionsRoot": "0x661a9febcfa8f1890af549b874faf9fa274aede26ef489d9db0b25daa569450e",
- "uncles": []
- }`,
- },
- }
-
- for i, tc := range testSuite {
- resp := RPCMarshalBlock(block, tc.inclTx, tc.fullTx, params.MainnetChainConfig)
- out, err := json.Marshal(resp)
- if err != nil {
- t.Errorf("test %d: json marshal error: %v", i, err)
- continue
- }
- require.JSONEqf(t, tc.want, string(out), "test %d", i)
- }
-}
-
-func TestRPCGetBlockOrHeader(t *testing.T) {
- t.Parallel()
-
- // Initialize test accounts
- var (
- acc1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
- acc2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
- acc1Addr = crypto.PubkeyToAddress(acc1Key.PublicKey)
- acc2Addr = crypto.PubkeyToAddress(acc2Key.PublicKey)
- genesis = &core.Genesis{
- Config: params.TestChainConfig,
- Alloc: types.GenesisAlloc{
- acc1Addr: {Balance: big.NewInt(params.Ether)},
- acc2Addr: {Balance: big.NewInt(params.Ether)},
- },
- }
- genBlocks = 10
- signer = types.HomesteadSigner{}
- tx = types.NewTx(&types.LegacyTx{
- Nonce: 11,
- GasPrice: big.NewInt(11111),
- Gas: 1111,
- To: &acc2Addr,
- Value: big.NewInt(111),
- Data: []byte{0x11, 0x11, 0x11},
- })
- withdrawal = &types.Withdrawal{
- Index: 0,
- Validator: 1,
- Address: common.Address{0x12, 0x34},
- Amount: 10,
- }
- pending = types.NewBlockWithWithdrawals(&types.Header{Number: big.NewInt(11), Time: 42}, []*types.Transaction{tx}, nil, nil, []*types.Withdrawal{withdrawal}, blocktest.NewHasher())
- )
- backend := newTestBackend(t, genBlocks, genesis, ethash.NewFaker(), func(i int, b *core.BlockGen) {
- // Transfer from account[0] to account[1]
- // value: 1000 wei
- // fee: 0 wei
- tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: &acc2Addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), Data: nil}), signer, acc1Key)
- b.AddTx(tx)
- })
- backend.setPendingBlock(pending)
- api := NewBlockChainAPI(backend)
- blockHashes := make([]common.Hash, genBlocks+1)
- ctx := context.Background()
- for i := 0; i <= genBlocks; i++ {
- header, err := backend.HeaderByNumber(ctx, rpc.BlockNumber(i))
- if err != nil {
- t.Errorf("failed to get block: %d err: %v", i, err)
- }
- blockHashes[i] = header.Hash()
- }
- pendingHash := pending.Hash()
-
- var testSuite = []struct {
- blockNumber rpc.BlockNumber
- blockHash *common.Hash
- fullTx bool
- reqHeader bool
- file string
- expectErr error
- }{
- // 0. latest header
- {
- blockNumber: rpc.LatestBlockNumber,
- reqHeader: true,
- file: "tag-latest",
- },
- // 1. genesis header
- {
- blockNumber: rpc.BlockNumber(0),
- reqHeader: true,
- file: "number-0",
- },
- // 2. #1 header
- {
- blockNumber: rpc.BlockNumber(1),
- reqHeader: true,
- file: "number-1",
- },
- // 3. latest-1 header
- {
- blockNumber: rpc.BlockNumber(9),
- reqHeader: true,
- file: "number-latest-1",
- },
- // 4. latest+1 header
- {
- blockNumber: rpc.BlockNumber(11),
- reqHeader: true,
- file: "number-latest+1",
- },
- // 5. pending header
- {
- blockNumber: rpc.PendingBlockNumber,
- reqHeader: true,
- file: "tag-pending",
- },
- // 6. latest block
- {
- blockNumber: rpc.LatestBlockNumber,
- file: "tag-latest",
- },
- // 7. genesis block
- {
- blockNumber: rpc.BlockNumber(0),
- file: "number-0",
- },
- // 8. #1 block
- {
- blockNumber: rpc.BlockNumber(1),
- file: "number-1",
- },
- // 9. latest-1 block
- {
- blockNumber: rpc.BlockNumber(9),
- fullTx: true,
- file: "number-latest-1",
- },
- // 10. latest+1 block
- {
- blockNumber: rpc.BlockNumber(11),
- fullTx: true,
- file: "number-latest+1",
- },
- // 11. pending block
- {
- blockNumber: rpc.PendingBlockNumber,
- file: "tag-pending",
- },
- // 12. pending block + fullTx
- {
- blockNumber: rpc.PendingBlockNumber,
- fullTx: true,
- file: "tag-pending-fullTx",
- },
- // 13. latest header by hash
- {
- blockHash: &blockHashes[len(blockHashes)-1],
- reqHeader: true,
- file: "hash-latest",
- },
- // 14. genesis header by hash
- {
- blockHash: &blockHashes[0],
- reqHeader: true,
- file: "hash-0",
- },
- // 15. #1 header
- {
- blockHash: &blockHashes[1],
- reqHeader: true,
- file: "hash-1",
- },
- // 16. latest-1 header
- {
- blockHash: &blockHashes[len(blockHashes)-2],
- reqHeader: true,
- file: "hash-latest-1",
- },
- // 17. empty hash
- {
- blockHash: &common.Hash{},
- reqHeader: true,
- file: "hash-empty",
- },
- // 18. pending hash
- {
- blockHash: &pendingHash,
- reqHeader: true,
- file: `hash-pending`,
- },
- // 19. latest block
- {
- blockHash: &blockHashes[len(blockHashes)-1],
- file: "hash-latest",
- },
- // 20. genesis block
- {
- blockHash: &blockHashes[0],
- file: "hash-genesis",
- },
- // 21. #1 block
- {
- blockHash: &blockHashes[1],
- file: "hash-1",
- },
- // 22. latest-1 block
- {
- blockHash: &blockHashes[len(blockHashes)-2],
- fullTx: true,
- file: "hash-latest-1-fullTx",
- },
- // 23. empty hash + body
- {
- blockHash: &common.Hash{},
- fullTx: true,
- file: "hash-empty-fullTx",
- },
- // 24. pending block
- {
- blockHash: &pendingHash,
- file: `hash-pending`,
- },
- // 25. pending block + fullTx
- {
- blockHash: &pendingHash,
- fullTx: true,
- file: "hash-pending-fullTx",
- },
- }
-
- for i, tt := range testSuite {
- var (
- result map[string]interface{}
- err error
- rpc string
- )
- if tt.blockHash != nil {
- if tt.reqHeader {
- result = api.GetHeaderByHash(context.Background(), *tt.blockHash)
- rpc = "eth_getHeaderByHash"
- } else {
- result, err = api.GetBlockByHash(context.Background(), *tt.blockHash, tt.fullTx)
- rpc = "eth_getBlockByHash"
- }
- } else {
- if tt.reqHeader {
- result, err = api.GetHeaderByNumber(context.Background(), tt.blockNumber)
- rpc = "eth_getHeaderByNumber"
- } else {
- result, err = api.GetBlockByNumber(context.Background(), tt.blockNumber, tt.fullTx)
- rpc = "eth_getBlockByNumber"
- }
- }
- if tt.expectErr != nil {
- if err == nil {
- t.Errorf("test %d: want error %v, have nothing", i, tt.expectErr)
- continue
- }
- if !errors.Is(err, tt.expectErr) {
- t.Errorf("test %d: error mismatch, want %v, have %v", i, tt.expectErr, err)
- }
- continue
- }
- if err != nil {
- t.Errorf("test %d: want no error, have %v", i, err)
- continue
- }
-
- testRPCResponseWithFile(t, i, result, rpc, tt.file)
- }
-}
-
-func setupReceiptBackend(t *testing.T, genBlocks int) (*testBackend, []common.Hash) {
- config := *params.MergedTestChainConfig
- var (
- acc1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
- acc2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
- acc1Addr = crypto.PubkeyToAddress(acc1Key.PublicKey)
- acc2Addr = crypto.PubkeyToAddress(acc2Key.PublicKey)
- contract = common.HexToAddress("0000000000000000000000000000000000031ec7")
- genesis = &core.Genesis{
- Config: &config,
- ExcessBlobGas: new(uint64),
- BlobGasUsed: new(uint64),
- Alloc: types.GenesisAlloc{
- acc1Addr: {Balance: big.NewInt(params.Ether)},
- acc2Addr: {Balance: big.NewInt(params.Ether)},
- // // SPDX-License-Identifier: GPL-3.0
- // pragma solidity >=0.7.0 <0.9.0;
- //
- // contract Token {
- // event Transfer(address indexed from, address indexed to, uint256 value);
- // function transfer(address to, uint256 value) public returns (bool) {
- // emit Transfer(msg.sender, to, value);
- // return true;
- // }
- // }
- contract: {Balance: big.NewInt(params.Ether), Code: common.FromHex("0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063a9059cbb14610030575b600080fd5b61004a6004803603810190610045919061016a565b610060565b60405161005791906101c5565b60405180910390f35b60008273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516100bf91906101ef565b60405180910390a36001905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610101826100d6565b9050919050565b610111816100f6565b811461011c57600080fd5b50565b60008135905061012e81610108565b92915050565b6000819050919050565b61014781610134565b811461015257600080fd5b50565b6000813590506101648161013e565b92915050565b60008060408385031215610181576101806100d1565b5b600061018f8582860161011f565b92505060206101a085828601610155565b9150509250929050565b60008115159050919050565b6101bf816101aa565b82525050565b60006020820190506101da60008301846101b6565b92915050565b6101e981610134565b82525050565b600060208201905061020460008301846101e0565b9291505056fea2646970667358221220b469033f4b77b9565ee84e0a2f04d496b18160d26034d54f9487e57788fd36d564736f6c63430008120033")},
- },
- }
- signer = types.LatestSignerForChainID(params.TestChainConfig.ChainID)
- txHashes = make([]common.Hash, genBlocks)
- )
-
- backend := newTestBackend(t, genBlocks, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) {
- var (
- tx *types.Transaction
- err error
- )
- b.SetPoS()
- switch i {
- case 0:
- // transfer 1000wei
- tx, err = types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: &acc2Addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), Data: nil}), types.HomesteadSigner{}, acc1Key)
- case 1:
- // create contract
- tx, err = types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: nil, Gas: 53100, GasPrice: b.BaseFee(), Data: common.FromHex("0x60806040")}), signer, acc1Key)
- case 2:
- // with logs
- // transfer(address to, uint256 value)
- data := fmt.Sprintf("0xa9059cbb%s%s", common.HexToHash(common.BigToAddress(big.NewInt(int64(i + 1))).Hex()).String()[2:], common.BytesToHash([]byte{byte(i + 11)}).String()[2:])
- tx, err = types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: &contract, Gas: 60000, GasPrice: b.BaseFee(), Data: common.FromHex(data)}), signer, acc1Key)
- case 3:
- // dynamic fee with logs
- // transfer(address to, uint256 value)
- data := fmt.Sprintf("0xa9059cbb%s%s", common.HexToHash(common.BigToAddress(big.NewInt(int64(i + 1))).Hex()).String()[2:], common.BytesToHash([]byte{byte(i + 11)}).String()[2:])
- fee := big.NewInt(500)
- fee.Add(fee, b.BaseFee())
- tx, err = types.SignTx(types.NewTx(&types.DynamicFeeTx{Nonce: uint64(i), To: &contract, Gas: 60000, Value: big.NewInt(1), GasTipCap: big.NewInt(500), GasFeeCap: fee, Data: common.FromHex(data)}), signer, acc1Key)
- case 4:
- // access list with contract create
- accessList := types.AccessList{{
- Address: contract,
- StorageKeys: []common.Hash{{0}},
- }}
- tx, err = types.SignTx(types.NewTx(&types.AccessListTx{Nonce: uint64(i), To: nil, Gas: 58100, GasPrice: b.BaseFee(), Data: common.FromHex("0x60806040"), AccessList: accessList}), signer, acc1Key)
- case 5:
- // blob tx
- fee := big.NewInt(500)
- fee.Add(fee, b.BaseFee())
- tx, err = types.SignTx(types.NewTx(&types.BlobTx{
- Nonce: uint64(i),
- GasTipCap: uint256.NewInt(1),
- GasFeeCap: uint256.MustFromBig(fee),
- Gas: params.TxGas,
- To: acc2Addr,
- BlobFeeCap: uint256.NewInt(1),
- BlobHashes: []common.Hash{{1}},
- Value: new(uint256.Int),
- }), signer, acc1Key)
-
- case 6:
- // blob tx with blobSidecar
- blobSidecars := makeBlkSidecars(1, 1)
- blobHashes := blobSidecars[0].BlobHashes()
- fee := big.NewInt(500)
- fee.Add(fee, b.BaseFee())
- tx, err = types.SignTx(types.NewTx(&types.BlobTx{
- Nonce: uint64(i),
- GasTipCap: uint256.NewInt(1),
- GasFeeCap: uint256.MustFromBig(fee),
- Gas: params.TxGas,
- To: acc2Addr,
- BlobFeeCap: uint256.NewInt(1),
- BlobHashes: blobHashes,
- Value: new(uint256.Int),
- }), signer, acc1Key)
- b.AddBlobSidecar(&types.BlobSidecar{
- BlobTxSidecar: *blobSidecars[0],
- TxHash: tx.Hash(),
- TxIndex: 0,
- })
- }
- if err != nil {
- t.Errorf("failed to sign tx: %v", err)
- }
- if tx != nil {
- b.AddTx(tx)
- txHashes[i] = tx.Hash()
- }
- })
- return backend, txHashes
-}
-
-func TestRPCGetTransactionReceipt(t *testing.T) {
- t.Parallel()
-
- var (
- backend, txHashes = setupReceiptBackend(t, 6)
- api = NewTransactionAPI(backend, new(AddrLocker))
- )
-
- var testSuite = []struct {
- txHash common.Hash
- file string
- }{
- // 0. normal success
- {
- txHash: txHashes[0],
- file: "normal-transfer-tx",
- },
- // 1. create contract
- {
- txHash: txHashes[1],
- file: "create-contract-tx",
- },
- // 2. with logs success
- {
- txHash: txHashes[2],
- file: "with-logs",
- },
- // 3. dynamic tx with logs success
- {
- txHash: txHashes[3],
- file: `dynamic-tx-with-logs`,
- },
- // 4. access list tx with create contract
- {
- txHash: txHashes[4],
- file: "create-contract-with-access-list",
- },
- // 5. txhash empty
- {
- txHash: common.Hash{},
- file: "txhash-empty",
- },
- // 6. txhash not found
- {
- txHash: common.HexToHash("deadbeef"),
- file: "txhash-notfound",
- },
- // 7. blob tx
- {
- txHash: txHashes[5],
- file: "blob-tx",
- },
- }
-
- for i, tt := range testSuite {
- var (
- result interface{}
- err error
- )
- result, err = api.GetTransactionReceipt(context.Background(), tt.txHash)
- if err != nil {
- t.Errorf("test %d: want no error, have %v", i, err)
- continue
- }
- testRPCResponseWithFile(t, i, result, "eth_getTransactionReceipt", tt.file)
- }
-}
-
-func TestRPCGetBlockReceipts(t *testing.T) {
- t.Parallel()
-
- var (
- genBlocks = 6
- backend, _ = setupReceiptBackend(t, genBlocks)
- api = NewBlockChainAPI(backend)
- )
- blockHashes := make([]common.Hash, genBlocks+1)
- ctx := context.Background()
- for i := 0; i <= genBlocks; i++ {
- header, err := backend.HeaderByNumber(ctx, rpc.BlockNumber(i))
- if err != nil {
- t.Errorf("failed to get block: %d err: %v", i, err)
- }
- blockHashes[i] = header.Hash()
- }
-
- var testSuite = []struct {
- test rpc.BlockNumberOrHash
- file string
- }{
- // 0. block without any txs(hash)
- {
- test: rpc.BlockNumberOrHashWithHash(blockHashes[0], false),
- file: "number-0",
- },
- // 1. block without any txs(number)
- {
- test: rpc.BlockNumberOrHashWithNumber(0),
- file: "number-1",
- },
- // 2. earliest tag
- {
- test: rpc.BlockNumberOrHashWithNumber(rpc.EarliestBlockNumber),
- file: "tag-earliest",
- },
- // 3. latest tag
- {
- test: rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber),
- file: "tag-latest",
- },
- // 4. block with legacy transfer tx(hash)
- {
- test: rpc.BlockNumberOrHashWithHash(blockHashes[1], false),
- file: "block-with-legacy-transfer-tx",
- },
- // 5. block with contract create tx(number)
- {
- test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(2)),
- file: "block-with-contract-create-tx",
- },
- // 6. block with legacy contract call tx(hash)
- {
- test: rpc.BlockNumberOrHashWithHash(blockHashes[3], false),
- file: "block-with-legacy-contract-call-tx",
- },
- // 7. block with dynamic fee tx(number)
- {
- test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(4)),
- file: "block-with-dynamic-fee-tx",
- },
- // 8. block is empty
- {
- test: rpc.BlockNumberOrHashWithHash(common.Hash{}, false),
- file: "hash-empty",
- },
- // 9. block is not found
- {
- test: rpc.BlockNumberOrHashWithHash(common.HexToHash("deadbeef"), false),
- file: "hash-notfound",
- },
- // 10. block is not found
- {
- test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(genBlocks + 1)),
- file: "block-notfound",
- },
- // 11. block with blob tx
- {
- test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(6)),
- file: "block-with-blob-tx",
- },
- }
-
- for i, tt := range testSuite {
- var (
- result interface{}
- err error
- )
- result, err = api.GetBlockReceipts(context.Background(), tt.test)
- if err != nil {
- t.Errorf("test %d: want no error, have %v", i, err)
- continue
- }
- testRPCResponseWithFile(t, i, result, "eth_getBlockReceipts", tt.file)
- }
-}
-
-func makeBlkSidecars(n, nPerTx int) []*types.BlobTxSidecar {
- if n <= 0 {
- return nil
- }
- ret := make([]*types.BlobTxSidecar, n)
- for i := 0; i < n; i++ {
- blobs := make([]kzg4844.Blob, nPerTx)
- commitments := make([]kzg4844.Commitment, nPerTx)
- proofs := make([]kzg4844.Proof, nPerTx)
- for i := 0; i < nPerTx; i++ {
- commitments[i], _ = kzg4844.BlobToCommitment(blobs[i])
- proofs[i], _ = kzg4844.ComputeBlobProof(blobs[i], commitments[i])
- }
- ret[i] = &types.BlobTxSidecar{
- Blobs: blobs,
- Commitments: commitments,
- Proofs: proofs,
- }
- }
- return ret
-}
-
-func TestRPCGetBlobSidecars(t *testing.T) {
- t.Parallel()
- var (
- genBlocks = 7
- backend, _ = setupReceiptBackend(t, genBlocks)
- api = NewBlockChainAPI(backend)
- )
- blockHashes := make([]common.Hash, genBlocks+1)
- ctx := context.Background()
- for i := 0; i <= genBlocks; i++ {
- header, err := backend.HeaderByNumber(ctx, rpc.BlockNumber(i))
- if err != nil {
- t.Errorf("failed to get block: %d err: %v", i, err)
- }
- blockHashes[i] = header.Hash()
- }
-
- var testSuite = []struct {
- test rpc.BlockNumberOrHash
- fullBlob bool
- file string
- }{
- // 1. block without any txs(number)
- {
- test: rpc.BlockNumberOrHashWithNumber(0),
- fullBlob: true,
- file: "number-1",
- },
- // 2. earliest tag
- {
- test: rpc.BlockNumberOrHashWithNumber(rpc.EarliestBlockNumber),
- fullBlob: true,
- file: "tag-earliest",
- },
- // 3. latest tag
- {
- test: rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber),
- fullBlob: true,
- file: "tag-latest",
- },
- // 4. block is empty
- {
- test: rpc.BlockNumberOrHashWithHash(common.Hash{}, false),
- fullBlob: true,
- file: "hash-empty",
- },
- // 5. block is not found
- {
- test: rpc.BlockNumberOrHashWithHash(common.HexToHash("deadbeef"), false),
- fullBlob: true,
- file: "hash-notfound",
- },
- // 6. block is not found
- {
- test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(genBlocks + 1)),
- fullBlob: true,
- file: "block-notfound",
- },
- // 7. block with blob tx
- {
- test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(6)),
- fullBlob: true,
- file: "block-with-blob-tx",
- },
- // 8. block with sidecar
- {
- test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(7)),
- fullBlob: true,
- file: "block-with-blobSidecars",
- },
- // 9. block with sidecar but show little
- {
- test: rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(7)),
- fullBlob: false,
- file: "block-with-blobSidecars-show-little",
- },
- }
-
- for i, tt := range testSuite {
- var (
- result interface{}
- err error
- )
- result, err = api.GetBlobSidecars(context.Background(), tt.test, &tt.fullBlob)
- if err != nil {
- t.Errorf("test %d: want no error, have %v", i, err)
- continue
- }
- testRPCResponseWithFile(t, i, result, "eth_getBlobSidecars", tt.file)
- }
-}
-
-func TestGetBlobSidecarByTxHash(t *testing.T) {
- t.Parallel()
- var (
- backend, txHashs = setupReceiptBackend(t, 7)
- api = NewBlockChainAPI(backend)
- )
- var testSuite = []struct {
- test common.Hash
- fullBlob bool
- file string
- }{
- // 0. txHash is empty
- {
- test: common.Hash{},
- fullBlob: true,
- file: "hash-empty",
- },
- // 1. txHash is not found
- {
- test: common.HexToHash("deadbeef"),
- fullBlob: true,
- file: "hash-notfound",
- },
- // 2. txHash is not blob tx
- {
- test: common.HexToHash("deadbeef"),
- fullBlob: true,
- file: "not-blob-tx",
- },
- // 3. block with blob tx without sidecar
- {
- test: txHashs[5],
- fullBlob: true,
- file: "block-with-blob-tx",
- },
- // 4. block with sidecar
- {
- test: txHashs[6],
- fullBlob: true,
- file: "block-with-blobSidecars",
- },
- // 5. block show part blobs
- {
- test: txHashs[6],
- fullBlob: false,
- file: "block-with-blobSidecars-show-little",
- },
- }
-
- for i, tt := range testSuite {
- var (
- result interface{}
- err error
- )
- result, err = api.GetBlobSidecarByTxHash(context.Background(), tt.test, &tt.fullBlob)
- if err != nil {
- t.Errorf("test %d: want no error, have %v", i, err)
- continue
- }
- testRPCResponseWithFile(t, i, result, "eth_getBlobSidecarByTxHash", tt.file)
- }
-}
-
-func testRPCResponseWithFile(t *testing.T, testid int, result interface{}, rpc string, file string) {
- data, err := json.MarshalIndent(result, "", " ")
- if err != nil {
- t.Errorf("test %d: json marshal error", testid)
- return
- }
- outputFile := filepath.Join("testdata", fmt.Sprintf("%s-%s.json", rpc, file))
- if os.Getenv("WRITE_TEST_FILES") != "" {
- os.WriteFile(outputFile, data, 0644)
- }
- want, err := os.ReadFile(outputFile)
- if err != nil {
- t.Fatalf("error reading expected test file: %s output: %v", outputFile, err)
- }
- require.JSONEqf(t, string(want), string(data), "test %d: json not match, want: %s, have: %s", testid, string(want), string(data))
-}
diff --git a/miner/worker_test.go b/miner/worker_test.go
deleted file mode 100644
index 268f3f69a5..0000000000
--- a/miner/worker_test.go
+++ /dev/null
@@ -1,413 +0,0 @@
-// Copyright 2018 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package miner // TOFIX
-
-import (
- "math/big"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/clique"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/txpool"
- "github.com/ethereum/go-ethereum/core/txpool/legacypool"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/params"
- "github.com/holiman/uint256"
-)
-
-const (
- // testCode is the testing contract binary code which will initialises some
- // variables in constructor
- testCode = "0x60806040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0060005534801561003457600080fd5b5060fc806100436000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80630c4dae8814603757806398a213cf146053575b600080fd5b603d607e565b6040518082815260200191505060405180910390f35b607c60048036036020811015606757600080fd5b81019080803590602001909291905050506084565b005b60005481565b806000819055507fe9e44f9f7da8c559de847a3232b57364adc0354f15a2cd8dc636d54396f9587a6000546040518082815260200191505060405180910390a15056fea265627a7a723058208ae31d9424f2d0bc2a3da1a5dd659db2d71ec322a17db8f87e19e209e3a1ff4a64736f6c634300050a0032"
-
- // testGas is the gas required for contract deployment.
- testGas = 144109
-)
-
-var (
- // Test chain configurations
- testTxPoolConfig legacypool.Config
- ethashChainConfig *params.ChainConfig
- cliqueChainConfig *params.ChainConfig
-
- // Test accounts
- testBankKey, _ = crypto.GenerateKey()
- testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
- testBankFunds = big.NewInt(1000000000000000000)
-
- testUserKey, _ = crypto.GenerateKey()
- testUserAddress = crypto.PubkeyToAddress(testUserKey.PublicKey)
-
- // Test transactions
- pendingTxs []*types.Transaction
- newTxs []*types.Transaction
-
- testConfig = &Config{
- Recommit: time.Second,
- GasCeil: params.GenesisGasLimit,
- }
-)
-
-func init() {
- testTxPoolConfig = legacypool.DefaultConfig
- testTxPoolConfig.Journal = ""
- ethashChainConfig = new(params.ChainConfig)
- *ethashChainConfig = *params.TestChainConfig
- cliqueChainConfig = new(params.ChainConfig)
- *cliqueChainConfig = *params.TestChainConfig
- cliqueChainConfig.Clique = ¶ms.CliqueConfig{
- Period: 10,
- Epoch: 30000,
- }
-
- signer := types.LatestSigner(params.TestChainConfig)
- tx1 := types.MustSignNewTx(testBankKey, signer, &types.AccessListTx{
- ChainID: params.TestChainConfig.ChainID,
- Nonce: 0,
- To: &testUserAddress,
- Value: big.NewInt(1000),
- Gas: params.TxGas,
- GasPrice: big.NewInt(params.InitialBaseFee),
- })
- pendingTxs = append(pendingTxs, tx1)
-
- tx2 := types.MustSignNewTx(testBankKey, signer, &types.LegacyTx{
- Nonce: 1,
- To: &testUserAddress,
- Value: big.NewInt(1000),
- Gas: params.TxGas,
- GasPrice: big.NewInt(params.InitialBaseFee),
- })
- newTxs = append(newTxs, tx2)
-}
-
-// testWorkerBackend implements worker.Backend interfaces and wraps all information needed during the testing.
-type testWorkerBackend struct {
- db ethdb.Database
- txPool *txpool.TxPool
- chain *core.BlockChain
- genesis *core.Genesis
-}
-
-func newTestWorkerBackend(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine, db ethdb.Database, n int) *testWorkerBackend {
- var gspec = &core.Genesis{
- Config: chainConfig,
- Alloc: types.GenesisAlloc{testBankAddress: {Balance: testBankFunds}},
- }
- switch e := engine.(type) {
- case *clique.Clique:
- gspec.ExtraData = make([]byte, 32+common.AddressLength+crypto.SignatureLength)
- copy(gspec.ExtraData[32:32+common.AddressLength], testBankAddress.Bytes())
- e.Authorize(testBankAddress, func(account accounts.Account, s string, data []byte) ([]byte, error) {
- return crypto.Sign(crypto.Keccak256(data), testBankKey)
- })
- case *ethash.Ethash:
- default:
- t.Fatalf("unexpected consensus engine type: %T", engine)
- }
- chain, err := core.NewBlockChain(db, &core.CacheConfig{TrieDirtyDisabled: true}, gspec, nil, engine, vm.Config{}, nil, nil)
- if err != nil {
- t.Fatalf("core.NewBlockChain failed: %v", err)
- }
- pool := legacypool.New(testTxPoolConfig, chain)
- txpool, _ := txpool.New(testTxPoolConfig.PriceLimit, chain, []txpool.SubPool{pool})
-
- return &testWorkerBackend{
- db: db,
- chain: chain,
- txPool: txpool,
- genesis: gspec,
- }
-}
-
-func (b *testWorkerBackend) BlockChain() *core.BlockChain { return b.chain }
-func (b *testWorkerBackend) TxPool() *txpool.TxPool { return b.txPool }
-
-func (b *testWorkerBackend) newRandomTx(creation bool) *types.Transaction {
- var tx *types.Transaction
- gasPrice := big.NewInt(10 * params.InitialBaseFee)
- if creation {
- tx, _ = types.SignTx(types.NewContractCreation(b.txPool.Nonce(testBankAddress), big.NewInt(0), testGas, gasPrice, common.FromHex(testCode)), types.HomesteadSigner{}, testBankKey)
- } else {
- tx, _ = types.SignTx(types.NewTransaction(b.txPool.Nonce(testBankAddress), testUserAddress, big.NewInt(1000), params.TxGas, gasPrice, nil), types.HomesteadSigner{}, testBankKey)
- }
- return tx
-}
-
-func newTestWorker(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine, db ethdb.Database, blocks int) (*worker, *testWorkerBackend) {
- backend := newTestWorkerBackend(t, chainConfig, engine, db, blocks)
- backend.txPool.Add(pendingTxs, true, false)
- w := newWorker(testConfig, chainConfig, engine, backend, new(event.TypeMux), nil, false)
- w.setEtherbase(testBankAddress)
- return w, backend
-}
-
-func TestGenerateAndImportBlock(t *testing.T) {
- t.Parallel()
- var (
- db = rawdb.NewMemoryDatabase()
- config = *params.AllCliqueProtocolChanges
- )
- config.Clique = ¶ms.CliqueConfig{Period: 1, Epoch: 30000}
- engine := clique.New(config.Clique, db)
-
- w, b := newTestWorker(t, &config, engine, db, 0)
- defer w.close()
-
- // This test chain imports the mined blocks.
- chain, _ := core.NewBlockChain(rawdb.NewMemoryDatabase(), nil, b.genesis, nil, engine, vm.Config{}, nil, nil)
- defer chain.Stop()
-
- // Ignore empty commit here for less noise.
- w.skipSealHook = func(task *task) bool {
- return len(task.receipts) == 0
- }
-
- // Wait for mined blocks.
- sub := w.mux.Subscribe(core.NewMinedBlockEvent{})
- defer sub.Unsubscribe()
-
- // Start mining!
- w.start()
-
- for i := 0; i < 5; i++ {
- b.txPool.Add([]*types.Transaction{b.newRandomTx(true)}, true, false)
- b.txPool.Add([]*types.Transaction{b.newRandomTx(false)}, true, false)
-
- select {
- case ev := <-sub.Chan():
- block := ev.Data.(core.NewMinedBlockEvent).Block
- if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
- t.Fatalf("failed to insert new mined block %d: %v", block.NumberU64(), err)
- }
- case <-time.After(3 * time.Second): // Worker needs 1s to include new changes.
- t.Fatalf("timeout")
- }
- }
-}
-
-func TestEmptyWorkEthash(t *testing.T) {
- t.Parallel()
- testEmptyWork(t, ethashChainConfig, ethash.NewFaker())
-}
-func TestEmptyWorkClique(t *testing.T) {
- t.Parallel()
- testEmptyWork(t, cliqueChainConfig, clique.New(cliqueChainConfig.Clique, rawdb.NewMemoryDatabase()))
-}
-
-func testEmptyWork(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine) {
- defer engine.Close()
-
- w, _ := newTestWorker(t, chainConfig, engine, rawdb.NewMemoryDatabase(), 0)
- defer w.close()
-
- taskCh := make(chan struct{}, 2)
- checkEqual := func(t *testing.T, task *task) {
- // The work should contain 1 tx
- receiptLen, balance := 1, uint256.NewInt(1000)
- if len(task.receipts) != receiptLen {
- t.Fatalf("receipt number mismatch: have %d, want %d", len(task.receipts), receiptLen)
- }
- if task.state.GetBalance(testUserAddress).Cmp(balance) != 0 {
- t.Fatalf("account balance mismatch: have %d, want %d", task.state.GetBalance(testUserAddress), balance)
- }
- }
- w.newTaskHook = func(task *task) {
- if task.block.NumberU64() == 1 {
- checkEqual(t, task)
- taskCh <- struct{}{}
- }
- }
- w.skipSealHook = func(task *task) bool { return true }
- w.fullTaskHook = func() {
- time.Sleep(100 * time.Millisecond)
- }
- w.start() // Start mining!
- select {
- case <-taskCh:
- case <-time.NewTimer(3 * time.Second).C:
- t.Error("new task timeout")
- }
-}
-
-func TestGetSealingWorkEthash(t *testing.T) {
- t.Parallel()
- testGetSealingWork(t, ethashChainConfig, ethash.NewFaker())
-}
-
-func TestGetSealingWorkClique(t *testing.T) {
- t.Parallel()
- testGetSealingWork(t, cliqueChainConfig, clique.New(cliqueChainConfig.Clique, rawdb.NewMemoryDatabase()))
-}
-
-func TestGetSealingWorkPostMerge(t *testing.T) {
- t.Parallel()
- local := new(params.ChainConfig)
- *local = *ethashChainConfig
- local.TerminalTotalDifficulty = big.NewInt(0)
- testGetSealingWork(t, local, ethash.NewFaker())
-}
-
-func testGetSealingWork(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine) {
- defer engine.Close()
-
- w, b := newTestWorker(t, chainConfig, engine, rawdb.NewMemoryDatabase(), 0)
- defer w.close()
-
- w.setExtra([]byte{0x01, 0x02})
-
- w.skipSealHook = func(task *task) bool {
- return true
- }
- w.fullTaskHook = func() {
- time.Sleep(100 * time.Millisecond)
- }
- timestamp := uint64(time.Now().Unix())
- assertBlock := func(block *types.Block, number uint64, coinbase common.Address, random common.Hash) {
- if block.Time() != timestamp {
- // Sometime the timestamp will be mutated if the timestamp
- // is even smaller than parent block's. It's OK.
- t.Logf("Invalid timestamp, want %d, get %d", timestamp, block.Time())
- }
- _, isClique := engine.(*clique.Clique)
- if !isClique {
- if len(block.Extra()) != 2 {
- t.Error("Unexpected extra field")
- }
- if block.Coinbase() != coinbase {
- t.Errorf("Unexpected coinbase got %x want %x", block.Coinbase(), coinbase)
- }
- } else {
- if block.Coinbase() != (common.Address{}) {
- t.Error("Unexpected coinbase")
- }
- }
- if !isClique {
- if block.MixDigest() != random {
- t.Error("Unexpected mix digest")
- }
- }
- if block.Nonce() != 0 {
- t.Error("Unexpected block nonce")
- }
- if block.NumberU64() != number {
- t.Errorf("Mismatched block number, want %d got %d", number, block.NumberU64())
- }
- }
- var cases = []struct {
- parent common.Hash
- coinbase common.Address
- random common.Hash
- expectNumber uint64
- expectErr bool
- }{
- {
- b.chain.Genesis().Hash(),
- common.HexToAddress("0xdeadbeef"),
- common.HexToHash("0xcafebabe"),
- uint64(1),
- false,
- },
- {
- b.chain.CurrentBlock().Hash(),
- common.HexToAddress("0xdeadbeef"),
- common.HexToHash("0xcafebabe"),
- b.chain.CurrentBlock().Number.Uint64() + 1,
- false,
- },
- {
- b.chain.CurrentBlock().Hash(),
- common.Address{},
- common.HexToHash("0xcafebabe"),
- b.chain.CurrentBlock().Number.Uint64() + 1,
- false,
- },
- {
- b.chain.CurrentBlock().Hash(),
- common.Address{},
- common.Hash{},
- b.chain.CurrentBlock().Number.Uint64() + 1,
- false,
- },
- {
- common.HexToHash("0xdeadbeef"),
- common.HexToAddress("0xdeadbeef"),
- common.HexToHash("0xcafebabe"),
- 0,
- true,
- },
- }
-
- // This API should work even when the automatic sealing is not enabled
- for _, c := range cases {
- r := w.getSealingBlock(&generateParams{
- parentHash: c.parent,
- timestamp: timestamp,
- coinbase: c.coinbase,
- random: c.random,
- withdrawals: nil,
- beaconRoot: nil,
- noTxs: false,
- forceTime: true,
- })
- if c.expectErr {
- if r.err == nil {
- t.Error("Expect error but get nil")
- }
- } else {
- if r.err != nil {
- t.Errorf("Unexpected error %v", r.err)
- }
- assertBlock(r.block, c.expectNumber, c.coinbase, c.random)
- }
- }
-
- // This API should work even when the automatic sealing is enabled
- w.start()
- for _, c := range cases {
- r := w.getSealingBlock(&generateParams{
- parentHash: c.parent,
- timestamp: timestamp,
- coinbase: c.coinbase,
- random: c.random,
- withdrawals: nil,
- beaconRoot: nil,
- noTxs: false,
- forceTime: true,
- })
- if c.expectErr {
- if r.err == nil {
- t.Error("Expect error but get nil")
- }
- } else {
- if r.err != nil {
- t.Errorf("Unexpected error %v", r.err)
- }
- assertBlock(r.block, c.expectNumber, c.coinbase, c.random)
- }
- }
-}