@@ -69,7 +69,7 @@ func TestCadenceEvents_Block(t *testing.T) {
6969
7070 // generate txs
7171 for i := 0 ; i < txCount ; i ++ {
72- tx , _ , txEvent , err := newTransaction (uint64 (i ))
72+ tx , _ , txEvent , err := newTransaction (uint64 (i ), uint16 ( i ) )
7373 require .NoError (t , err )
7474 hashes [i ] = tx .Hash ()
7575 events = append (events , txEvent )
@@ -131,7 +131,7 @@ func TestCadenceEvents_Block(t *testing.T) {
131131 })
132132
133133 t .Run ("block with more transaction hashes" , func (t * testing.T ) {
134- tx , _ , _ , err := newTransaction (1 )
134+ tx , _ , _ , err := newTransaction (1 , 0 )
135135 require .NoError (t , err )
136136
137137 // generate single block
@@ -153,6 +153,78 @@ func TestCadenceEvents_Block(t *testing.T) {
153153 "block 1 references missing transaction/s" ,
154154 )
155155 })
156+
157+ t .Run ("EVM events are ordered by Flow TransactionIndex & EventIndex" , func (t * testing.T ) {
158+ txCount := 3
159+ blockEvents := flow.BlockEvents {
160+ BlockID : flow.Identifier {0x1 },
161+ Height : 1 ,
162+ }
163+
164+ // tx1 and tx2 are EVM transactions executed on a single Flow transaction.
165+ tx1 , _ , txEvent1 , err := newTransaction (0 , 0 )
166+ require .NoError (t , err )
167+ txEvent1 .TransactionIndex = 0
168+ txEvent1 .EventIndex = 2
169+
170+ tx2 , _ , txEvent2 , err := newTransaction (1 , 1 )
171+ require .NoError (t , err )
172+ txEvent2 .TransactionIndex = 0
173+ txEvent2 .EventIndex = 5
174+
175+ // tx3 is a Flow transaction with a single EVM transaction on EventIndex=1
176+ tx3 , _ , txEvent3 , err := newTransaction (2 , 0 )
177+ require .NoError (t , err )
178+ txEvent3 .TransactionIndex = 2
179+ txEvent3 .EventIndex = 1
180+
181+ // needed for computing the `TransactionHashRoot` field on
182+ // EVM.BlockExecuted event payload. the order is sensitive.
183+ hashes = []gethCommon.Hash {
184+ tx1 .Hash (),
185+ tx2 .Hash (),
186+ tx3 .Hash (),
187+ }
188+
189+ // add the tx events in a shuffled order
190+ blockEvents .Events = []flow.Event {
191+ txEvent3 ,
192+ txEvent1 ,
193+ txEvent2 ,
194+ }
195+
196+ // generate single block
197+ _ , blockEvent , err := newBlock (1 , hashes )
198+ require .NoError (t , err )
199+ blockEvent .TransactionIndex = 4
200+ blockEvent .EventIndex = 0
201+ blockEvents .Events = append (blockEvents .Events , blockEvent )
202+
203+ // parse the EventStreaming API response
204+ cdcEvents , err := NewCadenceEvents (blockEvents )
205+ require .NoError (t , err )
206+
207+ // assert that Flow events are sorted by their TransactionIndex and EventIndex fields
208+ assert .Equal (
209+ t ,
210+ []flow.Event {
211+ txEvent1 ,
212+ txEvent2 ,
213+ txEvent3 ,
214+ blockEvent ,
215+ },
216+ cdcEvents .events .Events ,
217+ )
218+
219+ // assert that EVM transactions & receipts are sorted by their
220+ // TransactionIndex field
221+ for i := 0 ; i < txCount ; i ++ {
222+ tx := cdcEvents .transactions [i ]
223+ receipt := cdcEvents .receipts [i ]
224+ assert .Equal (t , tx .Hash (), receipt .TxHash )
225+ assert .Equal (t , uint (i ), receipt .TransactionIndex )
226+ }
227+ })
156228}
157229
158230func Test_EventDecoding (t * testing.T ) {
@@ -171,7 +243,7 @@ func Test_EventDecoding(t *testing.T) {
171243 // generate txs
172244 for i := 0 ; i < txCount ; i ++ {
173245 var err error
174- txs [i ], results [i ], txEvents [i ], err = newTransaction (uint64 (i ))
246+ txs [i ], results [i ], txEvents [i ], err = newTransaction (uint64 (i ), uint16 ( i ) )
175247 require .NoError (t , err )
176248 hashes [i ] = txs [i ].Hash ()
177249 blockEvents .Events = append (blockEvents .Events , txEvents [i ])
@@ -224,12 +296,22 @@ func Test_EventDecoding(t *testing.T) {
224296 }
225297}
226298
227- func newTransaction (nonce uint64 ) (Transaction , * types.Result , flow.Event , error ) {
228- tx := gethTypes .NewTransaction (nonce , gethCommon .HexToAddress ("0x1" ), big .NewInt (10 ), uint64 (100 ), big .NewInt (123 ), nil )
299+ func newTransaction (nonce uint64 , txIndex uint16 ) (Transaction , * types.Result , flow.Event , error ) {
300+ tx := gethTypes .NewTransaction (
301+ nonce ,
302+ gethCommon .HexToAddress ("0x1" ),
303+ big .NewInt (10 ),
304+ uint64 (100 ),
305+ big .NewInt (123 ),
306+ nil ,
307+ )
229308 res := & types.Result {
309+ ValidationError : nil ,
230310 VMError : nil ,
231311 TxType : tx .Type (),
232312 GasConsumed : 1 ,
313+ CumulativeGasUsed : 1 ,
314+ GasRefund : 0 ,
233315 DeployedContractAddress : & types.Address {0x5 , 0x6 , 0x7 },
234316 ReturnedData : []byte {0x55 },
235317 Logs : []* gethTypes.Log {{
@@ -239,7 +321,10 @@ func newTransaction(nonce uint64) (Transaction, *types.Result, flow.Event, error
239321 Address : gethCommon.Address {0x3 , 0x5 },
240322 Topics : []gethCommon.Hash {{0x2 , 0x66 }, {0x7 , 0x1 }},
241323 }},
242- TxHash : tx .Hash (),
324+ TxHash : tx .Hash (),
325+ Index : txIndex ,
326+ PrecompiledCalls : []byte {},
327+ StateChangeCommitment : []byte {},
243328 }
244329
245330 txEncoded , err := tx .MarshalBinary ()
0 commit comments