Skip to content

Commit

Permalink
fix(bridge-ui): recallMessage fix (#17547)
Browse files Browse the repository at this point in the history
  • Loading branch information
KorbinianK authored Jun 10, 2024
1 parent d083eeb commit 11755d1
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
{ value: MessageStatus.RETRIABLE, label: $t('transactions.filter.retry') },
{ value: MessageStatus.DONE, label: $t('transactions.filter.claimed') },
{ value: MessageStatus.FAILED, label: $t('transactions.filter.failed') },
{ value: MessageStatus.RECALLED, label: $t('transactions.filter.released') },
];
const select = (option: (typeof options)[0]) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
{ value: MessageStatus.RETRIABLE, label: $t('transactions.filter.retry') },
{ value: MessageStatus.DONE, label: $t('transactions.filter.claimed') },
{ value: MessageStatus.FAILED, label: $t('transactions.filter.failed') },
{ value: MessageStatus.RECALLED, label: $t('transactions.filter.released') },
];
const toggleMenu = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@
<button class="status-btn" on:click={release} on:click={handleReleaseClick}>
{$t('transactions.button.release')}
</button>
{:else if bridgeTxStatus === MessageStatus.RECALLED}
<StatusDot type="error" />
<span>{$t('transactions.status.released.name')}</span>
{:else}
<!-- TODO: look into this possible state -->
<StatusDot type="error" />
Expand Down
4 changes: 4 additions & 0 deletions packages/bridge-ui/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@
"claimed": "Claimed",
"failed": "Failed",
"processing": "Processing",
"released": "Released",
"retry": "Retriable",
"title": "Filters"
},
Expand Down Expand Up @@ -592,6 +593,9 @@
"description": "Your bridged asset cannot be processed and is now accessible to you on the source chain.",
"name": "Release"
},
"released": {
"name": "Released"
},
"releasing": "Releasing",
"retry": {
"description": "The relayer was unable to process this message, and you will need to retry the processing yourself.",
Expand Down
2 changes: 1 addition & 1 deletion packages/bridge-ui/src/libs/bridge/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export enum MessageStatus {
RETRIABLE,
DONE,
FAILED,
PROVEN, // UI ONLY
RECALLED,
}

// struct Message {
Expand Down
24 changes: 24 additions & 0 deletions packages/bridge-ui/src/libs/polling/messageStatusPoller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ export function startPolling(bridgeTx: BridgeTransaction, runImmediately = true)
transport: http(),
});

const srcChainClient = createPublicClient({
chain: chains.find((chain) => chain.id === Number(srcChainId)),
transport: http(),
});

// We are gonna be polling the destination bridge contract
const destBridgeAddress = routingContractsMap[Number(destChainId)][Number(srcChainId)].bridgeAddress;
const destBridgeContract = getContract({
Expand All @@ -79,6 +84,14 @@ export function startPolling(bridgeTx: BridgeTransaction, runImmediately = true)
client: destChainClient,
});

// In case for recalled messages we need to check the source bridge contract
const srcBridgeAddress = routingContractsMap[Number(srcChainId)][Number(destChainId)].bridgeAddress;
const srcBridgeContract = getContract({
address: srcBridgeAddress,
abi: bridgeAbi,
client: srcChainClient,
});

const stopPolling = () => {
const interval = hashIntervalMap[hash];
if (interval) {
Expand Down Expand Up @@ -108,6 +121,17 @@ export function startPolling(bridgeTx: BridgeTransaction, runImmediately = true)
const messageStatus: MessageStatus = await destBridgeContract.read.messageStatus([bridgeTx.msgHash]);
emitter.emit(PollingEvent.STATUS, messageStatus);

if (messageStatus === MessageStatus.FAILED) {
// check if the message is recalled
const recallStatus = await srcBridgeContract.read.messageStatus([bridgeTx.msgHash]);
if (recallStatus === MessageStatus.RECALLED) {
log(`Message ${bridgeTx.msgHash} has been recalled.`);
emitter.emit(PollingEvent.STATUS, MessageStatus.RECALLED);
stopPolling();
return;
}
}

let blockNumber: Hex;
if (!bridgeTx.blockNumber) {
const receipt = await getTransactionReceipt(config, { hash: bridgeTx.hash });
Expand Down
34 changes: 31 additions & 3 deletions packages/bridge-ui/src/libs/proof/BridgeProver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ export class BridgeProver {
}

async getEncodedSignalProofForRecall({ bridgeTx }: { bridgeTx: BridgeTransaction }) {
const { message, msgHash } = bridgeTx;
const { blockNumber, message, msgHash } = bridgeTx;

log('msgHash', msgHash);
if (!message) throw new ProofGenerationError('Message is not defined');
Expand Down Expand Up @@ -304,8 +304,36 @@ export class BridgeProver {
// Get the signalServiceAddress for the source chain
const destSignalServiceAddress =
routingContractsMap[Number(destChainId)][Number(srcChainId)].signalServiceAddress;
const srcSignalServiceAddress = routingContractsMap[Number(srcChainId)][Number(destChainId)].signalServiceAddress;

const syncedChainData = await readContract(config, {
address: srcSignalServiceAddress,
abi: signalServiceAbi,
functionName: 'getSyncedChainData',
args: [destChainId, keccak256(toBytes('STATE_ROOT')), 0n],
chainId: Number(srcChainId),
});

log('syncedChainData', syncedChainData);

const latestSyncedblock = syncedChainData[0];

const synced = latestSyncedblock >= hexToBigInt(blockNumber);
log('synced', synced, latestSyncedblock, hexToBigInt(blockNumber));
if (!synced) {
throw new BlockNotSyncedError('block is not synced yet');
}

const block = await destChainClient.getBlock({ blockTag: 'latest' });
// Get the block based on the blocknumber from the destination chain
let block;
try {
block = await destChainClient.getBlock({ blockNumber: latestSyncedblock });
if (!block || block.hash === null || block.number === null) {
throw new BlockNotFoundError({ blockNumber: latestSyncedblock });
}
} catch {
throw new BlockNotFoundError({ blockNumber: latestSyncedblock });
}

const signal = await this.getSignalForFailedMessage(msgHash);

Expand All @@ -330,7 +358,7 @@ export class BridgeProver {

// Build the hopProof
const hopProof: HopProof = {
chainId: BigInt(destChainId),
chainId: BigInt(srcChainId),
blockId: BigInt(block.number),
rootHash: block.stateRoot,
cacheOption: 0n, // Todo: could be configurable
Expand Down

0 comments on commit 11755d1

Please sign in to comment.