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

     1  package systemcontracts
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/onflow/flow-go/model/flow"
    11  )
    12  
    13  // TestSystemContract_Address tests that we can retrieve a canonical address
    14  // for all accepted chains and contracts.
    15  func TestSystemContracts(t *testing.T) {
    16  	chains := flow.AllChainIDs()
    17  
    18  	for _, chain := range chains {
    19  		require.NotPanics(t, func() { SystemContractsForChain(chain) })
    20  		checkSystemContracts(t, chain)
    21  	}
    22  }
    23  
    24  // TestSystemContract_InvalidChainID tests that we get an error if querying by an
    25  // invalid chain ID.
    26  func TestSystemContract_InvalidChainID(t *testing.T) {
    27  	invalidChain := flow.ChainID("invalid-chain")
    28  
    29  	require.Panics(t, func() { SystemContractsForChain(invalidChain) })
    30  }
    31  
    32  // TestServiceEvents tests that we can retrieve service events for all accepted
    33  // chains and contracts.
    34  func TestServiceEvents(t *testing.T) {
    35  	chains := flow.AllChainIDs()
    36  
    37  	for _, chain := range chains {
    38  		require.NotPanics(t, func() { ServiceEventsForChain(chain) })
    39  		checkServiceEvents(t, chain)
    40  	}
    41  }
    42  
    43  // TestServiceEventLookup_Consistency sanity checks consistency of the lookup
    44  // method, in case an update to ServiceEvents forgets to update the lookup.
    45  func TestServiceEventAll_Consistency(t *testing.T) {
    46  	chains := flow.AllChainIDs()
    47  
    48  	fields := reflect.TypeOf(ServiceEvents{}).NumField()
    49  	for _, chain := range chains {
    50  		events := ServiceEventsForChain(chain)
    51  
    52  		// ensure all events are present
    53  		all := events.All()
    54  		assert.Equal(t, fields, len(all))
    55  	}
    56  }
    57  
    58  // TestServiceEvents_InvalidChainID tests that we get an error if querying by an
    59  // invalid chain ID.
    60  func TestServiceEvents_InvalidChainID(t *testing.T) {
    61  	invalidChain := flow.ChainID("invalid-chain")
    62  
    63  	require.Panics(t, func() { ServiceEventsForChain(invalidChain) })
    64  }
    65  
    66  func checkSystemContracts(t *testing.T, chainID flow.ChainID) {
    67  	contracts := SystemContractsForChain(chainID)
    68  
    69  	address := func(name string) flow.Address {
    70  		f, ok := contractAddressFunc[name]
    71  		require.True(t, ok, "missing contract %s for chain %s", name, chainID.String())
    72  		return f(chainID)
    73  	}
    74  
    75  	// entries may not be empty
    76  	assert.NotEqual(t, flow.EmptyAddress, address(ContractNameEpoch))
    77  	assert.NotEqual(t, flow.EmptyAddress, address(ContractNameClusterQC))
    78  	assert.NotEqual(t, flow.EmptyAddress, address(ContractNameDKG))
    79  	assert.NotEqual(t, flow.EmptyAddress, address(ContractNameNodeVersionBeacon))
    80  
    81  	// entries must match internal mapping
    82  	assert.Equal(t, address(ContractNameEpoch), contracts.Epoch.Address)
    83  	assert.Equal(t, address(ContractNameClusterQC), contracts.ClusterQC.Address)
    84  	assert.Equal(t, address(ContractNameDKG), contracts.DKG.Address)
    85  	assert.Equal(t, address(ContractNameNodeVersionBeacon), contracts.NodeVersionBeacon.Address)
    86  }
    87  
    88  func checkServiceEvents(t *testing.T, chainID flow.ChainID) {
    89  	events := ServiceEventsForChain(chainID)
    90  
    91  	address := func(name string) flow.Address {
    92  		f, ok := contractAddressFunc[name]
    93  		require.True(t, ok, "missing contract %s for chain %s", name, chainID.String())
    94  		return f(chainID)
    95  	}
    96  
    97  	epochContractAddr := address(ContractNameEpoch)
    98  	versionContractAddr := address(ContractNameNodeVersionBeacon)
    99  	// entries may not be empty
   100  	assert.NotEqual(t, flow.EmptyAddress, epochContractAddr)
   101  	assert.NotEqual(t, flow.EmptyAddress, versionContractAddr)
   102  
   103  	// entries must match internal mapping
   104  	assert.Equal(t, epochContractAddr, events.EpochSetup.Address)
   105  	assert.Equal(t, epochContractAddr, events.EpochCommit.Address)
   106  	assert.Equal(t, versionContractAddr, events.VersionBeacon.Address)
   107  	assert.Equal(t, versionContractAddr, events.ProtocolStateVersionUpgrade.Address)
   108  }