github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/environment/event_emitter_test.go (about) 1 package environment_test 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/assert" 7 "github.com/stretchr/testify/require" 8 9 "github.com/onflow/cadence" 10 "github.com/onflow/cadence/encoding/ccf" 11 "github.com/onflow/cadence/runtime/common" 12 "github.com/onflow/cadence/runtime/stdlib" 13 14 "github.com/onflow/flow-go/fvm/environment" 15 "github.com/onflow/flow-go/fvm/meter" 16 "github.com/onflow/flow-go/fvm/storage/state" 17 "github.com/onflow/flow-go/fvm/systemcontracts" 18 "github.com/onflow/flow-go/fvm/tracing" 19 "github.com/onflow/flow-go/model/flow" 20 ) 21 22 func Test_IsServiceEvent(t *testing.T) { 23 24 chain := flow.Emulator 25 events := systemcontracts.ServiceEventsForChain(chain) 26 27 t.Run("correct", func(t *testing.T) { 28 for _, event := range events.All() { 29 event := cadence.Event{ 30 EventType: &cadence.EventType{ 31 Location: common.AddressLocation{ 32 Address: common.MustBytesToAddress( 33 event.Address.Bytes()), 34 }, 35 QualifiedIdentifier: event.QualifiedIdentifier(), 36 }, 37 } 38 39 isServiceEvent, err := environment.IsServiceEvent(flow.EventType(event.Type().ID()), chain) 40 require.NoError(t, err) 41 assert.True(t, isServiceEvent) 42 } 43 }) 44 45 t.Run("wrong chain", func(t *testing.T) { 46 event := cadence.Event{ 47 EventType: &cadence.EventType{ 48 Location: common.AddressLocation{ 49 Address: common.MustBytesToAddress( 50 flow.Testnet.Chain().ServiceAddress().Bytes()), 51 }, 52 QualifiedIdentifier: events.EpochCommit.QualifiedIdentifier(), 53 }, 54 } 55 56 isServiceEvent, err := environment.IsServiceEvent(flow.EventType(event.Type().ID()), chain) 57 require.NoError(t, err) 58 assert.False(t, isServiceEvent) 59 }) 60 61 t.Run("wrong type", func(t *testing.T) { 62 event := cadence.Event{ 63 EventType: &cadence.EventType{ 64 Location: common.AddressLocation{ 65 Address: common.MustBytesToAddress( 66 chain.Chain().ServiceAddress().Bytes()), 67 }, 68 QualifiedIdentifier: "SomeContract.SomeEvent", 69 }, 70 } 71 72 isServiceEvent, err := environment.IsServiceEvent(flow.EventType(event.Type().ID()), chain) 73 require.NoError(t, err) 74 assert.False(t, isServiceEvent) 75 }) 76 } 77 78 func Test_ScriptEventEmitter(t *testing.T) { 79 // scripts use the NoEventEmitter 80 emitter := environment.NoEventEmitter{} 81 err := emitter.EmitEvent(cadence.Event{}) 82 require.NoError(t, err, "script should not error when emitting events") 83 } 84 85 func Test_EmitEvent_Limit(t *testing.T) { 86 t.Run("emit event - service account - within limit", func(t *testing.T) { 87 cadenceEvent1 := cadence.Event{ 88 EventType: &cadence.EventType{ 89 Location: stdlib.FlowLocation{}, 90 QualifiedIdentifier: "test", 91 }, 92 } 93 94 event1Size := getCadenceEventPayloadByteSize(cadenceEvent1) 95 eventEmitter := createTestEventEmitterWithLimit( 96 flow.Emulator, 97 flow.Emulator.Chain().ServiceAddress(), 98 event1Size+1) 99 100 err := eventEmitter.EmitEvent(cadenceEvent1) 101 require.NoError(t, err) 102 }) 103 104 t.Run("emit event - service account - exceeding limit", func(t *testing.T) { 105 cadenceEvent1 := cadence.Event{ 106 EventType: &cadence.EventType{ 107 Location: stdlib.FlowLocation{}, 108 QualifiedIdentifier: "test", 109 }, 110 } 111 112 event1Size := getCadenceEventPayloadByteSize(cadenceEvent1) 113 eventEmitter := createTestEventEmitterWithLimit( 114 flow.Emulator, 115 flow.Emulator.Chain().ServiceAddress(), 116 event1Size-1) 117 118 err := eventEmitter.EmitEvent(cadenceEvent1) 119 require.NoError(t, err) // service count doesn't have limit 120 }) 121 122 t.Run("emit event - non service account - within limit", func(t *testing.T) { 123 cadenceEvent1 := cadence.Event{ 124 EventType: &cadence.EventType{ 125 Location: stdlib.FlowLocation{}, 126 QualifiedIdentifier: "test", 127 }, 128 } 129 130 event1Size := getCadenceEventPayloadByteSize(cadenceEvent1) 131 eventEmitter := createTestEventEmitterWithLimit( 132 flow.Emulator, 133 flow.Emulator.Chain().NewAddressGenerator().CurrentAddress(), 134 event1Size+1) 135 136 err := eventEmitter.EmitEvent(cadenceEvent1) 137 require.NoError(t, err) 138 }) 139 140 t.Run("emit event - non service account - exceeding limit", func(t *testing.T) { 141 cadenceEvent1 := cadence.Event{ 142 EventType: &cadence.EventType{ 143 Location: stdlib.FlowLocation{}, 144 QualifiedIdentifier: "test", 145 }, 146 } 147 148 event1Size := getCadenceEventPayloadByteSize(cadenceEvent1) 149 eventEmitter := createTestEventEmitterWithLimit( 150 flow.Emulator, 151 flow.Emulator.Chain().NewAddressGenerator().CurrentAddress(), 152 event1Size-1) 153 154 err := eventEmitter.EmitEvent(cadenceEvent1) 155 require.Error(t, err) 156 }) 157 } 158 159 func createTestEventEmitterWithLimit(chain flow.ChainID, address flow.Address, eventEmitLimit uint64) environment.EventEmitter { 160 txnState := state.NewTransactionState( 161 nil, 162 state.DefaultParameters().WithMeterParameters( 163 meter.DefaultParameters().WithEventEmitByteLimit(eventEmitLimit), 164 )) 165 166 return environment.NewEventEmitter( 167 tracing.NewTracerSpan(), 168 environment.NewMeter(txnState), 169 chain.Chain(), 170 environment.TransactionInfoParams{ 171 TxId: flow.ZeroID, 172 TxIndex: 0, 173 TxBody: &flow.TransactionBody{ 174 Payer: address, 175 }, 176 }, 177 environment.EventEmitterParams{ 178 EventCollectionByteSizeLimit: eventEmitLimit, 179 EventEncoder: environment.NewCadenceEventEncoder(), 180 }, 181 ) 182 } 183 184 func getCadenceEventPayloadByteSize(event cadence.Event) uint64 { 185 payload, err := ccf.Encode(event) 186 if err != nil { 187 panic(err) 188 } 189 190 return uint64(len(payload)) 191 }