From 57275e661a763dc7eff126a30a9f476a8e3f0126 Mon Sep 17 00:00:00 2001 From: Geert G <117188496+cll-gg@users.noreply.github.com> Date: Tue, 3 Mar 2026 12:33:34 +0000 Subject: [PATCH] OEV-851 Send dualBroadcast params in TxMessage --- pkg/txm/metrics.go | 20 ++++++---- pkg/txm/metrics_test.go | 83 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 7 deletions(-) diff --git a/pkg/txm/metrics.go b/pkg/txm/metrics.go index d47de2cd5e..da78100d6b 100644 --- a/pkg/txm/metrics.go +++ b/pkg/txm/metrics.go @@ -134,14 +134,20 @@ func (m *txmMetrics) EmitTxMessage(ctx context.Context, txHash common.Hash, from toAddress = tx.ToAddress } + var dualBroadcastParams *string + if meta != nil && meta.DualBroadcast != nil && *meta.DualBroadcast { + dualBroadcastParams = meta.DualBroadcastParams + } + message := &svrv1.TxMessage{ - Hash: txHash.String(), - FromAddress: fromAddress.String(), - ToAddress: toAddress.String(), - Nonce: strconv.FormatUint(*tx.Nonce, 10), - CreatedAt: time.Now().UnixMicro(), - ChainId: m.chainID.String(), - FeedAddress: destAddress, + Hash: txHash.String(), + FromAddress: fromAddress.String(), + ToAddress: toAddress.String(), + Nonce: strconv.FormatUint(*tx.Nonce, 10), + CreatedAt: time.Now().UnixMicro(), + ChainId: m.chainID.String(), + FeedAddress: destAddress, + DualBroadcastParams: dualBroadcastParams, } messageBytes, err := proto.Marshal(message) diff --git a/pkg/txm/metrics_test.go b/pkg/txm/metrics_test.go index 15faa1d895..a1207940dc 100644 --- a/pkg/txm/metrics_test.go +++ b/pkg/txm/metrics_test.go @@ -1,6 +1,7 @@ package txm import ( + "encoding/json" "strconv" "testing" @@ -10,6 +11,7 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-common/pkg/beholder/beholdertest" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-evm/pkg/testutils" "github.com/smartcontractkit/chainlink-evm/pkg/txm/types" svrv1 "github.com/smartcontractkit/chainlink-protos/svr/v1" @@ -115,6 +117,87 @@ func TestEmitTxMessage(t *testing.T) { assert.Equal(t, expectedChain.String(), actualMessage.ChainId) assert.Equal(t, "", actualMessage.FeedAddress) }) + + t.Run("populates dual_broadcast_params when tx is a dual-broadcast secondary tx", func(t *testing.T) { + // GIVEN + ctx := t.Context() + beholderTester := beholdertest.NewObserver(t) + + toAddress := testutils.NewAddress() + fromAddress := testutils.NewAddress() + expectedNonce := uint64(7) + expectedChain := testutils.FixtureChainID + expectedParams := "hint=calldata&hint=logs&builder=flashbots" + isDualBroadcast := true + + metaBytes, err := json.Marshal(types.TxMeta{ + DualBroadcast: &isDualBroadcast, + DualBroadcastParams: &expectedParams, + }) + require.NoError(t, err) + meta := sqlutil.JSON(metaBytes) + + txmMetrics, err := NewTxmMetrics(expectedChain) + require.NoError(t, err) + + tx := &types.Transaction{ + IsPurgeable: false, + FromAddress: fromAddress, + ToAddress: toAddress, + Nonce: &expectedNonce, + Meta: &meta, + } + + // WHEN + err = txmMetrics.EmitTxMessage(ctx, common.Hash{}, fromAddress, tx) + require.NoError(t, err) + + // THEN + messages := beholderTester.Messages(t) + assert.Len(t, messages, 1) + + var actualMessage svrv1.TxMessage + err = proto.Unmarshal(messages[0].Body, &actualMessage) + require.NoError(t, err) + + require.NotNil(t, actualMessage.DualBroadcastParams) + assert.Equal(t, expectedParams, *actualMessage.DualBroadcastParams) + }) + + t.Run("does not set dual_broadcast_params for a primary (non-dual-broadcast) tx", func(t *testing.T) { + // GIVEN + ctx := t.Context() + beholderTester := beholdertest.NewObserver(t) + + toAddress := testutils.NewAddress() + fromAddress := testutils.NewAddress() + expectedNonce := uint64(3) + expectedChain := testutils.FixtureChainID + + txmMetrics, err := NewTxmMetrics(expectedChain) + require.NoError(t, err) + + tx := &types.Transaction{ + IsPurgeable: false, + FromAddress: fromAddress, + ToAddress: toAddress, + Nonce: &expectedNonce, + } + + // WHEN + err = txmMetrics.EmitTxMessage(ctx, common.Hash{}, fromAddress, tx) + require.NoError(t, err) + + // THEN + messages := beholderTester.Messages(t) + assert.Len(t, messages, 1) + + var actualMessage svrv1.TxMessage + err = proto.Unmarshal(messages[0].Body, &actualMessage) + require.NoError(t, err) + + assert.Nil(t, actualMessage.DualBroadcastParams) + }) } func TestReachedMaxAttempts(t *testing.T) {