From 7fa327e5ab6dad9c2567e44e144502a6983c7241 Mon Sep 17 00:00:00 2001 From: Bolek <1416262+bolekk@users.noreply.github.com> Date: Mon, 11 Sep 2023 22:20:53 -0700 Subject: [PATCH] Add extra sanity checks to config poller and contract transmitter (#10593) --- core/services/relay/evm/config_poller.go | 3 +++ core/services/relay/evm/config_poller_test.go | 10 ++++++---- core/services/relay/evm/contract_transmitter.go | 6 ++++++ core/services/relay/evm/functions/config_poller.go | 3 +++ .../services/relay/evm/functions/config_poller_test.go | 2 ++ .../relay/evm/functions/contract_transmitter.go | 6 ++++++ .../relay/evm/functions/contract_transmitter_test.go | 8 ++++++++ 7 files changed, 34 insertions(+), 4 deletions(-) diff --git a/core/services/relay/evm/config_poller.go b/core/services/relay/evm/config_poller.go index aada1242303..6d8d4588d07 100644 --- a/core/services/relay/evm/config_poller.go +++ b/core/services/relay/evm/config_poller.go @@ -138,6 +138,9 @@ func (cp *configPoller) LatestConfig(ctx context.Context, changedInBlock uint64) if err != nil { return ocrtypes.ContractConfig{}, err } + if len(lgs) == 0 { + return ocrtypes.ContractConfig{}, errors.New("no logs found") + } latestConfigSet, err := configFromLog(lgs[len(lgs)-1].Data) if err != nil { return ocrtypes.ContractConfig{}, err diff --git a/core/services/relay/evm/config_poller_test.go b/core/services/relay/evm/config_poller_test.go index 724c303210b..75e033dfeb7 100644 --- a/core/services/relay/evm/config_poller_test.go +++ b/core/services/relay/evm/config_poller_test.go @@ -64,12 +64,14 @@ func TestConfigPoller(t *testing.T) { lp := logpoller.NewLogPoller(lorm, ethClient, lggr, 100*time.Millisecond, 1, 2, 2, 1000) require.NoError(t, lp.Start(ctx)) t.Cleanup(func() { lp.Close() }) - logPoller, err := NewConfigPoller(lggr, lp, ocrAddress) + configPoller, err := NewConfigPoller(lggr, lp, ocrAddress) require.NoError(t, err) // Should have no config to begin with. - _, config, err := logPoller.LatestConfigDetails(testutils.Context(t)) + _, config, err := configPoller.LatestConfigDetails(testutils.Context(t)) require.NoError(t, err) require.Equal(t, ocrtypes2.ConfigDigest{}, config) + _, err = configPoller.LatestConfig(testutils.Context(t), 0) + require.Error(t, err) // Set the config contractConfig := setConfig(t, median.OffchainConfig{ AlphaReportInfinite: false, @@ -89,13 +91,13 @@ func TestConfigPoller(t *testing.T) { var digest [32]byte gomega.NewGomegaWithT(t).Eventually(func() bool { b.Commit() - configBlock, digest, err = logPoller.LatestConfigDetails(testutils.Context(t)) + configBlock, digest, err = configPoller.LatestConfigDetails(testutils.Context(t)) require.NoError(t, err) return ocrtypes2.ConfigDigest{} != digest }, testutils.WaitTimeout(t), 100*time.Millisecond).Should(gomega.BeTrue()) // Assert the config returned is the one we configured. - newConfig, err := logPoller.LatestConfig(testutils.Context(t), configBlock) + newConfig, err := configPoller.LatestConfig(testutils.Context(t), configBlock) require.NoError(t, err) // Note we don't check onchainConfig, as that is populated in the contract itself. assert.Equal(t, digest, [32]byte(newConfig.ConfigDigest)) diff --git a/core/services/relay/evm/contract_transmitter.go b/core/services/relay/evm/contract_transmitter.go index d4a2c6204ca..470b5bae076 100644 --- a/core/services/relay/evm/contract_transmitter.go +++ b/core/services/relay/evm/contract_transmitter.go @@ -93,6 +93,9 @@ func (oc *contractTransmitter) Transmit(ctx context.Context, reportCtx ocrtypes. var rs [][32]byte var ss [][32]byte var vs [32]byte + if len(signatures) > 32 { + return errors.New("too many signatures, maximum is 32") + } for i, as := range signatures { r, s, v, err := evmutil.SplitSignature(as.Signature) if err != nil { @@ -138,6 +141,9 @@ func parseTransmitted(log []byte) ([32]byte, uint32, error) { if err != nil { return [32]byte{}, 0, err } + if len(transmitted) < 2 { + return [32]byte{}, 0, errors.New("transmitted event log has too few arguments") + } configDigest := *abi.ConvertType(transmitted[0], new([32]byte)).(*[32]byte) epoch := *abi.ConvertType(transmitted[1], new(uint32)).(*uint32) return configDigest, epoch, err diff --git a/core/services/relay/evm/functions/config_poller.go b/core/services/relay/evm/functions/config_poller.go index 4feff842ce3..f068f13cc77 100644 --- a/core/services/relay/evm/functions/config_poller.go +++ b/core/services/relay/evm/functions/config_poller.go @@ -162,6 +162,9 @@ func (cp *configPoller) LatestConfig(ctx context.Context, changedInBlock uint64) if err != nil { return ocrtypes.ContractConfig{}, err } + if len(lgs) == 0 { + return ocrtypes.ContractConfig{}, errors.New("no logs found") + } latestConfigSet, err := configFromLog(lgs[len(lgs)-1].Data, cp.pluginType) if err != nil { return ocrtypes.ContractConfig{}, err diff --git a/core/services/relay/evm/functions/config_poller_test.go b/core/services/relay/evm/functions/config_poller_test.go index b6de78b49df..b53b2751b15 100644 --- a/core/services/relay/evm/functions/config_poller_test.go +++ b/core/services/relay/evm/functions/config_poller_test.go @@ -89,6 +89,8 @@ func runTest(t *testing.T, pluginType functions.FunctionsPluginType, expectedDig _, config, err := configPoller.LatestConfigDetails(testutils.Context(t)) require.NoError(t, err) require.Equal(t, ocrtypes2.ConfigDigest{}, config) + _, err = configPoller.LatestConfig(testutils.Context(t), 0) + require.Error(t, err) pluginConfig := &functionsConfig.ReportingPluginConfigWrapper{ Config: &functionsConfig.ReportingPluginConfig{ diff --git a/core/services/relay/evm/functions/contract_transmitter.go b/core/services/relay/evm/functions/contract_transmitter.go index ecbe3c49f96..3c6399fbd83 100644 --- a/core/services/relay/evm/functions/contract_transmitter.go +++ b/core/services/relay/evm/functions/contract_transmitter.go @@ -99,6 +99,9 @@ func (oc *contractTransmitter) Transmit(ctx context.Context, reportCtx ocrtypes. var rs [][32]byte var ss [][32]byte var vs [32]byte + if len(signatures) > 32 { + return errors.New("too many signatures, maximum is 32") + } for i, as := range signatures { r, s, v, err := evmutil.SplitSignature(as.Signature) if err != nil { @@ -169,6 +172,9 @@ func parseTransmitted(log []byte) ([32]byte, uint32, error) { if err != nil { return [32]byte{}, 0, err } + if len(transmitted) < 2 { + return [32]byte{}, 0, errors.New("transmitted event log has too few arguments") + } configDigest := *abi.ConvertType(transmitted[0], new([32]byte)).(*[32]byte) epoch := *abi.ConvertType(transmitted[1], new(uint32)).(*uint32) return configDigest, epoch, err diff --git a/core/services/relay/evm/functions/contract_transmitter_test.go b/core/services/relay/evm/functions/contract_transmitter_test.go index fb4a071de2a..6ce61c83a09 100644 --- a/core/services/relay/evm/functions/contract_transmitter_test.go +++ b/core/services/relay/evm/functions/contract_transmitter_test.go @@ -116,6 +116,14 @@ func TestContractTransmitter_Transmit_V1(t *testing.T) { reportBytes, err := codec.EncodeReport(processedRequests) require.NoError(t, err) + // success require.NoError(t, ot.Transmit(testutils.Context(t), ocrtypes.ReportContext{}, reportBytes, []ocrtypes.AttributedOnchainSignature{})) require.Equal(t, coordinatorAddress, ocrTransmitter.toAddress) + + // failure on too many signatures + signatures := []ocrtypes.AttributedOnchainSignature{} + for i := 0; i < 33; i++ { + signatures = append(signatures, ocrtypes.AttributedOnchainSignature{}) + } + require.Error(t, ot.Transmit(testutils.Context(t), ocrtypes.ReportContext{}, reportBytes, signatures)) }