About sequence_number and event_index in events.proto

What’s the difference between sequence_number and event_index in file “events.proto”?

message Event {
    uint64 sequence_number = 2;
message EventWithProof {
  uint64 transaction_version = 1;
  uint64 event_index = 2;
1 Like

Good question.

  • Each event is emitted from a given handle (e.g., received_events in LibraAccount). A handle keeps track of how many events it has emitted. The sequence_number in message Event is this number (e.g., "this is the ith event emitted by the event handle key").
  • Each transaction keeps a log of the events that were emitted during its execution. The event_index in EventProof is the position of the given event in this log (e.g., "this is the ith event emitted by the transaction at version").

It helps me a lot, thanks.

1 Like

@sam I don’t understand a little how to use and track events in the dApp. Could you explain it to me?
For example, I have two modules - Foo and Bar. In the transaction I call Foo, then Foo emits event and calls Bar, then Bar also emits event. So how could I find events from Foo and Bar and get source transaction and caller from them?

1 Like

In Libra, events are tied to event handles (a value) rather than to a module (code). In addition, the data that is packaged into an event is up to the programmer (since an event can be any Move struct type). So in your scenario, what you would probably want to do is:

  • Add a field of type EventHandle<FooEvent> to a resource declared in Foo and a field of type EventHandle<BarEvent> to a resource declared in Bar.
  • If you want the source transaction (transaction sender?) to be part of your event, you can add it as field of FooEvent and/or BarEvent
  • Add calls to LibraAccount::emit_event in the relevant procedure(s) of Foo and Bar
  • Each EventHandle value has a globally unique EventKey that can be used to look up events that are emitted to that handle
  • You can read the EventKey's for your EventHandles in Foo and Bar, then use these keys to grab events in client code/read the sender from them

Note: Move does not provide a primitive for asking for the caller of the current procedure, so that information cannot be included in the event. If you can share more concrete details about your use-case, hopefully we can help with implementation suggestions!