github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/evm/testutils/cadence.go (about)

     1  package testutils
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"encoding/hex"
     7  	"errors"
     8  	"fmt"
     9  	"strconv"
    10  	"strings"
    11  	"sync/atomic"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/onflow/atree"
    16  	"github.com/onflow/cadence"
    17  	"github.com/onflow/cadence/encoding/json"
    18  	"github.com/onflow/cadence/runtime"
    19  	"github.com/onflow/cadence/runtime/ast"
    20  	"github.com/onflow/cadence/runtime/common"
    21  	"github.com/onflow/cadence/runtime/interpreter"
    22  	"github.com/onflow/cadence/runtime/sema"
    23  	cadenceStdlib "github.com/onflow/cadence/runtime/stdlib"
    24  	"github.com/stretchr/testify/require"
    25  	"go.opentelemetry.io/otel/attribute"
    26  )
    27  
    28  // LocationResolver is a location Cadence runtime interface location resolver
    29  // very similar to ContractReader.ResolveLocation,
    30  // but it does not look up available contract names
    31  func LocationResolver(
    32  	identifiers []ast.Identifier,
    33  	location common.Location,
    34  ) (
    35  	result []sema.ResolvedLocation,
    36  	err error,
    37  ) {
    38  	addressLocation, isAddress := location.(common.AddressLocation)
    39  
    40  	// if the location is not an address location, e.g. an identifier location
    41  	// (`import Crypto`), then return a single resolved location which declares
    42  	// all identifiers.
    43  	if !isAddress {
    44  		return []runtime.ResolvedLocation{
    45  			{
    46  				Location:    location,
    47  				Identifiers: identifiers,
    48  			},
    49  		}, nil
    50  	}
    51  
    52  	// if the location is an address,
    53  	// and no specific identifiers where requested in the import statement,
    54  	// then assume the imported identifier is the address location's identifier (the contract)
    55  	if len(identifiers) == 0 {
    56  		identifiers = []ast.Identifier{
    57  			{Identifier: addressLocation.Name},
    58  		}
    59  	}
    60  
    61  	// return one resolved location per identifier.
    62  	// each resolved location is an address contract location
    63  	resolvedLocations := make([]runtime.ResolvedLocation, len(identifiers))
    64  	for i := range resolvedLocations {
    65  		identifier := identifiers[i]
    66  		resolvedLocations[i] = runtime.ResolvedLocation{
    67  			Location: common.AddressLocation{
    68  				Address: addressLocation.Address,
    69  				Name:    identifier.Identifier,
    70  			},
    71  			Identifiers: []runtime.Identifier{identifier},
    72  		}
    73  	}
    74  
    75  	return resolvedLocations, nil
    76  }
    77  
    78  // TODO: replace with Cadence runtime testing utils once available https://github.com/onflow/cadence/pull/2800
    79  
    80  func newLocationGenerator[T ~[32]byte]() func() T {
    81  	var count uint64
    82  	return func() T {
    83  		t := T{}
    84  		newCount := atomic.AddUint64(&count, 1)
    85  		binary.LittleEndian.PutUint64(t[:], newCount)
    86  		return t
    87  	}
    88  }
    89  
    90  func NewTransactionLocationGenerator() func() common.TransactionLocation {
    91  	return newLocationGenerator[common.TransactionLocation]()
    92  }
    93  
    94  func NewScriptLocationGenerator() func() common.ScriptLocation {
    95  	return newLocationGenerator[common.ScriptLocation]()
    96  }
    97  
    98  func EncodeArgs(argValues []cadence.Value) [][]byte {
    99  	args := make([][]byte, len(argValues))
   100  	for i, arg := range argValues {
   101  		var err error
   102  		args[i], err = json.Encode(arg)
   103  		if err != nil {
   104  			panic(fmt.Errorf("broken test: invalid argument: %w", err))
   105  		}
   106  	}
   107  	return args
   108  }
   109  
   110  type TestLedger struct {
   111  	StoredValues           map[string][]byte
   112  	OnValueExists          func(owner, key []byte) (exists bool, err error)
   113  	OnGetValue             func(owner, key []byte) (value []byte, err error)
   114  	OnSetValue             func(owner, key, value []byte) (err error)
   115  	OnAllocateStorageIndex func(owner []byte) (atree.SlabIndex, error)
   116  }
   117  
   118  var _ atree.Ledger = TestLedger{}
   119  
   120  func (s TestLedger) GetValue(owner, key []byte) (value []byte, err error) {
   121  	return s.OnGetValue(owner, key)
   122  }
   123  
   124  func (s TestLedger) SetValue(owner, key, value []byte) (err error) {
   125  	return s.OnSetValue(owner, key, value)
   126  }
   127  
   128  func (s TestLedger) ValueExists(owner, key []byte) (exists bool, err error) {
   129  	return s.OnValueExists(owner, key)
   130  }
   131  
   132  func (s TestLedger) AllocateSlabIndex(owner []byte) (atree.SlabIndex, error) {
   133  	return s.OnAllocateStorageIndex(owner)
   134  }
   135  
   136  func (s TestLedger) Dump() {
   137  	// Only used for testing/debugging purposes
   138  	for key, data := range s.StoredValues { //nolint:maprange
   139  		fmt.Printf("%s:\n", strconv.Quote(key))
   140  		fmt.Printf("%s\n", hex.Dump(data))
   141  		println()
   142  	}
   143  }
   144  
   145  func NewTestLedger(
   146  	onRead func(owner, key, value []byte),
   147  	onWrite func(owner, key, value []byte),
   148  ) TestLedger {
   149  
   150  	storageKey := func(owner, key string) string {
   151  		return strings.Join([]string{owner, key}, "|")
   152  	}
   153  
   154  	storedValues := map[string][]byte{}
   155  
   156  	storageIndices := map[string]uint64{}
   157  
   158  	return TestLedger{
   159  		StoredValues: storedValues,
   160  		OnValueExists: func(owner, key []byte) (bool, error) {
   161  			value := storedValues[storageKey(string(owner), string(key))]
   162  			return len(value) > 0, nil
   163  		},
   164  		OnGetValue: func(owner, key []byte) (value []byte, err error) {
   165  			value = storedValues[storageKey(string(owner), string(key))]
   166  			if onRead != nil {
   167  				onRead(owner, key, value)
   168  			}
   169  			return value, nil
   170  		},
   171  		OnSetValue: func(owner, key, value []byte) (err error) {
   172  			storedValues[storageKey(string(owner), string(key))] = value
   173  			if onWrite != nil {
   174  				onWrite(owner, key, value)
   175  			}
   176  			return nil
   177  		},
   178  		OnAllocateStorageIndex: func(owner []byte) (result atree.SlabIndex, err error) {
   179  			index := storageIndices[string(owner)] + 1
   180  			storageIndices[string(owner)] = index
   181  			binary.BigEndian.PutUint64(result[:], index)
   182  			return
   183  		},
   184  	}
   185  }
   186  
   187  type TestRuntimeInterface struct {
   188  	Storage atree.Ledger
   189  
   190  	OnResolveLocation func(
   191  		identifiers []runtime.Identifier,
   192  		location runtime.Location,
   193  	) (
   194  		[]runtime.ResolvedLocation,
   195  		error,
   196  	)
   197  	OnGetCode          func(_ runtime.Location) ([]byte, error)
   198  	OnGetAndSetProgram func(
   199  		location runtime.Location,
   200  		load func() (*interpreter.Program, error),
   201  	) (*interpreter.Program, error)
   202  	OnSetInterpreterSharedState func(state *interpreter.SharedState)
   203  	OnGetInterpreterSharedState func() *interpreter.SharedState
   204  	OnCreateAccount             func(payer runtime.Address) (address runtime.Address, err error)
   205  	OnAddEncodedAccountKey      func(address runtime.Address, publicKey []byte) error
   206  	OnRemoveEncodedAccountKey   func(address runtime.Address, index int) (publicKey []byte, err error)
   207  	OnAddAccountKey             func(
   208  		address runtime.Address,
   209  		publicKey *cadenceStdlib.PublicKey,
   210  		hashAlgo runtime.HashAlgorithm,
   211  		weight int,
   212  	) (*cadenceStdlib.AccountKey, error)
   213  	OnGetAccountKey             func(address runtime.Address, index int) (*cadenceStdlib.AccountKey, error)
   214  	OnRemoveAccountKey          func(address runtime.Address, index int) (*cadenceStdlib.AccountKey, error)
   215  	OnAccountKeysCount          func(address runtime.Address) (uint64, error)
   216  	OnUpdateAccountContractCode func(location common.AddressLocation, code []byte) error
   217  	OnGetAccountContractCode    func(location common.AddressLocation) (code []byte, err error)
   218  	OnRemoveAccountContractCode func(location common.AddressLocation) (err error)
   219  	OnGetSigningAccounts        func() ([]runtime.Address, error)
   220  	OnProgramLog                func(string)
   221  	OnEmitEvent                 func(cadence.Event) error
   222  	OnResourceOwnerChanged      func(
   223  		interpreter *interpreter.Interpreter,
   224  		resource *interpreter.CompositeValue,
   225  		oldAddress common.Address,
   226  		newAddress common.Address,
   227  	)
   228  	OnGenerateUUID       func() (uint64, error)
   229  	OnMeterComputation   func(compKind common.ComputationKind, intensity uint) error
   230  	OnDecodeArgument     func(b []byte, t cadence.Type) (cadence.Value, error)
   231  	OnProgramParsed      func(location runtime.Location, duration time.Duration)
   232  	OnProgramChecked     func(location runtime.Location, duration time.Duration)
   233  	OnProgramInterpreted func(location runtime.Location, duration time.Duration)
   234  	OnReadRandom         func([]byte) error
   235  	OnVerifySignature    func(
   236  		signature []byte,
   237  		tag string,
   238  		signedData []byte,
   239  		publicKey []byte,
   240  		signatureAlgorithm runtime.SignatureAlgorithm,
   241  		hashAlgorithm runtime.HashAlgorithm,
   242  	) (bool, error)
   243  	OnHash func(
   244  		data []byte,
   245  		tag string,
   246  		hashAlgorithm runtime.HashAlgorithm,
   247  	) ([]byte, error)
   248  	OnSetCadenceValue            func(owner runtime.Address, key string, value cadence.Value) (err error)
   249  	OnGetAccountBalance          func(_ runtime.Address) (uint64, error)
   250  	OnGetAccountAvailableBalance func(_ runtime.Address) (uint64, error)
   251  	OnGetStorageUsed             func(_ runtime.Address) (uint64, error)
   252  	OnGetStorageCapacity         func(_ runtime.Address) (uint64, error)
   253  	Programs                     map[runtime.Location]*interpreter.Program
   254  	OnImplementationDebugLog     func(message string) error
   255  	OnValidatePublicKey          func(publicKey *cadenceStdlib.PublicKey) error
   256  	OnBLSVerifyPOP               func(pk *cadenceStdlib.PublicKey, s []byte) (bool, error)
   257  	OnBLSAggregateSignatures     func(sigs [][]byte) ([]byte, error)
   258  	OnBLSAggregatePublicKeys     func(keys []*cadenceStdlib.PublicKey) (*cadenceStdlib.PublicKey, error)
   259  	OnGetAccountContractNames    func(address runtime.Address) ([]string, error)
   260  	OnRecordTrace                func(
   261  		operation string,
   262  		location runtime.Location,
   263  		duration time.Duration,
   264  		attrs []attribute.KeyValue,
   265  	)
   266  	OnMeterMemory       func(usage common.MemoryUsage) error
   267  	OnComputationUsed   func() (uint64, error)
   268  	OnMemoryUsed        func() (uint64, error)
   269  	OnInteractionUsed   func() (uint64, error)
   270  	OnGenerateAccountID func(address common.Address) (uint64, error)
   271  
   272  	lastUUID            uint64
   273  	accountIDs          map[common.Address]uint64
   274  	updatedContractCode bool
   275  }
   276  
   277  // TestRuntimeInterface should implement Interface
   278  var _ runtime.Interface = &TestRuntimeInterface{}
   279  
   280  func (i *TestRuntimeInterface) ResolveLocation(
   281  	identifiers []runtime.Identifier,
   282  	location runtime.Location,
   283  ) ([]runtime.ResolvedLocation, error) {
   284  	if i.OnResolveLocation == nil {
   285  		return []runtime.ResolvedLocation{
   286  			{
   287  				Location:    location,
   288  				Identifiers: identifiers,
   289  			},
   290  		}, nil
   291  	}
   292  	return i.OnResolveLocation(identifiers, location)
   293  }
   294  
   295  func (i *TestRuntimeInterface) GetCode(location runtime.Location) ([]byte, error) {
   296  	if i.OnGetCode == nil {
   297  		return nil, nil
   298  	}
   299  	return i.OnGetCode(location)
   300  }
   301  
   302  func (i *TestRuntimeInterface) GetOrLoadProgram(
   303  	location runtime.Location,
   304  	load func() (*interpreter.Program, error),
   305  ) (
   306  	program *interpreter.Program,
   307  	err error,
   308  ) {
   309  	if i.OnGetAndSetProgram == nil {
   310  		if i.Programs == nil {
   311  			i.Programs = map[runtime.Location]*interpreter.Program{}
   312  		}
   313  
   314  		var ok bool
   315  		program, ok = i.Programs[location]
   316  		if ok {
   317  			return
   318  		}
   319  
   320  		program, err = load()
   321  
   322  		// NOTE: important: still set empty program,
   323  		// even if error occurred
   324  
   325  		i.Programs[location] = program
   326  
   327  		return
   328  	}
   329  
   330  	return i.OnGetAndSetProgram(location, load)
   331  }
   332  
   333  func (i *TestRuntimeInterface) SetInterpreterSharedState(state *interpreter.SharedState) {
   334  	if i.OnSetInterpreterSharedState == nil {
   335  		return
   336  	}
   337  
   338  	i.OnSetInterpreterSharedState(state)
   339  }
   340  
   341  func (i *TestRuntimeInterface) GetInterpreterSharedState() *interpreter.SharedState {
   342  	if i.OnGetInterpreterSharedState == nil {
   343  		return nil
   344  	}
   345  
   346  	return i.OnGetInterpreterSharedState()
   347  }
   348  
   349  func (i *TestRuntimeInterface) ValueExists(owner, key []byte) (exists bool, err error) {
   350  	return i.Storage.ValueExists(owner, key)
   351  }
   352  
   353  func (i *TestRuntimeInterface) GetValue(owner, key []byte) (value []byte, err error) {
   354  	return i.Storage.GetValue(owner, key)
   355  }
   356  
   357  func (i *TestRuntimeInterface) SetValue(owner, key, value []byte) (err error) {
   358  	return i.Storage.SetValue(owner, key, value)
   359  }
   360  
   361  func (i *TestRuntimeInterface) AllocateSlabIndex(owner []byte) (atree.SlabIndex, error) {
   362  	return i.Storage.AllocateSlabIndex(owner)
   363  }
   364  
   365  func (i *TestRuntimeInterface) CreateAccount(payer runtime.Address) (address runtime.Address, err error) {
   366  	if i.OnCreateAccount == nil {
   367  		panic("must specify TestRuntimeInterface.OnCreateAccount")
   368  	}
   369  	return i.OnCreateAccount(payer)
   370  }
   371  
   372  func (i *TestRuntimeInterface) AddEncodedAccountKey(address runtime.Address, publicKey []byte) error {
   373  	if i.OnAddEncodedAccountKey == nil {
   374  		panic("must specify TestRuntimeInterface.OnAddEncodedAccountKey")
   375  	}
   376  	return i.OnAddEncodedAccountKey(address, publicKey)
   377  }
   378  
   379  func (i *TestRuntimeInterface) RevokeEncodedAccountKey(address runtime.Address, index int) ([]byte, error) {
   380  	if i.OnRemoveEncodedAccountKey == nil {
   381  		panic("must specify TestRuntimeInterface.OnRemoveEncodedAccountKey")
   382  	}
   383  	return i.OnRemoveEncodedAccountKey(address, index)
   384  }
   385  
   386  func (i *TestRuntimeInterface) AddAccountKey(
   387  	address runtime.Address,
   388  	publicKey *cadenceStdlib.PublicKey,
   389  	hashAlgo runtime.HashAlgorithm,
   390  	weight int,
   391  ) (*cadenceStdlib.AccountKey, error) {
   392  	if i.OnAddAccountKey == nil {
   393  		panic("must specify TestRuntimeInterface.OnAddAccountKey")
   394  	}
   395  	return i.OnAddAccountKey(address, publicKey, hashAlgo, weight)
   396  }
   397  
   398  func (i *TestRuntimeInterface) GetAccountKey(address runtime.Address, index int) (*cadenceStdlib.AccountKey, error) {
   399  	if i.OnGetAccountKey == nil {
   400  		panic("must specify TestRuntimeInterface.OnGetAccountKey")
   401  	}
   402  	return i.OnGetAccountKey(address, index)
   403  }
   404  
   405  func (i *TestRuntimeInterface) AccountKeysCount(address runtime.Address) (uint64, error) {
   406  	if i.OnAccountKeysCount == nil {
   407  		panic("must specify TestRuntimeInterface.OnAccountKeysCount")
   408  	}
   409  	return i.OnAccountKeysCount(address)
   410  }
   411  
   412  func (i *TestRuntimeInterface) RevokeAccountKey(address runtime.Address, index int) (*cadenceStdlib.AccountKey, error) {
   413  	if i.OnRemoveAccountKey == nil {
   414  		panic("must specify TestRuntimeInterface.OnRemoveAccountKey")
   415  	}
   416  	return i.OnRemoveAccountKey(address, index)
   417  }
   418  
   419  func (i *TestRuntimeInterface) UpdateAccountContractCode(location common.AddressLocation, code []byte) (err error) {
   420  	if i.OnUpdateAccountContractCode == nil {
   421  		panic("must specify TestRuntimeInterface.OnUpdateAccountContractCode")
   422  	}
   423  
   424  	err = i.OnUpdateAccountContractCode(location, code)
   425  	if err != nil {
   426  		return err
   427  	}
   428  
   429  	i.updatedContractCode = true
   430  
   431  	return nil
   432  }
   433  
   434  func (i *TestRuntimeInterface) GetAccountContractCode(location common.AddressLocation) (code []byte, err error) {
   435  	if i.OnGetAccountContractCode == nil {
   436  		panic("must specify TestRuntimeInterface.OnGetAccountContractCode")
   437  	}
   438  	return i.OnGetAccountContractCode(location)
   439  }
   440  
   441  func (i *TestRuntimeInterface) RemoveAccountContractCode(location common.AddressLocation) (err error) {
   442  	if i.OnRemoveAccountContractCode == nil {
   443  		panic("must specify TestRuntimeInterface.OnRemoveAccountContractCode")
   444  	}
   445  	return i.OnRemoveAccountContractCode(location)
   446  }
   447  
   448  func (i *TestRuntimeInterface) GetSigningAccounts() ([]runtime.Address, error) {
   449  	if i.OnGetSigningAccounts == nil {
   450  		return nil, nil
   451  	}
   452  	return i.OnGetSigningAccounts()
   453  }
   454  
   455  func (i *TestRuntimeInterface) ProgramLog(message string) error {
   456  	i.OnProgramLog(message)
   457  	return nil
   458  }
   459  
   460  func (i *TestRuntimeInterface) EmitEvent(event cadence.Event) error {
   461  	return i.OnEmitEvent(event)
   462  }
   463  
   464  func (i *TestRuntimeInterface) ResourceOwnerChanged(
   465  	interpreter *interpreter.Interpreter,
   466  	resource *interpreter.CompositeValue,
   467  	oldOwner common.Address,
   468  	newOwner common.Address,
   469  ) {
   470  	if i.OnResourceOwnerChanged != nil {
   471  		i.OnResourceOwnerChanged(
   472  			interpreter,
   473  			resource,
   474  			oldOwner,
   475  			newOwner,
   476  		)
   477  	}
   478  }
   479  
   480  func (i *TestRuntimeInterface) GenerateUUID() (uint64, error) {
   481  	if i.OnGenerateUUID == nil {
   482  		i.lastUUID++
   483  		return i.lastUUID, nil
   484  	}
   485  	return i.OnGenerateUUID()
   486  }
   487  
   488  func (i *TestRuntimeInterface) MeterComputation(compKind common.ComputationKind, intensity uint) error {
   489  	if i.OnMeterComputation == nil {
   490  		return nil
   491  	}
   492  	return i.OnMeterComputation(compKind, intensity)
   493  }
   494  
   495  func (i *TestRuntimeInterface) DecodeArgument(b []byte, t cadence.Type) (cadence.Value, error) {
   496  	if i.OnDecodeArgument == nil {
   497  		panic("must specify TestRuntimeInterface.OnDecodeArgument")
   498  	}
   499  	return i.OnDecodeArgument(b, t)
   500  }
   501  
   502  func (i *TestRuntimeInterface) ProgramParsed(location runtime.Location, duration time.Duration) {
   503  	if i.OnProgramParsed == nil {
   504  		return
   505  	}
   506  	i.OnProgramParsed(location, duration)
   507  }
   508  
   509  func (i *TestRuntimeInterface) ProgramChecked(location runtime.Location, duration time.Duration) {
   510  	if i.OnProgramChecked == nil {
   511  		return
   512  	}
   513  	i.OnProgramChecked(location, duration)
   514  }
   515  
   516  func (i *TestRuntimeInterface) ProgramInterpreted(location runtime.Location, duration time.Duration) {
   517  	if i.OnProgramInterpreted == nil {
   518  		return
   519  	}
   520  	i.OnProgramInterpreted(location, duration)
   521  }
   522  
   523  func (i *TestRuntimeInterface) GetCurrentBlockHeight() (uint64, error) {
   524  	return 1, nil
   525  }
   526  
   527  func (i *TestRuntimeInterface) GetBlockAtHeight(height uint64) (block cadenceStdlib.Block, exists bool, err error) {
   528  
   529  	buf := new(bytes.Buffer)
   530  	err = binary.Write(buf, binary.BigEndian, height)
   531  	if err != nil {
   532  		panic(err)
   533  	}
   534  
   535  	encoded := buf.Bytes()
   536  	var hash cadenceStdlib.BlockHash
   537  	copy(hash[sema.BlockTypeIdFieldType.Size-int64(len(encoded)):], encoded)
   538  
   539  	block = cadenceStdlib.Block{
   540  		Height:    height,
   541  		View:      height,
   542  		Hash:      hash,
   543  		Timestamp: time.Unix(int64(height), 0).UnixNano(),
   544  	}
   545  	return block, true, nil
   546  }
   547  
   548  func (i *TestRuntimeInterface) ReadRandom(buffer []byte) error {
   549  	if i.OnReadRandom == nil {
   550  		return nil
   551  	}
   552  	return i.OnReadRandom(buffer)
   553  }
   554  
   555  func (i *TestRuntimeInterface) VerifySignature(
   556  	signature []byte,
   557  	tag string,
   558  	signedData []byte,
   559  	publicKey []byte,
   560  	signatureAlgorithm runtime.SignatureAlgorithm,
   561  	hashAlgorithm runtime.HashAlgorithm,
   562  ) (bool, error) {
   563  	if i.OnVerifySignature == nil {
   564  		return false, nil
   565  	}
   566  	return i.OnVerifySignature(
   567  		signature,
   568  		tag,
   569  		signedData,
   570  		publicKey,
   571  		signatureAlgorithm,
   572  		hashAlgorithm,
   573  	)
   574  }
   575  
   576  func (i *TestRuntimeInterface) Hash(data []byte, tag string, hashAlgorithm runtime.HashAlgorithm) ([]byte, error) {
   577  	if i.OnHash == nil {
   578  		return nil, nil
   579  	}
   580  	return i.OnHash(data, tag, hashAlgorithm)
   581  }
   582  
   583  func (i *TestRuntimeInterface) SetCadenceValue(owner common.Address, key string, value cadence.Value) (err error) {
   584  	if i.OnSetCadenceValue == nil {
   585  		panic("must specify TestRuntimeInterface.OnSetCadenceValue")
   586  	}
   587  	return i.OnSetCadenceValue(owner, key, value)
   588  }
   589  
   590  func (i *TestRuntimeInterface) GetAccountBalance(address runtime.Address) (uint64, error) {
   591  	if i.OnGetAccountBalance == nil {
   592  		panic("must specify TestRuntimeInterface.OnGetAccountBalance")
   593  	}
   594  	return i.OnGetAccountBalance(address)
   595  }
   596  
   597  func (i *TestRuntimeInterface) GetAccountAvailableBalance(address runtime.Address) (uint64, error) {
   598  	if i.OnGetAccountAvailableBalance == nil {
   599  		panic("must specify TestRuntimeInterface.OnGetAccountAvailableBalance")
   600  	}
   601  	return i.OnGetAccountAvailableBalance(address)
   602  }
   603  
   604  func (i *TestRuntimeInterface) GetStorageUsed(address runtime.Address) (uint64, error) {
   605  	if i.OnGetStorageUsed == nil {
   606  		panic("must specify TestRuntimeInterface.OnGetStorageUsed")
   607  	}
   608  	return i.OnGetStorageUsed(address)
   609  }
   610  
   611  func (i *TestRuntimeInterface) GetStorageCapacity(address runtime.Address) (uint64, error) {
   612  	if i.OnGetStorageCapacity == nil {
   613  		panic("must specify TestRuntimeInterface.OnGetStorageCapacity")
   614  	}
   615  	return i.OnGetStorageCapacity(address)
   616  }
   617  
   618  func (i *TestRuntimeInterface) ImplementationDebugLog(message string) error {
   619  	if i.OnImplementationDebugLog == nil {
   620  		return nil
   621  	}
   622  	return i.OnImplementationDebugLog(message)
   623  }
   624  
   625  func (i *TestRuntimeInterface) ValidatePublicKey(key *cadenceStdlib.PublicKey) error {
   626  	if i.OnValidatePublicKey == nil {
   627  		return errors.New("mock defaults to public key validation failure")
   628  	}
   629  
   630  	return i.OnValidatePublicKey(key)
   631  }
   632  
   633  func (i *TestRuntimeInterface) BLSVerifyPOP(key *cadenceStdlib.PublicKey, s []byte) (bool, error) {
   634  	if i.OnBLSVerifyPOP == nil {
   635  		return false, nil
   636  	}
   637  
   638  	return i.OnBLSVerifyPOP(key, s)
   639  }
   640  
   641  func (i *TestRuntimeInterface) BLSAggregateSignatures(sigs [][]byte) ([]byte, error) {
   642  	if i.OnBLSAggregateSignatures == nil {
   643  		return []byte{}, nil
   644  	}
   645  
   646  	return i.OnBLSAggregateSignatures(sigs)
   647  }
   648  
   649  func (i *TestRuntimeInterface) BLSAggregatePublicKeys(keys []*cadenceStdlib.PublicKey) (*cadenceStdlib.PublicKey, error) {
   650  	if i.OnBLSAggregatePublicKeys == nil {
   651  		return nil, nil
   652  	}
   653  
   654  	return i.OnBLSAggregatePublicKeys(keys)
   655  }
   656  
   657  func (i *TestRuntimeInterface) GetAccountContractNames(address runtime.Address) ([]string, error) {
   658  	if i.OnGetAccountContractNames == nil {
   659  		return []string{}, nil
   660  	}
   661  
   662  	return i.OnGetAccountContractNames(address)
   663  }
   664  
   665  func (i *TestRuntimeInterface) GenerateAccountID(address common.Address) (uint64, error) {
   666  	if i.OnGenerateAccountID == nil {
   667  		if i.accountIDs == nil {
   668  			i.accountIDs = map[common.Address]uint64{}
   669  		}
   670  		i.accountIDs[address]++
   671  		return i.accountIDs[address], nil
   672  	}
   673  
   674  	return i.OnGenerateAccountID(address)
   675  }
   676  
   677  func (i *TestRuntimeInterface) RecordTrace(
   678  	operation string,
   679  	location runtime.Location,
   680  	duration time.Duration,
   681  	attrs []attribute.KeyValue,
   682  ) {
   683  	if i.OnRecordTrace == nil {
   684  		return
   685  	}
   686  	i.OnRecordTrace(operation, location, duration, attrs)
   687  }
   688  
   689  func (i *TestRuntimeInterface) MeterMemory(usage common.MemoryUsage) error {
   690  	if i.OnMeterMemory == nil {
   691  		return nil
   692  	}
   693  
   694  	return i.OnMeterMemory(usage)
   695  }
   696  
   697  func (i *TestRuntimeInterface) ComputationUsed() (uint64, error) {
   698  	if i.OnComputationUsed == nil {
   699  		return 0, nil
   700  	}
   701  
   702  	return i.OnComputationUsed()
   703  }
   704  
   705  func (i *TestRuntimeInterface) MemoryUsed() (uint64, error) {
   706  	if i.OnMemoryUsed == nil {
   707  		return 0, nil
   708  	}
   709  
   710  	return i.OnMemoryUsed()
   711  }
   712  
   713  func (i *TestRuntimeInterface) InteractionUsed() (uint64, error) {
   714  	if i.OnInteractionUsed == nil {
   715  		return 0, nil
   716  	}
   717  
   718  	return i.OnInteractionUsed()
   719  }
   720  
   721  func CheckCadenceEventTypes(t testing.TB, events []cadence.Event, expectedTypes []string) {
   722  	require.Equal(t, len(events), len(expectedTypes))
   723  	for i, ev := range events {
   724  		require.Equal(t, expectedTypes[i], ev.EventType.QualifiedIdentifier)
   725  	}
   726  }