From 2c03c8cbd07cd792219a9e2fbb8fd4f4cc3b2379 Mon Sep 17 00:00:00 2001 From: prathamesh0 <42446521+prathamesh0@users.noreply.github.com> Date: Wed, 21 Sep 2022 17:15:03 +0530 Subject: [PATCH] Support `debug_traceCall` API (#192) * Implement debug_traceCall API * Use API implementation from geth with custom backend * Update refs in GitHub workflow --- .github/workflows/on-pr-publish.yaml | 2 +- cmd/serve.go | 2 +- pkg/debug/backend.go | 54 ++++++++++++++++++++++++++ pkg/eth/backend.go | 9 ++++- pkg/graphql/graphql.go | 2 +- pkg/rpc/ipc.go | 1 + pkg/serve/config.go | 2 + pkg/serve/service.go | 21 +++++++--- test/README.md | 4 +- test/watch_address_integration_test.go | 1 + 10 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 pkg/debug/backend.go diff --git a/.github/workflows/on-pr-publish.yaml b/.github/workflows/on-pr-publish.yaml index c046ab7d..6b07b704 100644 --- a/.github/workflows/on-pr-publish.yaml +++ b/.github/workflows/on-pr-publish.yaml @@ -29,7 +29,7 @@ jobs: BUILD_KEY: ${{ secrets.BUILD_KEY }} with: STACK_ORCHESTRATOR_REF: "f2fd766f5400fcb9eb47b50675d2e3b1f2753702" - GO_ETHEREUM_REF: "be1757b9fd884cb20c8d7faac8fa81fc49bb7216" + GO_ETHEREUM_REF: "0c1e451c9865d8d47797b35526c4875f0d224772" IPLD_ETH_DB_REF: "be345e0733d2c025e4082c5154e441317ae94cf7" build: name: Run docker build diff --git a/cmd/serve.go b/cmd/serve.go index 59b9fbc4..fde02ee7 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -133,7 +133,7 @@ func startServers(server s.Server, settings *s.Config) error { if settings.HTTPEnabled { logWithCommand.Info("starting up HTTP server") - _, err := srpc.StartHTTPEndpoint(settings.HTTPEndpoint, server.APIs(), []string{"vdb", "eth", "net"}, nil, []string{"*"}, rpc.HTTPTimeouts{}) + _, err := srpc.StartHTTPEndpoint(settings.HTTPEndpoint, server.APIs(), []string{"vdb", "eth", "debug", "net"}, nil, []string{"*"}, rpc.HTTPTimeouts{}) if err != nil { return err } diff --git a/pkg/debug/backend.go b/pkg/debug/backend.go new file mode 100644 index 00000000..bf4a1b40 --- /dev/null +++ b/pkg/debug/backend.go @@ -0,0 +1,54 @@ +// VulcanizeDB +// Copyright © 2022 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package debug + +import ( + "context" + "errors" + + "github.com/ethereum/go-ethereum/core" + "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/eth/tracers" + "github.com/ethereum/go-ethereum/rpc" + + "github.com/cerc-io/ipld-eth-server/v4/pkg/eth" +) + +var _ tracers.Backend = &Backend{} + +var ( + errMethodNotSupported = errors.New("backend method not supported") +) + +// Backend implements tracers.Backend interface +type Backend struct { + eth.Backend +} + +// StateAtBlock retrieves the state database associated with a certain block +func (b *Backend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, checkLive, preferDisk bool) (*state.StateDB, error) { + rpcBlockNumber := rpc.BlockNumber(block.NumberU64()) + statedb, _, err := b.StateAndHeaderByNumberOrHash(ctx, rpc.BlockNumberOrHashWithNumber(rpcBlockNumber)) + return statedb, err +} + +// StateAtTransaction returns the execution environment of a certain transaction +func (b *Backend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, error) { + return nil, vm.BlockContext{}, nil, errMethodNotSupported +} diff --git a/pkg/eth/backend.go b/pkg/eth/backend.go index 0a1d9517..7e55877c 100644 --- a/pkg/eth/backend.go +++ b/pkg/eth/backend.go @@ -258,6 +258,11 @@ func (b *Backend) GetTd(blockHash common.Hash) (*big.Int, error) { return td, nil } +// ChainConfig returns the active chain configuration. +func (b *Backend) ChainConfig() *params.ChainConfig { + return b.Config.ChainConfig +} + // CurrentBlock returns the current block func (b *Backend) CurrentBlock() (*types.Block, error) { block, err := b.BlockByNumber(context.Background(), rpc.LatestBlockNumber) @@ -849,8 +854,8 @@ func (b *Backend) ValidateTrie(stateRoot common.Hash) error { } // RPCGasCap returns the configured gas cap for the rpc server -func (b *Backend) RPCGasCap() *big.Int { - return b.Config.RPCGasCap +func (b *Backend) RPCGasCap() uint64 { + return b.Config.RPCGasCap.Uint64() } func (b *Backend) SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription { diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go index 9047839d..b4dc9ffe 100644 --- a/pkg/graphql/graphql.go +++ b/pkg/graphql/graphql.go @@ -838,7 +838,7 @@ func (b *Block) Call(ctx context.Context, args struct { return nil, err } } - result, err := eth.DoCall(ctx, b.backend, args.Data, *b.numberOrHash, nil, 5*time.Second, b.backend.RPCGasCap().Uint64()) + result, err := eth.DoCall(ctx, b.backend, args.Data, *b.numberOrHash, nil, 5*time.Second, b.backend.RPCGasCap()) if err != nil { return nil, err } diff --git a/pkg/rpc/ipc.go b/pkg/rpc/ipc.go index e18fe4af..5a09f5af 100644 --- a/pkg/rpc/ipc.go +++ b/pkg/rpc/ipc.go @@ -25,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum/p2p/netutil" "github.com/ethereum/go-ethereum/rpc" log "github.com/sirupsen/logrus" + "github.com/cerc-io/ipld-eth-server/v4/pkg/prom" ) diff --git a/pkg/serve/config.go b/pkg/serve/config.go index 09e484cb..fd345ed2 100644 --- a/pkg/serve/config.go +++ b/pkg/serve/config.go @@ -219,6 +219,8 @@ func NewConfig() (*Config, error) { if rpcGasCap, ok := new(big.Int).SetString(rpcGasCapStr, 10); ok { c.RPCGasCap = rpcGasCap } + } else { + c.RPCGasCap = big.NewInt(0) } chainConfigPath := viper.GetString("ethereum.chainConfig") if chainConfigPath != "" { diff --git a/pkg/serve/service.go b/pkg/serve/service.go index 10f97ee9..297b7183 100644 --- a/pkg/serve/service.go +++ b/pkg/serve/service.go @@ -24,6 +24,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/tracers" ethnode "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/rlp" @@ -31,6 +32,7 @@ import ( "github.com/jmoiron/sqlx" log "github.com/sirupsen/logrus" + "github.com/cerc-io/ipld-eth-server/v4/pkg/debug" "github.com/cerc-io/ipld-eth-server/v4/pkg/eth" "github.com/cerc-io/ipld-eth-server/v4/pkg/net" ) @@ -139,16 +141,23 @@ func (sap *Service) APIs() []rpc.API { Public: true, }, } + ethAPI, err := eth.NewPublicEthAPI(sap.backend, sap.client, sap.supportsStateDiffing, sap.forwardEthCalls, sap.proxyOnError) if err != nil { log.Fatalf("unable to create public eth api: %v", err) } - return append(apis, rpc.API{ - Namespace: eth.APIName, - Version: eth.APIVersion, - Service: ethAPI, - Public: true, - }) + + debugTracerAPI := tracers.APIs(&debug.Backend{Backend: *sap.backend})[0] + + return append(apis, + rpc.API{ + Namespace: eth.APIName, + Version: eth.APIVersion, + Service: ethAPI, + Public: true, + }, + debugTracerAPI, + ) } // Serve listens for incoming converter data off the screenAndServePayload from the Sync process diff --git a/test/README.md b/test/README.md index 02c21b9d..2a4bb99c 100644 --- a/test/README.md +++ b/test/README.md @@ -10,10 +10,10 @@ git checkout v4.2.1-alpha ``` -- Checkout [v4 release](https://github.com/vulcanize/go-ethereum/releases/tag/v1.10.21-statediff-4.1.2-alpha) in go-ethereum repo. +- Checkout [v4 release](https://github.com/vulcanize/go-ethereum/releases/tag/v1.10.23-statediff-4.2.0-alpha) in go-ethereum repo. ```bash # In go-ethereum repo. - git checkout v1.10.21-statediff-4.1.2-alpha + git checkout v1.10.23-statediff-4.2.0-alpha ``` - Checkout working commit in stack-orchestrator repo. diff --git a/test/watch_address_integration_test.go b/test/watch_address_integration_test.go index ffa00aee..0ee334b7 100644 --- a/test/watch_address_integration_test.go +++ b/test/watch_address_integration_test.go @@ -13,6 +13,7 @@ import ( sdtypes "github.com/ethereum/go-ethereum/statediff/types" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + integration "github.com/cerc-io/ipld-eth-server/v4/test" )