Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

feat: cache receipts data #175

Merged
merged 22 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packages/app/load.envs.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,16 @@ function getEnvName() {

function getBridgeTokenContracts() {
if (process.env.VITE_FUEL_CHAIN === 'fuelDev') {
// On the ci I was encountering issues
// with the erc20-deployer server not
// completely started before the e2e tests began
const IS_CI = !!process.env.CI;
const { body } = retus('http://localhost:8082/deployments', {
json: true,
retry: {
limit: IS_CI ? 5 : 2,
delay: IS_CI ? 15000 : 0,
},
});

return body;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,21 @@ export const txEthToFuelMachine = createMachine(
},
},
checkingSettlement: {
initial: 'gettingReceiptsInfo',
initial: 'checkingDoneCache',
states: {
checkingDoneCache: {
tags: ['isSettlementLoading', 'isSettlementSelected'],
always: [
{
actions: ['assignReceiptsInfoFromCache'],
cond: 'isTxEthToFuelDone',
target: '#(machine).checkingSettlement.checkingRelay.done',
},
{
target: 'gettingReceiptsInfo',
},
],
},
gettingReceiptsInfo: {
tags: ['isSettlementLoading', 'isSettlementSelected'],
invoke: {
Expand All @@ -111,7 +124,7 @@ export const txEthToFuelMachine = createMachine(
{
actions: ['assignReceiptsInfo', 'notifyEthTxSuccess'],
cond: 'hasEthTxNonce',
target: 'checkingDoneCache',
target: 'gettingFuelMessageStatus',
},
],
},
Expand All @@ -121,18 +134,6 @@ export const txEthToFuelMachine = createMachine(
},
},
},
checkingDoneCache: {
tags: ['isSettlementLoading', 'isSettlementSelected'],
always: [
{
cond: 'isTxEthToFuelDone',
target: '#(machine).checkingSettlement.checkingRelay.done',
},
{
target: 'gettingFuelMessageStatus',
},
],
},
gettingFuelMessageStatus: {
tags: ['isSettlementLoading', 'isSettlementSelected'],
invoke: {
Expand Down Expand Up @@ -315,7 +316,7 @@ export const txEthToFuelMachine = createMachine(
},
},
done: {
entry: ['setEthToFuelTxDone'],
entry: ['setEthToFuelTxDone', 'setEthToFuelTxReceiptCached'],
tags: ['isReceiveDone'],
type: 'final',
},
Expand Down Expand Up @@ -363,6 +364,39 @@ export const txEthToFuelMachine = createMachine(
EthTxCache.removeTxCreated(ctx.ethTxId);
}
},
setEthToFuelTxReceiptCached: (ctx) => {
if (
ctx.ethTxId &&
ctx.ethTxNonce &&
ctx.fuelRecipient &&
ctx.amount &&
ctx.ethDepositBlockHeight &&
ctx.blockDate
) {
EthTxCache.setTxReceipt(ctx.ethTxId, {
erc20Token: ctx.erc20Token,
nonce: ctx.ethTxNonce,
amount: ctx.amount,
recipient: ctx.fuelRecipient,
ethDepositBlockHeight: ctx.ethDepositBlockHeight,
blockDate: ctx.blockDate,
});
}
},
assignReceiptsInfoFromCache: assign((ctx) => {
const receiptInfo = EthTxCache.getTxReceipt(ctx.ethTxId || '');
if (!receiptInfo) {
throw new Error('No receipt');
}
return {
erc20Token: receiptInfo.erc20Token,
ethTxNonce: receiptInfo.nonce,
amount: receiptInfo.amount,
fuelRecipient: receiptInfo.recipient,
ethDepositBlockHeight: receiptInfo.ethDepositBlockHeight,
blockDate: receiptInfo.blockDate,
};
}),
},
guards: {
hasFuelMessage: (ctx, ev) => !!ctx.fuelMessage || !!ev?.data,
Expand Down
64 changes: 64 additions & 0 deletions packages/app/src/systems/Chains/eth/utils/txCache.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { bn } from 'fuels';
import type { Address } from 'viem';

import type { GetReceiptsInfoReturn } from '../services';

const BLOCK_DATE_KEY_SUBSTRING = 'ethBlockDate-';
const HASH_DONE_KEY_SUBSTRING = 'ethToFuelTx';
const TX_CREATED_KEY_SUBSTRING = 'ethTxCreated';
const TX_RECEIPT_KEY_SUBSTRING = 'ethToFuelTxReceipt';

export const EthTxCache = {
getBlockDate: (blockHash: string) => {
Expand Down Expand Up @@ -37,6 +43,60 @@ export const EthTxCache = {
getTxIsCreated: (txId: string) => {
return localStorage.getItem(generateTxCreatedKey(txId)) === 'true';
},
setTxReceipt: (txId: string, receiptInfo: GetReceiptsInfoReturn) => {
const receiptInfoToStringify = {
...receiptInfo,
erc20Token: receiptInfo.erc20Token && {
...receiptInfo.erc20Token,
totalSupply: {
...receiptInfo.erc20Token?.totalSupply,
value: receiptInfo.erc20Token?.totalSupply.value.toString(),
},
},
nonce: receiptInfo.nonce?.toString(),
amount: receiptInfo.amount?.toString(),
blockdate: receiptInfo.blockDate?.toUTCString(), // This is necessary bc stringyfing a Date type loses info
};
const stringifiedReceipt = JSON.stringify(receiptInfoToStringify);
localStorage.setItem(generateTxReceiptKey(txId), stringifiedReceipt);
},
getTxReceipt: (txId: string): GetReceiptsInfoReturn | null => {
const stringifiedReceipt = localStorage.getItem(generateTxReceiptKey(txId));
if (!stringifiedReceipt) {
return null;
}
const parsedReceipt = JSON.parse(stringifiedReceipt) as Omit<
GetReceiptsInfoReturn,
'erc20Token' | 'nonce' | 'amount'
> & {
nonce: string;
amount: string;
erc20Token?: {
address: Address;
decimals: number;
name: string;
symbol: string;
totalSupply: {
formatted: string;
value: string;
};
};
};
const typedReceipt = {
...parsedReceipt,
erc20Token: parsedReceipt.erc20Token && {
...parsedReceipt.erc20Token,
totalSupply: {
...parsedReceipt.erc20Token.totalSupply,
value: BigInt(parsedReceipt.erc20Token.totalSupply.value),
},
},
nonce: bn(parsedReceipt.nonce),
amount: bn(parsedReceipt.amount),
blockDate: new Date(parsedReceipt.blockDate!),
};
return typedReceipt;
},
};

const generateBlockDateKey = (blockHash: string) => {
Expand All @@ -50,3 +110,7 @@ const generateHashDoneKey = (blockhash: string) => {
const generateTxCreatedKey = (txId: string) => {
return `${TX_CREATED_KEY_SUBSTRING}-${txId}`;
};

const generateTxReceiptKey = (txId: string) => {
return `${TX_RECEIPT_KEY_SUBSTRING}-${txId}`;
};