From 53bd56b5ebe10e914dab66c31986806dd0323aff Mon Sep 17 00:00:00 2001 From: connorwstein Date: Mon, 25 Sep 2023 19:14:50 -0400 Subject: [PATCH] Fix more tests --- .../plugins/ccip/abihelpers/abi_helpers.go | 112 ------------------ .../ccip/internal/ccipdata/onramp_v1_0_0.go | 2 +- .../internal/ccipdata/onramp_v1_0_0_test.go | 6 +- .../ccip/internal/ccipdata/onramp_v1_2_0.go | 70 ++++++++++- .../internal/ccipdata/onramp_v1_2_0_test.go | 69 +++++++++++ .../ccip/internal/ccipdata/usdc_reader.go | 4 +- .../internal/ccipdata/usdc_reader_test.go | 10 +- .../ccip/testhelpers/ccip_contracts.go | 2 +- .../ccip/tokendata/usdc/usdc_blackbox_test.go | 86 ++------------ .../plugins/ccip/tokendata/usdc/usdc_test.go | 21 ++-- 10 files changed, 173 insertions(+), 209 deletions(-) diff --git a/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go b/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go index 095e1c0808..5eedc30242 100644 --- a/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go +++ b/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go @@ -14,7 +14,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -65,26 +64,7 @@ func GetIDOrPanic(name string, abi2 abi.ABI) common.Hash { return event.ID } -func getTupleNamedElem(name string, arg abi.Argument) *abi.Type { - if arg.Type.T != abi.TupleTy { - return nil - } - for i, elem := range arg.Type.TupleElems { - if arg.Type.TupleRawNames[i] == name { - return elem - } - } - return nil -} - func init() { - //onRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_onramp.EVM2EVMOnRampABI)) - //if err != nil { - // panic(err) - //} - //EventSignatures.SendRequested = GetIDOrPanic("CCIPSendRequested", onRampABI) - //EventSignatures.SendRequestedSequenceNumberWord = 4 - commitStoreABI, err := abi.JSON(strings.NewReader(commit_store.CommitStoreABI)) if err != nil { panic(err) @@ -110,14 +90,6 @@ func init() { EventSignatures.FeeTokenAdded = GetIDOrPanic("FeeTokenAdded", priceRegistryABI) EventSignatures.FeeTokenRemoved = GetIDOrPanic("FeeTokenRemoved", priceRegistryABI) - // arguments - //MessageArgs = onRampABI.Events["CCIPSendRequested"].Inputs - //tokenAmountsTy := getTupleNamedElem("tokenAmounts", MessageArgs[0]) - //if tokenAmountsTy == nil { - // panic(fmt.Sprintf("missing component '%s' in tuple %+v", "tokenAmounts", MessageArgs)) - //} - //TokenAmountsArgs = abi.Arguments{{Type: *tokenAmountsTy, Name: "tokenAmounts"}} - CommitReportArgs = commitStoreABI.Events["ReportAccepted"].Inputs manuallyExecuteMethod, ok := offRampABI.Methods["manuallyExecute"] @@ -125,8 +97,6 @@ func init() { panic("missing event 'manuallyExecute'") } ExecutionReportArgs = manuallyExecuteMethod.Inputs[:1] - - //EventSignatures.USDCMessageSent = utils.Keccak256Fixed([]byte("MessageSent(bytes)")) } func MessagesFromExecutionReport(report types.Report) ([]evm_2_evm_offramp.InternalEVM2EVMMessage, error) { @@ -137,88 +107,6 @@ func MessagesFromExecutionReport(report types.Report) ([]evm_2_evm_offramp.Inter return decodedExecutionReport.Messages, nil } -func DecodeOffRampMessage(b []byte) (*evm_2_evm_offramp.InternalEVM2EVMMessage, error) { - unpacked, err := MessageArgs.Unpack(b) - if err != nil { - return nil, err - } - if len(unpacked) == 0 { - return nil, fmt.Errorf("no message found when unpacking") - } - - // Note must use unnamed type here - receivedCp, ok := unpacked[0].(struct { - SourceChainSelector uint64 `json:"sourceChainSelector"` - Sender common.Address `json:"sender"` - Receiver common.Address `json:"receiver"` - SequenceNumber uint64 `json:"sequenceNumber"` - GasLimit *big.Int `json:"gasLimit"` - Strict bool `json:"strict"` - Nonce uint64 `json:"nonce"` - FeeToken common.Address `json:"feeToken"` - FeeTokenAmount *big.Int `json:"feeTokenAmount"` - Data []uint8 `json:"data"` - TokenAmounts []struct { - Token common.Address `json:"token"` - Amount *big.Int `json:"amount"` - } `json:"tokenAmounts"` - SourceTokenData [][]byte `json:"sourceTokenData"` - MessageId [32]byte `json:"messageId"` - }) - if !ok { - return nil, fmt.Errorf("invalid format have %T want %T", unpacked[0], receivedCp) - } - var tokensAndAmounts []evm_2_evm_offramp.ClientEVMTokenAmount - for _, tokenAndAmount := range receivedCp.TokenAmounts { - tokensAndAmounts = append(tokensAndAmounts, evm_2_evm_offramp.ClientEVMTokenAmount{ - Token: tokenAndAmount.Token, - Amount: tokenAndAmount.Amount, - }) - } - - return &evm_2_evm_offramp.InternalEVM2EVMMessage{ - SourceChainSelector: receivedCp.SourceChainSelector, - Sender: receivedCp.Sender, - Receiver: receivedCp.Receiver, - SequenceNumber: receivedCp.SequenceNumber, - GasLimit: receivedCp.GasLimit, - Strict: receivedCp.Strict, - Nonce: receivedCp.Nonce, - FeeToken: receivedCp.FeeToken, - FeeTokenAmount: receivedCp.FeeTokenAmount, - Data: receivedCp.Data, - TokenAmounts: tokensAndAmounts, - SourceTokenData: receivedCp.SourceTokenData, - MessageId: receivedCp.MessageId, - }, nil -} - -func OnRampMessageToOffRampMessage(msg evm_2_evm_onramp.InternalEVM2EVMMessage) evm_2_evm_offramp.InternalEVM2EVMMessage { - tokensAndAmounts := make([]evm_2_evm_offramp.ClientEVMTokenAmount, len(msg.TokenAmounts)) - for i, tokenAndAmount := range msg.TokenAmounts { - tokensAndAmounts[i] = evm_2_evm_offramp.ClientEVMTokenAmount{ - Token: tokenAndAmount.Token, - Amount: tokenAndAmount.Amount, - } - } - - return evm_2_evm_offramp.InternalEVM2EVMMessage{ - SourceChainSelector: msg.SourceChainSelector, - Sender: msg.Sender, - Receiver: msg.Receiver, - SequenceNumber: msg.SequenceNumber, - GasLimit: msg.GasLimit, - Strict: msg.Strict, - Nonce: msg.Nonce, - FeeToken: msg.FeeToken, - FeeTokenAmount: msg.FeeTokenAmount, - Data: msg.Data, - TokenAmounts: tokensAndAmounts, - SourceTokenData: msg.SourceTokenData, - MessageId: msg.MessageId, - } -} - // ProofFlagsToBits transforms a list of boolean proof flags to a *big.Int // encoded number. func ProofFlagsToBits(proofFlags []bool) *big.Int { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0.go index e71c194168..425ac63eba 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0.go @@ -51,7 +51,7 @@ func (t *LeafHasherV1_0_0) HashLeaf(log types.Log) ([32]byte, error) { } encodedTokens, err := utils.ABIEncode( `[ -{"components": [{"name":"token","type":"address"},{"name":"amount","type":"uint256"}], "type":"tuple"}]`, message.Message.TokenAmounts) +{"components": [{"name":"token","type":"address"},{"name":"amount","type":"uint256"}], "type":"tuple[]"}]`, message.Message.TokenAmounts) if err != nil { return [32]byte{}, err } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0_test.go index 720576bf9e..310ad641e8 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0_test.go @@ -16,7 +16,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/hashlib" ) -func TestHasher(t *testing.T) { +func TestHasherV1_0_0(t *testing.T) { sourceChainSelector, destChainSelector := uint64(1), uint64(4) onRampAddress := common.HexToAddress("0x5550000000000000000000000000000000000001") onRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_onramp_1_0_0.EVM2EVMOnRampABI)) @@ -48,7 +48,7 @@ func TestHasher(t *testing.T) { require.NoError(t, err) // NOTE: Must match spec - require.Equal(t, "46ad031bfb052db2e4a2514fed8dc480b98e5ce4acb55d5640d91407e0d8a3e9", hex.EncodeToString(hash[:])) + require.Equal(t, "26f282c6ac8231933b1799648d01ff6cec792a33fb37408b4d135968f9168ace", hex.EncodeToString(hash[:])) message = evm_2_evm_onramp_1_0_0.InternalEVM2EVMMessage{ SourceChainSelector: sourceChainSelector, @@ -74,7 +74,7 @@ func TestHasher(t *testing.T) { require.NoError(t, err) // NOTE: Must match spec - require.Equal(t, "4362a13a42e52ff5ce4324e7184dc7aa41704c3146bc842d35d95b94b32a78b6", hex.EncodeToString(hash[:])) + require.Equal(t, "05cee92e7cb86a37b6536554828a5b21ff20ac3d4ef821ec47056f1d963313de", hex.EncodeToString(hash[:])) } func TestMetaDataHash(t *testing.T) { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0.go index 940aec8aa9..e978a54caf 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0.go @@ -3,6 +3,7 @@ package ccipdata import ( "context" "fmt" + "math/big" "strings" "github.com/ethereum/go-ethereum/accounts/abi" @@ -37,6 +38,71 @@ func init() { CCIPSendRequestEventSigV1_2_0 = abihelpers.GetIDOrPanic("CCIPSendRequested", onRampABI) } +// Backwards compat for integration tests +func DecodeOffRampMessageV1_2_0(b []byte) (*evm_2_evm_offramp.InternalEVM2EVMMessage, error) { + offRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_offramp.EVM2EVMOffRampABI)) + if err != nil { + panic(err) + } + event, ok := offRampABI.Events["EVM2EVMMessage"] + if !ok { + panic("no such event") + } + unpacked, err := event.Inputs.Unpack(b) + if err != nil { + return nil, err + } + if len(unpacked) == 0 { + return nil, fmt.Errorf("no message found when unpacking") + } + + // Note must use unnamed type here + receivedCp, ok := unpacked[0].(struct { + SourceChainSelector uint64 `json:"sourceChainSelector"` + Sender common.Address `json:"sender"` + Receiver common.Address `json:"receiver"` + SequenceNumber uint64 `json:"sequenceNumber"` + GasLimit *big.Int `json:"gasLimit"` + Strict bool `json:"strict"` + Nonce uint64 `json:"nonce"` + FeeToken common.Address `json:"feeToken"` + FeeTokenAmount *big.Int `json:"feeTokenAmount"` + Data []uint8 `json:"data"` + TokenAmounts []struct { + Token common.Address `json:"token"` + Amount *big.Int `json:"amount"` + } `json:"tokenAmounts"` + SourceTokenData [][]byte `json:"sourceTokenData"` + MessageId [32]byte `json:"messageId"` + }) + if !ok { + return nil, fmt.Errorf("invalid format have %T want %T", unpacked[0], receivedCp) + } + var tokensAndAmounts []evm_2_evm_offramp.ClientEVMTokenAmount + for _, tokenAndAmount := range receivedCp.TokenAmounts { + tokensAndAmounts = append(tokensAndAmounts, evm_2_evm_offramp.ClientEVMTokenAmount{ + Token: tokenAndAmount.Token, + Amount: tokenAndAmount.Amount, + }) + } + + return &evm_2_evm_offramp.InternalEVM2EVMMessage{ + SourceChainSelector: receivedCp.SourceChainSelector, + Sender: receivedCp.Sender, + Receiver: receivedCp.Receiver, + SequenceNumber: receivedCp.SequenceNumber, + GasLimit: receivedCp.GasLimit, + Strict: receivedCp.Strict, + Nonce: receivedCp.Nonce, + FeeToken: receivedCp.FeeToken, + FeeTokenAmount: receivedCp.FeeTokenAmount, + Data: receivedCp.Data, + TokenAmounts: tokensAndAmounts, + SourceTokenData: receivedCp.SourceTokenData, + MessageId: receivedCp.MessageId, + }, nil +} + type LeafHasherV1_2_0 struct { metaDataHash [32]byte ctx hashlib.Ctx[[32]byte] @@ -57,7 +123,9 @@ func (t *LeafHasherV1_2_0) HashLeaf(log types.Log) ([32]byte, error) { return [32]byte{}, err } message := msg.Message - encodedTokens, err := abihelpers.TokenAmountsArgs.PackValues([]interface{}{message.TokenAmounts}) + encodedTokens, err := utils.ABIEncode( + `[ +{"components": [{"name":"token","type":"address"},{"name":"amount","type":"uint256"}], "type":"tuple[]"}]`, message.TokenAmounts) if err != nil { return [32]byte{}, err } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0_test.go index 11080ea69d..b50cb08fc2 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0_test.go @@ -2,9 +2,13 @@ package ccipdata import ( "context" + "encoding/hex" "math/big" + "strings" "testing" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -13,11 +17,76 @@ import ( evmClientMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/hashlib" "github.com/smartcontractkit/chainlink/v2/core/utils" ) +func TestHasherV1_2_0(t *testing.T) { + sourceChainSelector, destChainSelector := uint64(1), uint64(4) + onRampAddress := common.HexToAddress("0x5550000000000000000000000000000000000001") + onRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_onramp.EVM2EVMOnRampABI)) + require.NoError(t, err) + + hashingCtx := hashlib.NewKeccakCtx() + ramp, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampAddress, nil) + require.NoError(t, err) + hasher := NewLeafHasherV1_2_0(sourceChainSelector, destChainSelector, onRampAddress, hashingCtx, ramp) + + message := evm_2_evm_onramp.InternalEVM2EVMMessage{ + SourceChainSelector: sourceChainSelector, + Sender: common.HexToAddress("0x1110000000000000000000000000000000000001"), + Receiver: common.HexToAddress("0x2220000000000000000000000000000000000001"), + SequenceNumber: 1337, + GasLimit: big.NewInt(100), + Strict: false, + Nonce: 1337, + FeeToken: common.Address{}, + FeeTokenAmount: big.NewInt(1), + Data: []byte{}, + TokenAmounts: []evm_2_evm_onramp.ClientEVMTokenAmount{{Token: common.HexToAddress("0x4440000000000000000000000000000000000001"), Amount: big.NewInt(12345678900)}}, + SourceTokenData: [][]byte{}, + MessageId: [32]byte{}, + } + + data, err := onRampABI.Events["CCIPSendRequested"].Inputs.Pack(message) + require.NoError(t, err) + hash, err := hasher.HashLeaf(types.Log{Topics: []common.Hash{CCIPSendRequestEventSigV1_2_0}, Data: data}) + require.NoError(t, err) + + // NOTE: Must match spec + require.Equal(t, "46ad031bfb052db2e4a2514fed8dc480b98e5ce4acb55d5640d91407e0d8a3e9", hex.EncodeToString(hash[:])) + + message = evm_2_evm_onramp.InternalEVM2EVMMessage{ + SourceChainSelector: sourceChainSelector, + Sender: common.HexToAddress("0x1110000000000000000000000000000000000001"), + Receiver: common.HexToAddress("0x2220000000000000000000000000000000000001"), + SequenceNumber: 1337, + GasLimit: big.NewInt(100), + Strict: false, + Nonce: 1337, + FeeToken: common.Address{}, + FeeTokenAmount: big.NewInt(1e12), + Data: []byte("foo bar baz"), + TokenAmounts: []evm_2_evm_onramp.ClientEVMTokenAmount{ + {Token: common.HexToAddress("0x4440000000000000000000000000000000000001"), Amount: big.NewInt(12345678900)}, + {Token: common.HexToAddress("0x6660000000000000000000000000000000000001"), Amount: big.NewInt(4204242)}, + }, + SourceTokenData: [][]byte{{0x2, 0x1}}, + MessageId: [32]byte{}, + } + + data, err = onRampABI.Events["CCIPSendRequested"].Inputs.Pack(message) + require.NoError(t, err) + hash, err = hasher.HashLeaf(types.Log{Topics: []common.Hash{CCIPSendRequestEventSigV1_2_0}, Data: data}) + require.NoError(t, err) + + // NOTE: Must match spec + require.Equal(t, "4362a13a42e52ff5ce4324e7184dc7aa41704c3146bc842d35d95b94b32a78b6", hex.EncodeToString(hash[:])) +} + func TestLogPollerClient_GetSendRequestsGteSeqNum(t *testing.T) { onRampAddr := utils.RandomAddress() seqNum := uint64(100) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader.go index 3c2a792e61..e8a071d4ba 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader.go @@ -50,7 +50,7 @@ func (d usdcPayload) Validate() error { return nil } -func parseUSDCMessageSent(logData []byte) ([]byte, error) { +func ParseUSDCMessageSent(logData []byte) ([]byte, error) { decodeAbiStruct, err := abihelpers.DecodeAbiStruct[usdcPayload](logData) if err != nil { return nil, err @@ -72,7 +72,7 @@ func (u *USDCReaderImpl) GetLastUSDCMessagePriorToLogIndexInTx(ctx context.Conte current := logs[len(logs)-i-1] if current.LogIndex < logIndex { u.lggr.Infow("Found USDC message", "logIndex", current.LogIndex, "txHash", current.TxHash.Hex(), "data", hexutil.Encode(current.Data)) - return parseUSDCMessageSent(current.Data) + return ParseUSDCMessageSent(current.Data) } } return nil, errors.Errorf("no USDC message found prior to log index %d in tx %s", logIndex, txHash.Hex()) diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_test.go index 16bd4d7607..6c833f6b2d 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_test.go @@ -20,7 +20,8 @@ func TestLogPollerClient_GetLastUSDCMessagePriorToLogIndexInTx(t *testing.T) { txHash := utils.RandomAddress().Hash() ccipLogIndex := int64(100) - expectedData := []byte("-1") + expectedData := "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc08610000000000000000" + expectedPostParse := "0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861" lggr := logger.TestLogger(t) t.Run("multiple found", func(t *testing.T) { @@ -34,15 +35,14 @@ func TestLogPollerClient_GetLastUSDCMessagePriorToLogIndexInTx(t *testing.T) { mock.Anything, ).Return([]logpoller.Log{ {LogIndex: ccipLogIndex - 2, Data: []byte("-2")}, - {LogIndex: ccipLogIndex - 1, Data: expectedData}, + {LogIndex: ccipLogIndex - 1, Data: hexutil.MustDecode(expectedData)}, {LogIndex: ccipLogIndex, Data: []byte("0")}, {LogIndex: ccipLogIndex + 1, Data: []byte("1")}, }, nil) usdcMessageData, err := u.GetLastUSDCMessagePriorToLogIndexInTx(context.Background(), ccipLogIndex, txHash) assert.NoError(t, err) - assert.Equal(t, expectedData, usdcMessageData) - + assert.Equal(t, expectedPostParse, hexutil.Encode(usdcMessageData)) lp.AssertExpectations(t) }) @@ -69,7 +69,7 @@ func TestParse(t *testing.T) { expectedBody, err := hexutil.Decode("0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc08610000000000000000") require.NoError(t, err) - parsedBody, err := parseUSDCMessageSent(expectedBody) + parsedBody, err := ParseUSDCMessageSent(expectedBody) require.NoError(t, err) expectedPostParse := "0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861" diff --git a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go index efdec65182..aee8f196c6 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go @@ -1386,7 +1386,7 @@ func (args *ManualExecArgs) execute(report *commit_store.CommitStoreCommitReport leaves = append(leaves, hash) if sendRequestedIterator.Event.Message.SequenceNumber == seqNr { fmt.Printf("Found proving %d %+v\n", curr, sendRequestedIterator.Event.Message) - msg, err2 := abihelpers.DecodeOffRampMessage(sendRequestedIterator.Event.Raw.Data) + msg, err2 := ccipdata.DecodeOffRampMessageV1_2_0(sendRequestedIterator.Event.Raw.Data) if err2 != nil { return nil, err2 } diff --git a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go index 4846c9afd5..6d47d94f74 100644 --- a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go +++ b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go @@ -7,7 +7,6 @@ import ( "net/http" "net/http/httptest" "net/url" - "strings" "testing" "github.com/ethereum/go-ethereum/common" @@ -17,67 +16,30 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata/usdc" "github.com/smartcontractkit/chainlink/v2/core/utils" ) -var ( - mockOnRampAddress = utils.RandomAddress() - mockUSDCTokenAddress = utils.RandomAddress() - mockMsgTransmitter = utils.RandomAddress() -) - type attestationResponse struct { Status string `json:"status"` Attestation string `json:"attestation"` } -type messageAndAttestation struct { - Message []byte - Attestation []byte -} - -func (m messageAndAttestation) AbiString() string { - return ` - [{ - "components": [ - {"name": "message", "type": "bytes"}, - {"name": "attestation", "type": "bytes"} - ], - "type": "tuple" - }]` -} - -func (m messageAndAttestation) Validate() error { - return nil -} - -type usdcPayload []byte - -func (d usdcPayload) AbiString() string { - return `[{"type": "bytes"}]` -} - -func (d usdcPayload) Validate() error { - return nil -} - func TestUSDCReader_ReadTokenData(t *testing.T) { response := attestationResponse{ Status: "complete", Attestation: "0x9049623e91719ef2aa63c55f357be2529b0e7122ae552c18aff8db58b4633c4d3920ff03d3a6d1ddf11f06bf64d7fd60d45447ac81f527ba628877dc5ca759651b08ffae25a6d3b1411749765244f0a1c131cbfe04430d687a2e12fd9d2e6dc08e118ad95d94ad832332cf3c4f7a4f3da0baa803b7be024b02db81951c0f0714de1b", } - abiEncodedMessageBody, err := hexutil.Decode("0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc08610000000000000000") - require.NoError(t, err) - rawMessageBody, err := abihelpers.DecodeAbiStruct[usdcPayload](abiEncodedMessageBody) - require.NoError(t, err) + // Message is the bytes itself from MessageSend(bytes message) + // i.e. ABI parsed. + message := "0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861" + expectedMessageAndAttestation := "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861000000000000000000000000000000000000000000000000000000000000000000000000000000829049623e91719ef2aa63c55f357be2529b0e7122ae552c18aff8db58b4633c4d3920ff03d3a6d1ddf11f06bf64d7fd60d45447ac81f527ba628877dc5ca759651b08ffae25a6d3b1411749765244f0a1c131cbfe04430d687a2e12fd9d2e6dc08e118ad95d94ad832332cf3c4f7a4f3da0baa803b7be024b02db81951c0f0714de1b000000000000000000000000000000000000000000000000000000000000" lggr := logger.TestLogger(t) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - messageHash := utils.Keccak256Fixed(rawMessageBody) + messageHash := utils.Keccak256Fixed(hexutil.MustDecode(message)) expectedUrl := "/v1/attestations/0x" + hex.EncodeToString(messageHash[:]) require.Equal(t, expectedUrl, r.URL.Path) @@ -94,33 +56,16 @@ func TestUSDCReader_ReadTokenData(t *testing.T) { txHash := utils.RandomBytes32() logIndex := int64(4) - eventsClient := ccipdata.MockUSDCReader{} - //eventsClient.On("GetSendRequestsBetweenSeqNums", - // mock.Anything, - // mockOnRampAddress, - // seqNum, - // seqNum, - // 0, - //).Return([]ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]{ - // { - // Data: evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested{ - // Raw: types.Log{ - // TxHash: txHash, - // Index: uint(logIndex), - // }, - // }, - // }, - //}, nil) - - eventsClient.On("GetLastUSDCMessagePriorToLogIndexInTx", + usdcReader := ccipdata.MockUSDCReader{} + usdcReader.On("GetLastUSDCMessagePriorToLogIndexInTx", mock.Anything, logIndex, common.Hash(txHash), - ).Return(abiEncodedMessageBody, nil) + ).Return(hexutil.MustDecode(message), nil) attestationURI, err := url.ParseRequestURI(ts.URL) require.NoError(t, err) - usdcService := usdc.NewUSDCTokenDataReader(lggr, &eventsClient, attestationURI) + usdcService := usdc.NewUSDCTokenDataReader(lggr, &usdcReader, attestationURI) msgAndAttestation, err := usdcService.ReadTokenData(context.Background(), internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ InternalEVM2EVMMessage: evm_2_evm_offramp.InternalEVM2EVMMessage{ SequenceNumber: seqNum, @@ -129,15 +74,6 @@ func TestUSDCReader_ReadTokenData(t *testing.T) { LogIndex: uint(logIndex), }) require.NoError(t, err) - - attestationBytes, err := hex.DecodeString(strings.TrimPrefix(response.Attestation, "0x")) - require.NoError(t, err) - - encodeAbiStruct, err := abihelpers.EncodeAbiStruct[messageAndAttestation](messageAndAttestation{ - Message: rawMessageBody, - Attestation: attestationBytes, - }) - require.NoError(t, err) - - require.Equal(t, encodeAbiStruct, msgAndAttestation) + // Expected attestation for parsed body. + require.Equal(t, expectedMessageAndAttestation, hexutil.Encode(msgAndAttestation)) } diff --git a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go index f4f7bdf59f..226b7a8e1c 100644 --- a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go +++ b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" @@ -53,7 +54,9 @@ func TestUSDCReader_callAttestationApiMock(t *testing.T) { require.NoError(t, err) lggr := logger.TestLogger(t) - usdcReader, err := ccipdata.NewUSDCReader(lggr, mockMsgTransmitter, nil) + lp := mocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + usdcReader, err := ccipdata.NewUSDCReader(lggr, mockMsgTransmitter, lp) require.NoError(t, err) usdcService := NewUSDCTokenDataReader(lggr, usdcReader, attestationURI) attestation, err := usdcService.callAttestationApi(context.Background(), utils.RandomBytes32()) @@ -72,7 +75,9 @@ func TestUSDCReader_callAttestationApiMockError(t *testing.T) { require.NoError(t, err) lggr := logger.TestLogger(t) - usdcReader, err := ccipdata.NewUSDCReader(lggr, mockMsgTransmitter, nil) + lp := mocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + usdcReader, err := ccipdata.NewUSDCReader(lggr, mockMsgTransmitter, lp) require.NoError(t, err) usdcService := NewUSDCTokenDataReader(lggr, usdcReader, attestationURI) _, err = usdcService.callAttestationApi(context.Background(), utils.RandomBytes32()) @@ -91,24 +96,22 @@ func getMockUSDCEndpoint(t *testing.T, response attestationResponse) *httptest.S func TestGetUSDCMessageBody(t *testing.T) { expectedBody := []byte("0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861") - sourceChainEventsMock := ccipdata.MockUSDCReader{} - sourceChainEventsMock.On("GetLastUSDCMessagePriorToLogIndexInTx", mock.Anything, mock.Anything, mock.Anything).Return(expectedBody, nil) + usdcReader := ccipdata.MockUSDCReader{} + usdcReader.On("GetLastUSDCMessagePriorToLogIndexInTx", mock.Anything, mock.Anything, mock.Anything).Return(expectedBody, nil) lggr := logger.TestLogger(t) - usdcReader, err := ccipdata.NewUSDCReader(lggr, mockMsgTransmitter, nil) - require.NoError(t, err) - usdcService := NewUSDCTokenDataReader(lggr, usdcReader, nil) + usdcService := NewUSDCTokenDataReader(lggr, &usdcReader, nil) // Make the first call and assert the underlying function is called body, err := usdcService.getUSDCMessageBody(context.Background(), internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{}) require.NoError(t, err) require.Equal(t, body, expectedBody) - sourceChainEventsMock.AssertNumberOfCalls(t, "GetLastUSDCMessagePriorToLogIndexInTx", 1) + usdcReader.AssertNumberOfCalls(t, "GetLastUSDCMessagePriorToLogIndexInTx", 1) // Make another call and assert that the cache is used body, err = usdcService.getUSDCMessageBody(context.Background(), internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{}) require.NoError(t, err) require.Equal(t, body, expectedBody) - sourceChainEventsMock.AssertNumberOfCalls(t, "GetLastUSDCMessagePriorToLogIndexInTx", 1) + usdcReader.AssertNumberOfCalls(t, "GetLastUSDCMessagePriorToLogIndexInTx", 1) }