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 filters over indexed events #9646

Merged
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
6f51ec2
update builtin-actors v10 bundle to http://filecoin-project/builtin-a…
raulk Nov 15, 2022
5249a35
update ffi to filecoin-project/filecoin-ffi#332.
raulk Nov 15, 2022
476a933
fix Event schema + cbor-gen.
raulk Nov 15, 2022
7cc2c5c
fix types in Eth API.
raulk Nov 15, 2022
f434133
cli: evm/invoke-evm-actor: print events.
raulk Nov 15, 2022
28ec43c
Merge branch 'feat/nv18-events' into raulk/events-integrate-fvm
raulk Nov 15, 2022
43e2a2b
fix merge error.
raulk Nov 15, 2022
f22762d
create EVM utilities in itest framework.
raulk Nov 15, 2022
4313917
Merge branch 'feat/nv18-fevm' into raulk/events-integrate-fvm
raulk Nov 15, 2022
907c201
add a FEVM events itest.
raulk Nov 15, 2022
0e8dd9e
Add historic event indexing
iand Nov 14, 2022
0d9c474
Implement EthGetLogs
iand Nov 15, 2022
32839f6
Initialise event index in di
iand Nov 15, 2022
bf1fcf8
Check actor event database schema version
iand Nov 15, 2022
e2ddc97
Fix lint error
iand Nov 15, 2022
73655ed
Fix for event entry key type is now a string
iand Nov 15, 2022
48ea469
go mod tidy
iand Nov 15, 2022
c31662d
make gen
iand Nov 15, 2022
ade75af
Update filecoin-ffi to https://github.com/filecoin-project/filecoin-f…
iand Nov 15, 2022
1035711
Add basic itests for ethereum filter api
iand Nov 15, 2022
7ef9973
make gen
iand Nov 15, 2022
98210ec
Add lint directive
iand Nov 15, 2022
bcdfc17
Fix TestEthNewFilterCatchAll
iand Nov 15, 2022
2803552
Merge branch 'feat/nv18-events' into feat/nv18-events-historic
raulk Nov 16, 2022
0376b7b
More assertions in TestEthNewFilterCatchAll
iand Nov 16, 2022
b5f95b7
Fix invalid address flake in TestEthNewFilterCatchAll
iand Nov 16, 2022
d5177a3
Add TestEthGetLogsAll itest
iand Nov 16, 2022
41bf2a0
Load actor to resolve address
iand Nov 16, 2022
8134d2f
Parse block heights as hex
iand Nov 16, 2022
314fb31
Fix signature of EthSubscribe
iand Nov 16, 2022
5a1f8d8
Return eth blocks not tipsets in subscriptions
iand Nov 16, 2022
7c2dcc8
Eth JSON-RPC API: add aliases for new methods.
raulk Nov 16, 2022
32385a9
Eth JSON-RPC API: return logs in eth_getTransactionReceipt.
raulk Nov 16, 2022
1ab39a4
simplify by moving receipt constructor logic to API.
raulk Nov 16, 2022
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
Binary file modified build/actors/v10.tar.zst
Binary file not shown.
210 changes: 105 additions & 105 deletions build/builtin_actors_gen.go

Large diffs are not rendered by default.

53 changes: 44 additions & 9 deletions chain/events/filter/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ import (
"github.com/filecoin-project/lotus/chain/types"
)

type RobustAddresser interface {
LookupRobustAddress(ctx context.Context, idAddr address.Address, ts *types.TipSet) (address.Address, error)
}

const indexed uint8 = 0x01

type EventFilter struct {
Expand All @@ -42,7 +38,7 @@ type EventFilter struct {
var _ Filter = (*EventFilter)(nil)

type CollectedEvent struct {
Event *types.Event
Entries []types.EventEntry
EmitterAddr address.Address // f4 address of emitter
EventIdx int // index of the event within the list of emitted events
Reverted bool
Expand Down Expand Up @@ -104,7 +100,7 @@ func (f *EventFilter) CollectEvents(ctx context.Context, te *TipSetEvents, rever

// event matches filter, so record it
cev := &CollectedEvent{
Event: ev,
Entries: ev.Entries,
EmitterAddr: addr,
EventIdx: evIdx,
Reverted: revert,
Expand Down Expand Up @@ -134,6 +130,12 @@ func (f *EventFilter) CollectEvents(ctx context.Context, te *TipSetEvents, rever
return nil
}

func (f *EventFilter) setCollectedEvents(ces []*CollectedEvent) {
f.mu.Lock()
f.collected = ces
f.mu.Unlock()
}

func (f *EventFilter) TakeCollectedEvents(ctx context.Context) []*CollectedEvent {
f.mu.Lock()
collected := f.collected
Expand Down Expand Up @@ -198,7 +200,7 @@ func (f *EventFilter) matchKeys(ees []types.EventEntry) bool {
continue
}

keyname := string(ee.Key)
keyname := ee.Key

// skip if we have already matched this key
if matched[keyname] {
Expand Down Expand Up @@ -282,14 +284,18 @@ type EventFilterManager struct {
ChainStore *cstore.ChainStore
AddressResolver func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool)
MaxFilterResults int
EventIndex *EventIndex

mu sync.Mutex // guards mutations to filters
filters map[string]*EventFilter
mu sync.Mutex // guards mutations to filters
filters map[string]*EventFilter
currentHeight abi.ChainEpoch
}

func (m *EventFilterManager) Apply(ctx context.Context, from, to *types.TipSet) error {
m.mu.Lock()
defer m.mu.Unlock()
m.currentHeight = to.Height()

if len(m.filters) == 0 {
return nil
}
Expand All @@ -300,6 +306,12 @@ func (m *EventFilterManager) Apply(ctx context.Context, from, to *types.TipSet)
load: m.loadExecutedMessages,
}

if m.EventIndex != nil {
if err := m.EventIndex.CollectEvents(ctx, tse, false, m.AddressResolver); err != nil {
return err
}
}

// TODO: could run this loop in parallel with errgroup if there are many filters
for _, f := range m.filters {
if err := f.CollectEvents(ctx, tse, false, m.AddressResolver); err != nil {
Expand All @@ -313,6 +325,8 @@ func (m *EventFilterManager) Apply(ctx context.Context, from, to *types.TipSet)
func (m *EventFilterManager) Revert(ctx context.Context, from, to *types.TipSet) error {
m.mu.Lock()
defer m.mu.Unlock()
m.currentHeight = to.Height()

if len(m.filters) == 0 {
return nil
}
Expand All @@ -323,6 +337,12 @@ func (m *EventFilterManager) Revert(ctx context.Context, from, to *types.TipSet)
load: m.loadExecutedMessages,
}

if m.EventIndex != nil {
if err := m.EventIndex.CollectEvents(ctx, tse, true, m.AddressResolver); err != nil {
return err
}
}

// TODO: could run this loop in parallel with errgroup if there are many filters
for _, f := range m.filters {
if err := f.CollectEvents(ctx, tse, true, m.AddressResolver); err != nil {
Expand All @@ -334,6 +354,14 @@ func (m *EventFilterManager) Revert(ctx context.Context, from, to *types.TipSet)
}

func (m *EventFilterManager) Install(ctx context.Context, minHeight, maxHeight abi.ChainEpoch, tipsetCid cid.Cid, addresses []address.Address, keys map[string][][]byte) (*EventFilter, error) {
m.mu.Lock()
currentHeight := m.currentHeight
m.mu.Unlock()

if m.EventIndex == nil && minHeight < currentHeight {
return nil, xerrors.Errorf("historic event index disabled")
}

id, err := uuid.NewRandom()
if err != nil {
return nil, xerrors.Errorf("new uuid: %w", err)
Expand All @@ -349,6 +377,13 @@ func (m *EventFilterManager) Install(ctx context.Context, minHeight, maxHeight a
maxResults: m.MaxFilterResults,
}

if m.EventIndex != nil && minHeight < currentHeight {
// Filter needs historic events
if err := m.EventIndex.PrefillFilter(ctx, f); err != nil {
return nil, err
}
}

m.mu.Lock()
m.filters[id.String()] = f
m.mu.Unlock()
Expand Down
6 changes: 3 additions & 3 deletions chain/events/filter/event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func TestEventFilterCollectEvents(t *testing.T) {
noCollectedEvents := []*CollectedEvent{}
oneCollectedEvent := []*CollectedEvent{
{
Event: ev1,
Entries: ev1.Entries,
EmitterAddr: a1,
EventIdx: 0,
Reverted: false,
Expand Down Expand Up @@ -286,15 +286,15 @@ func fakeEvent(emitter abi.ActorID, indexed []kv, unindexed []kv) *types.Event {
for _, in := range indexed {
ev.Entries = append(ev.Entries, types.EventEntry{
Flags: 0x01,
Key: []byte(in.k),
Key: in.k,
Value: in.v,
})
}

for _, in := range unindexed {
ev.Entries = append(ev.Entries, types.EventEntry{
Flags: 0x00,
Key: []byte(in.k),
Key: in.k,
Value: in.v,
})
}
Expand Down
Loading