diff --git a/core/capabilities/targets/write_target.go b/core/capabilities/targets/write_target.go index a7452be7fc8..677b1148ebb 100644 --- a/core/capabilities/targets/write_target.go +++ b/core/capabilities/targets/write_target.go @@ -176,6 +176,24 @@ func (cap *EvmWrite) Execute(ctx context.Context, callback chan<- capabilities.C return err } inputs := inputsAny.(map[string]any) + rep, ok := inputs["report"] + if !ok { + return errors.New("malformed data: inputs doesn't contain a report key") + } + + if rep == nil { + // We received any empty report -- this means we should skip transmission. + cap.lggr.Debugw("Skipping empty report", "request", request) + go func() { + // TODO: cast tx.Error to Err (or Value to Value?) + callback <- capabilities.CapabilityResponse{ + Value: nil, + Err: nil, + } + close(callback) + }() + return nil + } // evaluate any variables in reqConfig.Params args, err := evaluateParams(reqConfig.Params, inputs) @@ -222,7 +240,7 @@ func (cap *EvmWrite) Execute(ctx context.Context, callback chan<- capabilities.C if err != nil { return err } - fmt.Printf("Transaction submitted %v", tx.ID) + cap.lggr.Debugw("Transaction submitted", "request", request, "transaction", tx) go func() { // TODO: cast tx.Error to Err (or Value to Value?) callback <- capabilities.CapabilityResponse{ diff --git a/core/capabilities/targets/write_target_test.go b/core/capabilities/targets/write_target_test.go index c71c84e172e..fd68234ca70 100644 --- a/core/capabilities/targets/write_target_test.go +++ b/core/capabilities/targets/write_target_test.go @@ -90,3 +90,55 @@ func TestEvmWrite(t *testing.T) { response := <-ch require.Nil(t, response.Err) } + +func TestEvmWrite_EmptyReport(t *testing.T) { + chain := evmmocks.NewChain(t) + + txManager := txmmocks.NewMockEvmTxManager(t) + chain.On("ID").Return(big.NewInt(11155111)) + chain.On("TxManager").Return(txManager) + + cfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + a := testutils.NewAddress() + addr, err := types.NewEIP55Address(a.Hex()) + require.NoError(t, err) + c.EVM[0].ChainWriter.FromAddress = &addr + + forwarderA := testutils.NewAddress() + forwarderAddr, err := types.NewEIP55Address(forwarderA.Hex()) + require.NoError(t, err) + c.EVM[0].ChainWriter.ForwarderAddress = &forwarderAddr + }) + evmcfg := evmtest.NewChainScopedConfig(t, cfg) + chain.On("Config").Return(evmcfg) + + capability := targets.NewEvmWrite(chain, logger.TestLogger(t)) + ctx := testutils.Context(t) + + config, err := values.NewMap(map[string]any{ + "abi": "receive(report bytes)", + "params": []any{"$(report)"}, + }) + require.NoError(t, err) + + inputs, err := values.NewMap(map[string]any{ + "report": nil, + }) + require.NoError(t, err) + + req := capabilities.CapabilityRequest{ + Metadata: capabilities.RequestMetadata{ + WorkflowID: "hello", + }, + Config: config, + Inputs: inputs, + } + + ch := make(chan capabilities.CapabilityResponse) + + err = capability.Execute(ctx, ch, req) + require.NoError(t, err) + + response := <-ch + require.Nil(t, response.Err) +} diff --git a/core/services/workflows/delegate.go b/core/services/workflows/delegate.go index b81ec5407e2..fb9540844fa 100644 --- a/core/services/workflows/delegate.go +++ b/core/services/workflows/delegate.go @@ -49,19 +49,17 @@ consensus: targets: - type: "write_polygon-testnet-mumbai" inputs: - report: - - "$(evm_median.outputs.reports)" + report: "$(evm_median.outputs.report)" config: address: "0x3F3554832c636721F1fD1822Ccca0354576741Ef" - params: ["$(inputs.report)"] + params: ["$(report)"] abi: "receive(report bytes)" - type: "write_ethereum-testnet-sepolia" inputs: - report: - - "$(evm_median.outputs.reports)" + report: "$(evm_median.outputs.report)" config: address: "0x54e220867af6683aE6DcBF535B4f952cB5116510" - params: ["$(inputs.report)"] + params: ["$(report)"] abi: "receive(report bytes)" ` diff --git a/core/services/workflows/engine_test.go b/core/services/workflows/engine_test.go index a87e841121d..e456eefb729 100644 --- a/core/services/workflows/engine_test.go +++ b/core/services/workflows/engine_test.go @@ -86,9 +86,9 @@ func TestEngineWithHardcodedWorkflow(t *testing.T) { "v1.0.0", ), func(req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { - list := req.Inputs.Underlying["report"].(*values.List) + m := req.Inputs.Underlying["report"].(*values.Map) return capabilities.CapabilityResponse{ - Value: list.Underlying[0], + Value: m, }, nil }, ) @@ -152,11 +152,10 @@ consensus: targets: - type: "write_polygon-testnet-mumbai" inputs: - report: - - "$(evm_median.outputs.reports)" + report: "$(evm_median.outputs.report)" config: address: "0x3F3554832c636721F1fD1822Ccca0354576741Ef" - params: ["$(inputs.report)"] + params: ["$(report)"] abi: "receive(report bytes)" ` ) @@ -207,9 +206,9 @@ func mockConsensus() *mockCapability { ), func(req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { obs := req.Inputs.Underlying["observations"] - reports := obs.(*values.List) + report := obs.(*values.List) rm := map[string]any{ - "reports": reports.Underlying[0], + "report": report.Underlying[0], } rv, err := values.NewMap(rm) if err != nil { @@ -232,9 +231,9 @@ func mockTarget() *mockCapability { "v1.0.0", ), func(req capabilities.CapabilityRequest) (capabilities.CapabilityResponse, error) { - list := req.Inputs.Underlying["report"].(*values.List) + m := req.Inputs.Underlying["report"].(*values.Map) return capabilities.CapabilityResponse{ - Value: list.Underlying[0], + Value: m, }, nil }, ) @@ -314,11 +313,10 @@ consensus: targets: - type: "write_polygon-testnet-mumbai" inputs: - report: - - "$(evm_median.outputs.reports)" + report: "$(evm_median.outputs.report)" config: address: "0x3F3554832c636721F1fD1822Ccca0354576741Ef" - params: ["$(inputs.report)"] + params: ["$(report)"] abi: "receive(report bytes)" ` )