@@ -15,7 +15,7 @@ import (
1515 "github.com/stretchr/testify/require"
1616)
1717
18- func TestCadenceEvents_Block (t * testing.T ) {
18+ func TestNewSingleBlockEvents (t * testing.T ) {
1919 invalid := cadence .String ("invalid" )
2020
2121 b0 , e0 , err := newBlock (0 , nil )
@@ -47,17 +47,18 @@ func TestCadenceEvents_Block(t *testing.T) {
4747
4848 for _ , tt := range tests {
4949 t .Run (tt .name , func (t * testing.T ) {
50- e , err := NewCadenceEvents (tt .events )
51- require .NoError (t , err )
50+ evmEvents := NewSingleBlockEvents (tt .events )
51+ require .NoError (t , evmEvents . Err )
5252
53+ cdcEvents := evmEvents .Events
5354 if tt .block != nil {
5455 ttHash , err := tt .block .Hash ()
5556 require .NoError (t , err )
56- hash , err := e .Block ().Hash ()
57+ hash , err := cdcEvents .Block ().Hash ()
5758 require .NoError (t , err )
5859 assert .Equal (t , ttHash , hash )
5960 } else {
60- assert .Nil (t , e .Block ())
61+ assert .Nil (t , cdcEvents .Block ())
6162 }
6263 })
6364 }
@@ -75,6 +76,26 @@ func TestCadenceEvents_Block(t *testing.T) {
7576 events = append (events , txEvent )
7677 }
7778
79+ t .Run ("missing block with transactions" , func (t * testing.T ) {
80+ // generate single block
81+ _ , _ , err := newBlock (cadenceHeight , hashes )
82+ require .NoError (t , err )
83+
84+ blockEvents := flow.BlockEvents {
85+ BlockID : flow.Identifier {0x1 },
86+ Height : cadenceHeight ,
87+ Events : events ,
88+ }
89+
90+ evmEvents := NewSingleBlockEvents (blockEvents )
91+ require .Error (t , evmEvents .Err )
92+ assert .ErrorContains (
93+ t ,
94+ evmEvents .Err ,
95+ "missing block EVM block nil at flow block: 1" ,
96+ )
97+ })
98+
7899 t .Run ("block with less transaction hashes" , func (t * testing.T ) {
79100 // generate single block
80101 _ , blockEvent , err := newBlock (cadenceHeight , hashes [:txCount - 2 ])
@@ -88,11 +109,11 @@ func TestCadenceEvents_Block(t *testing.T) {
88109
89110 blockEvents .Events = append (blockEvents .Events , blockEvent )
90111
91- _ , err = NewCadenceEvents (blockEvents )
92- require .Error (t , err )
112+ evmEvents := NewSingleBlockEvents (blockEvents )
113+ require .Error (t , evmEvents . Err )
93114 assert .ErrorContains (
94115 t ,
95- err ,
116+ evmEvents . Err ,
96117 "block 1 references missing transaction/s" ,
97118 )
98119 })
@@ -110,8 +131,8 @@ func TestCadenceEvents_Block(t *testing.T) {
110131
111132 blockEvents .Events = append (blockEvents .Events , blockEvent )
112133
113- _ , err = NewCadenceEvents (blockEvents )
114- require .NoError (t , err )
134+ evmEvents := NewSingleBlockEvents (blockEvents )
135+ require .NoError (t , evmEvents . Err )
115136 })
116137
117138 t .Run ("block with empty transaction hashes" , func (t * testing.T ) {
@@ -126,8 +147,8 @@ func TestCadenceEvents_Block(t *testing.T) {
126147
127148 blockEvents .Events = append (blockEvents .Events , blockEvent )
128149
129- _ , err = NewCadenceEvents (blockEvents )
130- require .NoError (t , err )
150+ evmEvents := NewSingleBlockEvents (blockEvents )
151+ require .NoError (t , evmEvents . Err )
131152 })
132153
133154 t .Run ("block with more transaction hashes" , func (t * testing.T ) {
@@ -145,11 +166,11 @@ func TestCadenceEvents_Block(t *testing.T) {
145166
146167 blockEvents .Events = append (blockEvents .Events , blockEvent )
147168
148- _ , err = NewCadenceEvents (blockEvents )
149- require .Error (t , err )
169+ evmEvents := NewSingleBlockEvents (blockEvents )
170+ require .Error (t , evmEvents . Err )
150171 assert .ErrorContains (
151172 t ,
152- err ,
173+ evmEvents . Err ,
153174 "block 1 references missing transaction/s" ,
154175 )
155176 })
@@ -201,9 +222,9 @@ func TestCadenceEvents_Block(t *testing.T) {
201222 blockEvents .Events = append (blockEvents .Events , blockEvent )
202223
203224 // parse the EventStreaming API response
204- blkEvents := NewSingleBlockEvents (blockEvents )
205- require .NoError (t , blkEvents .Err )
206- cdcEvents := blkEvents .Events
225+ evmEvents := NewSingleBlockEvents (blockEvents )
226+ require .NoError (t , evmEvents .Err )
227+ cdcEvents := evmEvents .Events
207228
208229 // assert that Flow events are sorted by their TransactionIndex and EventIndex fields
209230 assert .Equal (
@@ -240,6 +261,239 @@ func TestCadenceEvents_Block(t *testing.T) {
240261 })
241262}
242263
264+ func TestNewMultiBlockEvents (t * testing.T ) {
265+ invalid := cadence .String ("invalid" )
266+
267+ b0 , e0 , err := newBlock (0 , nil )
268+ require .NoError (t , err )
269+
270+ tests := []struct {
271+ name string
272+ events flow.BlockEvents
273+ block * Block
274+ err error
275+ }{
276+ {
277+ name : "BlockExecutedEventExists" ,
278+ events : flow.BlockEvents {Events : []flow.Event {e0 }},
279+ block : b0 ,
280+ }, {
281+ name : "BlockExecutedEventEmpty" ,
282+ events : flow.BlockEvents {Events : []flow.Event {}},
283+ block : nil ,
284+ }, {
285+ name : "BlockExecutedNotFound" ,
286+ events : flow.BlockEvents {Events : []flow.Event {{
287+ Type : e0 .Type ,
288+ Value : cadence .NewEvent ([]cadence.Value {invalid }),
289+ }}},
290+ block : nil ,
291+ },
292+ }
293+
294+ for _ , tt := range tests {
295+ t .Run (tt .name , func (t * testing.T ) {
296+ evmEvents := NewMultiBlockEvents (tt .events )
297+ require .NoError (t , evmEvents .Err )
298+
299+ cdcEvents := evmEvents .Events
300+ if tt .block != nil {
301+ ttHash , err := tt .block .Hash ()
302+ require .NoError (t , err )
303+ hash , err := cdcEvents .Block ().Hash ()
304+ require .NoError (t , err )
305+ assert .Equal (t , ttHash , hash )
306+ } else {
307+ assert .Nil (t , cdcEvents .Block ())
308+ }
309+ })
310+ }
311+
312+ cadenceHeight := uint64 (15 )
313+ txCount := 10
314+ hashes := make ([]gethCommon.Hash , txCount )
315+ evmTxEvents := make ([]flow.BlockEvents , txCount )
316+
317+ // generate txs
318+ for i := 0 ; i < txCount ; i ++ {
319+ tx , _ , txEvent , err := newTransaction (uint64 (i ), uint16 (i ))
320+ require .NoError (t , err )
321+ hashes [i ] = tx .Hash ()
322+ evmTxEvents [i ] = flow.BlockEvents {
323+ BlockID : flow .BytesToID ([]byte {uint8 (i + 1 )}),
324+ Height : uint64 (i + 1 ),
325+ Events : []flow.Event {txEvent },
326+ }
327+ }
328+
329+ t .Run ("missing block with transactions" , func (t * testing.T ) {
330+ // generate single block
331+ _ , _ , err := newBlock (cadenceHeight , hashes )
332+ require .NoError (t , err )
333+
334+ blockEvents := flow.BlockEvents {
335+ BlockID : flow.Identifier {0x1 },
336+ Height : cadenceHeight ,
337+ }
338+
339+ // Below we add all the EVM transaction events, but we have omitted
340+ // the EVM.BlockExecuted event.
341+ for i := 0 ; i < txCount ; i ++ {
342+ blockEvents .Events = append (blockEvents .Events , evmTxEvents [i ].Events ... )
343+ }
344+
345+ evmEvents := NewSingleBlockEvents (blockEvents )
346+ require .Error (t , evmEvents .Err )
347+ assert .ErrorContains (
348+ t ,
349+ evmEvents .Err ,
350+ "missing block EVM block nil at flow block: 1" ,
351+ )
352+ })
353+
354+ t .Run ("block with less transaction hashes" , func (t * testing.T ) {
355+ // generate single block
356+ _ , blockEvent , err := newBlock (cadenceHeight , hashes )
357+ require .NoError (t , err )
358+
359+ blockEvents := flow.BlockEvents {
360+ BlockID : flow.Identifier {0x1 },
361+ Height : cadenceHeight ,
362+ }
363+
364+ // Below we omit 2 EVM transactions from the events
365+ for i := 0 ; i < txCount - 2 ; i ++ {
366+ blockEvents .Events = append (blockEvents .Events , evmTxEvents [i ].Events ... )
367+ }
368+
369+ blockEvents .Events = append (blockEvents .Events , blockEvent )
370+
371+ evmEvents := NewMultiBlockEvents (blockEvents )
372+ require .Error (t , evmEvents .Err )
373+ assert .ErrorContains (
374+ t ,
375+ evmEvents .Err ,
376+ "block 15 references missing transaction/s" ,
377+ )
378+ })
379+
380+ t .Run ("block with equal transaction hashes" , func (t * testing.T ) {
381+ // generate single block
382+ _ , blockEvent , err := newBlock (cadenceHeight , hashes )
383+ require .NoError (t , err )
384+
385+ blockEvents := flow.BlockEvents {
386+ BlockID : flow.Identifier {0x1 },
387+ Height : cadenceHeight ,
388+ }
389+
390+ // Below we add all the EVM transaction events
391+ for i := 0 ; i < txCount ; i ++ {
392+ blockEvents .Events = append (blockEvents .Events , evmTxEvents [i ].Events ... )
393+ }
394+
395+ blockEvents .Events = append (blockEvents .Events , blockEvent )
396+
397+ evmEvents := NewMultiBlockEvents (blockEvents )
398+ require .NoError (t , evmEvents .Err )
399+ })
400+
401+ t .Run ("block with empty transaction hashes" , func (t * testing.T ) {
402+ // generate single block
403+ _ , blockEvent , err := newBlock (cadenceHeight , []gethCommon.Hash {})
404+ require .NoError (t , err )
405+
406+ blockEvents := flow.BlockEvents {
407+ BlockID : flow.Identifier {0x1 },
408+ Height : cadenceHeight ,
409+ }
410+
411+ blockEvents .Events = append (blockEvents .Events , blockEvent )
412+
413+ evmEvents := NewMultiBlockEvents (blockEvents )
414+ require .NoError (t , evmEvents .Err )
415+ })
416+
417+ t .Run ("block with more transaction hashes" , func (t * testing.T ) {
418+ tx , _ , _ , err := newTransaction (1 , 0 )
419+ require .NoError (t , err )
420+
421+ // generate single block
422+ _ , blockEvent , err := newBlock (cadenceHeight , []gethCommon.Hash {tx .Hash ()})
423+ require .NoError (t , err )
424+
425+ blockEvents := flow.BlockEvents {
426+ BlockID : flow.Identifier {0x1 },
427+ Height : cadenceHeight ,
428+ }
429+
430+ blockEvents .Events = append (blockEvents .Events , blockEvent )
431+
432+ evmEvents := NewMultiBlockEvents (blockEvents )
433+ require .Error (t , evmEvents .Err )
434+ assert .ErrorContains (
435+ t ,
436+ evmEvents .Err ,
437+ "block 15 references missing transaction/s" ,
438+ )
439+ })
440+
441+ t .Run ("EVM.TransactionExecuted events should be properly ordered" , func (t * testing.T ) {
442+ blockEvents := flow.BlockEvents {
443+ BlockID : flow.Identifier {0x1 },
444+ Height : cadenceHeight ,
445+ }
446+
447+ // tx1 and tx2 are EVM transactions executed on a single Flow transaction.
448+ tx1 , _ , txEvent1 , err := newTransaction (0 , 0 )
449+ require .NoError (t , err )
450+ txEvent1 .TransactionIndex = 0
451+ txEvent1 .EventIndex = 2
452+
453+ tx2 , _ , txEvent2 , err := newTransaction (1 , 1 )
454+ require .NoError (t , err )
455+ txEvent2 .TransactionIndex = 0
456+ txEvent2 .EventIndex = 5
457+
458+ // tx3 is a Flow transaction with a single EVM transaction on EventIndex=1
459+ tx3 , _ , txEvent3 , err := newTransaction (2 , 0 )
460+ require .NoError (t , err )
461+ txEvent3 .TransactionIndex = 2
462+ txEvent3 .EventIndex = 1
463+
464+ // needed for computing the `TransactionHashRoot` field on
465+ // EVM.BlockExecuted event payload. the order is sensitive.
466+ hashes = []gethCommon.Hash {
467+ tx1 .Hash (),
468+ tx2 .Hash (),
469+ tx3 .Hash (),
470+ }
471+
472+ // add the tx events in a shuffled order
473+ blockEvents .Events = []flow.Event {
474+ txEvent3 ,
475+ txEvent1 ,
476+ txEvent2 ,
477+ }
478+
479+ // generate single block
480+ _ , blockEvent , err := newBlock (cadenceHeight , hashes )
481+ require .NoError (t , err )
482+ blockEvent .TransactionIndex = 4
483+ blockEvent .EventIndex = 0
484+ blockEvents .Events = append (blockEvents .Events , blockEvent )
485+
486+ // parse the EventStreaming API response
487+ evmEvents := NewMultiBlockEvents (blockEvents )
488+ require .Error (t , evmEvents .Err )
489+ assert .ErrorContains (
490+ t ,
491+ evmEvents .Err ,
492+ "block 15 references missing transaction/s" ,
493+ )
494+ })
495+ }
496+
243497func Test_EventDecoding (t * testing.T ) {
244498 cadenceHeight := uint64 (1 )
245499 txCount := 10
0 commit comments