use ipld-eth-statedb for eth_call and graphql endpoints

This commit is contained in:
i-norden 2023-03-13 11:25:19 -05:00
parent ba5cdecf93
commit aab5a2ef0b
7 changed files with 33 additions and 33 deletions

4
go.mod
View File

@ -6,13 +6,14 @@ require (
github.com/cerc-io/eth-ipfs-state-validator/v4 v4.0.10-alpha
github.com/cerc-io/go-eth-state-node-iterator v1.1.9
github.com/cerc-io/ipfs-ethdb/v4 v4.0.10-alpha
github.com/cerc-io/ipld-eth-statedb v0.0.1-alpha
github.com/cerc-io/ipld-eth-statedb v0.0.2-alpha
github.com/ethereum/go-ethereum v1.10.26
github.com/google/uuid v1.3.0
github.com/graph-gophers/graphql-go v1.3.0
github.com/ipfs/go-cid v0.2.0
github.com/ipfs/go-ipfs-blockstore v1.2.0
github.com/ipfs/go-ipfs-ds-help v1.1.0
github.com/jackc/pgx/v4 v4.18.1
github.com/jmoiron/sqlx v1.3.5
github.com/joho/godotenv v1.4.0
github.com/lib/pq v1.10.6
@ -145,7 +146,6 @@ require (
github.com/jackc/pgproto3/v2 v2.3.2 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgtype v1.14.0 // indirect
github.com/jackc/pgx/v4 v4.18.1 // indirect
github.com/jackc/puddle v1.3.0 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect

4
go.sum
View File

@ -153,8 +153,8 @@ github.com/cerc-io/go-ethereum v1.10.26-statediff-4.2.2-alpha h1:gesMZEbNU+fcAMc
github.com/cerc-io/go-ethereum v1.10.26-statediff-4.2.2-alpha/go.mod h1:lKBVBWksSwBDR/5D9CAxaGQzDPIS3ueWb6idy7X1Shg=
github.com/cerc-io/ipfs-ethdb/v4 v4.0.10-alpha h1:5iqNXeitkj3g7FxyKK/Pz+1HN7Ac9JZzCRj3Lv+uHiw=
github.com/cerc-io/ipfs-ethdb/v4 v4.0.10-alpha/go.mod h1:dPscFRMvTWPKnoZ4U0D9v4bsrw6XdH7sOp8hUrVzOWA=
github.com/cerc-io/ipld-eth-statedb v0.0.1-alpha h1:oUSxncZCzMO4JXep/CoP+u1lgpdf97mbCUYWnjcHw6w=
github.com/cerc-io/ipld-eth-statedb v0.0.1-alpha/go.mod h1:914KQXnRylWQxRQOvlIr74NmGw7t1CyJJaEr5VSKW8E=
github.com/cerc-io/ipld-eth-statedb v0.0.2-alpha h1:Dj6XG6T14iHRBMFYHKcnMkNsdxZ7xqAaah2Z+QiOe1k=
github.com/cerc-io/ipld-eth-statedb v0.0.2-alpha/go.mod h1:914KQXnRylWQxRQOvlIr74NmGw7t1CyJJaEr5VSKW8E=
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=

View File

@ -42,6 +42,7 @@ type Backend struct {
}
// StateAtBlock retrieves the state database associated with a certain block
// We can't sub in our ipld-eth-statedb here because to match the expected interface we need to return *state.StateDB not vm.StateDB
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))

View File

@ -28,13 +28,13 @@ import (
"time"
"github.com/cerc-io/ipld-eth-server/v4/pkg/log"
ipld_eth_statedb "github.com/cerc-io/ipld-eth-statedb"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
"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/crypto"
"github.com/ethereum/go-ethereum/eth/filters"
@ -875,6 +875,7 @@ func (pea *PublicEthAPI) GetProof(ctx context.Context, address common.Address, s
return nil, err
}
// this continues to use ipfs-ethdb based geth StateDB as it requires trie access
func (pea *PublicEthAPI) localGetProof(ctx context.Context, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*AccountResult, error) {
state, _, err := pea.B.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
if state == nil || err != nil {
@ -977,7 +978,7 @@ type OverrideAccount struct {
type StateOverride map[common.Address]OverrideAccount
// Apply overrides the fields of specified accounts into the given state.
func (diff *StateOverride) Apply(state *state.StateDB) error {
func (diff *StateOverride) Apply(state *ipld_eth_statedb.StateDB) error {
if diff == nil {
return nil
}
@ -1054,7 +1055,7 @@ func DoCall(ctx context.Context, b *Backend, args CallArgs, blockNrOrHash rpc.Bl
log.Debugxf(ctx, "Executing EVM call finished %s runtime %s", time.Now().String(), time.Since(start).String())
}(time.Now())
state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
state, header, err := b.IPLDStateDBAndHeaderByNumberOrHash(ctx, blockNrOrHash)
if state == nil || err != nil {
return nil, err
}

View File

@ -632,7 +632,6 @@ func (b *Backend) GetLogs(ctx context.Context, hash common.Hash, number uint64)
}
// StateAndHeaderByNumberOrHash returns the statedb and header for the provided block number or hash
// TODO: this needs to be updated to use the new StateDB implementation
func (b *Backend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) {
if blockNr, ok := blockNrOrHash.Number(); ok {
return b.StateAndHeaderByNumber(ctx, blockNr)
@ -659,9 +658,9 @@ func (b *Backend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHas
}
// IPLDStateDBAndHeaderByNumberOrHash returns the statedb and header for the provided block number or hash
func (b *Backend) IPLDStateDBAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (vm.StateDB, *types.Header, error) {
func (b *Backend) IPLDStateDBAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*ipld_eth_statedb.StateDB, *types.Header, error) {
if blockNr, ok := blockNrOrHash.Number(); ok {
return b.StateAndHeaderByNumber(ctx, blockNr)
return b.IPLDStateDBAndHeaderByNumber(ctx, blockNr)
}
if hash, ok := blockNrOrHash.Hash(); ok {
header, err := b.HeaderByHash(ctx, hash)
@ -684,24 +683,6 @@ func (b *Backend) IPLDStateDBAndHeaderByNumberOrHash(ctx context.Context, blockN
return nil, nil, errors.New("invalid arguments; neither block nor hash specified")
}
// IPLDStateDBAndHeaderByNumber returns the statedb and header for a provided block number
func (b *Backend) IPLDStateDBAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (vm.StateDB, *types.Header, error) {
// Pending state is only known by the miner
if number == rpc.PendingBlockNumber {
return nil, nil, errPendingBlockNumber
}
// Otherwise resolve the block number and return its state
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 := ipld_eth_statedb.New(header.Root, b.IpldStateDatabase)
return stateDb, header, err
}
// StateAndHeaderByNumber returns the statedb and header for a provided block number
func (b *Backend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
// Pending state is only known by the miner
@ -720,6 +701,24 @@ func (b *Backend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNu
return stateDb, header, err
}
// IPLDStateDBAndHeaderByNumber returns the statedb and header for a provided block number
func (b *Backend) IPLDStateDBAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*ipld_eth_statedb.StateDB, *types.Header, error) {
// Pending state is only known by the miner
if number == rpc.PendingBlockNumber {
return nil, nil, errPendingBlockNumber
}
// Otherwise resolve the block number and return its state
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 := ipld_eth_statedb.New(header.Root, b.IpldStateDatabase)
return stateDb, header, err
}
// GetCanonicalHash gets the canonical hash for the provided number, if there is one
func (b *Backend) GetCanonicalHash(number uint64) (common.Hash, error) {
var hashResult string
@ -741,7 +740,7 @@ func (b *Backend) GetCanonicalHeader(number uint64) (string, []byte, error) {
}
// GetEVM constructs and returns a vm.EVM
func (b *Backend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) {
func (b *Backend) GetEVM(ctx context.Context, msg core.Message, state vm.StateDB, header *types.Header) (*vm.EVM, func() error, error) {
vmError := func() error { return nil }
txContext := core.NewEVMTxContext(msg)
blockContext := core.NewEVMBlockContext(header, b, nil)

View File

@ -29,7 +29,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"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/eth/filters"
"github.com/ethereum/go-ethereum/rlp"
@ -51,8 +50,8 @@ type Account struct {
}
// getState fetches the StateDB object for an account.
func (a *Account) getState(ctx context.Context) (*state.StateDB, error) {
state, _, err := a.backend.StateAndHeaderByNumberOrHash(ctx, a.blockNrOrHash)
func (a *Account) getState(ctx context.Context) (*ipld_eth_statedb.StateDB, error) {
state, _, err := a.backend.IPLDStateDBAndHeaderByNumberOrHash(ctx, a.blockNrOrHash)
return state, err
}

View File

@ -81,7 +81,7 @@ func (s *Service) Start(server *p2p.Server) error {
return nil
}
// newHandler returns a new `http.Handler` that will answer GraphQL queries.
// NewHandler returns a new `http.Handler` that will answer GraphQL queries.
// It additionally exports an interactive query browser on the / endpoint.
func NewHandler(backend *eth.Backend) (http.Handler, error) {
q := Resolver{backend}