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 }