Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement a few ethereum JSON-RPC API methods #5563

Merged
merged 3 commits into from
Dec 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions app/node/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/filecoin-project/venus-auth/jwtclient"
"github.com/filecoin-project/venus/app/submodule/dagservice"
"github.com/filecoin-project/venus/app/submodule/eth"
"github.com/filecoin-project/venus/app/submodule/network"

logging "github.com/ipfs/go-log"
Expand Down Expand Up @@ -165,6 +166,10 @@ func (b *Builder) build(ctx context.Context) (*Node, error) {
blockDelay := b.repo.Config().NetworkParams.BlockDelay
nd.common = common.NewCommonModule(nd.chain, nd.network, blockDelay)

if nd.eth, err = eth.NewEthSubModule(nd.chain); err != nil {
return nil, err
}

apiBuilder := NewBuilder()
apiBuilder.NameSpace("Filecoin")

Expand All @@ -181,6 +186,7 @@ func (b *Builder) build(ctx context.Context) (*Node, error) {
nd.paychan,
nd.market,
nd.common,
nd.eth,
)

if err != nil {
Expand Down
1 change: 1 addition & 0 deletions app/node/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type Env struct {
MarketAPI v1api.IMarket
PaychAPI v1api.IPaychan
CommonAPI v1api.ICommon
EthAPI v1api.IETH
}

var _ cmds.Environment = (*Env)(nil)
Expand Down
4 changes: 4 additions & 0 deletions app/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/filecoin-project/venus/app/submodule/common"
configModule "github.com/filecoin-project/venus/app/submodule/config"
"github.com/filecoin-project/venus/app/submodule/dagservice"
"github.com/filecoin-project/venus/app/submodule/eth"
"github.com/filecoin-project/venus/app/submodule/market"
"github.com/filecoin-project/venus/app/submodule/mining"
"github.com/filecoin-project/venus/app/submodule/mpool"
Expand Down Expand Up @@ -95,6 +96,8 @@ type Node struct {

common *common.CommonModule

eth *eth.EthSubModule

//
// Jsonrpc
//
Expand Down Expand Up @@ -358,6 +361,7 @@ func (node *Node) createServerEnv(ctx context.Context) *Env {
MarketAPI: node.market.API(),
MultiSigAPI: &apiwrapper.WrapperV1IMultiSig{IMultiSig: node.multiSig.API(), IMessagePool: node.mpool.API()},
CommonAPI: node.common,
EthAPI: node.eth.API(),
}

return &env
Expand Down
29 changes: 29 additions & 0 deletions app/node/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,35 @@ func (builder *RPCBuilder) Build(version string, limiter *ratelimit.RateLimiter)
default:
panic("invalid version: " + version)
}
aliasETHAPI(server)

return server
}

func aliasETHAPI(rpcServer *jsonrpc.RPCServer) {
// TODO: use reflect to automatically register all the eth aliases
rpcServer.AliasMethod("eth_accounts", "Filecoin.EthAccounts")
rpcServer.AliasMethod("eth_blockNumber", "Filecoin.EthBlockNumber")
rpcServer.AliasMethod("eth_getBlockTransactionCountByNumber", "Filecoin.EthGetBlockTransactionCountByNumber")
rpcServer.AliasMethod("eth_getBlockTransactionCountByHash", "Filecoin.EthGetBlockTransactionCountByHash")

rpcServer.AliasMethod("eth_getBlockByHash", "Filecoin.EthGetBlockByHash")
rpcServer.AliasMethod("eth_getBlockByNumber", "Filecoin.EthGetBlockByNumber")
rpcServer.AliasMethod("eth_getTransactionByHash", "Filecoin.EthGetTransactionByHash")
rpcServer.AliasMethod("eth_getTransactionCount", "Filecoin.EthGetTransactionCount")
rpcServer.AliasMethod("eth_getTransactionReceipt", "Filecoin.EthGetTransactionReceipt")
rpcServer.AliasMethod("eth_getTransactionByBlockHashAndIndex", "Filecoin.EthGetTransactionByBlockHashAndIndex")
rpcServer.AliasMethod("eth_getTransactionByBlockNumberAndIndex", "Filecoin.EthGetTransactionByBlockNumberAndIndex")

rpcServer.AliasMethod("eth_getCode", "Filecoin.EthGetCode")
rpcServer.AliasMethod("eth_getStorageAt", "Filecoin.EthGetStorageAt")
rpcServer.AliasMethod("eth_getBalance", "Filecoin.EthGetBalance")
rpcServer.AliasMethod("eth_chainId", "Filecoin.EthChainId")
rpcServer.AliasMethod("eth_protocolVersion", "Filecoin.EthProtocolVersion")
rpcServer.AliasMethod("eth_maxPriorityFeePerGas", "Filecoin.EthMaxPriorityFeePerGas")
rpcServer.AliasMethod("eth_gasPrice", "Filecoin.EthGasPrice")
rpcServer.AliasMethod("eth_sendRawTransaction", "Filecoin.EthSendRawTransaction")

rpcServer.AliasMethod("net_version", "Filecoin.NetVersion")
rpcServer.AliasMethod("net_listening", "Filecoin.NetListening")
}
139 changes: 139 additions & 0 deletions app/submodule/eth/eth_api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package eth

import (
"context"
"fmt"
"strconv"

"github.com/filecoin-project/go-state-types/abi"
v1 "github.com/filecoin-project/venus/venus-shared/api/chain/v1"
"github.com/filecoin-project/venus/venus-shared/types"
)

type ethAPI struct {
em *EthSubModule
chain v1.IChain
}

func (a *ethAPI) EthBlockNumber(ctx context.Context) (types.EthInt, error) {
head, err := a.chain.ChainHead(ctx)
if err != nil {
return types.EthInt(0), err
}
return types.EthInt(head.Height()), nil
}

func (a *ethAPI) EthAccounts(context.Context) ([]types.EthAddress, error) {
// The lotus node is not expected to hold manage accounts, so we'll always return an empty array
return []types.EthAddress{}, nil
}

func (a *ethAPI) countTipsetMsgs(ctx context.Context, ts *types.TipSet) (int, error) {
msgs, err := a.em.chainModule.MessageStore.LoadTipSetMessage(ctx, ts)
if err != nil {
return 0, fmt.Errorf("error loading messages for tipset: %v: %w", ts, err)
}

return len(msgs), nil
}

func (a *ethAPI) EthGetBlockTransactionCountByNumber(ctx context.Context, blkNum types.EthInt) (types.EthInt, error) {
ts, err := a.em.chainModule.ChainReader.GetTipSetByHeight(ctx, nil, abi.ChainEpoch(blkNum), false)
if err != nil {
return types.EthInt(0), fmt.Errorf("error loading tipset %s: %w", ts, err)
}

count, err := a.countTipsetMsgs(ctx, ts)
return types.EthInt(count), err
}

func (a *ethAPI) EthGetBlockTransactionCountByHash(ctx context.Context, blkHash types.EthHash) (types.EthInt, error) {
ts, err := a.em.chainModule.ChainReader.GetTipSetByCid(ctx, blkHash.ToCid())
if err != nil {
return types.EthInt(0), fmt.Errorf("error loading tipset %s: %w", ts, err)
}
count, err := a.countTipsetMsgs(ctx, ts)
return types.EthInt(count), err
}

func (a *ethAPI) EthGetBlockByHash(ctx context.Context, blkHash types.EthHash, fullTxInfo bool) (types.EthBlock, error) {
return types.EthBlock{}, nil
}

func (a *ethAPI) EthGetBlockByNumber(ctx context.Context, blkNum types.EthInt, fullTxInfo bool) (types.EthBlock, error) {
return types.EthBlock{}, nil
}

func (a *ethAPI) EthGetTransactionByHash(ctx context.Context, txHash types.EthHash) (types.EthTx, error) {
return types.EthTx{}, nil
}

func (a *ethAPI) EthGetTransactionCount(ctx context.Context, sender types.EthAddress, blkParam string) (types.EthInt, error) {
return types.EthInt(0), nil
}

func (a *ethAPI) EthGetTransactionReceipt(ctx context.Context, blkHash types.EthHash) (types.EthTxReceipt, error) {
return types.EthTxReceipt{}, nil
}

func (a *ethAPI) EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash types.EthHash, txIndex types.EthInt) (types.EthTx, error) {
return types.EthTx{}, nil
}

func (a *ethAPI) EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum types.EthInt, txIndex types.EthInt) (types.EthTx, error) {
return types.EthTx{}, nil
}

// EthGetCode returns string value of the compiled bytecode
func (a *ethAPI) EthGetCode(ctx context.Context, address types.EthAddress) (string, error) {
return "", nil
}

func (a *ethAPI) EthGetStorageAt(ctx context.Context, address types.EthAddress, position types.EthInt, blkParam string) (string, error) {
return "", nil
}

func (a *ethAPI) EthGetBalance(ctx context.Context, address types.EthAddress, blkParam string) (types.EthBigInt, error) {
filAddr, err := address.ToFilecoinAddress()
if err != nil {
return types.EthBigInt{}, err
}

actor, err := a.chain.StateGetActor(ctx, filAddr, types.EmptyTSK)
if err != nil {
return types.EthBigInt{}, err
}

return types.EthBigInt{Int: actor.Balance.Int}, nil
}

func (a *ethAPI) EthChainId(ctx context.Context) (types.EthInt, error) {
return types.EthInt(0), nil
}

func (a *ethAPI) NetVersion(ctx context.Context) (string, error) {
// Note that networkId is not encoded in hex
nv, err := a.chain.StateNetworkVersion(ctx, types.EmptyTSK)
if err != nil {
return "", err
}
return strconv.FormatUint(uint64(nv), 10), nil
}

func (a *ethAPI) NetListening(ctx context.Context) (bool, error) {
return true, nil
}

func (a *ethAPI) EthProtocolVersion(ctx context.Context) (types.EthInt, error) {
return types.EthInt(0), nil
}

func (a *ethAPI) EthMaxPriorityFeePerGas(ctx context.Context) (types.EthInt, error) {
return types.EthInt(0), nil
}

func (a *ethAPI) EthGasPrice(ctx context.Context) (types.EthInt, error) {
return types.EthInt(0), nil
}

var _ v1.IETH = (*ethAPI)(nil)
20 changes: 20 additions & 0 deletions app/submodule/eth/eth_submodule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package eth

import (
"github.com/filecoin-project/venus/app/submodule/chain"
v1api "github.com/filecoin-project/venus/venus-shared/api/chain/v1"
)

func NewEthSubModule(chainModule *chain.ChainSubmodule) (*EthSubModule, error) {
return &EthSubModule{
chainModule: chainModule,
}, nil
}

type EthSubModule struct { // nolint
chainModule *chain.ChainSubmodule
}

func (em *EthSubModule) API() v1api.IETH {
return &ethAPI{em: em}
}
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ require (
github.com/dustin/go-humanize v1.0.0
github.com/fatih/color v1.13.0
github.com/filecoin-project/filecoin-ffi v0.30.4-0.20200910194244-f640612a1a1f
github.com/filecoin-project/go-address v1.0.0
github.com/filecoin-project/go-address v1.1.0
github.com/filecoin-project/go-bitfield v0.2.4
github.com/filecoin-project/go-cbor-util v0.0.1
github.com/filecoin-project/go-commp-utils v0.1.3
Expand All @@ -30,7 +30,7 @@ require (
github.com/filecoin-project/go-fil-markets v1.24.0-v17
github.com/filecoin-project/go-jsonrpc v0.1.5
github.com/filecoin-project/go-paramfetch v0.0.4
github.com/filecoin-project/go-state-types v0.9.8
github.com/filecoin-project/go-state-types v0.10.0-alpha-2
github.com/filecoin-project/pubsub v1.0.0
github.com/filecoin-project/specs-actors v0.9.15
github.com/filecoin-project/specs-actors/v2 v2.3.6
Expand All @@ -49,6 +49,7 @@ require (
github.com/golang/mock v1.6.0
github.com/google/go-github v17.0.0+incompatible
github.com/google/uuid v1.3.0
github.com/gorilla/websocket v1.5.0
github.com/hako/durafmt v0.0.0-20200710122514-c0fb7b4da026
github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e
github.com/hashicorp/go-multierror v1.1.1
Expand Down Expand Up @@ -83,6 +84,7 @@ require (
github.com/libp2p/go-libp2p v0.22.0
github.com/libp2p/go-libp2p-kad-dht v0.18.0
github.com/libp2p/go-libp2p-pubsub v0.8.0
github.com/libp2p/go-msgio v0.2.0
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1
github.com/mitchellh/go-homedir v1.1.0
github.com/multiformats/go-multiaddr v0.6.0
Expand Down Expand Up @@ -178,7 +180,6 @@ require (
github.com/google/go-querystring v1.0.0 // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/hannahhoward/cbor-gen-for v0.0.0-20200817222906-ea96cece81f1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
Expand Down Expand Up @@ -220,7 +221,6 @@ require (
github.com/libp2p/go-libp2p-core v0.20.0 // indirect
github.com/libp2p/go-libp2p-kbucket v0.4.7 // indirect
github.com/libp2p/go-libp2p-record v0.2.0 // indirect
github.com/libp2p/go-msgio v0.2.0 // indirect
github.com/libp2p/go-nat v0.1.0 // indirect
github.com/libp2p/go-netroute v0.2.0 // indirect
github.com/libp2p/go-openssl v0.1.0 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@ github.com/filecoin-project/dagstore v0.5.2 h1:Nd6oXdnolbbVhpMpkYT5PJHOjQp4OBSnt
github.com/filecoin-project/go-address v0.0.3/go.mod h1:jr8JxKsYx+lQlQZmF5i2U0Z+cGQ59wMIps/8YW/lDj8=
github.com/filecoin-project/go-address v0.0.5/go.mod h1:jr8JxKsYx+lQlQZmF5i2U0Z+cGQ59wMIps/8YW/lDj8=
github.com/filecoin-project/go-address v0.0.6/go.mod h1:7B0/5DA13n6nHkB8bbGx1gWzG/dbTsZ0fgOJVGsM3TE=
github.com/filecoin-project/go-address v1.0.0 h1:IrexI0kpADLaPP+CdmU3CVAUqnW/FQC0KTmz4lVKiFU=
github.com/filecoin-project/go-address v1.0.0/go.mod h1:5t3z6qPmIADZBtuE9EIzi0EwzcRy2nVhpo0I/c1r0OA=
github.com/filecoin-project/go-address v1.1.0 h1:ofdtUtEsNxkIxkDw67ecSmvtzaVSdcea4boAmLbnHfE=
github.com/filecoin-project/go-address v1.1.0/go.mod h1:5t3z6qPmIADZBtuE9EIzi0EwzcRy2nVhpo0I/c1r0OA=
github.com/filecoin-project/go-amt-ipld/v2 v2.1.0/go.mod h1:nfFPoGyX0CU9SkXX8EoCcSuHN1XcbN0c6KBh7yvP5fs=
github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20201006184820-924ee87a1349 h1:pIuR0dnMD0i+as8wNnjjHyQrnhP5O5bmba/lmgQeRgU=
github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20201006184820-924ee87a1349/go.mod h1:vgmwKBkx+ca5OIeEvstiQgzAZnb7R6QaqE1oEDSqa6g=
Expand Down Expand Up @@ -342,8 +342,8 @@ github.com/filecoin-project/go-state-types v0.1.4/go.mod h1:xCA/WfKlC2zcn3fUmDv4
github.com/filecoin-project/go-state-types v0.1.6/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q=
github.com/filecoin-project/go-state-types v0.1.8/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q=
github.com/filecoin-project/go-state-types v0.1.10/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q=
github.com/filecoin-project/go-state-types v0.9.8 h1:xkdITiR7h691z1tWOhNCJxHI+cq+Mq7ATkpHQ7f1gu8=
github.com/filecoin-project/go-state-types v0.9.8/go.mod h1:+HCZifUV+e8TlQkgll22Ucuiq8OrVJkK+4Kh4u75iiw=
github.com/filecoin-project/go-state-types v0.10.0-alpha-2 h1:xz8+sXAuCMane7SkEYCtQjD/zYJ4n1d5bxwYNL8Thf0=
github.com/filecoin-project/go-state-types v0.10.0-alpha-2/go.mod h1:7ty480tvttEAqWKywhAaDCElk7ksTqEXtXWAzTSdEKo=
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
github.com/filecoin-project/go-statemachine v1.0.2 h1:421SSWBk8GIoCoWYYTE/d+qCWccgmRH0uXotXRDjUbc=
github.com/filecoin-project/go-statemachine v1.0.2/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54=
Expand Down
25 changes: 25 additions & 0 deletions pkg/chain/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,24 @@ func (store *Store) GetTipSetByHeight(ctx context.Context, ts *types.TipSet, h a
return store.GetTipSet(ctx, lbts.Parents())
}

func (store *Store) GetTipSetByCid(ctx context.Context, c cid.Cid) (*types.TipSet, error) {
blk, err := store.bsstore.Get(ctx, c)
if err != nil {
return nil, fmt.Errorf("cannot find tipset with cid %s: %w", c, err)
}

tsk := new(types.TipSetKey)
if err := tsk.UnmarshalCBOR(bytes.NewReader(blk.RawData())); err != nil {
return nil, fmt.Errorf("cannot unmarshal block into tipset key: %w", err)
}

ts, err := store.GetTipSet(ctx, *tsk)
if err != nil {
return nil, fmt.Errorf("cannot get tipset from key: %w", err)
}
return ts, nil
}

// GetTipSetState returns the aggregate state of the tipset identified by `key`.
func (store *Store) GetTipSetState(ctx context.Context, ts *types.TipSet) (tree.Tree, error) {
if ts == nil {
Expand Down Expand Up @@ -548,6 +566,13 @@ func (store *Store) SetHead(ctx context.Context, newTS *types.TipSet) error {
old: dropped,
new: added,
}

tskBlk, err := newTS.Key().ToStorageBlock()
if err != nil {
log.Errorf("failed to create a block from tsk: %s", newTS.Key())
}
_ = store.bsstore.Put(ctx, tskBlk)

return nil
}

Expand Down
7 changes: 7 additions & 0 deletions venus-devtool/api-gen/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,13 @@ func init() {

uuidTmp := auuid.MustParse("102334ec-35a3-4b36-be9f-02883844503a")
addExample(&uuidTmp)

// eth types
ethint := types.EthInt(5)
addExample(ethint)
addExample(&ethint)
ethaddr, _ := types.EthAddressFromHex("0x5CbEeCF99d3fDB3f25E309Cc264f240bb0664031")
addExample(&ethaddr)
}

func ExampleValue(method string, t, parent reflect.Type) interface{} {
Expand Down
Loading