Skip to content

Commit

Permalink
Remove v3 relayer refund leaf
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholaspai committed Feb 12, 2024
1 parent 15967b1 commit 36e2b5e
Show file tree
Hide file tree
Showing 6 changed files with 10 additions and 206 deletions.
23 changes: 4 additions & 19 deletions src/clients/SpokePoolClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,11 @@ import {
V2DepositWithBlock,
V2Fill,
V2FillWithBlock,
V2RelayerRefundExecutionWithBlock,
V2SpeedUp,
V3DepositWithBlock,
V3FillWithBlock,
V3FundsDepositedEvent,
V3RelayData,
V3RelayerRefundExecutionWithBlock,
V3SpeedUp,
} from "../interfaces";
import { SpokePool } from "../typechain";
Expand Down Expand Up @@ -892,23 +890,10 @@ export class SpokePoolClient extends BaseAbstractClient {
}
}

// Exact sequencing of relayer refund executions doesn't seem to be important. There are very few consumers of
// these objects, and they are typically used to search for a specific rootBundleId & leafId pair. Therefore,
// relayerRefundExecutions don't need exact sequencing and parsing of v2/v3 events can occur without sorting.
if (eventsToQuery.includes("ExecutedRelayerRefundRoot") || eventsToQuery.includes("ExecutedV3RelayerRefundRoot")) {
const v2RefundEvents = queryResults[eventsToQuery.indexOf("ExecutedRelayerRefundRoot")] ?? [];
for (const event of v2RefundEvents) {
const executedRefund = spreadEventWithBlockNumber(event) as V2RelayerRefundExecutionWithBlock;
executedRefund.l2TokenAddress = SpokePoolClient.getExecutedRefundLeafL2Token(
executedRefund.chainId,
executedRefund.l2TokenAddress
);
this.relayerRefundExecutions.push(executedRefund);
}

const v3RefundEvents = queryResults[eventsToQuery.indexOf("ExecutedV3RelayerRefundRoot")] ?? [];
for (const event of v3RefundEvents) {
const executedRefund = spreadEventWithBlockNumber(event) as V3RelayerRefundExecutionWithBlock;
if (eventsToQuery.includes("ExecutedRelayerRefundRoot")) {
const refundEvents = queryResults[eventsToQuery.indexOf("ExecutedRelayerRefundRoot")] ?? [];
for (const event of refundEvents) {
const executedRefund = spreadEventWithBlockNumber(event) as RelayerRefundExecutionWithBlock;
executedRefund.l2TokenAddress = SpokePoolClient.getExecutedRefundLeafL2Token(
executedRefund.chainId,
executedRefund.l2TokenAddress
Expand Down
34 changes: 2 additions & 32 deletions src/clients/mocks/MockSpokePoolClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@ import {
FillType,
FundsDepositedEvent,
RealizedLpFee,
RelayerRefundExecutionWithBlock,
SlowFillRequestWithBlock,
V2DepositWithBlock,
V2FillWithBlock,
V2RelayerRefundExecutionWithBlock,
V2SpeedUp,
V3DepositWithBlock,
V3Fill,
V3FillWithBlock,
V3RelayerRefundExecutionWithBlock,
V3SlowFillLeaf,
V3SpeedUp,
} from "../../interfaces";
Expand Down Expand Up @@ -403,7 +402,7 @@ export class MockSpokePoolClient extends SpokePoolClient {
return this.fillV3Relay(fill as V3FillWithBlock);
}

executeRelayerRefundLeaf(refund: V2RelayerRefundExecutionWithBlock): Event {
executeRelayerRefundLeaf(refund: RelayerRefundExecutionWithBlock): Event {
const event = "ExecutedRelayerRefundRoot";

const chainId = refund.chainId ?? this.chainId;
Expand All @@ -430,35 +429,6 @@ export class MockSpokePoolClient extends SpokePoolClient {
});
}

executeV3RelayerRefundLeaf(refund: V3RelayerRefundExecutionWithBlock): Event {
const event = "ExecutedV3RelayerRefundRoot";

const chainId = refund.chainId ?? this.chainId;
assert(chainId === this.chainId);

const { rootBundleId, leafId } = refund;
const topics = [chainId, rootBundleId, leafId];
const args = {
chainId,
rootBundleId,
leafId,
amountToReturn: refund.amountToReturn,
l2TokenAddress: refund.l2TokenAddress,
refundAddresses: refund.refundAddresses,
refundAmounts: refund.refundAmounts,
fillsRefundedRoot: refund.fillsRefundedRoot,
fillsRefundedHash: refund.fillsRefundedHash,
};

return this.eventManager.generateEvent({
event,
address: this.spokePool.address,
topics: topics.map((topic) => topic.toString()),
args,
blockNumber: refund.blockNumber,
});
}

setEnableRoute(
originToken: string,
destinationChainId: number,
Expand Down
11 changes: 1 addition & 10 deletions src/interfaces/HubPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,14 @@ export interface PoolRebalanceLeaf {
l1Tokens: string[];
}

export interface RelayerRefundLeafCommon {
export interface RelayerRefundLeaf {
amountToReturn: BigNumber;
chainId: number;
refundAmounts: BigNumber[];
leafId: number;
l2TokenAddress: string;
refundAddresses: string[];
}

export interface V2RelayerRefundLeaf extends RelayerRefundLeafCommon {}
export interface V3RelayerRefundLeaf extends RelayerRefundLeafCommon {
fillsRefundedRoot: string;
fillsRefundedHash: string;
}

export type RelayerRefundLeaf = V2RelayerRefundLeaf;

export interface ProposedRootBundle extends SortableEvent {
challengePeriodEndTimestamp: number;
poolRebalanceLeafCount: number;
Expand Down
14 changes: 3 additions & 11 deletions src/interfaces/SpokePool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { BigNumber } from "ethers";
import { SortableEvent } from "./Common";
import { FilledRelayEvent, FilledV3RelayEvent, FundsDepositedEvent, V3FundsDepositedEvent } from "../typechain";
import { SpokePoolClient } from "../clients";
import { V2RelayerRefundLeaf, V3RelayerRefundLeaf } from "./HubPool";
import { RelayerRefundLeaf } from "./HubPool";

export type { FilledRelayEvent, FilledV3RelayEvent, FundsDepositedEvent, V3FundsDepositedEvent };

Expand Down Expand Up @@ -159,19 +159,11 @@ export interface RootBundleRelay {

export interface RootBundleRelayWithBlock extends RootBundleRelay, SortableEvent {}

export interface V2RelayerRefundExecution extends V2RelayerRefundLeaf {
export interface RelayerRefundExecution extends RelayerRefundLeaf {
rootBundleId: number;
}

export interface V3RelayerRefundExecution extends V3RelayerRefundLeaf {
rootBundleId: number;
}

export interface V2RelayerRefundExecutionWithBlock extends V2RelayerRefundExecution, SortableEvent {}
export interface V3RelayerRefundExecutionWithBlock extends V3RelayerRefundExecution, SortableEvent {}

export type RelayerRefundExecution = V2RelayerRefundExecution | V3RelayerRefundExecution;
export type RelayerRefundExecutionWithBlock = V2RelayerRefundExecutionWithBlock | V3RelayerRefundExecutionWithBlock;
export interface RelayerRefundExecutionWithBlock extends RelayerRefundExecution, SortableEvent {}

export interface UnfilledDeposit {
deposit: V2Deposit;
Expand Down
34 changes: 0 additions & 34 deletions src/utils/V3Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@ import {
V2Deposit,
V2Fill,
V2RelayData,
V2RelayerRefundExecution,
V2RelayerRefundLeaf,
V2SlowFillLeaf,
V2SpeedUp,
V3Deposit,
V3Fill,
V3RelayData,
V3RelayerRefundExecution,
V3RelayerRefundLeaf,
V3SlowFillLeaf,
V3SpeedUp,
} from "../interfaces";
Expand Down Expand Up @@ -108,36 +104,6 @@ export function isV3SlowFillLeaf<T extends MinV3SlowFillLeaf, U extends MinV2Slo
return unsafeIsType<T, U>(slowFillLeaf, "updatedOutputAmount");
}

type MinV2RelayerRefundLeaf = Pick<V2RelayerRefundLeaf, "amountToReturn">;
type MinV3RelayerRefundLeaf = Pick<V3RelayerRefundLeaf, "fillsRefundedRoot" | "fillsRefundedHash">;
export function isV2RelayerRefundLeaf<T extends MinV2RelayerRefundLeaf, U extends MinV3RelayerRefundLeaf>(
leaf: T | U
): leaf is T {
return unsafeIsType<T, U>(leaf, "amountToReturn") && !isV3RelayerRefundLeaf(leaf);
}

export function isV3RelayerRefundLeaf<T extends MinV3RelayerRefundLeaf, U extends MinV2RelayerRefundLeaf>(
leaf: T | U
): leaf is T {
return unsafeIsType<T, U>(leaf, "fillsRefundedRoot");
}

type MinV2RelayerRefundExecution = Pick<V2RelayerRefundExecution, "amountToReturn">;
type MinV3RelayerRefundExecution = Pick<V3RelayerRefundExecution, "fillsRefundedRoot" | "fillsRefundedHash">;
export function isV2RelayerRefundExecution<
T extends MinV2RelayerRefundExecution,
U extends MinV3RelayerRefundExecution,
>(leaf: T | U): leaf is T {
return unsafeIsType<T, U>(leaf, "amountToReturn") && !isV3RelayerRefundExecution(leaf);
}

export function isV3RelayerRefundExecution<
T extends MinV3RelayerRefundExecution,
U extends MinV2RelayerRefundExecution,
>(leaf: T | U): leaf is T {
return unsafeIsType<T, U>(leaf, "fillsRefundedRoot");
}

export function getDepositInputToken<T extends MinV2Deposit, U extends MinV3Deposit>(deposit: T | U): string {
return isV2Deposit(deposit) ? deposit.originToken : deposit.inputToken;
}
Expand Down
100 changes: 0 additions & 100 deletions test/SpokePoolClient.v3Events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,9 @@ import {
SlowFillRequestWithBlock,
V2DepositWithBlock,
V2FillWithBlock,
V2RelayerRefundExecution,
V2RelayerRefundExecutionWithBlock,
V3DepositWithBlock,
V3FillWithBlock,
V3RelayData,
V3RelayerRefundExecution,
V3RelayerRefundExecutionWithBlock,
} from "../src/interfaces";
import { EMPTY_MESSAGE, ZERO_ADDRESS } from "../src/constants";
import {
Expand All @@ -28,11 +24,9 @@ import {
isV2Fill,
isV3Deposit,
isV3Fill,
isV3RelayerRefundExecution,
randomAddress,
} from "../src/utils";
import {
BigNumber,
createSpyLogger,
fillFromDeposit,
deployConfigStore,
Expand All @@ -41,7 +35,6 @@ import {
ethers,
modifyRelayHelper,
SignerWithAddress,
toBNWei,
} from "./utils";

type EventSearchConfig = sdkUtils.EventSearchConfig;
Expand All @@ -51,7 +44,6 @@ describe("SpokePoolClient: Event Filtering", function () {
const requestedSpeedUpEvents = ["RequestedSpeedUpDeposit", "RequestedSpeedUpV3Deposit"];
const slowFillRequestedEvents = ["RequestedV3SlowFill"];
const filledRelayEvents = ["FilledRelay", "FilledV3Relay"];
const executedRelayerRefundEvents = ["ExecutedRelayerRefundRoot", "ExecutedV3RelayerRefundRoot"];

let owner: SignerWithAddress, depositor: SignerWithAddress;
let chainIds: number[];
Expand Down Expand Up @@ -382,96 +374,4 @@ describe("SpokePoolClient: Event Filtering", function () {
expect(outputToken).to.equal(expectedOutputToken);
});
});

it("Correctly retrieves ExecutedV3RelayerRefundRoot events", async function () {
const randomNumber = (max = 1_000_000): number => Math.round(Math.random() * max);
const randomAmount = (max = 1_000_000): BigNumber => toBNWei(randomNumber(max).toPrecision(6));

const _generateRelayerRefund = (
chainId: number,
rootBundleId: number,
leafId: number,
nRefunds: number
): V2RelayerRefundExecution => {
const refundAmounts: BigNumber[] = [];
const refundAddresses: string[] = [];
for (let i = 0; i < nRefunds; ++i) {
refundAmounts.push(randomAmount());
refundAddresses.push(randomAddress());
}

return {
chainId,
rootBundleId,
leafId,
amountToReturn: randomAmount(),
l2TokenAddress: randomAddress(),
refundAmounts,
refundAddresses,
};
};

const generateV2RelayerRefund = (
spokePoolClient: MockSpokePoolClient,
rootBundleId: number,
leafId: number,
nRefunds: number
): Event => {
const refund = _generateRelayerRefund(spokePoolClient.chainId, rootBundleId, leafId, nRefunds);
return spokePoolClient.executeRelayerRefundLeaf(refund as V2RelayerRefundExecutionWithBlock);
};

const generateV3RelayerRefund = (
spokePoolClient: MockSpokePoolClient,
rootBundleId: number,
leafId: number,
nRefunds: number
): Event => {
const refund: V3RelayerRefundExecution = {
..._generateRelayerRefund(spokePoolClient.chainId, rootBundleId, leafId, nRefunds),
// The following fields are not representative of onchain events, but should be unique for test.
fillsRefundedRoot: randomAmount().toString(),
fillsRefundedHash: randomAmount().toString(),
};
return spokePoolClient.executeV3RelayerRefundLeaf(refund as V3RelayerRefundExecutionWithBlock);
};

const refundEvents: Event[] = [];
const nLoops = 10;

// Enqueue a range of refund events.
for (let idx = 0; idx < nLoops; ++idx) {
refundEvents.push(generateV2RelayerRefund(destinationSpokePoolClient, idx, 0, idx));
refundEvents.push(generateV3RelayerRefund(destinationSpokePoolClient, idx, 1, idx));
}
expect(refundEvents.length).to.equal(nLoops * 2);

await destinationSpokePoolClient.update(executedRelayerRefundEvents);
const refunds = destinationSpokePoolClient.getRelayerRefundExecutions();

expect(refunds.length).to.equal(refundEvents.length);
expect(refunds.filter(isV3RelayerRefundExecution).length).to.equal(refundEvents.length / 2);

refundEvents.forEach((expectedEvent) => {
let refund = refunds.find(
({ rootBundleId, leafId }) =>
rootBundleId === expectedEvent.args?.rootBundleId && leafId === expectedEvent.args?.leafId
);
expect(refund).to.not.be.undefined;
refund = refund!;

expect(refund.blockNumber).to.equal(expectedEvent.blockNumber);
expect(refund.transactionHash).to.equal(expectedEvent.transactionHash);

expect(refund.rootBundleId).to.equal(expectedEvent.args!.rootBundleId);
expect(refund.leafId).to.equal(expectedEvent.args!.leafId);
expect(refund.l2TokenAddress).to.equal(expectedEvent.args!.l2TokenAddress);
expect(refund.amountToReturn.eq(expectedEvent.args!.amountToReturn)).to.be.true;

if (isV3RelayerRefundExecution(refund)) {
expect(refund.fillsRefundedRoot).to.equal(expectedEvent.args!.fillsRefundedRoot);
expect(refund.fillsRefundedHash).to.equal(expectedEvent.args!.fillsRefundedHash);
}
});
});
});

0 comments on commit 36e2b5e

Please sign in to comment.