Skip to content

Commit 11755d1

Browse files
authored
fix(bridge-ui): recallMessage fix (#17547)
1 parent d083eeb commit 11755d1

File tree

7 files changed

+65
-4
lines changed

7 files changed

+65
-4
lines changed

packages/bridge-ui/src/components/Transactions/Filter/StatusFilterDialog.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
{ value: MessageStatus.RETRIABLE, label: $t('transactions.filter.retry') },
2222
{ value: MessageStatus.DONE, label: $t('transactions.filter.claimed') },
2323
{ value: MessageStatus.FAILED, label: $t('transactions.filter.failed') },
24+
{ value: MessageStatus.RECALLED, label: $t('transactions.filter.released') },
2425
];
2526
2627
const select = (option: (typeof options)[0]) => {

packages/bridge-ui/src/components/Transactions/Filter/StatusFilterDropdown.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
{ value: MessageStatus.RETRIABLE, label: $t('transactions.filter.retry') },
2727
{ value: MessageStatus.DONE, label: $t('transactions.filter.claimed') },
2828
{ value: MessageStatus.FAILED, label: $t('transactions.filter.failed') },
29+
{ value: MessageStatus.RECALLED, label: $t('transactions.filter.released') },
2930
];
3031
3132
const toggleMenu = () => {

packages/bridge-ui/src/components/Transactions/Status/Status.svelte

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@
124124
<button class="status-btn" on:click={release} on:click={handleReleaseClick}>
125125
{$t('transactions.button.release')}
126126
</button>
127+
{:else if bridgeTxStatus === MessageStatus.RECALLED}
128+
<StatusDot type="error" />
129+
<span>{$t('transactions.status.released.name')}</span>
127130
{:else}
128131
<!-- TODO: look into this possible state -->
129132
<StatusDot type="error" />

packages/bridge-ui/src/i18n/en.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@
532532
"claimed": "Claimed",
533533
"failed": "Failed",
534534
"processing": "Processing",
535+
"released": "Released",
535536
"retry": "Retriable",
536537
"title": "Filters"
537538
},
@@ -592,6 +593,9 @@
592593
"description": "Your bridged asset cannot be processed and is now accessible to you on the source chain.",
593594
"name": "Release"
594595
},
596+
"released": {
597+
"name": "Released"
598+
},
595599
"releasing": "Releasing",
596600
"retry": {
597601
"description": "The relayer was unable to process this message, and you will need to retry the processing yourself.",

packages/bridge-ui/src/libs/bridge/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export enum MessageStatus {
99
RETRIABLE,
1010
DONE,
1111
FAILED,
12-
PROVEN, // UI ONLY
12+
RECALLED,
1313
}
1414

1515
// struct Message {

packages/bridge-ui/src/libs/polling/messageStatusPoller.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ export function startPolling(bridgeTx: BridgeTransaction, runImmediately = true)
7171
transport: http(),
7272
});
7373

74+
const srcChainClient = createPublicClient({
75+
chain: chains.find((chain) => chain.id === Number(srcChainId)),
76+
transport: http(),
77+
});
78+
7479
// We are gonna be polling the destination bridge contract
7580
const destBridgeAddress = routingContractsMap[Number(destChainId)][Number(srcChainId)].bridgeAddress;
7681
const destBridgeContract = getContract({
@@ -79,6 +84,14 @@ export function startPolling(bridgeTx: BridgeTransaction, runImmediately = true)
7984
client: destChainClient,
8085
});
8186

87+
// In case for recalled messages we need to check the source bridge contract
88+
const srcBridgeAddress = routingContractsMap[Number(srcChainId)][Number(destChainId)].bridgeAddress;
89+
const srcBridgeContract = getContract({
90+
address: srcBridgeAddress,
91+
abi: bridgeAbi,
92+
client: srcChainClient,
93+
});
94+
8295
const stopPolling = () => {
8396
const interval = hashIntervalMap[hash];
8497
if (interval) {
@@ -108,6 +121,17 @@ export function startPolling(bridgeTx: BridgeTransaction, runImmediately = true)
108121
const messageStatus: MessageStatus = await destBridgeContract.read.messageStatus([bridgeTx.msgHash]);
109122
emitter.emit(PollingEvent.STATUS, messageStatus);
110123

124+
if (messageStatus === MessageStatus.FAILED) {
125+
// check if the message is recalled
126+
const recallStatus = await srcBridgeContract.read.messageStatus([bridgeTx.msgHash]);
127+
if (recallStatus === MessageStatus.RECALLED) {
128+
log(`Message ${bridgeTx.msgHash} has been recalled.`);
129+
emitter.emit(PollingEvent.STATUS, MessageStatus.RECALLED);
130+
stopPolling();
131+
return;
132+
}
133+
}
134+
111135
let blockNumber: Hex;
112136
if (!bridgeTx.blockNumber) {
113137
const receipt = await getTransactionReceipt(config, { hash: bridgeTx.hash });

packages/bridge-ui/src/libs/proof/BridgeProver.ts

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ export class BridgeProver {
211211
}
212212

213213
async getEncodedSignalProofForRecall({ bridgeTx }: { bridgeTx: BridgeTransaction }) {
214-
const { message, msgHash } = bridgeTx;
214+
const { blockNumber, message, msgHash } = bridgeTx;
215215

216216
log('msgHash', msgHash);
217217
if (!message) throw new ProofGenerationError('Message is not defined');
@@ -304,8 +304,36 @@ export class BridgeProver {
304304
// Get the signalServiceAddress for the source chain
305305
const destSignalServiceAddress =
306306
routingContractsMap[Number(destChainId)][Number(srcChainId)].signalServiceAddress;
307+
const srcSignalServiceAddress = routingContractsMap[Number(srcChainId)][Number(destChainId)].signalServiceAddress;
308+
309+
const syncedChainData = await readContract(config, {
310+
address: srcSignalServiceAddress,
311+
abi: signalServiceAbi,
312+
functionName: 'getSyncedChainData',
313+
args: [destChainId, keccak256(toBytes('STATE_ROOT')), 0n],
314+
chainId: Number(srcChainId),
315+
});
316+
317+
log('syncedChainData', syncedChainData);
318+
319+
const latestSyncedblock = syncedChainData[0];
320+
321+
const synced = latestSyncedblock >= hexToBigInt(blockNumber);
322+
log('synced', synced, latestSyncedblock, hexToBigInt(blockNumber));
323+
if (!synced) {
324+
throw new BlockNotSyncedError('block is not synced yet');
325+
}
307326

308-
const block = await destChainClient.getBlock({ blockTag: 'latest' });
327+
// Get the block based on the blocknumber from the destination chain
328+
let block;
329+
try {
330+
block = await destChainClient.getBlock({ blockNumber: latestSyncedblock });
331+
if (!block || block.hash === null || block.number === null) {
332+
throw new BlockNotFoundError({ blockNumber: latestSyncedblock });
333+
}
334+
} catch {
335+
throw new BlockNotFoundError({ blockNumber: latestSyncedblock });
336+
}
309337

310338
const signal = await this.getSignalForFailedMessage(msgHash);
311339

@@ -330,7 +358,7 @@ export class BridgeProver {
330358

331359
// Build the hopProof
332360
const hopProof: HopProof = {
333-
chainId: BigInt(destChainId),
361+
chainId: BigInt(srcChainId),
334362
blockId: BigInt(block.number),
335363
rootHash: block.stateRoot,
336364
cacheOption: 0n, // Todo: could be configurable

0 commit comments

Comments
 (0)