Skip to content

Commit

Permalink
refactor: Replace ethers Event with Log (#1830)
Browse files Browse the repository at this point in the history
This follows a similar change in the SDK, with the same motivations.
Reverting to Log instead of Event does not sacrifice any functionality
but makes it easier to migrate away from ethers v5.
  • Loading branch information
pxrl authored Sep 24, 2024
1 parent 9cf491b commit f749ca3
Show file tree
Hide file tree
Showing 19 changed files with 78 additions and 130 deletions.
5 changes: 4 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ module.exports = {
"error",
{
patterns: [{ group: ["@ethersproject/bignumber"], message: "Use 'src/utils/BNUtils' instead" }],
paths: [{ name: "ethers", importNames: ["BigNumber"], message: "Use 'src/utils/BNUtils' instead" }],
paths: [
{ name: "ethers", importNames: ["BigNumber"], message: "Use 'src/utils/BNUtils' instead" },
{ name: "ethers", importNames: ["Event"], message: "Use Log from 'src/interfaces/Common' instead" },
],
},
],
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"dependencies": {
"@across-protocol/constants": "^3.1.14",
"@across-protocol/contracts": "^3.0.10",
"@across-protocol/sdk": "^3.1.36",
"@across-protocol/sdk": "^3.2.0",
"@arbitrum/sdk": "^3.1.3",
"@consensys/linea-sdk": "^0.2.1",
"@defi-wonderland/smock": "^2.3.5",
Expand Down
6 changes: 3 additions & 3 deletions src/adapter/bridges/OpStackWethBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import {
paginatedEventQuery,
Signer,
Provider,
Event,
ZERO_ADDRESS,
TOKEN_SYMBOLS_MAP,
} from "../../utils";
import { CONTRACT_ADDRESSES } from "../../common";
import { Log } from "../../interfaces";
import { matchL2EthDepositAndWrapEvents, processEvent } from "../utils";
import { utils } from "@across-protocol/sdk";
import { BridgeTransactionDetails, BaseBridgeAdapter, BridgeEvents } from "./BaseBridgeAdapter";
Expand Down Expand Up @@ -67,7 +67,7 @@ export class OpStackWethBridge extends BaseBridgeAdapter {
});
}

private convertEventListToBridgeEvents(events: Event[]): BridgeEvents {
private convertEventListToBridgeEvents(events: Log[]): BridgeEvents {
return {
[this.resolveL2TokenAddress(TOKEN_SYMBOLS_MAP.WETH.addresses[this.hubChainId])]: events.map((event) =>
processEvent(event, "_amount", "_to", "_from")
Expand Down Expand Up @@ -176,7 +176,7 @@ export class OpStackWethBridge extends BaseBridgeAdapter {
fromAddress: string,
eventConfig: EventSearchConfig,
l2Weth = this.l2Weth
): Promise<Event[]> {
): Promise<Log[]> {
return paginatedEventQuery(l2Weth, l2Weth.filters.Deposit(fromAddress), eventConfig);
}
}
5 changes: 2 additions & 3 deletions src/adapter/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Event } from "ethers";
import { TOKEN_APPROVALS_TO_FIRST_ZERO } from "../common";
import {
BigNumber,
Expand All @@ -13,7 +12,7 @@ import {
winston,
} from "../utils";
import { BridgeEvent } from "./bridges/BaseBridgeAdapter";
import { SortableEvent } from "../interfaces";
import { Log, SortableEvent } from "../interfaces";
import { ExpandedERC20 } from "@across-protocol/contracts";

export {
Expand Down Expand Up @@ -55,7 +54,7 @@ export async function approveTokens(
return ["*Approval transactions:*", ...approvalMarkdwn].join("\n");
}

export function processEvent(event: Event, amountField: string, toField: string, fromField: string): BridgeEvent {
export function processEvent(event: Log, amountField: string, toField: string, fromField: string): BridgeEvent {
const eventSpread = spreadEventWithBlockNumber(event) as SortableEvent & {
amount: BigNumber;
to: string;
Expand Down
9 changes: 5 additions & 4 deletions src/clients/SpokePoolClient.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import assert from "assert";
import { ChildProcess, spawn } from "child_process";
import { Contract, Event } from "ethers";
import { Contract } from "ethers";
import { clients, utils as sdkUtils } from "@across-protocol/sdk";
import { Log } from "../interfaces";
import { CHAIN_MAX_BLOCK_LOOKBACK, RELAYER_DEFAULT_SPOKEPOOL_INDEXER } from "../common/Constants";
import { EventSearchConfig, getNetworkName, isDefined, MakeOptional, winston } from "../utils";
import { EventsAddedMessage, EventRemovedMessage } from "../utils/SuperstructUtils";
Expand Down Expand Up @@ -43,8 +44,8 @@ export class IndexedSpokePoolClient extends clients.SpokePoolClient {
private pendingCurrentTime: number;
private pendingOldestTime: number;

private pendingEvents: Event[][];
private pendingEventsRemoved: Event[];
private pendingEvents: Log[][];
private pendingEventsRemoved: Log[];

constructor(
readonly logger: winston.Logger,
Expand Down Expand Up @@ -194,7 +195,7 @@ export class IndexedSpokePoolClient extends clients.SpokePoolClient {
* @param event An Ethers event instance.
* @returns void
*/
protected removeEvent(event: Event): boolean {
protected removeEvent(event: Log): boolean {
let removed = false;
const eventIdx = this.queryableEventNames.indexOf(event.event);
const pendingEvents = this.pendingEvents[eventIdx];
Expand Down
7 changes: 3 additions & 4 deletions src/clients/TokenTransferClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ import {
winston,
assign,
ERC20,
Event,
Contract,
paginatedEventQuery,
spreadEventWithBlockNumber,
} from "../utils";
import { TokenTransfer, TransfersByChain } from "../interfaces";
import { Log, TokenTransfer, TransfersByChain } from "../interfaces";
import { Provider } from "@ethersproject/abstract-provider";

export class TokenTransferClient {
Expand Down Expand Up @@ -52,7 +51,7 @@ export class TokenTransferClient {
this.querySendAndReceiveEvents(tokenContract, monitoredAddress, searchConfigByChainIds[chainId])
)
);
const transferEventsPerToken: { [tokenAddress: string]: Event[][] } = Object.fromEntries(
const transferEventsPerToken: { [tokenAddress: string]: Log[][] } = Object.fromEntries(
transferEventsList.map((transferEvents, i) => [tokenContracts[i].address, transferEvents])
);

Expand Down Expand Up @@ -89,7 +88,7 @@ export class TokenTransferClient {
}

// Returns outgoing and incoming transfers for the specified tokenContract and address.
querySendAndReceiveEvents(tokenContract: Contract, address: string, config: EventSearchConfig): Promise<Event[][]> {
querySendAndReceiveEvents(tokenContract: Contract, address: string, config: EventSearchConfig): Promise<Log[][]> {
const eventFilters = [[address], [undefined, address]];
return Promise.all(
eventFilters.map((eventFilter) =>
Expand Down
5 changes: 2 additions & 3 deletions src/clients/bridges/op-stack/OpStackAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
BigNumberish,
bnZero,
TransactionResponse,
Event,
checkAddressChecksum,
spreadEventWithBlockNumber,
assign,
Expand All @@ -16,7 +15,7 @@ import {
} from "../../../utils";
import { SpokePoolClient } from "../../";
import { BaseAdapter } from "../";
import { SortableEvent, OutstandingTransfers } from "../../../interfaces";
import { Log, SortableEvent, OutstandingTransfers } from "../../../interfaces";
import { OpStackBridge } from "./OpStackBridgeInterface";
import { WethBridge } from "./WethBridge";
import { DefaultERC20Bridge } from "./DefaultErc20Bridge";
Expand Down Expand Up @@ -82,7 +81,7 @@ export class OpStackAdapter extends BaseAdapter {
const { l1SearchConfig, l2SearchConfig } = this.getUpdatedSearchConfigs();
const availableL1Tokens = this.filterSupportedTokens(l1Tokens);

const processEvent = (event: Event) => {
const processEvent = (event: Log) => {
const eventSpread = spreadEventWithBlockNumber(event) as SortableEvent & {
_amount: BigNumberish;
_to: string;
Expand Down
13 changes: 3 additions & 10 deletions src/clients/bridges/op-stack/OpStackBridgeInterface.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
import {
Contract,
BigNumber,
Event,
EventSearchConfig,
Signer,
Provider,
getTranslatedTokenAddress,
} from "../../../utils";
import { Log } from "../../../interfaces";
import { Contract, BigNumber, EventSearchConfig, Signer, Provider, getTranslatedTokenAddress } from "../../../utils";

export interface BridgeTransactionDetails {
readonly contract: Contract;
readonly method: string;
readonly args: unknown[];
}

export type OpStackEvents = { [l2Token: string]: Event[] };
export type OpStackEvents = { [l2Token: string]: Log[] };

export abstract class OpStackBridge {
constructor(
Expand Down
6 changes: 3 additions & 3 deletions src/clients/bridges/op-stack/WethBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import {
Signer,
Provider,
ZERO_ADDRESS,
Event,
TOKEN_SYMBOLS_MAP,
} from "../../../utils";
import { Log } from "../../../interfaces";
import { CONTRACT_ADDRESSES } from "../../../common";
import { matchL2EthDepositAndWrapEvents } from "../utils";
import { utils } from "@across-protocol/sdk";
Expand Down Expand Up @@ -81,7 +81,7 @@ export class WethBridge extends OpStackBridge {
};
}

private convertEventListToOpStackEvents(events: Event[]): OpStackEvents {
private convertEventListToOpStackEvents(events: Log[]): OpStackEvents {
return {
[this.resolveL2TokenAddress(TOKEN_SYMBOLS_MAP.WETH.addresses[this.hubChainId])]: events,
};
Expand Down Expand Up @@ -195,7 +195,7 @@ export class WethBridge extends OpStackBridge {
fromAddress: string,
eventConfig: EventSearchConfig,
l2Weth = this.l2Weth
): Promise<Event[]> {
): Promise<Log[]> {
return paginatedEventQuery(l2Weth, l2Weth.filters.Deposit(fromAddress), eventConfig);
}
}
7 changes: 4 additions & 3 deletions src/clients/bridges/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Contract, Event } from "ethers";
import { Contract } from "ethers";
import { Log } from "../../interfaces";
import { TOKEN_APPROVALS_TO_FIRST_ZERO } from "../../common";
import {
BigNumber,
Expand Down Expand Up @@ -32,9 +33,9 @@ import {
* @returns List of l2EthDepositEvents followed by a l2WrapEvent. None of the
* l2EthDepositEvents will match with the same l2WrapEvent.
*/
export function matchL2EthDepositAndWrapEvents(l2EthDepositEvents: Event[], _l2WrapEvents: Event[]): Event[] {
export function matchL2EthDepositAndWrapEvents(l2EthDepositEvents: Log[], _l2WrapEvents: Log[]): Log[] {
const l2WrapEvents = [..._l2WrapEvents]; // deep-copy because we're going to modify this in-place.
return l2EthDepositEvents.filter((l2EthDepositEvent: Event) => {
return l2EthDepositEvents.filter((l2EthDepositEvent) => {
// Search from left to right to find the first following wrap event.
const followingWrapEventIndex = l2WrapEvents.findIndex(
(wrapEvent) => wrapEvent.blockNumber >= l2EthDepositEvent.blockNumber
Expand Down
1 change: 1 addition & 0 deletions src/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface OutstandingTransfers {
}

// Common interfaces
export type Log = interfaces.Log;
export type SortableEvent = interfaces.SortableEvent;
export type BigNumberForToken = interfaces.BigNumberForToken;

Expand Down
20 changes: 10 additions & 10 deletions src/libexec/RelayerSpokePoolIndexer.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import assert from "assert";
import minimist from "minimist";
import { Contract, Event, EventFilter, providers as ethersProviders, utils as ethersUtils } from "ethers";
import { Contract, EventFilter, providers as ethersProviders, utils as ethersUtils } from "ethers";
import { utils as sdkUtils } from "@across-protocol/sdk";
import * as utils from "../../scripts/utils";
import { Log } from "../interfaces";
import { SpokePoolClientMessage } from "../clients";
import {
disconnectRedisClients,
Expand All @@ -18,7 +19,6 @@ import {
getRedisCache,
getWSProviders,
Logger,
mangleEventArgs,
paginatedEventQuery,
sortEventsAscending,
winston,
Expand Down Expand Up @@ -73,17 +73,17 @@ function getEventFilterArgs(relayer?: string): { [event: string]: string[] } {
* process (if defined).
* @param blockNumber Block number up to which the update applies.
* @param currentTime The SpokePool timestamp at blockNumber.
* @param events An array of Ethers Event objects to be submitted.
* @param events An array of Log objects to be submitted.
* @returns void
*/
function postEvents(blockNumber: number, currentTime: number, events: Event[]): void {
function postEvents(blockNumber: number, currentTime: number, events: Log[]): void {
if (!isDefined(process.send) || stop) {
return;
}

// Drop the array component of event.args and retain the named k/v pairs,
// otherwise stringification tends to retain only the array.
events = sortEventsAscending(events.map(mangleEventArgs));
events = sortEventsAscending(events);

const message: SpokePoolClientMessage = {
blockNumber,
Expand All @@ -97,16 +97,16 @@ function postEvents(blockNumber: number, currentTime: number, events: Event[]):

/**
* Given an event removal notification, post the message to the parent process.
* @param event Ethers Event instance.
* @param event Log instance.
* @returns void
*/
function removeEvent(event: Event): void {
function removeEvent(event: Log): void {
if (!isDefined(process.send) || stop) {
return;
}

const message: SpokePoolClientMessage = {
event: JSON.stringify(mangleEventArgs(event), sdkUtils.jsonReplacerWithBigNumbers),
event: JSON.stringify(event, sdkUtils.jsonReplacerWithBigNumbers),
};
process.send(JSON.stringify(message));
}
Expand All @@ -127,7 +127,7 @@ async function scrapeEvents(spokePool: Contract, eventName: string, opts: Scrape

let tStart: number, tStop: number;

const pollEvents = async (filter: EventFilter, searchConfig: EventSearchConfig): Promise<Event[]> => {
const pollEvents = async (filter: EventFilter, searchConfig: EventSearchConfig): Promise<Log[]> => {
tStart = performance.now();
const events = await paginatedEventQuery(spokePool, filter, searchConfig);
tStop = performance.now();
Expand Down Expand Up @@ -187,7 +187,7 @@ async function listen(
eventNames.forEach((eventName) => {
const filter = getEventFilter(spokePool, eventName, filterArgs[eventName]);
spokePool.connect(provider).on(filter, (...rawEvent) => {
const event = rawEvent.at(-1);
const event = sdkUtils.eventToLog(rawEvent.at(-1));
if (event.removed) {
eventMgr.remove(event, host);
// Notify the parent immediately in case the event was already submitted.
Expand Down
5 changes: 2 additions & 3 deletions src/scripts/validateRunningBalances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import {
config,
Logger,
toBN,
Event,
fromWei,
isDefined,
Contract,
Expand All @@ -56,7 +55,7 @@ import {
} from "../utils";
import { createDataworker } from "../dataworker";
import { getBlockForChain } from "../dataworker/DataworkerUtils";
import { ProposedRootBundle, SpokePoolClientsByChain, SlowFillLeaf } from "../interfaces";
import { Log, ProposedRootBundle, SpokePoolClientsByChain, SlowFillLeaf } from "../interfaces";
import { CONTRACT_ADDRESSES, constructSpokePoolClientsWithStartBlocks, updateSpokePoolClients } from "../common";
import { createConsoleTransport } from "@uma/logger";

Expand Down Expand Up @@ -212,7 +211,7 @@ export async function runScript(_logger: winston.Logger, baseSigner: Signer): Pr
`Looking for previous net send amount between blocks ${previousBundleEndBlockForChain.toNumber()} and ${bundleEndBlockForChain.toNumber()}`
);
const spokePoolAddress = spokePoolClients[leaf.chainId].spokePool.address;
let depositsToSpokePool: Event[];
let depositsToSpokePool: Log[];
// Handle the case that L1-->L2 deposits for some chains for ETH do not emit Transfer events, but
// emit other events instead. This is the case for OpStack chains which emit DepositFinalized events
// including the L1 and L2 ETH (native gas token) addresses.
Expand Down
3 changes: 2 additions & 1 deletion src/utils/CCTPUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { utils } from "@across-protocol/sdk";
import { TransactionReceipt } from "@ethersproject/abstract-provider";
import axios from "axios";
import { ethers } from "ethers";
import { Log } from "../interfaces";
import { CONTRACT_ADDRESSES, chainIdsToCctpDomains } from "../common";
import { EventSearchConfig, paginatedEventQuery } from "./EventUtils";
import { BigNumber } from "./BNUtils";
Expand Down Expand Up @@ -80,7 +81,7 @@ export async function retrieveOutstandingCCTPBridgeUSDCTransfers(
sourceChainId: number,
destinationChainId: number,
fromAddress: string
): Promise<ethers.Event[]> {
): Promise<Log[]> {
const sourceDomain = chainIdsToCctpDomains[sourceChainId];
const targetDestinationDomain = chainIdsToCctpDomains[destinationChainId];

Expand Down
Loading

0 comments on commit f749ca3

Please sign in to comment.