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: ethereum compatible actor event API #9623

Merged
merged 5 commits into from
Nov 14, 2022

Conversation

iand
Copy link
Contributor

@iand iand commented Nov 10, 2022

Related Issues

Part of #9473

Intended to be merged after #9624 and currently includes those commits - will rebase once #9624 is merged.

Replaces #9499 and #9517 (both are included as commits in this PR) and #9535

Proposed Changes

This PR implements the Ethereum compatible API for retrieving and subscribing to event logs produced by FVM actors. The naming and types are designed to be compatible with the Ethereum API (see for example eth_getfilterchanges). Terminology used in naming fields and types has been kept close to Ethereum but are mapped into Filecoin concepts.

Features:

  • API methods
    • EthGetLogs (requires historic event indexing)
    • EthGetFilterChanges
    • EthGetFilterLogs
    • EthNewFilter
    • EthNewBlockFilter
    • EthNewPendingTransactionFilter
    • EthUninstallFilter
    • EthSubscribe
    • EthUnsubscribe
  • Configuration
    • Enable/disable realtime filter API methods
    • Enable/disable historic filter API methods
    • Limits on resource usage of filters
    • Garbage collection of unused filters
    • Limits on resource usage of websockets
  • Historic event indexing
  • Integration tests

Checklist

Before you mark the PR ready for review, please make sure that:

  • Commits have a clear commit message.
  • PR title is in the form of of <PR type>: <area>: <change being made>
    • example: fix: mempool: Introduce a cache for valid signatures
    • PR type: fix, feat, build, chore, ci, docs, perf, refactor, revert, style, test
    • area, e.g. api, chain, state, market, mempool, multisig, networking, paych, proving, sealing, wallet, deps
  • New features have usage guidelines and / or documentation updates in
  • Tests exist for new functionality or change in behavior
  • CI is green

@iand iand force-pushed the feat/nv18-ethevents branch from c2eabbf to c0fd878 Compare November 10, 2022 10:54
Copy link
Contributor

@vyzo vyzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I ask for some better commit hyigene please?

Specifically, can you keep make gen and friends in separate commits?

Same for ffi and go.mod changes.
This make it easy to avoid certain conflicts during rebase by dropping some commits.

@iand iand force-pushed the feat/nv18-ethevents branch from c0fd878 to 5621dd6 Compare November 10, 2022 11:14
@iand
Copy link
Contributor Author

iand commented Nov 10, 2022

Can I ask for some better commit hyigene please?

Specifically, can you keep make gen and friends in separate commits?

Same for ffi and go.mod changes. This make it easy to avoid certain conflicts during rebase by dropping some commits.

Will split those out once I am satisified that build is clean

@iand iand force-pushed the feat/nv18-ethevents branch from 5621dd6 to acd5026 Compare November 10, 2022 11:36
@iand iand force-pushed the feat/nv18-ethevents branch from 751eb2a to 7383ecb Compare November 10, 2022 15:05
Copy link
Member

@raulk raulk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass. This is looking pretty promising. Main issues revolve around:

  • DAG-CBOR encoding for event entry values.
  • Returning block data from block subscriptions performed via eth_subscribe?
  • Resolving supplied addresses into actor IDs for event matching.

Once we get the comments here sorted, we should move to implement:

  1. eth_getLogs and the historical store. <= this one is critical as it blocks feature completeness.
  2. An eventstore segregated from the chainstore (to be injected into the fvm).

@@ -26,7 +26,7 @@ import (
abinetwork "github.com/filecoin-project/go-state-types/network"

apitypes "github.com/filecoin-project/lotus/api/types"
"github.com/filecoin-project/lotus/chain/actors/builtin"
builtinactors "github.com/filecoin-project/lotus/chain/actors/builtin"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Let's avoid making these changes unless an import conflict arises. The patch is large, so little thing that we can do to avoid extra noise helps!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to resolve a problem with make gen where we have two imports with the same package name

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see. Yes, I've had that problem. I would've imagined it was solved in master already, though?

@@ -322,7 +322,7 @@ type StorageMiner interface {

CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storiface.SectorRef, expensive bool) (map[abi.SectorNumber]string, error) //perm:admin

ComputeProof(ctx context.Context, ssi []builtin.ExtendedSectorInfo, rand abi.PoStRandomness, poStEpoch abi.ChainEpoch, nv abinetwork.Version) ([]builtin.PoStProof, error) //perm:read
ComputeProof(ctx context.Context, ssi []builtinactors.ExtendedSectorInfo, rand abi.PoStRandomness, poStEpoch abi.ChainEpoch, nv abinetwork.Version) ([]builtinactors.PoStProof, error) //perm:read
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: revert this file.

api/eth_types.go Outdated Show resolved Hide resolved
api/eth_types.go Outdated Show resolved Hide resolved
api/eth_types.go Show resolved Hide resolved
Comment on lines +1275 to +1286
for _, tsk := range tsks {
c, err := tsk.Cid()
if err != nil {
return nil, err
}
hash, err := api.EthHashFromCid(c)
if err != nil {
return nil, err
}

res.NewBlockHashes = append(res.NewBlockHashes, hash)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure we don't need to return the full block data here? See https://docs.infura.io/infura/networks/ethereum/json-rpc-methods/subscription-methods/eth_subscribe.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's just for subscriptions which is handled in the ethSubscription.start method. The lines you are commenting on called by EthGetFilterChanges. See https://docs.infura.io/infura/networks/ethereum/json-rpc-methods/filter-methods/eth_getfilterchanges which says "For filters created with eth_newBlockFilter the return are block hashes (32 Bytes), e.g. ['0x3454645634534...']."

@@ -463,7 +496,7 @@ func (a *EthModule) EthProtocolVersion(ctx context.Context) (api.EthUint64, erro
}

func (a *EthModule) EthMaxPriorityFeePerGas(ctx context.Context) (api.EthBigInt, error) {
gasPremium, err := a.GasAPI.GasEstimateGasPremium(ctx, 0, builtin.SystemActorAddr, 10000, types.EmptyTSK)
gasPremium, err := a.GasAPI.GasEstimateGasPremium(ctx, 0, builtinactors.SystemActorAddr, 10000, types.EmptyTSK)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: revert

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See earlier comment about gen conflict

@@ -601,3 +601,31 @@ type Wallet struct {
type FeeConfig struct {
DefaultMaxFee types.FIL
}

type ActorEventConfig struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be nested inside an Eth API configuration struct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned earlier, the filter implementation and associated config isn't necessarily ethereum specific. EnableRealTimeFilterAPI and EnableHistoricFilterAPI would also apply to any native filecoin apis that touch the same filter code


var _ events.EventAPI = &EventAPI{}

func EthEvent(cfg config.ActorEventConfig) func(helpers.MetricsCtx, fx.Lifecycle, *store.ChainStore, EventAPI, *messagepool.MessagePool) (*full.EthEvent, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably find another name for this component as it makes it sound like it's an Ethereum event, e.g. EthEventManager?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to EthEventAPI in follow on branch

Comment on lines 378 to 389
evtArr, err := blockadt.AsArray(st, rct.EventsRoot)
if err != nil {
return nil, xerrors.Errorf("load events amt: %w", err)
}

ems[i].evs = make([]*types.Event, evtArr.Length())
var evt types.Event
_ = arr.ForEach(&evt, func(i int64) error {
cpy := evt
ems[i].evs[int(i)] = &cpy
return nil
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is going to be the tricky part. The goal is to store events in a separate eventstore, so events won't be be available in the "actor store". That should probably be the thing we implement next.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that being done as part of the nv-18events branch?

}
for msgIdx, em := range ems {
for evIdx, ev := range em.Events() {
if !f.matchAddress(ev.Emitter) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was an error in the spec, which Alex pointed out. The Emitter will be an ActorID, not an Address. So we need to resolve the supplied address into an ActorID in the Eth API before we feed it further onwards.

@raulk raulk changed the base branch from feat/nv18-fevm to feat/nv18-events November 14, 2022 11:10
@raulk
Copy link
Member

raulk commented Nov 14, 2022

As agreed with @iand, I'm merging this into the feat/nv18-events staging branch so I can unblock other refactors there. Follow-ups to this PR will be submitted as separate PRs against feat/nv18-events.

@raulk raulk marked this pull request as ready for review November 14, 2022 11:55
@raulk raulk requested a review from a team as a code owner November 14, 2022 11:55
@raulk raulk merged commit 4eccf30 into filecoin-project:feat/nv18-events Nov 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants