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