Skip to content

Commit a22b951

Browse files
committed
Add more unit tests for NewSingleBlockEvents & NewMultiBlockEvents methods
1 parent ca18d33 commit a22b951

File tree

1 file changed

+272
-18
lines changed

1 file changed

+272
-18
lines changed

models/events_test.go

Lines changed: 272 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
243497
func Test_EventDecoding(t *testing.T) {
244498
cadenceHeight := uint64(1)
245499
txCount := 10

0 commit comments

Comments
 (0)