-
Notifications
You must be signed in to change notification settings - Fork 48
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
Let USDC look for the exact nonce instead of relying on ordering #1025
base: ccip-develop
Are you sure you want to change the base?
Conversation
LCOV of commit
|
// fetch all the usdc logs for the provided tx hash | ||
logs, err := u.lp.IndexedLogsByTxHash( | ||
func (u *USDCReaderImpl) GetUSDCMessageWithNonce(ctx context.Context, nonce [32]byte) ([]byte, error) { | ||
logs, err := u.lp.IndexedLogsTopicRange( |
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.
hmm not sure I follow this - we want this event https://github.com/circlefin/evm-cctp-contracts/blob/master/src/MessageTransmitter.sol#L41 (MessageSent not MessageReceived)?
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.
This PR doesn't change the event we're looking for, it's still u.usdcMessageSent
which is eventSig := utils.Keccak256Fixed([]byte("MessageSent(bytes)"))
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.
Ahhh I see what you're saying. I was looking at
event DepositForBurn(
uint64 indexed nonce,
address indexed burnToken,
uint256 amount,
address indexed depositor,
bytes32 mintRecipient,
uint32 destinationDomain,
bytes32 destinationTokenMessenger,
bytes32 destinationCaller
);
Which is the USDC msg but not the CCTP msg, which is
event MessageSent(bytes message);
uint32 _msgVersion,
uint32 _msgSourceDomain,
uint32 _msgDestinationDomain,
uint64 _msgNonce,
bytes32 _msgSender,
bytes32 _msgRecipient,
bytes32 _msgDestinationCaller,
bytes memory _msgRawBody
emit MessageSent(abi.encodePacked(
_msgVersion,
_msgSourceDomain,
_msgDestinationDomain,
_msgNonce,
_msgSender,
_msgRecipient,
_msgDestinationCaller,
_msgRawBody
);
);
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.
I feel like we can still construct the query for this log though, as the first 5 elements should all be known, so we could construct the query for the first slot using those. For EVM (the only supported networks for USDC anyway) you don't even have to know the msg sender, as it will always be a 160 bit EVM address which adds only 0x000.... to the first slot
_msgVersion
is always 0
_msgSourceDomain
is known
_msgDestinationDomain
is known
_msgNonce
is known
_msgSender
is known (the pool)
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.
yeah seems possible, not the most straightforward thing though. I think you'd have to account for the offset/length slots of the bytes encoding as well so it'd be 3 words and the length would include the burn message body length, which looks like its static as well (luckily). Also would need to read the dest domain and pool address from the chain to smoothly support adding new dest domains/pool upgrades. I think worth a little exploratory doc/discussion though
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.
We would only have to query for the third slot, which contains the items I mentioned above.
MessageSent
[topic0] 0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036
0000000000000000000000000000000000000000000000000000000000000020
00000000000000000000000000000000000000000000000000000000000000f8
0000000000000000000000020000000000011c30000000000000000000000000
.....
This is a real MessageSent event emitted on mainnet. As you can see, we'd be interested in the last slot I copied here. Afaik the logPoller simply treats each slot as a queryable object.
0000000000000000000000020000000000011c30000000000000000000000000
=>
00000000 00000000 00000002 0000000000011c30 000000000000000000000000
version srcDom dstDom nonce start of sender (evm, so always 000...)
ctx, | ||
u.usdcMessageSent, | ||
u.transmitterAddress, | ||
common.HexToHash(txHash), | ||
USDC_MESSAGE_NONCE_INDEX, |
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.
Why are we getting the topicIndex
3? Shouldn't we have only 1 topic considering that the event doesn't emit indexed value?
event MessageSent(bytes message);
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.
Expect if topicIndex
in logpoller actually means slots. Then, I understand that we need to get the 3rd slot (0: event signature, 1: offset to data, 2: length of data, 3: packed data).
nonceBytes := [8]byte{} | ||
binary.BigEndian.PutUint64(nonceBytes[:], nonce) | ||
|
||
senderBytes := [12]byte{} |
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.
The sender address is the pool address. We probably need to have it as an input param (like sourceDomain and destDomain)
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.
We can get the sourceDomain
from the MessageTransmitter https://github.com/circlefin/evm-cctp-contracts/blob/master/src/MessageTransmitter.sol#L72. This means we probably need to add method in usdc_reader.
nonceBytes := [8]byte{} | ||
binary.BigEndian.PutUint64(nonceBytes[:], nonce) | ||
|
||
senderBytes := [12]byte{} |
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.
We can get the sourceDomain
from the MessageTransmitter https://github.com/circlefin/evm-cctp-contracts/blob/master/src/MessageTransmitter.sol#L72. This means we probably need to add method in usdc_reader.
@@ -119,6 +141,8 @@ func NewUSDCReader(lggr logger.Logger, jobID string, transmitter common.Address, | |||
Retention: CommitExecLogsRetention, | |||
}, | |||
transmitterAddress: transmitter, | |||
sourceDomain: 0, // TODO | |||
destDomain: 1, // TODO |
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.
For the destDomain
, it cannot be fetched from the source MessageTransmitter
contract. I wonder if we can add the MessageTransmitter destination contract address in the config too and call the the domain
This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days. |
This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days. |
Motivation
We don't want to have the offchain code be reliant on onchain ordering of events.
Solution
Since we only relied on the ordering of USDC events, we can solve the dependency by removing the ordering requirement for USDC. With this new method we look for the exact nonce, which is significantly less brittle overal. It should not care about log ordering, so we can remove the comment from the onRamps