Skip to content

Commit

Permalink
Adjust actor event API after review
Browse files Browse the repository at this point in the history
  • Loading branch information
rvagg committed Feb 23, 2024
1 parent 5ee59f6 commit ac997e6
Show file tree
Hide file tree
Showing 24 changed files with 398 additions and 219 deletions.
2 changes: 1 addition & 1 deletion api/api_full.go
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,7 @@ type FullNode interface {
// This API also allows clients to read all historical events matching the given filter before
// any real-time events are written to the response stream.
// NOTE: THIS API IS ONLY SUPPORTED OVER WEBSOCKETS FOR NOW
SubscribeActorEvents(ctx context.Context, filter *types.SubActorEventFilter) (<-chan *types.ActorEvent, error) //perm:read
SubscribeActorEvents(ctx context.Context, filter *types.ActorEventFilter) (<-chan *types.ActorEvent, error) //perm:read
}

// reverse interface to the client, called after EthSubscribe
Expand Down
2 changes: 1 addition & 1 deletion api/api_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,5 @@ type Gateway interface {
EthTraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*ethtypes.EthTraceReplayBlockTransaction, error)

GetActorEvents(ctx context.Context, filter *types.ActorEventFilter) ([]*types.ActorEvent, error)
SubscribeActorEvents(ctx context.Context, filter *types.SubActorEventFilter) (<-chan *types.ActorEvent, error)
SubscribeActorEvents(ctx context.Context, filter *types.ActorEventFilter) (<-chan *types.ActorEvent, error)
}
26 changes: 7 additions & 19 deletions api/docgen/docgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,25 +430,8 @@ func init() {
},
},
},
FromEpoch: "earliest",
ToEpoch: "latest",
})

addExample(&types.SubActorEventFilter{
Filter: types.ActorEventFilter{
Addresses: []address.Address{addr},
Fields: map[string][]types.ActorEventBlock{
"abc": {
{
Codec: 0x51,
Value: []byte("ddata"),
},
},
},
FromEpoch: "earliest",
ToEpoch: "latest",
},
Prefill: true,
FromHeight: epochPtr(1010),
ToHeight: epochPtr(1020),
})
}

Expand Down Expand Up @@ -555,6 +538,11 @@ func exampleStruct(method string, t, parent reflect.Type) interface{} {
return ns.Interface()
}

func epochPtr(ei int64) *abi.ChainEpoch {
ep := abi.ChainEpoch(ei)
return &ep
}

type Visitor struct {
Root string
Methods map[string]ast.Node
Expand Down
2 changes: 1 addition & 1 deletion api/mocks/mock_full.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions api/proxy_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified build/openrpc/full.json.gz
Binary file not shown.
Binary file modified build/openrpc/gateway.json.gz
Binary file not shown.
32 changes: 11 additions & 21 deletions chain/types/actor_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,6 @@ type ActorEventBlock struct {
Value []byte `json:"value"`
}

type SubActorEventFilter struct {
Filter ActorEventFilter `json:"filter"`

// If true, all available matching historical events will be written to the response stream
// before any new real-time events that match the given filter are written.
// If `Prefill` is true and `FromEpoch` is set to latest, the pre-fill operation will become a no-op.
// if `Prefill` is false and `FromEpoch` is set to earliest, historical events will still be sent to the client.
Prefill bool `json:"prefill"`
}

type ActorEventFilter struct {
// Matches events from one of these actors, or any actor if empty.
// For now, this MUST be a Filecoin address.
Expand All @@ -37,25 +27,25 @@ type ActorEventFilter struct {
// If the value is an empty slice, the filter will match on the key only, accepting any value.
Fields map[string][]ActorEventBlock `json:"fields,omitempty"`

// Interpreted as an epoch (in hex) or one of "latest" for last mined block, "earliest" for first,
// Optional, default: "latest".
FromEpoch string `json:"fromEpoch,omitempty"`
// The height of the earliest tipset to include in the query. If empty, the query starts at the
// last finalized tipset.
FromHeight *abi.ChainEpoch `json:"fromHeight,omitempty"`

// Interpreted as an epoch (in hex) or one of "latest" for last mined block, "earliest" for first,
// Optional, default: "latest".
ToEpoch string `json:"toEpoch,omitempty"`
// The height of the latest tipset to include in the query. If empty, the query ends at the
// latest tipset.
ToHeight *abi.ChainEpoch `json:"toHeight,omitempty"`

// Restricts events returned to those emitted from messages contained in this tipset.
// If `TipSetCid` is present in the filter criteria, then neither `FromEpoch` nor `ToEpoch` are allowed.
TipSetCid *cid.Cid `json:"tipsetCid,omitempty"`
// If `TipSetKey` is legt empty in the filter criteria, then neither `FromHeight` nor `ToHeight` are allowed.
TipSetKey *TipSetKey `json:"tipsetKey,omitempty"`
}

type ActorEvent struct {
// Event entries in log form.
Entries []EventEntry `json:"entries"`

// Filecoin address of the actor that emitted this event.
EmitterAddr address.Address `json:"emitter"`
Emitter address.Address `json:"emitter"`

// Reverted is set to true if the message that produced this event was reverted because of a network re-org
// in that case, the event should be considered as reverted as well.
Expand All @@ -64,8 +54,8 @@ type ActorEvent struct {
// Height of the tipset that contained the message that produced this event.
Height abi.ChainEpoch `json:"height"`

// CID of the tipset that contained the message that produced this event.
TipSetCid cid.Cid `json:"tipsetCid"`
// The tipset that contained the message that produced this event.
TipSetKey TipSetKey `json:"tipsetKey"`

// CID of message that produced this event.
MsgCid cid.Cid `json:"msgCid"`
Expand Down
28 changes: 15 additions & 13 deletions chain/types/actor_event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
builtintypes "github.com/filecoin-project/go-state-types/builtin"
)

Expand All @@ -29,11 +30,11 @@ func TestActorEventJson(t *testing.T) {
Value: []byte("value2"),
},
},
EmitterAddr: randomF4Addr(t, rng),
Reverted: false,
Height: 1001,
TipSetCid: randomCid(t, rng),
MsgCid: randomCid(t, rng),
Emitter: randomF4Addr(t, rng),
Reverted: false,
Height: 1001,
TipSetKey: NewTipSetKey(randomCid(t, rng)),
MsgCid: randomCid(t, rng),
}

bz, err := json.Marshal(in)
Expand All @@ -46,7 +47,7 @@ func TestActorEventJson(t *testing.T) {
require.Equal(t, in, out)

s := `
{"entries":[{"Flags":0,"Key":"key1","Codec":81,"Value":"dmFsdWUx"},{"Flags":0,"Key":"key2","Codec":82,"Value":"dmFsdWUy"}],"emitter":"f410fagkp3qx2f76maqot74jaiw3tzbxe76k76zrkl3xifk67isrnbn2sll3yua","reverted":false,"height":1001,"tipsetCid":{"/":"bafkqacx3dag26sfht3qlcdi"},"msgCid":{"/":"bafkqacrziziykd6uuf4islq"}}
{"entries":[{"Flags":0,"Key":"key1","Codec":81,"Value":"dmFsdWUx"},{"Flags":0,"Key":"key2","Codec":82,"Value":"dmFsdWUy"}],"emitter":"f410fagkp3qx2f76maqot74jaiw3tzbxe76k76zrkl3xifk67isrnbn2sll3yua","reverted":false,"height":1001,"tipsetKey":[{"/":"bafkqacx3dag26sfht3qlcdi"}],"msgCid":{"/":"bafkqacrziziykd6uuf4islq"}}
`
var out2 ActorEvent
err = json.Unmarshal([]byte(s), &out2)
Expand Down Expand Up @@ -77,9 +78,9 @@ func TestActorEventBlockJson(t *testing.T) {
}

func TestSubActorEventFilterJson(t *testing.T) {
c := randomCid(t, pseudo.New(pseudo.NewSource(0)))
from := "earliest"
to := "latest"
tsk := NewTipSetKey(randomCid(t, pseudo.New(pseudo.NewSource(0))))
from := abi.ChainEpoch(0)
to := abi.ChainEpoch(100)
f := ActorEventFilter{
Addresses: []address.Address{
randomF4Addr(t, pseudo.New(pseudo.NewSource(0))),
Expand All @@ -99,16 +100,17 @@ func TestSubActorEventFilterJson(t *testing.T) {
},
},
},
FromEpoch: from,
ToEpoch: to,
TipSetCid: &c,
FromHeight: &from,
ToHeight: &to,
TipSetKey: &tsk,
}

bz, err := json.Marshal(f)
require.NoError(t, err)
require.NotEmpty(t, bz)
t.Logf("%s", bz)

s := `{"addresses":["f410fagkp3qx2f76maqot74jaiw3tzbxe76k76zrkl3xifk67isrnbn2sll3yua","f410fagkp3qx2f76maqot74jaiw3tzbxe76k76zrkl3xifk67isrnbn2sll3yua"],"fields":{"key1":[{"codec":81,"value":"dmFsdWUx"}],"key2":[{"codec":82,"value":"dmFsdWUy"}]},"fromEpoch":"earliest","toEpoch":"latest","tipsetCid":{"/":"bafkqacqbst64f6rp7taeduy"}}`
s := `{"addresses":["f410fagkp3qx2f76maqot74jaiw3tzbxe76k76zrkl3xifk67isrnbn2sll3yua","f410fagkp3qx2f76maqot74jaiw3tzbxe76k76zrkl3xifk67isrnbn2sll3yua"],"fields":{"key1":[{"codec":81,"value":"dmFsdWUx"}],"key2":[{"codec":82,"value":"dmFsdWUy"}]},"fromHeight":0,"toHeight":100,"tipsetKey":[{"/":"bafkqacqbst64f6rp7taeduy"}]}`
var out ActorEventFilter
err = json.Unmarshal([]byte(s), &out)
require.NoError(t, err)
Expand Down
53 changes: 30 additions & 23 deletions documentation/en/api-v1-unstable-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -3413,8 +3413,8 @@ Inputs:
}
]
},
"fromEpoch": "earliest",
"toEpoch": "latest"
"fromHeight": 1010,
"toHeight": 1020
}
]
```
Expand All @@ -3434,9 +3434,14 @@ Response:
"emitter": "f01234",
"reverted": true,
"height": 10101,
"tipsetCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"tipsetKey": [
{
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
{
"/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve"
}
],
"msgCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
Expand Down Expand Up @@ -8794,22 +8799,19 @@ Inputs:
```json
[
{
"filter": {
"addresses": [
"f01234"
],
"fields": {
"abc": [
{
"codec": 81,
"value": "ZGRhdGE="
}
]
},
"fromEpoch": "earliest",
"toEpoch": "latest"
"addresses": [
"f01234"
],
"fields": {
"abc": [
{
"codec": 81,
"value": "ZGRhdGE="
}
]
},
"prefill": true
"fromHeight": 1010,
"toHeight": 1020
}
]
```
Expand All @@ -8828,9 +8830,14 @@ Response:
"emitter": "f01234",
"reverted": true,
"height": 10101,
"tipsetCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"tipsetKey": [
{
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
{
"/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve"
}
],
"msgCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
Expand Down
18 changes: 11 additions & 7 deletions documentation/en/default-lotus-config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -330,13 +330,6 @@
# env var: LOTUS_FEVM_ENABLEETHRPC
#EnableEthRPC = false

# EnableActorEventsAPI enables the Actor events API that enables clients to consume events emitted by (smart contracts + built-in Actors).
# This will also enable the RealTimeFilterAPI and HistoricFilterAPI by default, but they can be disabled by config options above.
#
# type: bool
# env var: LOTUS_FEVM_ENABLEACTOREVENTSAPI
#EnableActorEventsAPI = false

# EthTxHashMappingLifetimeDays the transaction hash lookup database will delete mappings that have been stored for more than x days
# Set to 0 to keep all mappings
#
Expand Down Expand Up @@ -396,6 +389,17 @@
#DatabasePath = ""


[ActorEvents]
# EnableActorEventsAPI enables the Actor events API that enables clients to consume events
# emitted by (smart contracts + built-in Actors).
# This will also enable the RealTimeFilterAPI and HistoricFilterAPI by default, but they can be
# disabled by setting their respective Disable* options in Fevm.Events.
#
# type: bool
# env var: LOTUS_ACTOREVENTS_ENABLEACTOREVENTSAPI
#EnableActorEventsAPI = false


[Index]
# EXPERIMENTAL FEATURE. USE WITH CAUTION
# EnableMsgIndex enables indexing of messages on chain.
Expand Down
2 changes: 1 addition & 1 deletion gateway/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ type TargetAPI interface {
EthTraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*ethtypes.EthTraceReplayBlockTransaction, error)

GetActorEvents(ctx context.Context, filter *types.ActorEventFilter) ([]*types.ActorEvent, error)
SubscribeActorEvents(ctx context.Context, filter *types.SubActorEventFilter) (<-chan *types.ActorEvent, error)
SubscribeActorEvents(ctx context.Context, filter *types.ActorEventFilter) (<-chan *types.ActorEvent, error)
}

var _ TargetAPI = *new(api.FullNode) // gateway depends on latest
Expand Down
2 changes: 1 addition & 1 deletion gateway/proxy_fil.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ func (gw *Node) GetActorEvents(ctx context.Context, filter *types.ActorEventFilt
return gw.target.GetActorEvents(ctx, filter)
}

func (gw *Node) SubscribeActorEvents(ctx context.Context, filter *types.SubActorEventFilter) (<-chan *types.ActorEvent, error) {
func (gw *Node) SubscribeActorEvents(ctx context.Context, filter *types.ActorEventFilter) (<-chan *types.ActorEvent, error) {
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit ac997e6

Please sign in to comment.