github.com/onflow/flow-go@v0.33.17/fvm/evm/testutils/emulator.go (about)

     1  package testutils
     2  
     3  import (
     4  	cryptoRand "crypto/rand"
     5  	"math/big"
     6  	"math/rand"
     7  	"testing"
     8  
     9  	gethCommon "github.com/ethereum/go-ethereum/common"
    10  	gethTypes "github.com/ethereum/go-ethereum/core/types"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"github.com/onflow/flow-go/fvm/evm/types"
    14  )
    15  
    16  type TestEmulator struct {
    17  	BalanceOfFunc      func(address types.Address) (*big.Int, error)
    18  	NonceOfFunc        func(address types.Address) (uint64, error)
    19  	CodeOfFunc         func(address types.Address) (types.Code, error)
    20  	DirectCallFunc     func(call *types.DirectCall) (*types.Result, error)
    21  	RunTransactionFunc func(tx *gethTypes.Transaction) (*types.Result, error)
    22  }
    23  
    24  var _ types.Emulator = &TestEmulator{}
    25  
    26  // NewBlock returns a new block
    27  func (em *TestEmulator) NewBlockView(_ types.BlockContext) (types.BlockView, error) {
    28  	return em, nil
    29  }
    30  
    31  // NewBlock returns a new block view
    32  func (em *TestEmulator) NewReadOnlyBlockView(_ types.BlockContext) (types.ReadOnlyBlockView, error) {
    33  	return em, nil
    34  }
    35  
    36  // BalanceOf returns the balance of this address
    37  func (em *TestEmulator) BalanceOf(address types.Address) (*big.Int, error) {
    38  	if em.BalanceOfFunc == nil {
    39  		panic("method not set")
    40  	}
    41  	return em.BalanceOfFunc(address)
    42  }
    43  
    44  // NonceOfFunc returns the nonce for this address
    45  func (em *TestEmulator) NonceOf(address types.Address) (uint64, error) {
    46  	if em.NonceOfFunc == nil {
    47  		panic("method not set")
    48  	}
    49  	return em.NonceOfFunc(address)
    50  }
    51  
    52  // CodeOf returns the code for this address (if smart contract is deployed at this address)
    53  func (em *TestEmulator) CodeOf(address types.Address) (types.Code, error) {
    54  	if em.CodeOfFunc == nil {
    55  		panic("method not set")
    56  	}
    57  	return em.CodeOfFunc(address)
    58  }
    59  
    60  // DirectCall executes a direct call
    61  func (em *TestEmulator) DirectCall(call *types.DirectCall) (*types.Result, error) {
    62  	if em.DirectCallFunc == nil {
    63  		panic("method not set")
    64  	}
    65  	return em.DirectCallFunc(call)
    66  }
    67  
    68  // RunTransaction runs a transaction and collect gas fees to the coinbase account
    69  func (em *TestEmulator) RunTransaction(tx *gethTypes.Transaction) (*types.Result, error) {
    70  	if em.RunTransactionFunc == nil {
    71  		panic("method not set")
    72  	}
    73  	return em.RunTransactionFunc(tx)
    74  }
    75  
    76  func RandomCommonHash(t testing.TB) gethCommon.Hash {
    77  	ret := gethCommon.Hash{}
    78  	_, err := cryptoRand.Read(ret[:gethCommon.HashLength])
    79  	require.NoError(t, err)
    80  	return ret
    81  }
    82  
    83  func RandomBigInt(limit int64) *big.Int {
    84  	return big.NewInt(rand.Int63n(limit) + 1)
    85  }
    86  
    87  func RandomAddress(t testing.TB) types.Address {
    88  	return types.NewAddress(RandomCommonAddress(t))
    89  }
    90  
    91  func RandomCommonAddress(t testing.TB) gethCommon.Address {
    92  	ret := gethCommon.Address{}
    93  	_, err := cryptoRand.Read(ret[:gethCommon.AddressLength])
    94  	require.NoError(t, err)
    95  	return ret
    96  }
    97  
    98  func RandomGas(limit int64) uint64 {
    99  	return uint64(rand.Int63n(limit) + 1)
   100  }
   101  
   102  func RandomData(t testing.TB) []byte {
   103  	// byte size [1, 100]
   104  	size := rand.Intn(100) + 1
   105  	ret := make([]byte, size)
   106  	_, err := cryptoRand.Read(ret[:])
   107  	require.NoError(t, err)
   108  	return ret
   109  }
   110  
   111  func GetRandomLogFixture(t testing.TB) *gethTypes.Log {
   112  	return &gethTypes.Log{
   113  		Address: RandomCommonAddress(t),
   114  		Topics: []gethCommon.Hash{
   115  			RandomCommonHash(t),
   116  			RandomCommonHash(t),
   117  		},
   118  		Data: RandomData(t),
   119  	}
   120  }