Skip to content

Commit

Permalink
fix: custom rpc provider is not used for tx recovery (#305)
Browse files Browse the repository at this point in the history
* chore: change the rpc endpoint for ethereum-2

* chore: allow passing custom rpc endpoint

* chore: fix tests

* fix: not utilized given rpc provider

* chore: update changelog

---------

Co-authored-by: Canh Trinh <[email protected]>
  • Loading branch information
npty and canhtrinh authored Mar 7, 2024
1 parent 80f0e0d commit 0cd1a9e
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 17 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [0.15.0] - 2024-FEBRUARY-21
## [0.15.0] - 2024-MARCH-X

- Improved the accuracy of `estimateGasFee` function by incorporating L1 rollup fee for destination L2 chain.
- Fix for `manualRelayToDestinationChain` to respect optional `provider` parameter

Breaking Changes:

Expand Down
40 changes: 29 additions & 11 deletions src/libs/TransactionRecoveryApi/AxelarGMPRecoveryAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import s3 from "./constants/s3";
import { Coin, OfflineSigner } from "@cosmjs/proto-signing";
import { DeliverTxResponse, SigningStargateClient, StdFee } from "@cosmjs/stargate";
import { COSMOS_GAS_RECEIVER_OPTIONS } from "./constants/cosmosGasReceiverOptions";
import { JsonRpcProvider } from "@ethersproject/providers";
export const GMPErrorMap: Record<string, ApproveGatewayError> = {
[GMPStatus.CANNOT_FETCH_STATUS]: ApproveGatewayError.FETCHING_STATUS_FAILED,
[GMPStatus.DEST_EXECUTED]: ApproveGatewayError.ALREADY_EXECUTED,
Expand Down Expand Up @@ -175,14 +176,15 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi {
return getCommandId(destChainId, txHash, eventIndex, this.environment, rpcInfo);
}

public async doesTxMeetConfirmHt(chain: string, txHash: string) {
const confirmations = await this.getSigner(chain, { useWindowEthereum: false })
public async doesTxMeetConfirmHt(chain: string, txHash: string, provider?: JsonRpcProvider) {
const confirmations = await this.getSigner(chain, { useWindowEthereum: false, provider })
.provider.getTransactionReceipt(txHash)
.then(async (receipt?: TransactionReceipt) => {
if (!receipt) {
const gmpTx = await this.fetchGMPTransaction(txHash);
const currentBlock = await this.getSigner(chain, {
useWindowEthereum: false,
provider,
}).provider.getBlockNumber();
return currentBlock - gmpTx.call.blockNumber;
}
Expand Down Expand Up @@ -216,7 +218,8 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi {
srcChainId: string,
destChainId: string,
srcTxHash: string,
srcTxEventIndex: number | undefined
srcTxEventIndex: number | undefined,
evmWalletDetails?: EvmWalletDetails
): Promise<{
commandId: string;
eventResponse: EventResponse;
Expand All @@ -226,7 +229,7 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi {
}> {
const eventIndex =
srcTxEventIndex ??
(await this.getEventIndex(srcChainId, srcTxHash)
(await this.getEventIndex(srcChainId, srcTxHash, evmWalletDetails)
.then((index) => index as number)
.catch(() => -1));

Expand Down Expand Up @@ -292,7 +295,11 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi {
],
};
} else {
const isConfirmFinalized = await this.doesTxMeetConfirmHt(srcChain, txHash);
const isConfirmFinalized = await this.doesTxMeetConfirmHt(
srcChain,
txHash,
evmWalletDetails.provider
);
if (!isConfirmFinalized) {
const minConfirmLevel = await this.axelarQueryApi.getConfirmationHeight(srcChain);
return {
Expand All @@ -315,7 +322,13 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi {
};
}

const updatedEvent = await this.getEvmEvent(srcChain, destChain, txHash, txEventIndex);
const updatedEvent = await this.getEvmEvent(
srcChain,
destChain,
txHash,
txEventIndex,
evmWalletDetails
);

if (this.isEVMEventCompleted(updatedEvent?.eventResponse)) {
return {
Expand Down Expand Up @@ -460,7 +473,7 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi {
if (routeDir === RouteDir.COSMOS_TO_EVM) {
return this.recoverCosmosToEvmTx(txHash, _evmWalletDetails, messageId);
} else if (routeDir === RouteDir.EVM_TO_COSMOS) {
return this.recoverEvmToCosmosTx(srcChain, txHash, eventIndex);
return this.recoverEvmToCosmosTx(srcChain, txHash, eventIndex, _evmWalletDetails);
} else {
return this.recoverEvmToEvmTx(
srcChain,
Expand All @@ -486,10 +499,15 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi {
private async recoverEvmToCosmosTx(
srcChain: string,
txHash: string,
txEventIndex?: number | null
txEventIndex?: number | null,
evmWalletDetails?: EvmWalletDetails
) {
// Check if the tx is confirmed on the source chain
const isConfirmed = await this.doesTxMeetConfirmHt(srcChain, txHash);
const isConfirmed = await this.doesTxMeetConfirmHt(
srcChain,
txHash,
evmWalletDetails?.provider
);
if (!isConfirmed) {
const minConfirmLevel = await this.axelarQueryApi.getConfirmationHeight(srcChain);
return {
Expand Down Expand Up @@ -790,8 +808,8 @@ export class AxelarGMPRecoveryAPI extends AxelarRecoveryApi {
);
}

public async getEventIndex(chain: string, txHash: string) {
const signer = this.getSigner(chain, { useWindowEthereum: false });
public async getEventIndex(chain: string, txHash: string, evmWalletDetails?: EvmWalletDetails) {
const signer = this.getSigner(chain, evmWalletDetails || { useWindowEthereum: false });
const receipt = await signer.provider.getTransactionReceipt(txHash).catch(() => undefined);

if (!receipt) {
Expand Down
2 changes: 1 addition & 1 deletion src/libs/TransactionRecoveryApi/client/EVMClient/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default class EVMClient {
this.provider =
useWindowEthereum && typeof window !== "undefined" && window?.ethereum
? new ethers.providers.Web3Provider(window.ethereum, networkOptions)
: new ethers.providers.JsonRpcProvider(rpcUrl, networkOptions);
: provider || new ethers.providers.JsonRpcProvider(rpcUrl, networkOptions);
}
this.signer = privateKey
? new ethers.Wallet(privateKey).connect(this.provider)
Expand Down
2 changes: 1 addition & 1 deletion src/libs/TransactionRecoveryApi/constants/chain/testnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const rpcMap: Record<EvmChain | string, string> = {
[EvmChain.POLYGON]: "https://rpc-mumbai.maticvigil.com",
[EvmChain.MOONBEAM]: "https://rpc.api.moonbase.moonbeam.network",
[EvmChain.AVALANCHE]: "https://api.avax-test.network/ext/bc/C/rpc",
"ethereum-2": "https://eth-goerli.api.onfinality.io/public",
"ethereum-2": "https://ethereum-goerli-rpc.publicnode.com",
[EvmChain.AURORA]: "https://testnet.aurora.dev",
[EvmChain.BINANCE]: "https://data-seed-prebsc-1-s1.binance.org:8545",
[EvmChain.BNBCHAIN]: "https://data-seed-prebsc-1-s1.binance.org:8545",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ describe("AxelarGMPRecoveryAPI", () => {
undefined
);
expect(mockConfirmGatewayTx).toHaveBeenCalledWith(txHash, EvmChain.AVALANCHE);
expect(mockDoesTxMeetConfirmHt).toHaveBeenCalledWith(EvmChain.AVALANCHE, txHash);
expect(mockDoesTxMeetConfirmHt).toHaveBeenCalledWith(EvmChain.AVALANCHE, txHash, undefined);
expect(response).toBeDefined();
expect(response.infoLogs.length).toBeGreaterThan(0);
expect(response.eventResponse).toBeDefined();
Expand Down Expand Up @@ -165,7 +165,7 @@ describe("AxelarGMPRecoveryAPI", () => {
);

expect(mockConfirmGatewayTx).toBeCalledTimes(0);
expect(mockDoesTxMeetConfirmHt).toHaveBeenCalledWith(EvmChain.AVALANCHE, txHash);
expect(mockDoesTxMeetConfirmHt).toHaveBeenCalledWith(EvmChain.AVALANCHE, txHash, undefined);
expect(response.success).toBeFalsy();
expect(response.eventResponse).toBeDefined();
expect(response.commandId).toBe("commandId");
Expand Down Expand Up @@ -198,7 +198,7 @@ describe("AxelarGMPRecoveryAPI", () => {
);

expect(mockConfirmGatewayTx).toHaveBeenCalledWith(txHash, EvmChain.AVALANCHE);
expect(mockDoesTxMeetConfirmHt).toHaveBeenCalledWith(EvmChain.AVALANCHE, txHash);
expect(mockDoesTxMeetConfirmHt).toHaveBeenCalledWith(EvmChain.AVALANCHE, txHash, undefined);
expect(response.success).toBeFalsy();
expect(response.eventResponse).toBeDefined();
expect(response.commandId).toBe("commandId");
Expand Down

0 comments on commit 0cd1a9e

Please sign in to comment.