mirror of
https://github.com/filecoin-project/lotus.git
synced 2025-08-24 01:08:42 +08:00
248 lines
7.1 KiB
Go
248 lines
7.1 KiB
Go
package modules
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"go.uber.org/fx"
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/filecoin-project/go-address"
|
|
"github.com/filecoin-project/go-state-types/abi"
|
|
|
|
"github.com/filecoin-project/lotus/api"
|
|
"github.com/filecoin-project/lotus/chain/events"
|
|
"github.com/filecoin-project/lotus/chain/events/filter"
|
|
"github.com/filecoin-project/lotus/chain/index"
|
|
"github.com/filecoin-project/lotus/chain/messagepool"
|
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
|
"github.com/filecoin-project/lotus/chain/store"
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
|
"github.com/filecoin-project/lotus/node/config"
|
|
"github.com/filecoin-project/lotus/node/impl/eth"
|
|
"github.com/filecoin-project/lotus/node/impl/full"
|
|
"github.com/filecoin-project/lotus/node/modules/helpers"
|
|
)
|
|
|
|
type EthTransactionParams struct {
|
|
fx.In
|
|
|
|
MetricsCtx helpers.MetricsCtx
|
|
Lifecycle fx.Lifecycle
|
|
ChainStore eth.ChainStore
|
|
StateManager eth.StateManager
|
|
StateAPI eth.StateAPI
|
|
MpoolAPI eth.MpoolAPI
|
|
EthEventsExtended eth.EthEventsInternal
|
|
Indexer index.Indexer
|
|
}
|
|
|
|
func MakeEthTransaction(cfg config.FevmConfig) func(EthTransactionParams) (eth.EthTransactionAPI, error) {
|
|
return func(params EthTransactionParams) (eth.EthTransactionAPI, error) {
|
|
// Prime the tipset cache with the entire chain to make sure tx and block lookups are fast
|
|
params.Lifecycle.Append(fx.Hook{
|
|
OnStart: func(context.Context) error {
|
|
go func() {
|
|
start := time.Now()
|
|
log.Infoln("Start prefilling GetTipsetByHeight cache")
|
|
_, err := params.ChainStore.GetTipsetByHeight(params.MetricsCtx, abi.ChainEpoch(0), params.ChainStore.GetHeaviestTipSet(), false)
|
|
if err != nil {
|
|
log.Warnf("error when prefilling GetTipsetByHeight cache: %w", err)
|
|
}
|
|
log.Infof("Prefilling GetTipsetByHeight done in %s", time.Since(start))
|
|
}()
|
|
return nil
|
|
},
|
|
})
|
|
|
|
return eth.NewEthTransactionAPI(
|
|
params.ChainStore,
|
|
params.StateManager,
|
|
params.StateAPI,
|
|
params.MpoolAPI,
|
|
params.Indexer,
|
|
params.EthEventsExtended,
|
|
cfg.EthBlkCacheSize,
|
|
)
|
|
}
|
|
}
|
|
|
|
func MakeEthTrace(cfg config.FevmConfig) func(
|
|
chainStore eth.ChainStore,
|
|
stateManager eth.StateManager,
|
|
ethTransaction eth.EthTransactionAPI,
|
|
) eth.EthTraceAPI {
|
|
return func(
|
|
chainStore eth.ChainStore,
|
|
stateManager eth.StateManager,
|
|
ethTransaction eth.EthTransactionAPI,
|
|
) eth.EthTraceAPI {
|
|
return eth.NewEthTraceAPI(chainStore, stateManager, ethTransaction, cfg.EthTraceFilterMaxResults)
|
|
}
|
|
}
|
|
|
|
type EventHelperAPI struct {
|
|
fx.In
|
|
|
|
full.ChainAPI
|
|
full.StateAPI
|
|
}
|
|
|
|
var _ events.EventHelperAPI = &EventHelperAPI{}
|
|
|
|
type EthEventsParams struct {
|
|
fx.In
|
|
|
|
MetricsCtx helpers.MetricsCtx
|
|
Lifecycle fx.Lifecycle
|
|
EventFilterManager *filter.EventFilterManager
|
|
ChainStore *store.ChainStore
|
|
StateManager *stmgr.StateManager
|
|
EventHelperAPI EventHelperAPI
|
|
MessagePool *messagepool.MessagePool
|
|
Indexer index.Indexer
|
|
}
|
|
|
|
func MakeEthEventsExtended(cfg config.EventsConfig, enableEthRPC bool) func(EthEventsParams) (eth.EthEventsInternal, error) {
|
|
return func(params EthEventsParams) (eth.EthEventsInternal, error) {
|
|
lctx := helpers.LifecycleCtx(params.MetricsCtx, params.Lifecycle)
|
|
|
|
var (
|
|
subscribtionCtx context.Context = lctx
|
|
chainStore eth.ChainStore = params.ChainStore
|
|
stateManager eth.StateManager = params.StateManager
|
|
chainIndexer index.Indexer = params.Indexer
|
|
eventFilterManager *filter.EventFilterManager
|
|
tipSetFilterManager *filter.TipSetFilterManager
|
|
memPoolFilterManager *filter.MemPoolFilterManager
|
|
filterStore filter.FilterStore
|
|
subscriptionManager *eth.EthSubscriptionManager
|
|
maxFilterHeightRange abi.ChainEpoch = abi.ChainEpoch(cfg.MaxFilterHeightRange)
|
|
)
|
|
|
|
if !enableEthRPC {
|
|
// all event functionality is disabled
|
|
// the historic filter API relies on the real time one
|
|
return eth.NewEthEventsAPI(
|
|
subscribtionCtx,
|
|
chainStore,
|
|
stateManager,
|
|
chainIndexer,
|
|
eventFilterManager,
|
|
tipSetFilterManager,
|
|
memPoolFilterManager,
|
|
filterStore,
|
|
subscriptionManager,
|
|
maxFilterHeightRange,
|
|
), nil
|
|
}
|
|
|
|
subscriptionManager = eth.NewEthSubscriptionManager(chainStore, stateManager)
|
|
filterStore = filter.NewMemFilterStore(cfg.MaxFilters)
|
|
tipSetFilterManager = &filter.TipSetFilterManager{MaxFilterResults: cfg.MaxFilterResults}
|
|
memPoolFilterManager = &filter.MemPoolFilterManager{MaxFilterResults: cfg.MaxFilterResults}
|
|
eventFilterManager = params.EventFilterManager
|
|
|
|
ee := eth.NewEthEventsAPI(
|
|
subscribtionCtx,
|
|
chainStore,
|
|
stateManager,
|
|
chainIndexer,
|
|
eventFilterManager,
|
|
tipSetFilterManager,
|
|
memPoolFilterManager,
|
|
filterStore,
|
|
subscriptionManager,
|
|
maxFilterHeightRange,
|
|
)
|
|
|
|
params.Lifecycle.Append(fx.Hook{
|
|
OnStart: func(context.Context) error {
|
|
ev, err := events.NewEvents(lctx, ¶ms.EventHelperAPI)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// ignore returned tipsets
|
|
_ = ev.Observe(tipSetFilterManager)
|
|
|
|
ch, err := params.MessagePool.Updates(lctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
go memPoolFilterManager.WaitForMpoolUpdates(lctx, ch)
|
|
|
|
go ee.GC(lctx, time.Duration(cfg.FilterTTL))
|
|
|
|
return nil
|
|
},
|
|
})
|
|
|
|
return ee, nil
|
|
}
|
|
}
|
|
|
|
// GatewayEthSend is a helper to provide the Gateway with the EthSendAPI but block the use of
|
|
// EthSendRawTransactionUntrusted. The Gateway API doesn't expose this method, so this is a
|
|
// precautionary measure.
|
|
type GatewayEthSend struct {
|
|
fx.In
|
|
api.Gateway
|
|
}
|
|
|
|
func (*GatewayEthSend) EthSendRawTransactionUntrusted(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) {
|
|
return ethtypes.EthHash{}, xerrors.New("EthSendRawTransactionUntrusted is not supported in gateway mode")
|
|
}
|
|
|
|
type EventFilterManagerParams struct {
|
|
fx.In
|
|
|
|
MetricsCtx helpers.MetricsCtx
|
|
Lifecycle fx.Lifecycle
|
|
ChainStore *store.ChainStore
|
|
StateManager *stmgr.StateManager
|
|
EventHelperAPI EventHelperAPI
|
|
Indexer index.Indexer
|
|
}
|
|
|
|
func MakeEventFilterManager(cfg config.EventsConfig) func(EventFilterManagerParams) (*filter.EventFilterManager, error) {
|
|
return func(params EventFilterManagerParams) (*filter.EventFilterManager, error) {
|
|
lctx := helpers.LifecycleCtx(params.MetricsCtx, params.Lifecycle)
|
|
|
|
// Enable indexing of actor events
|
|
|
|
fm := &filter.EventFilterManager{
|
|
ChainStore: params.ChainStore,
|
|
ChainIndexer: params.Indexer,
|
|
AddressResolver: func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) address.Address {
|
|
idAddr, err := address.NewIDAddress(uint64(emitter))
|
|
if err != nil {
|
|
return address.Undef
|
|
}
|
|
|
|
actor, err := params.StateManager.LoadActor(ctx, idAddr, ts)
|
|
if err != nil || actor.DelegatedAddress == nil {
|
|
return idAddr
|
|
}
|
|
|
|
return *actor.DelegatedAddress
|
|
},
|
|
|
|
MaxFilterResults: cfg.MaxFilterResults,
|
|
}
|
|
|
|
params.Lifecycle.Append(fx.Hook{
|
|
OnStart: func(context.Context) error {
|
|
ev, err := events.NewEvents(lctx, ¶ms.EventHelperAPI)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_ = ev.Observe(fm)
|
|
return nil
|
|
},
|
|
})
|
|
|
|
return fm, nil
|
|
}
|
|
}
|