diff --git a/blockgen.go b/blockgen.go index b0ade43..6456e7c 100644 --- a/blockgen.go +++ b/blockgen.go @@ -20,18 +20,28 @@ func genSimpleChain(engine consensus.Engine) (*core.Genesis, []*types.Block) { keyHex = "9c647b8b7c4e7c3490668fb6c11473619db80c93704c70893d3813af4090c39c" key, _ = crypto.HexToECDSA(keyHex) address = crypto.PubkeyToAddress(key.PublicKey) // 658bdf435d810c91414ec09147daa6db62406379 + aa = common.Address{0xaa} funds = big.NewInt(0).Mul(big.NewInt(1337), big.NewInt(params.Ether)) gspec = &core.Genesis{ - Config: params.TestChainConfig, + Config: params.AllEthashProtocolChanges, Alloc: core.GenesisAlloc{address: {Balance: funds}}, BaseFee: big.NewInt(params.InitialBaseFee), Difficulty: common.Big1, GasLimit: 5_000_000, } - gendb = rawdb.NewMemoryDatabase() - genesis = gspec.MustCommit(gendb) - signer = types.LatestSigner(gspec.Config) + gendb = rawdb.NewMemoryDatabase() + signer = types.LatestSigner(gspec.Config) ) + + // init 0xaa with some storage elements + storage := make(map[common.Hash]common.Hash) + storage[common.Hash{0x00}] = common.Hash{0x00} + storage[common.Hash{0x01}] = common.Hash{0x01} + storage[common.Hash{0x02}] = common.Hash{0x02} + gspec.Alloc[aa] = core.GenesisAccount{Balance: common.Big1, Nonce: 1, Storage: storage} + + genesis := gspec.MustCommit(gendb) + sealingEngine := sealingEngine{engine} chain, _ := core.GenerateChain(gspec.Config, genesis, sealingEngine, gendb, 3, func(i int, gen *core.BlockGen) { tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(address), address, big.NewInt(1000), params.TxGas, gen.BaseFee(), nil), signer, key) diff --git a/client.go b/client.go index 9886b40..8881c47 100644 --- a/client.go +++ b/client.go @@ -134,7 +134,7 @@ func runCmd(ctx context.Context, path string, verbose bool, args ...string) erro // writeChain writes the genesis and blocks to disk. func writeChain(path string, genesis *core.Genesis, blocks []*types.Block) error { - out, err := json.Marshal(genesis) + out, err := json.MarshalIndent(genesis, "", " ") if err != nil { return err } diff --git a/ethclient.go b/ethclient.go index c09c011..dc35301 100644 --- a/ethclient.go +++ b/ethclient.go @@ -9,14 +9,16 @@ import ( "os" "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/ethclient/gethclient" "github.com/ethereum/go-ethereum/rpc" ) type ethclientHandler struct { - ethclient *ethclient.Client - rpc *rpc.Client - logFile *os.File - transport *loggingRoundTrip + ethclient *ethclient.Client + gethclient *gethclient.Client + rpc *rpc.Client + logFile *os.File + transport *loggingRoundTrip } func newEthclientHandler(addr string) (*ethclientHandler, error) { @@ -28,7 +30,12 @@ func newEthclientHandler(addr string) (*ethclientHandler, error) { if err != nil { return nil, err } - return ðclientHandler{ethclient.NewClient(rpcClient), rpcClient, nil, rt}, nil + return ðclientHandler{ + ethclient.NewClient(rpcClient), + gethclient.New(rpcClient), + rpcClient, + nil, + rt}, nil } func (l *ethclientHandler) RotateLog(filename string) error { diff --git a/generate.go b/generate.go index 311c7d9..6b82969 100644 --- a/generate.go +++ b/generate.go @@ -65,7 +65,7 @@ func runGenerator(ctx context.Context) error { ctx, cancel := context.WithTimeout(ctx, 3*time.Second) defer cancel() - err := test.Run(ctx, testgen.NewT(handler.ethclient, handler.rpc, chain.bc)) + err := test.Run(ctx, testgen.NewT(handler.ethclient, handler.gethclient, handler.rpc, chain.bc)) if err != nil { fmt.Println(" fail.") fmt.Fprintf(os.Stderr, "failed to fill %s/%s: %s\n", methodTest.MethodName, test.Name, err) diff --git a/go.mod b/go.mod index e784fba..e662672 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,8 @@ require ( github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.2.0 // indirect + github.com/huin/goupnp v1.0.3 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/open-rpc/meta-schema v0.0.0-20210416041958-626a15d0a618 // indirect @@ -34,6 +36,7 @@ require ( github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect ) diff --git a/go.sum b/go.sum index c762887..dedc85b 100644 --- a/go.sum +++ b/go.sum @@ -59,6 +59,11 @@ github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iU github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= +github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -111,6 +116,8 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/testgen/generators.go b/testgen/generators.go index d26b5bd..c7bd60f 100644 --- a/testgen/generators.go +++ b/testgen/generators.go @@ -4,23 +4,26 @@ import ( "bytes" "context" "fmt" + "math/big" "strings" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/ethclient/gethclient" "github.com/ethereum/go-ethereum/rpc" ) type T struct { eth *ethclient.Client + geth *gethclient.Client rpc *rpc.Client chain *core.BlockChain } -func NewT(eth *ethclient.Client, rpc *rpc.Client, chain *core.BlockChain) *T { - return &T{eth, rpc, chain} +func NewT(eth *ethclient.Client, geth *gethclient.Client, rpc *rpc.Client, chain *core.BlockChain) *T { + return &T{eth, geth, rpc, chain} } // MethodTests is a collection of tests for a certain JSON-RPC method. @@ -41,6 +44,7 @@ type Test struct { var AllMethods = []MethodTests{ EthBlockNumber, EthGetBlockByNumber, + EthGetProof, DebugGetHeader, DebugGetBlock, DebugGetReceipts, @@ -102,6 +106,50 @@ var EthGetBlockByNumber = MethodTests{ }, } +// EthGetProof stores a list of all tests against the method. +var EthGetProof = MethodTests{ + "eth_getProof", + []Test{ + { + "get-account-proof", + "gets proof for a certain account", + func(ctx context.Context, t *T) error { + addr := common.Address{0xaa} + result, err := t.geth.GetProof(ctx, addr, nil, big.NewInt(3)) + if err != nil { + return err + } + state, _ := t.chain.State() + balance := state.GetBalance(addr) + if result.Balance.Cmp(balance) != 0 { + return fmt.Errorf("unexpected balance (got: %s, want: %s)", result.Balance, balance) + } + return nil + }, + }, + { + "get-account-proof-with-storage", + "gets proof for a certain account", + func(ctx context.Context, t *T) error { + addr := common.Address{0xaa} + result, err := t.geth.GetProof(ctx, addr, []string{"0x01"}, big.NewInt(3)) + if err != nil { + return err + } + state, _ := t.chain.State() + balance := state.GetBalance(addr) + if result.Balance.Cmp(balance) != 0 { + return fmt.Errorf("unexpected balance (got: %s, want: %s)", result.Balance, balance) + } + if len(result.StorageProof) == 0 || len(result.StorageProof[0].Proof) == 0 { + return fmt.Errorf("expected storage proof") + } + return nil + }, + }, + }, +} + var DebugGetHeader = MethodTests{ "debug_getHeader", []Test{