-
Notifications
You must be signed in to change notification settings - Fork 70
feat: finalize *tokenless* HubPool CCTP messages #2270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: Ihor Farion <[email protected]>
Signed-off-by: Ihor Farion <[email protected]>
Signed-off-by: Ihor Farion <[email protected]>
Signed-off-by: Ihor Farion <[email protected]>
Signed-off-by: Ihor Farion <[email protected]>
Signed-off-by: Ihor Farion <[email protected]>
DepositForBurn
messagesSigned-off-by: Ihor Farion <[email protected]>
Signed-off-by: Ihor Farion <[email protected]>
Signed-off-by: Ihor Farion <[email protected]>
Signed-off-by: Ihor Farion <[email protected]>
Signed-off-by: Ihor Farion <[email protected]>
Signed-off-by: Ihor Farion <[email protected]>
…ng status Signed-off-by: Ihor Farion <[email protected]>
…ying on cctpMessageIndex Signed-off-by: Ihor Farion <[email protected]>
Signed-off-by: Ihor Farion <[email protected]>
Signed-off-by: Ihor Farion <[email protected]>
…or pending attestations ... Signed-off-by: Ihor Farion <[email protected]>
Signed-off-by: Ihor Farion <[email protected]>
let lastMessageSentEventIdx = -1; | ||
receipt.logs.forEach((log, i) => { | ||
if (_isMessageSentEvent(log)) { | ||
if (lastMessageSentEventIdx == -1) { | ||
lastMessageSentEventIdx = i; | ||
} else { | ||
_addCommonMessageEventIfRelevant(receipt.logs[lastMessageSentEventIdx]); | ||
lastMessageSentEventIdx = i; | ||
} | ||
} else { | ||
const depositForBurnVersion = _getDepositForBurnVersion(log); | ||
if (depositForBurnVersion == -1) { | ||
// Skip non-`DepositForBurn` events | ||
return; | ||
} | ||
if (lastMessageSentEventIdx == -1) { | ||
throw new Error( | ||
"DepositForBurn event found without corresponding MessageSent event. " + | ||
"Each DepositForBurn event must have a preceding MessageSent event in the same transaction. " + | ||
`Transaction: ${receipt.transactionHash}, DepositForBurn log index: ${i}` | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you comment on what this loop is doing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Here, we go one by one over a receipts that we "suspect might have CCTP messages for finalization".
It's important to understand what we're looking for in the logs. It's either of 2 things:
MessageSent
+DepositForBurn
== a single USDC transfer from one chain to another (1)- solo
MessageSent
with noDepositForBurn
-> a single crosschain message (2)
Then for each receipt we traverse all logs in order, and keep the latest encountered MessageSent
index in lastMessageSentEventIdx
. Then if we encounter next MessageSent
-> the one stored in lastMessageSentEventIdx
was (2). If we encounter DepositForBurn
, then we bundle stored lastMessageSentEventIdx
with it to receive (1)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it fair to expect that a DepositForBurn
event always follows a MessageSent
event? If so, I'm wondering if we could first identify all DepositForBurn
events and then use their logIndex
fields for a subsequent pass over MessageSent
events. If a MessageSent
event has a logIndex
that immediately precedes a DepositForBurn
event then it'd be excluded. Could that work? (Motivation for this would be a bit less nesting, at the expense of additional loops - but I think it should be possible to do that in quite compact and concise code).
Also curious about some lines like 351 & 354 - it seems lastMessageSentEventIdx = i
is performed unconditionally because it sits on either side of the if
statement. Is that intended?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a MessageSent event has a logIndex that immediately precedes a DepositForBurn event then it'd be excluded. Could that work?
I'm a bit hesitant to do that beacuse I'm not 100% it's always the "one-before" index. Probably should be the case, but prev. impl. just relied smth like findLast(messageSent, starting_from_depositFrom_idx)
, so I kept that logic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lastMessageSentEventIdx = i is performed unconditionally because it sits on either side of the if statement. Is that intended?
It is yeah:
if lastMessageSentEventIdx == -1
: we don't have any preceding "unmatched"(not a part ofMessageSent
+DepositForBurn
sequence)MessageSent
events. We want to "remember" this event to process it later, so setlastMessageSentEventIdx = i
else
: we do already have a precedingMessageSent
event that is "unmatched". This means that event atlastMessageSentEventIdx
is a 'solo event' -> tokenless message. We process it by calling_addCommonMessageEventIfRelevant
and update ourlastMessageSentEventIdx
to point at our currentMessageSent
event instead
Does this make sense?
Signed-off-by: Ihor Farion <[email protected]>
Signed-off-by: Ihor Farion <[email protected]>
Signed-off-by: Ihor Farion <[email protected]>
Current implementation of CCTP finalizer is only tracking
DepositForBurn
events, and thus is not considering other types of CCTP messages. CCTP can send tokenless messages viaMessageTransmitter
contract, which emitsMessageSent(bytes message)
event.We use
HubPool
eventsTokensRelayed
andMessageRelayed
to find relevant tx hashes to search for suchMessageTransmitter
MessageSent
events in addition to allDepositForBurn
events.