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

chore: merge nv18 code #5682

Merged
merged 11 commits into from
Feb 1, 2023
9 changes: 3 additions & 6 deletions app/node/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,9 @@ func (b *Builder) build(ctx context.Context) (*Node, error) {
blockDelay := b.repo.Config().NetworkParams.BlockDelay
nd.common = common.NewCommonModule(nd.chain, nd.network, blockDelay)

var txHashDBPath string
if b.repo.Config().FevmConfig.EnableEthHashToFilecoinCidMapping {
txHashDBPath, err = b.repo.SqlitePath()
if err != nil {
return nil, err
}
txHashDBPath, err := b.repo.SqlitePath()
if err != nil {
return nil, err
}
if nd.eth, err = eth.NewEthSubModule(b.repo.Config(), nd.chain, nd.mpool, txHashDBPath); err != nil {
return nil, err
Expand Down
134 changes: 134 additions & 0 deletions app/submodule/eth/dummy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package eth

import (
"context"
"errors"

"github.com/ipfs/go-cid"

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

var ErrModuleDisabled = errors.New("module disabled, enable with Fevm.EnableEthRPC")

type ethAPIDummy struct{}

func (e *ethAPIDummy) EthGetMessageCidByTransactionHash(ctx context.Context, txHash *types.EthHash) (*cid.Cid, error) {
return nil, ErrModuleDisabled
}

func (e *ethAPIDummy) EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*types.EthHash, error) {
return nil, ErrModuleDisabled
}

func (e *ethAPIDummy) EthBlockNumber(ctx context.Context) (types.EthUint64, error) {
return 0, ErrModuleDisabled
}

func (e *ethAPIDummy) EthAccounts(ctx context.Context) ([]types.EthAddress, error) {
return nil, ErrModuleDisabled
}

func (e *ethAPIDummy) EthGetBlockTransactionCountByNumber(ctx context.Context, blkNum types.EthUint64) (types.EthUint64, error) {
return 0, ErrModuleDisabled
}

func (e *ethAPIDummy) EthGetBlockTransactionCountByHash(ctx context.Context, blkHash types.EthHash) (types.EthUint64, error) {
return 0, ErrModuleDisabled
}

func (e *ethAPIDummy) EthGetBlockByHash(ctx context.Context, blkHash types.EthHash, fullTxInfo bool) (types.EthBlock, error) {
return types.EthBlock{}, ErrModuleDisabled
}

func (e *ethAPIDummy) EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (types.EthBlock, error) {
return types.EthBlock{}, ErrModuleDisabled
}

func (e *ethAPIDummy) EthGetTransactionByHash(ctx context.Context, txHash *types.EthHash) (*types.EthTx, error) {
return nil, ErrModuleDisabled
}

func (e *ethAPIDummy) EthGetTransactionCount(ctx context.Context, sender types.EthAddress, blkOpt string) (types.EthUint64, error) {
return 0, ErrModuleDisabled
}

func (e *ethAPIDummy) EthGetTransactionReceipt(ctx context.Context, txHash types.EthHash) (*types.EthTxReceipt, error) {
return nil, ErrModuleDisabled
}

func (e *ethAPIDummy) EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash types.EthHash, txIndex types.EthUint64) (types.EthTx, error) {
return types.EthTx{}, ErrModuleDisabled
}

func (e *ethAPIDummy) EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum types.EthUint64, txIndex types.EthUint64) (types.EthTx, error) {
return types.EthTx{}, ErrModuleDisabled
}

func (e *ethAPIDummy) EthGetCode(ctx context.Context, address types.EthAddress, blkOpt string) (types.EthBytes, error) {
return nil, ErrModuleDisabled
}

func (e *ethAPIDummy) EthGetStorageAt(ctx context.Context, address types.EthAddress, position types.EthBytes, blkParam string) (types.EthBytes, error) {
return nil, ErrModuleDisabled
}

func (e *ethAPIDummy) EthGetBalance(ctx context.Context, address types.EthAddress, blkParam string) (types.EthBigInt, error) {
return types.EthBigIntZero, ErrModuleDisabled
}

func (e *ethAPIDummy) EthFeeHistory(ctx context.Context, blkCount types.EthUint64, newestBlk string, rewardPercentiles []float64) (types.EthFeeHistory, error) {
return types.EthFeeHistory{}, ErrModuleDisabled
}

func (e *ethAPIDummy) EthChainId(ctx context.Context) (types.EthUint64, error) {
return 0, ErrModuleDisabled
}

func (e *ethAPIDummy) NetVersion(ctx context.Context) (string, error) {
return "", ErrModuleDisabled
}

func (e *ethAPIDummy) NetListening(ctx context.Context) (bool, error) {
return false, ErrModuleDisabled
}

func (e *ethAPIDummy) EthProtocolVersion(ctx context.Context) (types.EthUint64, error) {
return 0, ErrModuleDisabled
}

func (e *ethAPIDummy) EthGasPrice(ctx context.Context) (types.EthBigInt, error) {
return types.EthBigIntZero, ErrModuleDisabled
}

func (e *ethAPIDummy) EthEstimateGas(ctx context.Context, tx types.EthCall) (types.EthUint64, error) {
return 0, ErrModuleDisabled
}

func (e *ethAPIDummy) EthCall(ctx context.Context, tx types.EthCall, blkParam string) (types.EthBytes, error) {
return nil, ErrModuleDisabled
}

func (e *ethAPIDummy) EthMaxPriorityFeePerGas(ctx context.Context) (types.EthBigInt, error) {
return types.EthBigIntZero, ErrModuleDisabled
}

func (e *ethAPIDummy) EthSendRawTransaction(ctx context.Context, rawTx types.EthBytes) (types.EthHash, error) {
return types.EthHash{}, ErrModuleDisabled
}

func (e *ethAPIDummy) Web3ClientVersion(ctx context.Context) (string, error) {
return "", ErrModuleDisabled
}

func (e *ethAPIDummy) start(_ context.Context) error {
return nil
}

func (e *ethAPIDummy) close() error {
return nil
}

var _ v1.IETH = &ethAPIDummy{}
var _ ehtAPIAdapter = &ethAPIDummy{}
139 changes: 111 additions & 28 deletions app/submodule/eth/eth_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"errors"
"fmt"
"path/filepath"
"strconv"
"time"

Expand All @@ -19,6 +20,7 @@ import (
"github.com/filecoin-project/venus/pkg/constants"
"github.com/filecoin-project/venus/pkg/crypto"
"github.com/filecoin-project/venus/pkg/ethhashlookup"
"github.com/filecoin-project/venus/pkg/events"
"github.com/filecoin-project/venus/pkg/fork"
"github.com/filecoin-project/venus/pkg/vm"
"github.com/filecoin-project/venus/pkg/vm/vmcontext"
Expand All @@ -33,20 +35,55 @@ import (

var log = logging.Logger("eth_api")

func newEthAPI(em *EthSubModule) *ethAPI {
return &ethAPI{
em: em,
chain: em.chainModule.API(),
mpool: em.mpoolModule.API(),
ethTxHashManager: em.ethTxHashManager,
func newEthAPI(em *EthSubModule) (*ethAPI, error) {
a := &ethAPI{
em: em,
chain: em.chainModule.API(),
mpool: em.mpoolModule.API(),
}

transactionHashLookup, err := ethhashlookup.NewTransactionHashLookup(filepath.Join(a.em.txHashDBPath, "txhash.db"))
if err != nil {
return nil, err
}

a.ethTxHashManager = &ethTxHashManager{
chainAPI: a.chain,
TransactionHashLookup: transactionHashLookup,
}

return a, nil
}

type ethAPI struct {
em *EthSubModule
chain v1.IChain
mpool v1.IMessagePool
ethTxHashManager *ethTxHashManager // may nil
ethTxHashManager *ethTxHashManager
}

func (a *ethAPI) start(ctx context.Context) error {
const ChainHeadConfidence = 1
ev, err := events.NewEventsWithConfidence(ctx, a.chain, ChainHeadConfidence)
if err != nil {
return err
}

// Tipset listener
_ = ev.Observe(a.ethTxHashManager)

ch, err := a.em.mpoolModule.MPool.Updates(ctx)
if err != nil {
return err
}
go waitForMpoolUpdates(ctx, ch, a.ethTxHashManager)
go ethTxHashGC(ctx, a.em.cfg.FevmConfig.EthTxHashMappingLifetimeDays, a.ethTxHashManager)

return nil
}

func (a *ethAPI) close() error {
return a.ethTxHashManager.TransactionHashLookup.Close()
}

func (a *ethAPI) StateNetworkName(ctx context.Context) (types.NetworkName, error) {
Expand Down Expand Up @@ -117,11 +154,6 @@ func (a *ethAPI) EthGetBlockByHash(ctx context.Context, blkHash types.EthHash, f
return newEthBlockFromFilecoinTipSet(ctx, ts, fullTxInfo, a.em.chainModule.MessageStore, a.chain)
}

func (a *ethAPI) EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*types.EthHash, error) {
hash, err := ethTxHashFromFilecoinMessageCid(ctx, cid, a.em.chainModule.MessageStore, a.chain)
return &hash, err
}

func (a *ethAPI) parseBlkParam(ctx context.Context, blkParam string) (tipset *types.TipSet, err error) {
if blkParam == "earliest" {
return nil, fmt.Errorf("block param \"earliest\" is not supported")
Expand Down Expand Up @@ -168,14 +200,11 @@ func (a *ethAPI) EthGetTransactionByHash(ctx context.Context, txHash *types.EthH
return nil, nil
}

c := cid.Undef
if a.ethTxHashManager != nil {
var err error
c, err = a.ethTxHashManager.TransactionHashLookup.GetCidFromHash(*txHash)
if err != nil {
log.Debug("could not find transaction hash %s in lookup table", txHash.String())
}
c, err := a.ethTxHashManager.TransactionHashLookup.GetCidFromHash(*txHash)
if err != nil {
log.Debug("could not find transaction hash %s in lookup table", txHash.String())
}

// This isn't an eth transaction we have the mapping for, so let's look it up as a filecoin message
if c == cid.Undef {
c = txHash.ToCid()
Expand Down Expand Up @@ -211,6 +240,53 @@ func (a *ethAPI) EthGetTransactionByHash(ctx context.Context, txHash *types.EthH
return nil, nil
}

func (a *ethAPI) EthGetMessageCidByTransactionHash(ctx context.Context, txHash *types.EthHash) (*cid.Cid, error) {
// Ethereum's behavior is to return null when the txHash is invalid, so we use nil to check if txHash is valid
if txHash == nil {
return nil, nil
}

c, err := a.ethTxHashManager.TransactionHashLookup.GetCidFromHash(*txHash)
// We fall out of the first condition and continue
if errors.Is(err, ethhashlookup.ErrNotFound) {
log.Debug("could not find transaction hash %s in lookup table", txHash.String())
} else if err != nil {
return nil, fmt.Errorf("database error: %w", err)
} else {
return &c, nil
}

// This isn't an eth transaction we have the mapping for, so let's try looking it up as a filecoin message
if c == cid.Undef {
c = txHash.ToCid()
}

_, err = a.em.chainModule.MessageStore.LoadSignedMessage(ctx, c)
if err == nil {
// This is an Eth Tx, Secp message, Or BLS message in the mpool
return &c, nil
}

_, err = a.em.chainModule.MessageStore.LoadUnsignedMessage(ctx, c)
if err == nil {
// This is a BLS message
return &c, nil
}

// Ethereum clients expect an empty response when the message was not found
return nil, nil
}

func (a *ethAPI) EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*types.EthHash, error) {
hash, err := ethTxHashFromFilecoinMessageCid(ctx, cid, a.em.chainModule.MessageStore, a.chain)
if hash == types.EmptyEthHash {
// not found
return nil, nil
}

return &hash, err
}

func (a *ethAPI) EthGetTransactionCount(ctx context.Context, sender types.EthAddress, blkParam string) (types.EthUint64, error) {
addr, err := sender.ToFilecoinAddress()
if err != nil {
Expand All @@ -228,14 +304,11 @@ func (a *ethAPI) EthGetTransactionCount(ctx context.Context, sender types.EthAdd
}

func (a *ethAPI) EthGetTransactionReceipt(ctx context.Context, txHash types.EthHash) (*types.EthTxReceipt, error) {
c := cid.Undef
if a.ethTxHashManager != nil {
var err error
c, err = a.ethTxHashManager.TransactionHashLookup.GetCidFromHash(txHash)
if err != nil {
log.Debug("could not find transaction hash %s in lookup table", txHash.String())
}
c, err := a.ethTxHashManager.TransactionHashLookup.GetCidFromHash(txHash)
if err != nil {
log.Debug("could not find transaction hash %s in lookup table", txHash.String())
}

// This isn't an eth transaction we have the mapping for, so let's look it up as a filecoin message
if c == cid.Undef {
c = txHash.ToCid()
Expand Down Expand Up @@ -827,10 +900,17 @@ func lookupEthAddress(ctx context.Context, addr address.Address, ca v1.IChain) (
func ethTxHashFromFilecoinMessageCid(ctx context.Context, c cid.Cid, ms *chain.MessageStore, ca v1.IChain) (types.EthHash, error) {
smsg, err := ms.LoadSignedMessage(ctx, c)
if err == nil {
// This is an Eth Tx, Secp message, Or BLS message in the mpool
return ethTxHashFromSignedFilecoinMessage(ctx, smsg, ca)
}

return types.EthHashFromCid(c)
_, err = ms.LoadUnsignedMessage(ctx, c)
if err == nil {
// This is a BLS message
return types.EthHashFromCid(c)
}

return types.EmptyEthHash, nil
}

func ethTxHashFromSignedFilecoinMessage(ctx context.Context, smsg *types.SignedMessage, ca v1.IChain) (types.EthHash, error) {
Expand Down Expand Up @@ -1070,7 +1150,7 @@ func newEthTxReceipt(ctx context.Context, tx types.EthTx, lookup *types.MsgLooku
}

for _, entry := range evt.Entries {
value := types.EthBytes(leftpad32(decodeLogBytes(entry.Value)))
value := types.EthBytes(leftpad32(entry.Value)) // value has already been cbor-decoded but see https://github.com/filecoin-project/ref-fvm/issues/1345
if entry.Key == types.EthTopic1 || entry.Key == types.EthTopic2 || entry.Key == types.EthTopic3 || entry.Key == types.EthTopic4 {
l.Topics = append(l.Topics, value)
} else {
Expand Down Expand Up @@ -1180,3 +1260,6 @@ func ethTxHashGC(ctx context.Context, retentionDays int, manager *ethTxHashManag
time.Sleep(gcPeriod)
}
}

var _ v1.IETH = &ethAPI{}
var _ ehtAPIAdapter = &ethAPI{}
Loading