@across-protocol/sdk 4.3.18-alpha.1 → 4.3.19-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/arch/svm/BlockUtils.js +4 -31
- package/dist/cjs/arch/svm/BlockUtils.js.map +1 -1
- package/dist/cjs/arch/svm/SpokeUtils.d.ts +8 -8
- package/dist/cjs/arch/svm/SpokeUtils.js +33 -36
- package/dist/cjs/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/cjs/arch/svm/utils.d.ts +11 -3
- package/dist/cjs/arch/svm/utils.js +40 -5
- package/dist/cjs/arch/svm/utils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.d.ts +2 -5
- package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js +75 -110
- package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.d.ts +124 -124
- package/dist/cjs/clients/SpokePoolClient/SVMSpokePoolClient.d.ts +1 -1
- package/dist/cjs/clients/SpokePoolClient/SVMSpokePoolClient.js +2 -3
- package/dist/cjs/clients/SpokePoolClient/SVMSpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js +4 -1
- package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/mocks/MockSpokePoolClient.d.ts +3 -1
- package/dist/cjs/clients/mocks/MockSpokePoolClient.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.d.ts +1 -1
- package/dist/cjs/utils/EventUtils.js +0 -21
- package/dist/cjs/utils/EventUtils.js.map +1 -1
- package/dist/esm/arch/svm/BlockUtils.js +4 -31
- package/dist/esm/arch/svm/BlockUtils.js.map +1 -1
- package/dist/esm/arch/svm/SpokeUtils.d.ts +8 -8
- package/dist/esm/arch/svm/SpokeUtils.js +35 -36
- package/dist/esm/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/esm/arch/svm/utils.d.ts +17 -4
- package/dist/esm/arch/svm/utils.js +44 -5
- package/dist/esm/arch/svm/utils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.d.ts +2 -5
- package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js +125 -150
- package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.d.ts +124 -124
- package/dist/esm/clients/SpokePoolClient/SVMSpokePoolClient.d.ts +1 -1
- package/dist/esm/clients/SpokePoolClient/SVMSpokePoolClient.js +2 -3
- package/dist/esm/clients/SpokePoolClient/SVMSpokePoolClient.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js +4 -1
- package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
- package/dist/esm/clients/mocks/MockSpokePoolClient.d.ts +3 -1
- package/dist/esm/clients/mocks/MockSpokePoolClient.js.map +1 -1
- package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.d.ts +1 -1
- package/dist/esm/utils/EventUtils.js +1 -29
- package/dist/esm/utils/EventUtils.js.map +1 -1
- package/dist/types/arch/svm/BlockUtils.d.ts.map +1 -1
- package/dist/types/arch/svm/SpokeUtils.d.ts +8 -8
- package/dist/types/arch/svm/SpokeUtils.d.ts.map +1 -1
- package/dist/types/arch/svm/utils.d.ts +17 -4
- package/dist/types/arch/svm/utils.d.ts.map +1 -1
- package/dist/types/clients/BundleDataClient/utils/DataworkerUtils.d.ts +2 -5
- package/dist/types/clients/BundleDataClient/utils/DataworkerUtils.d.ts.map +1 -1
- package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts +124 -124
- package/dist/types/clients/SpokePoolClient/SVMSpokePoolClient.d.ts +1 -1
- package/dist/types/clients/SpokePoolClient/SVMSpokePoolClient.d.ts.map +1 -1
- package/dist/types/clients/SpokePoolClient/SpokePoolClient.d.ts.map +1 -1
- package/dist/types/clients/mocks/MockSpokePoolClient.d.ts +3 -1
- package/dist/types/clients/mocks/MockSpokePoolClient.d.ts.map +1 -1
- package/dist/types/relayFeeCalculator/chain-queries/svmQuery.d.ts +1 -1
- package/dist/types/utils/EventUtils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/arch/svm/BlockUtils.ts +4 -12
- package/src/arch/svm/SpokeUtils.ts +24 -20
- package/src/arch/svm/utils.ts +29 -4
- package/src/clients/BundleDataClient/utils/DataworkerUtils.ts +6 -68
- package/src/clients/SpokePoolClient/SVMSpokePoolClient.ts +2 -7
- package/src/clients/SpokePoolClient/SpokePoolClient.ts +37 -14
- package/src/clients/mocks/MockSpokePoolClient.ts +1 -1
- package/src/utils/EventUtils.ts +1 -29
|
@@ -65,6 +65,7 @@ import {
|
|
|
65
65
|
import { SvmCpiEventsClient } from "./eventsClient";
|
|
66
66
|
import { SVM_NO_BLOCK_AT_SLOT, isSolanaError } from "./provider";
|
|
67
67
|
import { AttestedCCTPMessage, SVMEventNames, SVMProvider } from "./types";
|
|
68
|
+
import { getNearestSlotTime } from "./utils";
|
|
68
69
|
|
|
69
70
|
/**
|
|
70
71
|
* @note: Average Solana slot duration is about 400-500ms. We can be conservative
|
|
@@ -83,9 +84,10 @@ type ProtoFill = Omit<RelayData, "recipient" | "outputToken"> & {
|
|
|
83
84
|
*/
|
|
84
85
|
export async function getTimestampForSlot(provider: SVMProvider, slotNumber: bigint): Promise<number | undefined> {
|
|
85
86
|
// @note: getBlockTime receives a slot number, not a block number.
|
|
87
|
+
let _timestamp: bigint;
|
|
88
|
+
|
|
86
89
|
try {
|
|
87
|
-
|
|
88
|
-
return Number(blockTime);
|
|
90
|
+
_timestamp = await provider.getBlockTime(slotNumber).send();
|
|
89
91
|
} catch (err) {
|
|
90
92
|
if (!isSolanaError(err)) {
|
|
91
93
|
throw err;
|
|
@@ -98,6 +100,11 @@ export async function getTimestampForSlot(provider: SVMProvider, slotNumber: big
|
|
|
98
100
|
|
|
99
101
|
throw err; // Unhandled Solana error.
|
|
100
102
|
}
|
|
103
|
+
|
|
104
|
+
const timestamp = Number(_timestamp);
|
|
105
|
+
assert(BigInt(timestamp) === _timestamp, `Unexpected SVM block timestamp: ${_timestamp}`); // No truncation.
|
|
106
|
+
|
|
107
|
+
return timestamp;
|
|
101
108
|
}
|
|
102
109
|
|
|
103
110
|
/**
|
|
@@ -226,14 +233,17 @@ export async function relayFillStatus(
|
|
|
226
233
|
const provider = svmEventsClient.getRpc();
|
|
227
234
|
// Get fill status PDA using relayData
|
|
228
235
|
const fillStatusPda = await getFillStatusPda(programId, relayData, destinationChainId);
|
|
229
|
-
|
|
236
|
+
let toSlot = BigInt(atHeight ?? 0);
|
|
230
237
|
|
|
231
238
|
// If no specific slot is requested, try fetching the current status from the PDA
|
|
232
239
|
if (atHeight === undefined) {
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
|
|
240
|
+
const commitment = "confirmed";
|
|
241
|
+
const [fillStatusAccount, { slot: currentSlot, timestamp }] = await Promise.all([
|
|
242
|
+
fetchEncodedAccount(provider, fillStatusPda, { commitment }),
|
|
243
|
+
getNearestSlotTime(provider, { commitment }),
|
|
236
244
|
]);
|
|
245
|
+
toSlot = currentSlot;
|
|
246
|
+
|
|
237
247
|
// If the PDA exists, return the stored fill status
|
|
238
248
|
if (fillStatusAccount.exists) {
|
|
239
249
|
const decodedAccountData = decodeFillStatusAccount(fillStatusAccount);
|
|
@@ -241,14 +251,12 @@ export async function relayFillStatus(
|
|
|
241
251
|
}
|
|
242
252
|
// If the PDA doesn't exist and the deadline hasn't passed yet, the deposit must be unfilled,
|
|
243
253
|
// since PDAs can't be closed before the fill deadline.
|
|
244
|
-
else if (
|
|
254
|
+
else if (timestamp < relayData.fillDeadline) {
|
|
245
255
|
return FillStatus.Unfilled;
|
|
246
256
|
}
|
|
247
257
|
}
|
|
248
258
|
|
|
249
|
-
// If status couldn't be determined from the PDA, or if a specific slot was requested, reconstruct
|
|
250
|
-
const toSlot = atHeight ? BigInt(atHeight) : currentSlot;
|
|
251
|
-
|
|
259
|
+
// If status couldn't be determined from the PDA, or if a specific slot was requested, reconstruct from events.
|
|
252
260
|
return resolveFillStatusFromPdaEvents(fillStatusPda, toSlot, svmEventsClient);
|
|
253
261
|
}
|
|
254
262
|
|
|
@@ -816,7 +824,7 @@ export const createReceiveMessageInstruction = async (
|
|
|
816
824
|
input: MessageTransmitterClient.ReceiveMessageInput,
|
|
817
825
|
remainingAccounts: IAccountMeta<string>[]
|
|
818
826
|
) => {
|
|
819
|
-
const receiveMessageIx =
|
|
827
|
+
const receiveMessageIx = MessageTransmitterClient.getReceiveMessageInstruction(input);
|
|
820
828
|
(receiveMessageIx.accounts as IAccountMeta<string>[]).push(...remainingAccounts);
|
|
821
829
|
return pipe(await createDefaultTransaction(solanaClient, signer), (tx) =>
|
|
822
830
|
appendTransactionMessageInstruction(receiveMessageIx, tx)
|
|
@@ -919,15 +927,11 @@ async function fetchBatchFillStatusFromPdaAccounts(
|
|
|
919
927
|
relayDataArray: RelayData[]
|
|
920
928
|
): Promise<(FillStatus | undefined)[]> {
|
|
921
929
|
const chunkSize = 100; // SVM method getMultipleAccounts allows a max of 100 addresses per request
|
|
922
|
-
const
|
|
930
|
+
const commitment = "confirmed";
|
|
923
931
|
|
|
924
|
-
const [pdaAccounts,
|
|
925
|
-
Promise.all(
|
|
926
|
-
|
|
927
|
-
fetchEncodedAccounts(provider, chunk, { commitment: "confirmed" })
|
|
928
|
-
)
|
|
929
|
-
),
|
|
930
|
-
getTimestampForSlot(provider, currentSlot),
|
|
932
|
+
const [pdaAccounts, { timestamp }] = await Promise.all([
|
|
933
|
+
Promise.all(chunk(fillStatusPdas, chunkSize).map((chunk) => fetchEncodedAccounts(provider, chunk, { commitment }))),
|
|
934
|
+
getNearestSlotTime(provider, { commitment }),
|
|
931
935
|
]);
|
|
932
936
|
|
|
933
937
|
const fillStatuses = pdaAccounts.flat().map((account, index) => {
|
|
@@ -939,7 +943,7 @@ async function fetchBatchFillStatusFromPdaAccounts(
|
|
|
939
943
|
|
|
940
944
|
// If the PDA doesn't exist and the deadline hasn't passed yet, the deposit must be unfilled,
|
|
941
945
|
// since PDAs can't be closed before the fill deadline.
|
|
942
|
-
if (
|
|
946
|
+
if (timestamp < relayDataArray[index].fillDeadline) {
|
|
943
947
|
return FillStatus.Unfilled;
|
|
944
948
|
}
|
|
945
949
|
|
package/src/arch/svm/utils.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import assert from "assert";
|
|
1
2
|
import { MessageTransmitterClient, SvmSpokeClient } from "@across-protocol/contracts";
|
|
2
3
|
import { BN, BorshEventCoder, Idl } from "@coral-xyz/anchor";
|
|
3
4
|
import {
|
|
4
5
|
Address,
|
|
6
|
+
type Commitment,
|
|
5
7
|
IInstruction,
|
|
6
8
|
KeyPairSigner,
|
|
7
9
|
address,
|
|
@@ -24,6 +26,7 @@ import { ethers } from "ethers";
|
|
|
24
26
|
import { FillType, RelayData } from "../../interfaces";
|
|
25
27
|
import { BigNumber, Address as SdkAddress, getRelayDataHash, isDefined, isUint8Array } from "../../utils";
|
|
26
28
|
import { AttestedCCTPMessage, EventName, SVMEventNames, SVMProvider } from "./types";
|
|
29
|
+
import { getTimestampForSlot } from "./SpokeUtils";
|
|
27
30
|
|
|
28
31
|
export { isSolanaError } from "@solana/kit";
|
|
29
32
|
|
|
@@ -56,6 +59,27 @@ export function toAddress(address: SdkAddress): Address<string> {
|
|
|
56
59
|
return address.toBase58() as Address<string>;
|
|
57
60
|
}
|
|
58
61
|
|
|
62
|
+
/**
|
|
63
|
+
* For a given slot (or implicit head of chain), find the immediate preceding slot that contained a block.
|
|
64
|
+
* @param provider SVM Provider instance.
|
|
65
|
+
* @param opts An object containing a specific slot number, or a Solana commitment, defaulting to "confirmed".
|
|
66
|
+
* @returns An object containing the slot number and the relevant timestamp for the block.
|
|
67
|
+
*/
|
|
68
|
+
export async function getNearestSlotTime(
|
|
69
|
+
provider: SVMProvider,
|
|
70
|
+
opts: { slot: bigint } | { commitment: Commitment } = { commitment: "confirmed" }
|
|
71
|
+
): Promise<{ slot: bigint; timestamp: number }> {
|
|
72
|
+
let timestamp: number | undefined;
|
|
73
|
+
let slot = "slot" in opts ? opts.slot : await provider.getSlot(opts).send();
|
|
74
|
+
|
|
75
|
+
do {
|
|
76
|
+
timestamp = await getTimestampForSlot(provider, slot);
|
|
77
|
+
} while (!isDefined(timestamp) && --slot);
|
|
78
|
+
assert(isDefined(timestamp), `Unable to resolve block time for SVM slot ${slot}`);
|
|
79
|
+
|
|
80
|
+
return { slot, timestamp };
|
|
81
|
+
}
|
|
82
|
+
|
|
59
83
|
/**
|
|
60
84
|
* Resolve the latest finalized slot, and then work backwards to find the nearest slot containing a block.
|
|
61
85
|
* In most cases the first-resolved slot should also have a block. Avoid making arbitrary decisions about
|
|
@@ -285,15 +309,16 @@ export async function getTransferLiabilityPda(programId: Address, originToken: A
|
|
|
285
309
|
/**
|
|
286
310
|
* Returns the PDA for the SVM Spoke's root bundle account.
|
|
287
311
|
* @param programId the address of the spoke pool.
|
|
288
|
-
* @param statePda the spoke pool's state pda.
|
|
289
312
|
* @param rootBundleId the associated root bundle ID.
|
|
290
313
|
*/
|
|
291
|
-
export async function getRootBundlePda(programId: Address,
|
|
314
|
+
export async function getRootBundlePda(programId: Address, rootBundleId: number): Promise<Address> {
|
|
315
|
+
const seedEncoder = getU64Encoder();
|
|
316
|
+
const seed = seedEncoder.encode(0); // Default seed.
|
|
317
|
+
|
|
292
318
|
const intEncoder = getU32Encoder();
|
|
293
|
-
const addressEncoder = getAddressEncoder();
|
|
294
319
|
const [pda] = await getProgramDerivedAddress({
|
|
295
320
|
programAddress: programId,
|
|
296
|
-
seeds: ["root_bundle",
|
|
321
|
+
seeds: ["root_bundle", seed, intEncoder.encode(rootBundleId)],
|
|
297
322
|
});
|
|
298
323
|
return pda;
|
|
299
324
|
}
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
PoolRebalanceLeaf,
|
|
11
11
|
Refund,
|
|
12
12
|
RunningBalances,
|
|
13
|
-
SpokePoolClientsByChain,
|
|
14
13
|
} from "../../../interfaces";
|
|
15
14
|
import {
|
|
16
15
|
bnZero,
|
|
@@ -19,8 +18,6 @@ import {
|
|
|
19
18
|
count2DDictionaryValues,
|
|
20
19
|
count3DDictionaryValues,
|
|
21
20
|
toAddressType,
|
|
22
|
-
getImpliedBundleBlockRanges,
|
|
23
|
-
EvmAddress,
|
|
24
21
|
} from "../../../utils";
|
|
25
22
|
import {
|
|
26
23
|
addLastRunningBalance,
|
|
@@ -31,7 +28,6 @@ import {
|
|
|
31
28
|
} from "./PoolRebalanceUtils";
|
|
32
29
|
import { AcrossConfigStoreClient } from "../../AcrossConfigStoreClient";
|
|
33
30
|
import { HubPoolClient } from "../../HubPoolClient";
|
|
34
|
-
import { BundleDataClient } from "../../BundleDataClient";
|
|
35
31
|
import { buildPoolRebalanceLeafTree } from "./MerkleTreeUtils";
|
|
36
32
|
|
|
37
33
|
// and expired deposits.
|
|
@@ -118,7 +114,7 @@ export function getEndBlockBuffers(
|
|
|
118
114
|
return chainIdListForBundleEvaluationBlockNumbers.map((chainId: number) => blockRangeEndBlockBuffer[chainId] ?? 0);
|
|
119
115
|
}
|
|
120
116
|
|
|
121
|
-
export
|
|
117
|
+
export function _buildPoolRebalanceRoot(
|
|
122
118
|
latestMainnetBlock: number,
|
|
123
119
|
mainnetBundleEndBlock: number,
|
|
124
120
|
bundleV3Deposits: BundleDepositsV3,
|
|
@@ -126,14 +122,9 @@ export async function _buildPoolRebalanceRoot(
|
|
|
126
122
|
bundleSlowFillsV3: BundleSlowFills,
|
|
127
123
|
unexecutableSlowFills: BundleExcessSlowFills,
|
|
128
124
|
expiredDepositsToRefundV3: ExpiredDepositsToRefundV3,
|
|
129
|
-
clients: {
|
|
130
|
-
hubPoolClient: HubPoolClient;
|
|
131
|
-
configStoreClient: AcrossConfigStoreClient;
|
|
132
|
-
bundleDataClient: BundleDataClient;
|
|
133
|
-
spokePoolClients: SpokePoolClientsByChain;
|
|
134
|
-
},
|
|
125
|
+
clients: { hubPoolClient: HubPoolClient; configStoreClient: AcrossConfigStoreClient },
|
|
135
126
|
maxL1TokenCountOverride?: number
|
|
136
|
-
):
|
|
127
|
+
): PoolRebalanceRoot {
|
|
137
128
|
// Running balances are the amount of tokens that we need to send to each SpokePool to pay for all instant and
|
|
138
129
|
// slow relay refunds. They are decreased by the amount of funds already held by the SpokePool. Balances are keyed
|
|
139
130
|
// by the SpokePool's network and L1 token equivalent of the L2 token to refund.
|
|
@@ -306,62 +297,9 @@ export async function _buildPoolRebalanceRoot(
|
|
|
306
297
|
});
|
|
307
298
|
});
|
|
308
299
|
|
|
309
|
-
// Add to the running balance value from the last valid root bundle proposal
|
|
310
|
-
//
|
|
311
|
-
|
|
312
|
-
clients.hubPoolClient.getPendingRootBundle()?.bundleEvaluationBlockNumbers[0] === mainnetBundleEndBlock ||
|
|
313
|
-
!clients.hubPoolClient.hasPendingProposal() ||
|
|
314
|
-
clients.hubPoolClient
|
|
315
|
-
.getValidatedRootBundles()
|
|
316
|
-
.some((bundle) => bundle.bundleEvaluationBlockNumbers[0].toNumber() === mainnetBundleEndBlock)
|
|
317
|
-
) {
|
|
318
|
-
addLastRunningBalance(latestMainnetBlock, runningBalances, clients.hubPoolClient);
|
|
319
|
-
} else {
|
|
320
|
-
// Otherwise, the pool rebalance root for this root bundle must be for an optimistic proposal, so we need to reconstruct the pool rebalance root for the pending root bundle to obtain the running balances.
|
|
321
|
-
// @dev It is safe to index the hub pool client's proposed root bundles here since there is guaranteed to be a pending proposal in this code block.
|
|
322
|
-
const mostRecentProposedRootBundle = clients.hubPoolClient.getLatestProposedRootBundle();
|
|
323
|
-
const blockRangesForChains = getImpliedBundleBlockRanges(
|
|
324
|
-
clients.hubPoolClient,
|
|
325
|
-
clients.configStoreClient,
|
|
326
|
-
mostRecentProposedRootBundle
|
|
327
|
-
);
|
|
328
|
-
// We are loading data from a pending root bundle, so we want to use arweave if possible.
|
|
329
|
-
const prevRootBundleData = await clients.bundleDataClient.loadData(
|
|
330
|
-
blockRangesForChains,
|
|
331
|
-
clients.spokePoolClients,
|
|
332
|
-
true
|
|
333
|
-
);
|
|
334
|
-
const prevPoolRebalanceRoot = await _buildPoolRebalanceRoot(
|
|
335
|
-
latestMainnetBlock,
|
|
336
|
-
blockRangesForChains[0][1],
|
|
337
|
-
prevRootBundleData.bundleDepositsV3,
|
|
338
|
-
prevRootBundleData.bundleFillsV3,
|
|
339
|
-
prevRootBundleData.bundleSlowFillsV3,
|
|
340
|
-
prevRootBundleData.unexecutableSlowFills,
|
|
341
|
-
prevRootBundleData.expiredDepositsToRefundV3,
|
|
342
|
-
clients,
|
|
343
|
-
maxL1TokenCountOverride
|
|
344
|
-
);
|
|
345
|
-
// Update the running balances by adding the pending root bundle's running balance amounts to this bundle's running balances.
|
|
346
|
-
const { runningBalances: prevRunningBalances } = prevPoolRebalanceRoot;
|
|
347
|
-
Object.keys(runningBalances).forEach((repaymentChainId) => {
|
|
348
|
-
Object.keys(runningBalances[Number(repaymentChainId)]).forEach((l1TokenAddress) => {
|
|
349
|
-
const updateRunningBalanceAmount = prevRunningBalances[Number(repaymentChainId)]?.[l1TokenAddress];
|
|
350
|
-
// If the pending root bundle didn't have a running balance, fall back to the last running balance for that token and chain pair.
|
|
351
|
-
const { runningBalance: fallbackRunningBalance } = clients.hubPoolClient.getRunningBalanceBeforeBlockForChain(
|
|
352
|
-
latestMainnetBlock,
|
|
353
|
-
Number(repaymentChainId),
|
|
354
|
-
EvmAddress.from(l1TokenAddress)
|
|
355
|
-
);
|
|
356
|
-
updateRunningBalance(
|
|
357
|
-
runningBalances,
|
|
358
|
-
Number(repaymentChainId),
|
|
359
|
-
l1TokenAddress,
|
|
360
|
-
updateRunningBalanceAmount ?? fallbackRunningBalance
|
|
361
|
-
);
|
|
362
|
-
});
|
|
363
|
-
});
|
|
364
|
-
}
|
|
300
|
+
// Add to the running balance value from the last valid root bundle proposal for {chainId, l1Token}
|
|
301
|
+
// combination if found.
|
|
302
|
+
addLastRunningBalance(latestMainnetBlock, runningBalances, clients.hubPoolClient);
|
|
365
303
|
|
|
366
304
|
const leaves: PoolRebalanceLeaf[] = constructPoolRebalanceLeaves(
|
|
367
305
|
mainnetBundleEndBlock,
|
|
@@ -243,13 +243,8 @@ export class SVMSpokePoolClient extends SpokePoolClient {
|
|
|
243
243
|
/**
|
|
244
244
|
* Retrieves the fill status for a given relay data from the SVM chain.
|
|
245
245
|
*/
|
|
246
|
-
public override relayFillStatus(
|
|
247
|
-
relayData
|
|
248
|
-
atHeight?: number,
|
|
249
|
-
destinationChainId?: number
|
|
250
|
-
): Promise<FillStatus> {
|
|
251
|
-
destinationChainId ??= this.chainId;
|
|
252
|
-
return relayFillStatus(this.programId, relayData, destinationChainId, this.svmEventsClient, atHeight);
|
|
246
|
+
public override relayFillStatus(relayData: RelayData, atHeight?: number): Promise<FillStatus> {
|
|
247
|
+
return relayFillStatus(this.programId, relayData, this.chainId, this.svmEventsClient, atHeight);
|
|
253
248
|
}
|
|
254
249
|
|
|
255
250
|
/**
|
|
@@ -150,10 +150,10 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
|
|
|
150
150
|
*/
|
|
151
151
|
public getDepositsForDestinationChainWithDuplicates(destinationChainId: number): DepositWithBlock[] {
|
|
152
152
|
const deposits = this.getDepositsForDestinationChain(destinationChainId);
|
|
153
|
-
const duplicateDeposits = deposits.reduce((acc, deposit) => {
|
|
153
|
+
const duplicateDeposits = deposits.reduce<DepositWithBlock[]>((acc, deposit) => {
|
|
154
154
|
const duplicates = this._getDuplicateDeposits(deposit);
|
|
155
155
|
return acc.concat(duplicates);
|
|
156
|
-
}, []
|
|
156
|
+
}, []);
|
|
157
157
|
return sortEventsAscendingInPlace(deposits.concat(duplicateDeposits.flat()));
|
|
158
158
|
}
|
|
159
159
|
|
|
@@ -508,7 +508,7 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
|
|
|
508
508
|
|
|
509
509
|
if (eventsToQuery.includes("TokensBridged")) {
|
|
510
510
|
for (const _event of queryResults[eventsToQuery.indexOf("TokensBridged")]) {
|
|
511
|
-
const event = _event as TokensBridged & {
|
|
511
|
+
const event = _event as Omit<TokensBridged, "l2TokenAddress"> & {
|
|
512
512
|
l2TokenAddress: string;
|
|
513
513
|
};
|
|
514
514
|
this.tokensBridged.push({
|
|
@@ -521,7 +521,10 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
|
|
|
521
521
|
// Performs the indexing of a deposit-like spoke pool event.
|
|
522
522
|
const queryDepositEvents = async (eventName: string) => {
|
|
523
523
|
const depositEvents = (queryResults[eventsToQuery.indexOf(eventName)] ?? []).map((_event) => {
|
|
524
|
-
const event = _event as
|
|
524
|
+
const event = _event as Omit<
|
|
525
|
+
DepositWithBlock,
|
|
526
|
+
"depositor" | "recipient" | "inputToken" | "outputToken" | "exclusiveRelayer"
|
|
527
|
+
> & {
|
|
525
528
|
depositor: string;
|
|
526
529
|
recipient: string;
|
|
527
530
|
inputToken: string;
|
|
@@ -595,7 +598,10 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
|
|
|
595
598
|
const querySpeedUpDepositEvents = (eventName: string) => {
|
|
596
599
|
const speedUpEvents = (queryResults[eventsToQuery.indexOf(eventName)] ?? [])
|
|
597
600
|
.map((_event) => {
|
|
598
|
-
const event = _event as SpeedUpWithBlock
|
|
601
|
+
const event = _event as Omit<SpeedUpWithBlock, "depositor" | "updatedRecipient"> & {
|
|
602
|
+
depositor: string;
|
|
603
|
+
updatedRecipient: string;
|
|
604
|
+
};
|
|
599
605
|
|
|
600
606
|
const invalid = [event.depositor, event.updatedRecipient].some(
|
|
601
607
|
(addr) => !EvmAddress.validate(ethersUtils.arrayify(addr))
|
|
@@ -643,7 +649,10 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
|
|
|
643
649
|
// Performs indexing of "requested slow fill"-like events.
|
|
644
650
|
const queryRequestedSlowFillEvents = (eventName: string) => {
|
|
645
651
|
const slowFillRequests = (queryResults[eventsToQuery.indexOf(eventName)] ?? []).map((_event) => {
|
|
646
|
-
const event = _event as
|
|
652
|
+
const event = _event as Omit<
|
|
653
|
+
SlowFillRequestWithBlock,
|
|
654
|
+
"depositor" | "recipient" | "inputToken" | "outputToken" | "exclusiveRelayer"
|
|
655
|
+
> & {
|
|
647
656
|
depositor: string;
|
|
648
657
|
recipient: string;
|
|
649
658
|
inputToken: string;
|
|
@@ -686,14 +695,23 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
|
|
|
686
695
|
// Performs indexing of filled relay-like events.
|
|
687
696
|
const queryFilledRelayEvents = (eventName: string) => {
|
|
688
697
|
const fillEvents = (queryResults[eventsToQuery.indexOf(eventName)] ?? []).map((_event) => {
|
|
689
|
-
const event = _event as
|
|
698
|
+
const event = _event as Omit<
|
|
699
|
+
FillWithBlock,
|
|
700
|
+
| "depositor"
|
|
701
|
+
| "recipient"
|
|
702
|
+
| "inputToken"
|
|
703
|
+
| "outputToken"
|
|
704
|
+
| "exclusiveRelayer"
|
|
705
|
+
| "relayer"
|
|
706
|
+
| "relayExecutionInfo"
|
|
707
|
+
> & {
|
|
690
708
|
depositor: string;
|
|
691
709
|
recipient: string;
|
|
692
710
|
inputToken: string;
|
|
693
711
|
outputToken: string;
|
|
694
712
|
exclusiveRelayer: string;
|
|
695
713
|
relayer: string;
|
|
696
|
-
relayExecutionInfo: RelayExecutionEventInfo & { updatedRecipient: string };
|
|
714
|
+
relayExecutionInfo: Omit<RelayExecutionEventInfo, "updatedRecipient"> & { updatedRecipient: string };
|
|
697
715
|
};
|
|
698
716
|
return {
|
|
699
717
|
...event,
|
|
@@ -744,11 +762,13 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
|
|
|
744
762
|
});
|
|
745
763
|
|
|
746
764
|
if (eventsToQuery.includes("EnabledDepositRoute")) {
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
765
|
+
const enableDepositsEvents = queryResults[eventsToQuery.indexOf("EnabledDepositRoute")].map((_event) => {
|
|
766
|
+
const event = _event as Omit<EnabledDepositRouteWithBlock, "originToken"> & { originToken: string };
|
|
767
|
+
return {
|
|
768
|
+
...event,
|
|
769
|
+
originToken: toAddressType(event.originToken, CHAIN_IDs.MAINNET),
|
|
770
|
+
} as EnabledDepositRouteWithBlock;
|
|
771
|
+
});
|
|
752
772
|
|
|
753
773
|
for (const event of enableDepositsEvents) {
|
|
754
774
|
assign(this.depositRoutes, [event.originToken.toBytes32(), event.destinationChainId], event.enabled);
|
|
@@ -767,7 +787,10 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
|
|
|
767
787
|
if (eventsToQuery.includes("ExecutedRelayerRefundRoot")) {
|
|
768
788
|
const refundEvents = queryResults[eventsToQuery.indexOf("ExecutedRelayerRefundRoot")];
|
|
769
789
|
for (const _event of refundEvents) {
|
|
770
|
-
const event = _event as
|
|
790
|
+
const event = _event as Omit<RelayerRefundExecutionWithBlock, "l2TokenAddress" | "refundAddresses"> & {
|
|
791
|
+
l2TokenAddress: string;
|
|
792
|
+
refundAddresses: string[];
|
|
793
|
+
};
|
|
771
794
|
this.relayerRefundExecutions.push({
|
|
772
795
|
...event,
|
|
773
796
|
l2TokenAddress: toAddressType(event.l2TokenAddress, this.chainId),
|
|
@@ -279,7 +279,7 @@ export class MockSpokePoolClient extends EVMSpokePoolClient {
|
|
|
279
279
|
});
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
-
setTokensBridged(tokensBridged: TokensBridged): Log {
|
|
282
|
+
setTokensBridged(tokensBridged: Omit<TokensBridged, "l2TokenAddress"> & { l2TokenAddress: string }): Log {
|
|
283
283
|
const event = "TokensBridged";
|
|
284
284
|
const topics = [tokensBridged.chainId, tokensBridged.leafId, tokensBridged.l2TokenAddress];
|
|
285
285
|
const args = { ...tokensBridged };
|
package/src/utils/EventUtils.ts
CHANGED
|
@@ -3,27 +3,11 @@ import { Result } from "@ethersproject/abi";
|
|
|
3
3
|
import { Contract, Event, EventFilter } from "ethers";
|
|
4
4
|
import { Log, SortableEvent } from "../interfaces";
|
|
5
5
|
import { delay } from "./common";
|
|
6
|
-
import { isDefined, toBN, BigNumberish
|
|
6
|
+
import { isDefined, toBN, BigNumberish } from "./";
|
|
7
7
|
|
|
8
8
|
const maxRetries = 3;
|
|
9
9
|
const retrySleepTime = 10;
|
|
10
10
|
|
|
11
|
-
// Event fields which changed from an `address` to `bytes32` after the SVM contract upgrade.
|
|
12
|
-
const knownExtendedAddressFields = [
|
|
13
|
-
// TokensBridged
|
|
14
|
-
"l2TokenAddress",
|
|
15
|
-
// FundsDeposited/FilledRelay/RequestedSlowFill
|
|
16
|
-
"inputToken",
|
|
17
|
-
"outputToken",
|
|
18
|
-
"depositor",
|
|
19
|
-
"recipient",
|
|
20
|
-
"exclusiveRelayer",
|
|
21
|
-
// FilledRelay
|
|
22
|
-
"relayer",
|
|
23
|
-
// RequestedSpeedUpDeposit
|
|
24
|
-
"updatedRecipient",
|
|
25
|
-
];
|
|
26
|
-
|
|
27
11
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
12
|
export function spreadEvent(args: Result | Record<string, unknown>): { [key: string]: any } {
|
|
29
13
|
const keys = Object.keys(args).filter((key: string) => isNaN(+key)); // Extract non-numeric keys.
|
|
@@ -83,18 +67,6 @@ export function spreadEvent(args: Result | Record<string, unknown>): { [key: str
|
|
|
83
67
|
returnedObject.depositId = toBN(returnedObject.depositId as BigNumberish);
|
|
84
68
|
}
|
|
85
69
|
|
|
86
|
-
// Truncate all fields which may be bytes32 into a bytes20 string.
|
|
87
|
-
for (const field of knownExtendedAddressFields) {
|
|
88
|
-
if (isDefined(returnedObject[field])) {
|
|
89
|
-
let address = String(returnedObject[field]);
|
|
90
|
-
try {
|
|
91
|
-
address = toEvmAddress(address);
|
|
92
|
-
// eslint-disable-next-line no-empty
|
|
93
|
-
} catch (_) {}
|
|
94
|
-
returnedObject[field] = address;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
70
|
return returnedObject;
|
|
99
71
|
}
|
|
100
72
|
|