From 857c5a6862c11cd7fd7a3a32cea8e0835d2acd6c Mon Sep 17 00:00:00 2001 From: Aleksandr Bukata <96521086+bukata-sa@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:39:47 +0000 Subject: [PATCH 1/2] CCIP-4403 don't request lbtc attestation if payload is returned (#1557) Lombard send full payload if attestation is disabled. It can be enabled by redeploying token pools and synchronizing this between chains. If mistake took place and we got a message with full payload while attestation is enabled onchain at Lombard side, message will be available for manual exec --- .../ocr2/plugins/ccip/tokendata/lbtc/lbtc.go | 39 +++++++------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/core/services/ocr2/plugins/ccip/tokendata/lbtc/lbtc.go b/core/services/ocr2/plugins/ccip/tokendata/lbtc/lbtc.go index dece927d02..f7aad6ee94 100644 --- a/core/services/ocr2/plugins/ccip/tokendata/lbtc/lbtc.go +++ b/core/services/ocr2/plugins/ccip/tokendata/lbtc/lbtc.go @@ -3,7 +3,6 @@ package lbtc import ( "bytes" "context" - "crypto/sha256" "encoding/json" "fmt" "net/url" @@ -188,10 +187,20 @@ func (s *TokenDataReader) ReadTokenData(ctx context.Context, msg cciptypes.EVM2E } } - payloadHash, err := s.getLBTCPayloadHash(msg, tokenIndex) + decodedSourceTokenData, err := abihelpers.DecodeAbiStruct[sourceTokenData](msg.SourceTokenData[tokenIndex]) if err != nil { - return []byte{}, errors.Wrap(err, "failed getting the LBTC message body") + return []byte{}, err + } + destTokenData := decodedSourceTokenData.ExtraData + // We don't have better way to determine if the extraData is a payload or sha256(payload) + // Last parameter of the payload struct is 32-bytes nonce (see Lombard's Bridge._deposit(...) method), + // so we can assume that payload always exceeds 32 bytes + if len(destTokenData) != 32 { + s.lggr.Infow("SourceTokenData.extraData size is not 32. This is deposit payload, not sha256(payload). Attestation is disabled onchain", + "destTokenData", hexutil.Encode(destTokenData)) + return destTokenData, nil } + payloadHash := [32]byte(destTokenData) msgID := hexutil.Encode(msg.MessageID[:]) payloadHashHex := hexutil.Encode(payloadHash[:]) @@ -213,6 +222,9 @@ func (s *TokenDataReader) ReadTokenData(ctx context.Context, msg cciptypes.EVM2E attestation = attestationCandidate } } + if attestation == (messageAttestationResponse{}) { + return nil, fmt.Errorf("requested attestation %s not found in response", payloadHashHex) + } s.lggr.Infow("Got response from attestation API", "messageID", msgID, "attestationStatus", attestation.Status, "attestation", attestation) switch attestation.Status { @@ -232,27 +244,6 @@ func (s *TokenDataReader) ReadTokenData(ctx context.Context, msg cciptypes.EVM2E } } -func (s *TokenDataReader) getLBTCPayloadHash(msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta, tokenIndex int) ([32]byte, error) { - decodedSourceTokenData, err := abihelpers.DecodeAbiStruct[sourceTokenData](msg.SourceTokenData[tokenIndex]) - if err != nil { - return [32]byte{}, err - } - destTokenData := decodedSourceTokenData.ExtraData - var payloadHash [32]byte - // We don't have better way to determine if the extraData is a payload or sha256(payload) - // Last parameter of the payload struct is 32-bytes nonce (see Lombard's Bridge._deposit(...) method), - // so we can assume that payload always exceeds 32 bytes - if len(destTokenData) != 32 { - payloadHash = sha256.Sum256(destTokenData) - s.lggr.Warnw("SourceTokenData.extraData size is not 32. Probably this is deposit payload, not sha256(payload). "+ - "This message was sent when LBTC attestation was disabled onchain. Will use sha256 from this value", - "destTokenData", destTokenData, "newPayloadHash", payloadHash) - } else { - payloadHash = [32]byte(destTokenData) - } - return payloadHash, nil -} - func (s *TokenDataReader) callAttestationApi(ctx context.Context, lbtcMessageHash [32]byte) (attestationResponse, error) { attestationUrl := fmt.Sprintf("%s/bridge/%s/%s", s.attestationApi.String(), apiVersion, attestationPath) request := attestationRequest{PayloadHashes: []string{hexutil.Encode(lbtcMessageHash[:])}} From 6c62128b9753bf3fb1bba6c280d05c35c6e3ed13 Mon Sep 17 00:00:00 2001 From: Nour Elrashidy Date: Wed, 4 Dec 2024 09:22:02 +0100 Subject: [PATCH 2/2] CCIP-4472: Update default rate limit and cleanup comments (#1558) ## Motivation [CCIP-4472](https://smartcontract-it.atlassian.net/browse/CCIP-4472) ## Solution --- core/services/ocr2/plugins/ccip/tokendata/lbtc/lbtc.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/core/services/ocr2/plugins/ccip/tokendata/lbtc/lbtc.go b/core/services/ocr2/plugins/ccip/tokendata/lbtc/lbtc.go index f7aad6ee94..0e36e7ae5b 100644 --- a/core/services/ocr2/plugins/ccip/tokendata/lbtc/lbtc.go +++ b/core/services/ocr2/plugins/ccip/tokendata/lbtc/lbtc.go @@ -21,7 +21,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata/http" ) -// TODO: double check the validty of default values for lombard's API after checking docs const ( apiVersion = "v1" attestationPath = "deposits/getByHash" @@ -35,8 +34,8 @@ const ( maxCoolDownDuration = 10 * time.Minute // defaultRequestInterval defines the rate in requests per second that the attestation API can be called. - // this is set according to the APIs documentated 10 requests per second rate limit. - defaultRequestInterval = 100 * time.Millisecond + // this is set according to the APIs recommended 5 requests per second rate limit. + defaultRequestInterval = 200 * time.Millisecond // APIIntervalRateLimitDisabled is a special value to disable the rate limiting. APIIntervalRateLimitDisabled = -1 @@ -74,10 +73,9 @@ type TokenDataReader struct { type messageAttestationResponse struct { MessageHash string `json:"message_hash"` Status attestationStatus `json:"status"` - Attestation string `json:"attestation"` // Attestation represented by abi.encode(payload, proof) + Attestation string `json:"attestation,omitempty"` // Attestation represented by abi.encode(payload, proof) } -// TODO: Adjust after checking API docs type attestationRequest struct { PayloadHashes []string `json:"messageHash"` } @@ -86,8 +84,6 @@ type attestationResponse struct { Attestations []messageAttestationResponse `json:"attestations"` } -// TODO: Implement encoding/decoding - type sourceTokenData struct { SourcePoolAddress []byte DestTokenAddress []byte