From dd0e46986f19dcceb304fc48f2bd410685ecd179 Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Mon, 20 Nov 2023 18:18:57 -0500 Subject: [PATCH 1/2] fix(sdk): have getMessageStatus call messenger getMessageStatus was previously using event queries to figure out the status of the given message. We can do the same thing by making requests directly to the messenger contracts which is more reliable because most RPC endpoints won't allow massive block ranges. --- .changeset/purple-melons-explain.md | 5 ++ packages/sdk/src/cross-chain-messenger.ts | 61 ++++++++++++++++------- 2 files changed, 47 insertions(+), 19 deletions(-) create mode 100644 .changeset/purple-melons-explain.md diff --git a/.changeset/purple-melons-explain.md b/.changeset/purple-melons-explain.md new file mode 100644 index 000000000000..5f8a3c0f5cb6 --- /dev/null +++ b/.changeset/purple-melons-explain.md @@ -0,0 +1,5 @@ +--- +'@eth-optimism/sdk': patch +--- + +Simplifies getMessageStatus to use an O(1) lookup instead of an event query diff --git a/packages/sdk/src/cross-chain-messenger.ts b/packages/sdk/src/cross-chain-messenger.ts index 3e169e223f52..1f543eaedc06 100644 --- a/packages/sdk/src/cross-chain-messenger.ts +++ b/packages/sdk/src/cross-chain-messenger.ts @@ -667,25 +667,54 @@ export class CrossChainMessenger { toBlockOrBlockHash?: BlockTag ): Promise { const resolved = await this.toCrossChainMessage(message, messageIndex) - const receipt = await this.getMessageReceipt( - resolved, - messageIndex, - fromBlockOrBlockHash, - toBlockOrBlockHash + // legacy withdrawals relayed prebedrock are v1 + const messageHashV0 = hashCrossDomainMessagev0( + resolved.target, + resolved.sender, + resolved.message, + resolved.messageNonce ) + // bedrock withdrawals are v1 + // legacy withdrawals relayed postbedrock are v1 + // there is no good way to differentiate between the two types of legacy + // so what we will check for both + const messageHashV1 = hashCrossDomainMessagev1( + resolved.messageNonce, + resolved.sender, + resolved.target, + resolved.value, + resolved.minGasLimit, + resolved.message + ) + + // Here we want the messenger that will receive the message, not the one that sent it. + const messenger = + resolved.direction === MessageDirection.L1_TO_L2 + ? this.contracts.l2.L2CrossDomainMessenger + : this.contracts.l1.L1CrossDomainMessenger + + const success = + (await messenger.successfulMessages(messageHashV0)) || + (await messenger.successfulMessages(messageHashV1)) + + const failure = + (await messenger.failedMessages(messageHashV0)) || + (await messenger.failedMessages(messageHashV1)) if (resolved.direction === MessageDirection.L1_TO_L2) { - if (receipt === null) { - return MessageStatus.UNCONFIRMED_L1_TO_L2_MESSAGE + if (success) { + return MessageStatus.RELAYED + } else if (failure) { + return MessageStatus.FAILED_L1_TO_L2_MESSAGE } else { - if (receipt.receiptStatus === MessageReceiptStatus.RELAYED_SUCCEEDED) { - return MessageStatus.RELAYED - } else { - return MessageStatus.FAILED_L1_TO_L2_MESSAGE - } + return MessageStatus.UNCONFIRMED_L1_TO_L2_MESSAGE } } else { - if (receipt === null) { + if (success) { + return MessageStatus.RELAYED + } else if (failure) { + return MessageStatus.READY_FOR_RELAY + } else { let timestamp: number if (this.bedrock) { const output = await this.getMessageBedrockOutput( @@ -737,12 +766,6 @@ export class CrossChainMessenger { } else { return MessageStatus.READY_FOR_RELAY } - } else { - if (receipt.receiptStatus === MessageReceiptStatus.RELAYED_SUCCEEDED) { - return MessageStatus.RELAYED - } else { - return MessageStatus.READY_FOR_RELAY - } } } } From fa6a23383921d39f24715a8dee56e26561f0db2c Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Tue, 21 Nov 2023 14:55:42 -0500 Subject: [PATCH 2/2] fix(sdk): update MockMessenger --- packages/sdk/test/contracts/MockMessenger.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/sdk/test/contracts/MockMessenger.sol b/packages/sdk/test/contracts/MockMessenger.sol index 724d90ed6778..1f7b3d8cf737 100644 --- a/packages/sdk/test/contracts/MockMessenger.sol +++ b/packages/sdk/test/contracts/MockMessenger.sol @@ -8,6 +8,8 @@ contract MockMessenger is ICrossDomainMessenger { } uint256 public nonce; + mapping (bytes32 => bool) public successfulMessages; + mapping (bytes32 => bool) public failedMessages; // Empty function to satisfy the interface. function sendMessage( @@ -81,6 +83,7 @@ contract MockMessenger is ICrossDomainMessenger { ) public { for (uint256 i = 0; i < _params.length; i++) { emit RelayedMessage(_params[i]); + successfulMessages[_params[i]] = true; } } @@ -89,6 +92,7 @@ contract MockMessenger is ICrossDomainMessenger { ) public { for (uint256 i = 0; i < _params.length; i++) { emit FailedRelayedMessage(_params[i]); + failedMessages[_params[i]] = true; } } }