Skip to content

Commit

Permalink
feat(Monitor): Remove unknown transfers tracking (#1480)
Browse files Browse the repository at this point in the history
* feat(Monitor): Remove unknown transfers tracking

This function contains logic to handle Across V1 bond transfers and in general is not super useful. It adds a ton of overhead to the monitor and is currently buggy. I'd prefer to just remove it.

* Update Monitor.ts

* Update Monitor.ts
  • Loading branch information
nicholaspai authored May 5, 2024
1 parent aacfe54 commit 3f502a9
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 183 deletions.
164 changes: 1 addition & 163 deletions src/monitor/Monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import {
RelayerBalanceReport,
RelayerBalanceTable,
TokenTransfer,
TransfersByChain,
TransfersByTokens,
} from "../interfaces";
import {
BigNumber,
Expand Down Expand Up @@ -38,7 +36,6 @@ import { CombinedRefunds } from "../dataworker/DataworkerUtils";
export const REBALANCE_FINALIZE_GRACE_PERIOD = 40 * 60; // 40 minutes, which is 50% of the way through an 80 minute
// bundle frequency.
export const ALL_CHAINS_NAME = "All chains";
export const UNKNOWN_TRANSFERS_NAME = "Unknown transfers (incoming, outgoing, net)";
const ALL_BALANCE_TYPES = [
BalanceType.CURRENT,
BalanceType.PENDING,
Expand All @@ -47,13 +44,6 @@ const ALL_BALANCE_TYPES = [
BalanceType.TOTAL,
];

interface CategorizedTransfers {
all: TokenTransfer[];
bond: TokenTransfer[];
v1: TokenTransfer[];
other: TokenTransfer[];
}

type BalanceRequest = { chainId: number; token: string; account: string };

export class Monitor {
Expand Down Expand Up @@ -218,12 +208,11 @@ export class Monitor {
const relayers = this.monitorConfig.monitoredRelayers;
const allL1Tokens = this.clients.hubPoolClient.getL1Tokens();
const chainIds = this.monitorChains;
const allChainNames = chainIds.map(getNetworkName).concat([ALL_CHAINS_NAME, UNKNOWN_TRANSFERS_NAME]);
const allChainNames = chainIds.map(getNetworkName).concat([ALL_CHAINS_NAME]);
const reports = this.initializeBalanceReports(relayers, allL1Tokens, allChainNames);

await this.updateCurrentRelayerBalances(reports);
await this.updateLatestAndFutureRelayerRefunds(reports);
this.updateUnknownTransfers(reports);

for (const relayer of relayers) {
const report = reports[relayer];
Expand Down Expand Up @@ -616,157 +605,6 @@ export class Monitor {
}
}

updateUnknownTransfers(relayerBalanceReport: RelayerBalanceReport): void {
const { hubPoolClient, spokePoolClients } = this.clients;

for (const relayer of this.monitorConfig.monitoredRelayers) {
const report = relayerBalanceReport[relayer];
const transfersPerChain: TransfersByChain = this.clients.tokenTransferClient.getTokenTransfers(relayer);

let mrkdwn = "";
for (const chainId of this.monitorChains) {
const spokePoolClient = spokePoolClients[chainId];
const transfersPerToken: TransfersByTokens = transfersPerChain[chainId];
const l2ToL1Tokens = Object.fromEntries(
Object.keys(transfersPerToken).map((l2Token) => [
l2Token,
hubPoolClient.getTokenInfoForAddress(l2Token, chainId),
])
);

let currentChainMrkdwn = "";
for (const l2Token of Object.keys(l2ToL1Tokens)) {
let currentTokenMrkdwn = "";

const tokenInfo = l2ToL1Tokens[l2Token];
const transfers = transfersPerToken[l2Token];
// Skip if there has been no transfers of this token.
if (!transfers) {
continue;
}

let totalOutgoingAmount = bnZero;
// Filter v2 fills and bond payments from outgoing transfers.
const fillTransactionHashes = spokePoolClient.getFillsForRelayer(relayer).map((fill) => fill.transactionHash);
const outgoingTransfers = this.categorizeUnknownTransfers(transfers.outgoing, fillTransactionHashes);
if (outgoingTransfers.all.length > 0) {
currentTokenMrkdwn += "Outgoing:\n";
totalOutgoingAmount = totalOutgoingAmount.add(this.getTotalTransferAmount(outgoingTransfers.all));
currentTokenMrkdwn += this.formatCategorizedTransfers(outgoingTransfers, tokenInfo.decimals, chainId);
}

let totalIncomingAmount = bnZero;
// Filter v2 refunds and bond repayments from incoming transfers.
const refundTransactionHashes = spokePoolClient
.getRelayerRefundExecutions()
.map((refund) => refund.transactionHash);
const incomingTransfers = this.categorizeUnknownTransfers(transfers.incoming, refundTransactionHashes);
if (incomingTransfers.all.length > 0) {
currentTokenMrkdwn += "Incoming:\n";
totalIncomingAmount = totalIncomingAmount.add(this.getTotalTransferAmount(incomingTransfers.all));
currentTokenMrkdwn += this.formatCategorizedTransfers(incomingTransfers, tokenInfo.decimals, chainId);
}

// Record if there are net outgoing transfers.
const netTransfersAmount = totalIncomingAmount.sub(totalOutgoingAmount);
if (!netTransfersAmount.eq(bnZero)) {
const netAmount = convertFromWei(netTransfersAmount.toString(), tokenInfo.decimals);
currentTokenMrkdwn = `*${tokenInfo.symbol}: Net ${netAmount}*\n` + currentTokenMrkdwn;
currentChainMrkdwn += currentTokenMrkdwn;

// Report (incoming, outgoing, net) amounts.
this.incrementBalance(
report,
tokenInfo.symbol,
UNKNOWN_TRANSFERS_NAME,
BalanceType.CURRENT,
totalIncomingAmount
);
this.incrementBalance(
report,
tokenInfo.symbol,
UNKNOWN_TRANSFERS_NAME,
BalanceType.PENDING,
totalOutgoingAmount.mul(-1)
);
this.incrementBalance(
report,
tokenInfo.symbol,
UNKNOWN_TRANSFERS_NAME,
BalanceType.NEXT,
netTransfersAmount
);
}
}

// We only add to the markdown message if there was any unknown transfer for any token on this current chain.
if (currentChainMrkdwn) {
currentChainMrkdwn = `*[${getNetworkName(chainId)}]*\n` + currentChainMrkdwn;
mrkdwn += currentChainMrkdwn + "\n\n";
}
}

if (mrkdwn) {
this.logger.info({
at: "Monitor#updateUnknownTransfers",
message: `Transfers that are not fills for relayer ${relayer} 🦨`,
mrkdwn,
});
}
}
}

categorizeUnknownTransfers(transfers: TokenTransfer[], excludeTransactionHashes: string[]): CategorizedTransfers {
// Exclude specified transaction hashes.
const allUnknownOutgoingTransfers = transfers.filter((transfer) => {
return !excludeTransactionHashes.includes(transfer.transactionHash);
});

const hubPoolAddress = this.clients.hubPoolClient.hubPool.address;
const v1 = [];
const other = [];
const bond = [];
const v1Addresses = this.monitorConfig.knownV1Addresses;
for (const transfer of allUnknownOutgoingTransfers) {
if (transfer.from === hubPoolAddress || transfer.to === hubPoolAddress) {
bond.push(transfer);
} else if (v1Addresses.includes(transfer.from) || v1Addresses.includes(transfer.to)) {
v1.push(transfer);
} else {
other.push(transfer);
}
}
return { bond, v1, other, all: allUnknownOutgoingTransfers };
}

formatCategorizedTransfers(transfers: CategorizedTransfers, decimals: number, chainId: number): string {
let mrkdwn = this.formatKnownTransfers(transfers.bond, decimals, "bond");
mrkdwn += this.formatKnownTransfers(transfers.v1, decimals, "v1");
mrkdwn += this.formatOtherTransfers(transfers.other, decimals, chainId);
return mrkdwn + "\n";
}

formatKnownTransfers(transfers: TokenTransfer[], decimals: number, transferType: string): string {
if (transfers.length === 0) {
return "";
}

const totalAmount = this.getTotalTransferAmount(transfers);
return `${transferType}: ${convertFromWei(totalAmount.toString(), decimals)}\n`;
}

formatOtherTransfers(transfers: TokenTransfer[], decimals: number, chainId: number): string {
if (transfers.length === 0) {
return "";
}

const totalAmount = this.getTotalTransferAmount(transfers);
let mrkdwn = `other: ${convertFromWei(totalAmount.toString(), decimals)}\n`;
const transactionHashes = [...new Set(transfers.map((transfer) => transfer.transactionHash))];
mrkdwn += blockExplorerLinks(transactionHashes, chainId);
return mrkdwn;
}

getTotalTransferAmount(transfers: TokenTransfer[]): BigNumber {
return transfers.map((transfer) => transfer.value).reduce((a, b) => a.add(b));
}
Expand Down
21 changes: 1 addition & 20 deletions test/Monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@ import { CrossChainTransferClient } from "../src/clients/bridges";
import { spokePoolClientsToProviders } from "../src/common";
import { Dataworker } from "../src/dataworker/Dataworker";
import { BalanceType, V3DepositWithBlock } from "../src/interfaces";
import {
ALL_CHAINS_NAME,
Monitor,
REBALANCE_FINALIZE_GRACE_PERIOD,
UNKNOWN_TRANSFERS_NAME,
} from "../src/monitor/Monitor";
import { ALL_CHAINS_NAME, Monitor, REBALANCE_FINALIZE_GRACE_PERIOD } from "../src/monitor/Monitor";
import { MonitorConfig } from "../src/monitor/MonitorConfig";
import { MAX_UINT_VAL, getNetworkName, toBN } from "../src/utils";
import * as constants from "./constants";
Expand Down Expand Up @@ -374,20 +369,6 @@ describe("Monitor", async function () {
expect(log.lastArg.mrkdwn).to.contains("100.00");
});

it("Monitor should report unknown transfers", async function () {
await l2Token.connect(depositor).transfer(dataworker.address, 1);

await monitorInstance.update();
const reports = monitorInstance.initializeBalanceReports(
monitorInstance.monitorConfig.monitoredRelayers,
monitorInstance.clients.hubPoolClient.getL1Tokens(),
[UNKNOWN_TRANSFERS_NAME]
);
monitorInstance.updateUnknownTransfers(reports);

expect(lastSpyLogIncludes(spy, `Transfers that are not fills for relayer ${depositor.address} 🦨`)).to.be.true;
});

it("Monitor should send token refills", async function () {
const refillConfig = [
{
Expand Down

0 comments on commit 3f502a9

Please sign in to comment.