From 4dcd65882d12656f8460ee0c77c48caeb29c9f47 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Tue, 5 Mar 2024 15:49:04 +1100 Subject: [PATCH] Fix concerns and docs identified by review --- api/api_full.go | 13 ++++++--- build/openrpc/full.json.gz | Bin 35892 -> 35937 bytes chain/events/filter/event.go | 4 +-- documentation/en/api-v1-unstable-methods.md | 13 ++++++--- node/impl/full/actor_events.go | 12 ++++----- node/impl/full/actor_events_test.go | 28 ++++++++++---------- 6 files changed, 40 insertions(+), 30 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index c345bb12a..aa7f57e67 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -909,14 +909,17 @@ type FullNode interface { // Actor events - // GetActorEvents returns all FVM and built-in Actor events that match the given filter. + // GetActorEvents returns all user-programmed and built-in actor events that match the given + // filter. // This is a request/response API. // Results available from this API may be limited by the MaxFilterResults and MaxFilterHeightRange // configuration options and also the amount of historical data available in the node. + // + // This is an EXPERIMENTAL API and may be subject to change. GetActorEvents(ctx context.Context, filter *types.ActorEventFilter) ([]*types.ActorEvent, error) //perm:read - // SubscribeActorEvents returns a long-lived stream of all FVM and built-in Actor events that - // match the given filter. + // SubscribeActorEvents returns a long-lived stream of all user-programmed and built-in actor + // events that match the given filter. // Events that match the given filter are written to the stream in real-time as they are emitted // from the FVM. // The response stream is closed when the client disconnects, when a ToHeight is specified and is @@ -926,7 +929,9 @@ type FullNode interface { // FromHeight. // Results available from this API may be limited by the MaxFilterResults and MaxFilterHeightRange // configuration options and also the amount of historical data available in the node. - // NOTE: THIS API IS ONLY SUPPORTED OVER WEBSOCKETS FOR NOW + // + // Note: this API is only available via websocket connections. + // This is an EXPERIMENTAL API and may be subject to change. SubscribeActorEvents(ctx context.Context, filter *types.ActorEventFilter) (<-chan *types.ActorEvent, error) //perm:read } diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 97cd6f3d6080767086da0136ad1894651d0b565a..deaef44c05a30e8aaadd8b720712bbb7e6198239 100644 GIT binary patch delta 26177 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 UW;2f!j2^{reC2$R0vYaq0OfvA2mk;8 delta 26132 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 M2=EJI&5Ruf0NaI0*#H0l diff --git a/chain/events/filter/event.go b/chain/events/filter/event.go index 449b6ae18..1669d840e 100644 --- a/chain/events/filter/event.go +++ b/chain/events/filter/event.go @@ -41,7 +41,7 @@ type eventFilter struct { minHeight abi.ChainEpoch // minimum epoch to apply filter or -1 if no minimum maxHeight abi.ChainEpoch // maximum epoch to apply filter or -1 if no maximum tipsetCid cid.Cid - addresses []address.Address // list of f4 actor addresses that are extpected to emit the event + addresses []address.Address // list of actor addresses that are extpected to emit the event keysWithCodec map[string][]types.ActorEventBlock // map of key names to a list of alternate values that may match maxResults int // maximum number of results to collect, 0 is unlimited @@ -56,7 +56,7 @@ var _ Filter = (*eventFilter)(nil) type CollectedEvent struct { Entries []types.EventEntry - EmitterAddr address.Address // f4 address of emitter + EmitterAddr address.Address // address of emitter EventIdx int // index of the event within the list of emitted events Reverted bool Height abi.ChainEpoch diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 5aa9506cb..4c1dbdee4 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -3390,11 +3390,14 @@ Response: ### GetActorEvents -GetActorEvents returns all FVM and built-in Actor events that match the given filter. +GetActorEvents returns all user-programmed and built-in actor events that match the given +filter. This is a request/response API. Results available from this API may be limited by the MaxFilterResults and MaxFilterHeightRange configuration options and also the amount of historical data available in the node. +This is an EXPERIMENTAL API and may be subject to change. + Perms: read @@ -8829,8 +8832,8 @@ Response: ### SubscribeActorEvents -SubscribeActorEvents returns a long-lived stream of all FVM and built-in Actor events that -match the given filter. +SubscribeActorEvents returns a long-lived stream of all user-programmed and built-in actor +events that match the given filter. Events that match the given filter are written to the stream in real-time as they are emitted from the FVM. The response stream is closed when the client disconnects, when a ToHeight is specified and is @@ -8840,7 +8843,9 @@ real-time events are written to the response stream if the filter specifies an e FromHeight. Results available from this API may be limited by the MaxFilterResults and MaxFilterHeightRange configuration options and also the amount of historical data available in the node. -NOTE: THIS API IS ONLY SUPPORTED OVER WEBSOCKETS FOR NOW + +Note: this API is only available via websocket connections. +This is an EXPERIMENTAL API and may be subject to change. Perms: read diff --git a/node/impl/full/actor_events.go b/node/impl/full/actor_events.go index 8adfda782..fecd1d2b6 100644 --- a/node/impl/full/actor_events.go +++ b/node/impl/full/actor_events.go @@ -232,6 +232,11 @@ func (a *ActorEventHandler) SubscribeActorEvents(ctx context.Context, evtFilter out := make(chan *types.ActorEvent) + // When we start sending real-time events, we want to make sure that we don't fall behind more + // than one epoch's worth of events (approximately). Capture this value now, before we send + // historical events to allow for a little bit of slack in the historical event sending. + minBacklogHeight := a.chain.GetHeaviestTipSet().Height() - 1 + go func() { defer func() { // tell the caller we're done @@ -242,11 +247,6 @@ func (a *ActorEventHandler) SubscribeActorEvents(ctx context.Context, evtFilter } }() - // When we start sending real-time events, we want to make sure that we don't fall behind more - // than one epoch's worth of events (approximately). Capture this value now, before we send - // historical events to allow for a little bit of slack in the historical event sending. - minBacklogHeight := a.chain.GetHeaviestTipSet().Height() - 1 - // Handle any historical events that our filter may have picked up ----------------------------- evs := getCollected(ctx, fm) @@ -270,7 +270,7 @@ func (a *ActorEventHandler) SubscribeActorEvents(ctx context.Context, evtFilter // for the case where we have a MaxHeight set, we don't get a signal from the filter when we // reach that height, so we need to check it ourselves, do it now but also in the loop - if params.MaxHeight > 0 && a.chain.GetHeaviestTipSet().Height() > params.MaxHeight { + if params.MaxHeight > 0 && minBacklogHeight+1 >= params.MaxHeight { return } diff --git a/node/impl/full/actor_events_test.go b/node/impl/full/actor_events_test.go index 2bd4f62cf..ab446e57b 100644 --- a/node/impl/full/actor_events_test.go +++ b/node/impl/full/actor_events_test.go @@ -246,9 +246,6 @@ func TestGetActorEvents(t *testing.T) { } func TestSubscribeActorEvents(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) - defer cancel() - const ( seed = 984651320 maxFilterHeightRange = 100 @@ -279,14 +276,13 @@ func TestSubscribeActorEvents(t *testing.T) { {"1.5 block speed", blockDelay * 3 / 2, false, -1}, {"twice block speed", blockDelay * 2, false, -1}, } { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() tc := tc t.Run(tc.name, func(t *testing.T) { req := require.New(t) - ctx, cancel := context.WithCancel(ctx) - defer cancel() - mockClock.Set(time.Now()) mockFilterManager := newMockEventFilterManager(t) allEvents := makeCollectedEvents(t, rng, filterStartHeight, eventsPerEpoch, finishHeight) @@ -326,7 +322,10 @@ func TestSubscribeActorEvents(t *testing.T) { // Ticker to simulate both time and the chain advancing, including emitting events at // the right time directly to the filter. + var wg sync.WaitGroup + wg.Add(1) go func() { + defer wg.Done() for thisHeight := int64(currentHeight); ctx.Err() == nil; thisHeight++ { ts, err := types.NewTipSet([]*types.BlockHeader{newBlockHeader(minerAddr, thisHeight)}) req.NoError(err) @@ -334,9 +333,9 @@ func TestSubscribeActorEvents(t *testing.T) { var eventsThisEpoch []*filter.CollectedEvent if thisHeight <= finishHeight { - eventsThisEpoch = allEvents[(thisHeight-filterStartHeight)*eventsPerEpoch : (thisHeight-filterStartHeight+1)*eventsPerEpoch] + eventsThisEpoch = allEvents[(thisHeight-filterStartHeight)*eventsPerEpoch : (thisHeight-filterStartHeight+2)*eventsPerEpoch] } - for i := 0; i < eventsPerEpoch; i++ { + for i := 0; i < eventsPerEpoch && ctx.Err() == nil; i++ { if len(eventsThisEpoch) > 0 { mockFilter.sendEventToChannel(eventsThisEpoch[0]) eventsThisEpoch = eventsThisEpoch[1:] @@ -406,14 +405,14 @@ func TestSubscribeActorEvents(t *testing.T) { // cleanup mockFilter.requireClearSubChannelCalledEventually(500 * time.Millisecond) mockFilterManager.requireRemovedEventually(mockFilter.ID(), 500*time.Millisecond) + cancel() + wg.Wait() // wait for the chain to stop advancing }) } } func TestSubscribeActorEvents_OnlyHistorical(t *testing.T) { // Similar to TestSubscribeActorEvents but we set an explicit end that caps out at the current height - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) - defer cancel() const ( seed = 984651320 maxFilterHeightRange = 100 @@ -439,6 +438,8 @@ func TestSubscribeActorEvents_OnlyHistorical(t *testing.T) { {"1.5 block speed", 1.5, false}, {"twice block speed", 2, false}, } { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() tc := tc t.Run(tc.name, func(t *testing.T) { @@ -446,7 +447,7 @@ func TestSubscribeActorEvents_OnlyHistorical(t *testing.T) { mockClock.Set(time.Now()) mockFilterManager := newMockEventFilterManager(t) - allEvents := makeCollectedEvents(t, rng, filterStartHeight, eventsPerEpoch, currentHeight-1) + allEvents := makeCollectedEvents(t, rng, filterStartHeight, eventsPerEpoch, currentHeight) mockFilter := newMockFilter(ctx, t, rng, allEvents) mockFilterManager.expectInstall(abi.ChainEpoch(0), abi.ChainEpoch(currentHeight), cid.Undef, nil, nil, false, mockFilter) @@ -464,11 +465,10 @@ func TestSubscribeActorEvents_OnlyHistorical(t *testing.T) { // assume we can cleanly pick up all historical events in one go receiveLoop: - for len(gotEvents) < len(allEvents) && ctx.Err() == nil { + for ctx.Err() == nil { select { case e, ok := <-eventChan: - if tc.expectComplete || ok { - req.True(ok) + if ok { gotEvents = append(gotEvents, e) mockClock.Add(time.Duration(float64(blockDelay) * tc.blockTimeToComplete / float64(len(allEvents)))) // no need to advance the chain, we're also testing that's not necessary