Skip to content

improve: Create SVM relayDataHash with messageHash instead of message #1168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@across-protocol/sdk",
"author": "UMA Team",
"version": "4.3.37",
"version": "4.3.38",
"license": "AGPL-3.0",
"homepage": "https://docs.across.to/reference/sdk",
"files": [
Expand Down
9 changes: 5 additions & 4 deletions src/arch/evm/SpokeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
FillStatus,
FillWithBlock,
RelayData,
RelayDataWithMessageHash,
RelayExecutionEventInfo,
SpeedUpCommon,
} from "../../interfaces";
Expand Down Expand Up @@ -190,7 +191,7 @@ export async function findDepositBlock(
*/
export async function relayFillStatus(
spokePool: Contract,
relayData: RelayData,
relayData: RelayDataWithMessageHash,
blockTag: BlockTag = "latest",
destinationChainId?: number
): Promise<FillStatus> {
Expand All @@ -213,7 +214,7 @@ export async function relayFillStatus(

export async function fillStatusArray(
spokePool: Contract,
relayData: RelayData[],
relayData: RelayDataWithMessageHash[],
blockTag: BlockTag = "latest"
): Promise<(FillStatus | undefined)[]> {
const fillStatuses = "fillStatuses";
Expand Down Expand Up @@ -258,7 +259,7 @@ export async function fillStatusArray(
*/
export async function findFillBlock(
spokePool: Contract,
relayData: RelayData,
relayData: RelayDataWithMessageHash,
lowBlockNumber: number,
highBlockNumber?: number
): Promise<number | undefined> {
Expand Down Expand Up @@ -313,7 +314,7 @@ export async function findFillBlock(

export async function findFillEvent(
spokePool: Contract,
relayData: RelayData,
relayData: RelayDataWithMessageHash,
lowBlockNumber: number,
highBlockNumber?: number
): Promise<FillWithBlock | undefined> {
Expand Down
31 changes: 20 additions & 11 deletions src/arch/svm/SpokeUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MessageTransmitterClient, SvmSpokeClient, TokenMessengerMinterClient } from "@across-protocol/contracts";
import { decodeFillStatusAccount, fetchState } from "@across-protocol/contracts/dist/src/svm/clients/SvmSpoke";
import { decodeMessageHeader, hashNonEmptyMessage } from "@across-protocol/contracts/dist/src/svm/web3-v1";
import { decodeMessageHeader } from "@across-protocol/contracts/dist/src/svm/web3-v1";
import { intToU8Array32 } from "@across-protocol/contracts/dist/src/svm/web3-v1/conversionUtils";
import { SYSTEM_PROGRAM_ADDRESS } from "@solana-program/system";
import {
Expand Down Expand Up @@ -37,7 +37,14 @@ import assert from "assert";
import { arrayify, hexZeroPad, hexlify } from "ethers/lib/utils";
import { Logger } from "winston";
import { CHAIN_IDs, TOKEN_SYMBOLS_MAP } from "../../constants";
import { DepositWithBlock, FillStatus, FillWithBlock, RelayData, RelayExecutionEventInfo } from "../../interfaces";
import {
DepositWithBlock,
FillStatus,
FillWithBlock,
RelayData,
RelayDataWithMessageHash,
RelayExecutionEventInfo,
} from "../../interfaces";
import {
BigNumber,
EvmAddress,
Expand Down Expand Up @@ -83,7 +90,7 @@ import {
*/
export const SLOT_DURATION_MS = 400;

type ProtoFill = Omit<RelayData, "recipient" | "outputToken"> & {
type ProtoFill = Omit<RelayDataWithMessageHash, "recipient" | "outputToken"> & {
destinationChainId: number;
recipient: SvmAddress;
outputToken: SvmAddress;
Expand Down Expand Up @@ -261,7 +268,7 @@ export async function findDeposit(
*/
export async function relayFillStatus(
programId: Address,
relayData: RelayData,
relayData: RelayDataWithMessageHash,
destinationChainId: number,
svmEventsClient: SvmCpiEventsClient,
atHeight?: number
Expand Down Expand Up @@ -311,7 +318,7 @@ export async function relayFillStatus(
*/
export async function fillStatusArray(
programId: Address,
relayData: RelayData[],
relayData: RelayDataWithMessageHash[],
destinationChainId: number,
svmEventsClient: SvmCpiEventsClient,
atHeight?: number,
Expand Down Expand Up @@ -394,7 +401,7 @@ export async function fillStatusArray(
* @returns The fill event with block info, or `undefined` if not found.
*/
export async function findFillEvent(
relayData: RelayData,
relayData: RelayDataWithMessageHash,
destinationChainId: number,
svmEventsClient: SvmCpiEventsClient,
fromSlot: number,
Expand Down Expand Up @@ -566,7 +573,7 @@ export function createTokenAccountsInstruction(
export async function getFillRelayTx(
spokePoolAddr: SvmAddress,
solanaClient: SVMProvider,
relayData: Omit<RelayData, "recipient" | "outputToken"> & {
relayData: Omit<RelayDataWithMessageHash, "recipient" | "outputToken"> & {
destinationChainId: number;
recipient: SvmAddress;
outputToken: SvmAddress;
Expand All @@ -583,6 +590,7 @@ export async function getFillRelayTx(
);

const program = toAddress(spokePoolAddr);

const _relayDataHash = getRelayDataHash(relayData, destinationChainId);
const relayDataHash = new Uint8Array(Buffer.from(_relayDataHash.slice(2), "hex"));

Expand Down Expand Up @@ -770,7 +778,7 @@ export const createRequestSlowFillInstruction = async (
export async function getSlowFillRequestTx(
spokePoolAddr: SvmAddress,
solanaClient: SVMProvider,
relayData: Omit<RelayData, "recipient" | "outputToken"> & {
relayData: Omit<RelayDataWithMessageHash, "recipient" | "outputToken"> & {
destinationChainId: number;
recipient: SvmAddress;
outputToken: SvmAddress;
Expand All @@ -792,6 +800,7 @@ export async function getSlowFillRequestTx(
} = relayData;

const program = toAddress(spokePoolAddr);

const relayDataHash = getRelayDataHash(relayData, destinationChainId);

const [state, fillStatus, eventAuthority] = await Promise.all([
Expand Down Expand Up @@ -881,12 +890,12 @@ export async function getAssociatedTokenAddress(
return associatedToken;
}

export function getRelayDataHash(relayData: RelayData, destinationChainId: number): string {
export function getRelayDataHash(relayData: RelayDataWithMessageHash, destinationChainId: number): string {
const addressEncoder = getAddressEncoder();
const uint64Encoder = getU64Encoder();
const uint32Encoder = getU32Encoder();

assert(relayData.message.startsWith("0x"), "Message must be a hex string");
assert(relayData.messageHash.startsWith("0x"), "Message hash must be a hex string");
const encodeAddress = (data: SdkAddress) => Uint8Array.from(addressEncoder.encode(toAddress(data)));

const contentToHash = Buffer.concat([
Expand All @@ -901,7 +910,7 @@ export function getRelayDataHash(relayData: RelayData, destinationChainId: numbe
arrayify(hexZeroPad(hexlify(relayData.depositId), 32)),
Uint8Array.from(uint32Encoder.encode(relayData.fillDeadline)),
Uint8Array.from(uint32Encoder.encode(relayData.exclusivityDeadline)),
hashNonEmptyMessage(Buffer.from(arrayify(relayData.message))),
Uint8Array.from(Buffer.from(relayData.messageHash.slice(2), "hex")),
Uint8Array.from(uint64Encoder.encode(BigInt(destinationChainId))),
]);
return keccak256(contentToHash);
Expand Down
4 changes: 2 additions & 2 deletions src/arch/svm/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
import assert from "assert";
import bs58 from "bs58";
import { ethers } from "ethers";
import { FillType, RelayData } from "../../interfaces";
import { FillType, RelayDataWithMessageHash } from "../../interfaces";
import { BigNumber, Address as SdkAddress, biMin, getRelayDataHash, isDefined, isUint8Array } from "../../utils";
import { getTimestampForSlot } from "./SpokeUtils";
import { AttestedCCTPMessage, EventName, SVMEventNames, SVMProvider } from "./types";
Expand Down Expand Up @@ -264,7 +264,7 @@ export async function getStatePda(programId: Address): Promise<Address> {
*/
export async function getFillStatusPda(
programId: Address,
relayData: RelayData,
relayData: RelayDataWithMessageHash,
destinationChainId: number
): Promise<Address> {
const relayDataHash = getRelayDataHash(relayData, destinationChainId);
Expand Down
9 changes: 6 additions & 3 deletions src/clients/SpokePoolClient/EVMSpokePoolClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
relayFillStatus,
getTimestampForBlock as _getTimestampForBlock,
} from "../../arch/evm";
import { DepositWithBlock, FillStatus, RelayData } from "../../interfaces";
import { DepositWithBlock, FillStatus, RelayDataWithMessageHash } from "../../interfaces";
import {
BigNumber,
DepositSearchResult,
Expand Down Expand Up @@ -48,11 +48,14 @@ export class EVMSpokePoolClient extends SpokePoolClient {
this.spokePoolAddress = EvmAddress.from(spokePool.address);
}

public override relayFillStatus(relayData: RelayData, atHeight?: number): Promise<FillStatus> {
public override relayFillStatus(relayData: RelayDataWithMessageHash, atHeight?: number): Promise<FillStatus> {
return relayFillStatus(this.spokePool, relayData, atHeight, this.chainId);
}

public override fillStatusArray(relayData: RelayData[], atHeight?: number): Promise<(FillStatus | undefined)[]> {
public override fillStatusArray(
relayData: RelayDataWithMessageHash[],
atHeight?: number
): Promise<(FillStatus | undefined)[]> {
return fillStatusArray(this.spokePool, relayData, atHeight);
}

Expand Down
6 changes: 3 additions & 3 deletions src/clients/SpokePoolClient/SVMSpokePoolClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
relayFillStatus,
fillStatusArray,
} from "../../arch/svm";
import { FillStatus, RelayData, SortableEvent } from "../../interfaces";
import { FillStatus, RelayDataWithMessageHash, SortableEvent } from "../../interfaces";
import {
BigNumber,
DepositSearchResult,
Expand Down Expand Up @@ -243,7 +243,7 @@ export class SVMSpokePoolClient extends SpokePoolClient {
/**
* Retrieves the fill status for a given relay data from the SVM chain.
*/
public override relayFillStatus(relayData: RelayData, atHeight?: number): Promise<FillStatus> {
public override relayFillStatus(relayData: RelayDataWithMessageHash, atHeight?: number): Promise<FillStatus> {
return relayFillStatus(this.programId, relayData, this.chainId, this.svmEventsClient, atHeight);
}

Expand All @@ -254,7 +254,7 @@ export class SVMSpokePoolClient extends SpokePoolClient {
* @returns The fill status for each of the given relay data.
*/
public fillStatusArray(
relayData: RelayData[],
relayData: RelayDataWithMessageHash[],
atHeight?: number,
destinationChainId?: number
): Promise<(FillStatus | undefined)[]> {
Expand Down
8 changes: 6 additions & 2 deletions src/clients/SpokePoolClient/SpokePoolClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
SpeedUpWithBlock,
TokensBridged,
RelayExecutionEventInfo,
RelayDataWithMessageHash,
} from "../../interfaces";
import { BaseAbstractClient, UpdateFailureReason } from "../BaseAbstractClient";
import { AcrossConfigStoreClient } from "../AcrossConfigStoreClient";
Expand Down Expand Up @@ -980,13 +981,16 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
* @param atHeight The height at which to query the fill status.
* @returns The fill status for the given relay data.
*/
public abstract relayFillStatus(relayData: RelayData, atHeight?: number): Promise<FillStatus>;
public abstract relayFillStatus(relayData: RelayDataWithMessageHash, atHeight?: number): Promise<FillStatus>;

/**
* Retrieves the fill status for an array of given relay data.
* @param relayData The array relay data to retrieve the fill status for.
* @param atHeight The height at which to query the fill status.
* @returns The fill status for each of the given relay data.
*/
public abstract fillStatusArray(relayData: RelayData[], atHeight?: number): Promise<(FillStatus | undefined)[]>;
public abstract fillStatusArray(
relayData: RelayDataWithMessageHash[],
atHeight?: number
): Promise<(FillStatus | undefined)[]>;
}
4 changes: 4 additions & 0 deletions src/interfaces/SpokePool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { SpokePoolClient } from "../clients";
import { BigNumber, Address, EvmAddress } from "../utils";
import { RelayerRefundLeaf } from "./HubPool";

export interface RelayDataWithMessageHash extends RelayData {
messageHash: string;
}

export interface RelayData {
originChainId: number;
depositor: Address;
Expand Down
6 changes: 3 additions & 3 deletions src/relayFeeCalculator/chain-queries/baseQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { isL2Provider as isOptimismL2Provider } from "@eth-optimism/sdk/dist/l2-
import { PopulatedTransaction, providers, VoidSigner } from "ethers";
import { Coingecko } from "../../coingecko";
import { CHAIN_IDs } from "../../constants";
import { RelayData } from "../../interfaces";
import { RelayData, RelayDataWithMessageHash } from "../../interfaces";
import { SpokePool, SpokePool__factory } from "../../typechain";
import { populateV3Relay } from "../../arch/evm";
import {
Expand Down Expand Up @@ -72,7 +72,7 @@ export class QueryBase implements QueryInterface {
* @returns The gas estimate for this function call (multiplied with the optional buffer).
*/
async getGasCosts(
relayData: RelayData & { destinationChainId: number },
relayData: RelayDataWithMessageHash & { destinationChainId: number },
relayer = getDefaultRelayer(relayData.destinationChainId),
options: Partial<{
gasPrice: BigNumberish;
Expand Down Expand Up @@ -144,7 +144,7 @@ export class QueryBase implements QueryInterface {
* @returns Estimated gas cost based on ethers.VoidSigner's gas estimation
*/
async getNativeGasCost(
relayData: RelayData & { destinationChainId: number },
relayData: RelayDataWithMessageHash & { destinationChainId: number },
relayer = getDefaultRelayer(relayData.destinationChainId)
): Promise<BigNumber> {
const { recipient, outputToken, exclusiveRelayer } = relayData;
Expand Down
8 changes: 4 additions & 4 deletions src/relayFeeCalculator/chain-queries/svmQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { SVMProvider, SolanaVoidSigner, getFillRelayTx } from "../../arch/svm";
import { Coingecko } from "../../coingecko";
import { CHAIN_IDs } from "../../constants";
import { getGasPriceEstimate } from "../../gasPriceOracle";
import { RelayData } from "../../interfaces";
import { RelayDataWithMessageHash } from "../../interfaces";
import { Address, BigNumber, BigNumberish, SvmAddress, TransactionCostEstimate, toBN } from "../../utils";
import { Logger, QueryInterface, getDefaultRelayer } from "../relayFeeCalculator";
import { SymbolMappingType } from "./";
Expand Down Expand Up @@ -53,7 +53,7 @@ export class SvmQuery implements QueryInterface {
* @returns The gas estimate for this function call (multiplied with the optional buffer).
*/
async getGasCosts(
relayData: RelayData & { destinationChainId: number },
relayData: RelayDataWithMessageHash & { destinationChainId: number },
relayer = getDefaultRelayer(relayData.destinationChainId),
options: Partial<{
gasPrice: BigNumberish;
Expand Down Expand Up @@ -105,7 +105,7 @@ export class SvmQuery implements QueryInterface {
* @returns Estimated gas cost in compute units
*/
async getNativeGasCost(
deposit: RelayData & { destinationChainId: number },
deposit: RelayDataWithMessageHash & { destinationChainId: number },
relayer = getDefaultRelayer(deposit.destinationChainId)
): Promise<BigNumber> {
const { destinationChainId, recipient, outputToken, exclusiveRelayer } = deposit;
Expand All @@ -131,7 +131,7 @@ export class SvmQuery implements QueryInterface {
* @returns FillRelay transaction
*/
protected async getFillRelayTx(
relayData: Omit<RelayData, "recipient" | "outputToken"> & {
relayData: Omit<RelayDataWithMessageHash, "recipient" | "outputToken"> & {
destinationChainId: number;
recipient: SvmAddress;
outputToken: SvmAddress;
Expand Down
13 changes: 8 additions & 5 deletions src/relayFeeCalculator/relayFeeCalculator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
DEFAULT_SIMULATED_RELAYER_ADDRESS_SVM,
TOKEN_SYMBOLS_MAP,
} from "../constants";
import { RelayData } from "../interfaces";
import { RelayDataWithMessageHash } from "../interfaces";
import {
BigNumber,
BigNumberish,
Expand Down Expand Up @@ -33,7 +33,7 @@ import {
// This needs to be implemented for every chain and passed into RelayFeeCalculator
export interface QueryInterface {
getGasCosts: (
deposit: RelayData & { destinationChainId: number },
deposit: RelayDataWithMessageHash & { destinationChainId: number },
relayer: Address,
options?: Partial<{
gasPrice: BigNumberish;
Expand All @@ -45,7 +45,10 @@ export interface QueryInterface {
}>
) => Promise<TransactionCostEstimate>;
getTokenPrice: (tokenSymbol: string) => Promise<number>;
getNativeGasCost: (deposit: RelayData & { destinationChainId: number }, relayer: Address) => Promise<BigNumber>;
getNativeGasCost: (
deposit: RelayDataWithMessageHash & { destinationChainId: number },
relayer: Address
) => Promise<BigNumber>;
}

export const expectedCapitalCostsKeys = ["lowerBound", "upperBound", "cutoff", "decimals"];
Expand Down Expand Up @@ -254,7 +257,7 @@ export class RelayFeeCalculator {
* the correct parameters to see a full fill.
*/
async gasFeePercent(
deposit: RelayData & { destinationChainId: number },
deposit: RelayDataWithMessageHash & { destinationChainId: number },
outputAmount: BigNumberish,
simulateZeroFill = false,
relayerAddress = getDefaultRelayer(deposit.destinationChainId),
Expand Down Expand Up @@ -493,7 +496,7 @@ export class RelayFeeCalculator {
* @returns A resulting `RelayerFeeDetails` object
*/
async relayerFeeDetails(
deposit: RelayData & { destinationChainId: number },
deposit: RelayDataWithMessageHash & { destinationChainId: number },
outputAmount?: BigNumberish,
simulateZeroFill = false,
relayerAddress = getDefaultRelayer(deposit.destinationChainId),
Expand Down
Loading