You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Document how getEvents orders transaction and operation events (#2831)
* Document how getEvents orders transaction and operation events
* Name the getEvents and getTransaction event response fields exactly
* Say that getEvents returns fee event topics and values as base64 ScVals
`getEvents` returns events in ascending order of their `id`. The `id` holds a [TOID](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0035.md#specification) and an event index, so the sort key is the ledger sequence, then the transaction index, then the operation index, then the event index.
16
+
17
+
Protocol 23 keeps events in two separate XDR fields. `TransactionMetaV4.events` holds the transaction-level events. Each `OperationMetaV2.events` holds the events of one operation. A transaction-level event also carries a [stage](https://github.com/stellar/stellar-xdr/blob/v23.0/Stellar-ledger.x#L488-L498), because these events happen at different points of the ledger apply flow. Operation events all happen when the transaction is applied.
18
+
19
+
Stellar RPC re-derives the execution order of Stellar Core and builds each cursor from it:
20
+
21
+
| XDR field | Stage | Transaction index | Operation index |
A TOID gives 12 bits to the operation index and 20 bits to the transaction index. `4095` is therefore the largest operation index, which sorts an `AFTER_TX` event after every operation of its transaction. `1048575` is the largest transaction index, which sorts an `AFTER_ALL_TXS` event after every transaction of the ledger. Transaction indexes start at `1`, so index `0` sorts before every transaction of the ledger.
29
+
30
+
Events in one ledger come back in this order:
31
+
32
+
1. Every fee charge event.
33
+
2. For each transaction, in transaction order: its operation events, then its post-transaction events.
34
+
3. Every fee refund event.
35
+
36
+
To reproduce this order from meta XDR, sort your own events by the same four values. The [`getTransaction`](./getTransaction.mdx) and [`getTransactions`](./getTransactions.mdx) methods return the two XDR fields separately, in their `events` object, as `events.transactionEventsXdr` and `events.contractEventsXdr`.
37
+
38
+
:::note
39
+
40
+
`transactionIndex` and `operationIndex` come from the cursor. On a transaction-level event they hold the sort values in the table above, not a real position in the ledger. Read `txHash` to find the transaction that a fee event belongs to.
41
+
42
+
:::
43
+
44
+
Fee events are the only transaction-level events today. Stellar Core emits the fee charge at the `BEFORE_ALL_TXS` stage. It emits a Soroban fee refund at the `AFTER_ALL_TXS` stage. Both are `contract` events from the native asset contract, and their topics are the symbol `fee` and the fee source address. A refund carries a negative amount. Stellar Core emits no event when the amount is zero.
45
+
46
+
Those are the decoded values. This method returns `topic` and `value` as base64 ScVals unless you set `xdrFormat` to `json`. A topic filter therefore takes the encoded symbol, `AAAADwAAAANmZWUA`, and not the string `fee`.
47
+
13
48
### Using the Lab
14
49
15
50
Let's test the example request for **Native XLM Transfer Events** directly on [the Stellar Laboratory](https://laboratory.stellar.org).
0 commit comments