@hyperlane-xyz/sdk 41.1.0 → 41.3.0
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/block-explorer/etherscan.d.ts +16 -0
- package/dist/block-explorer/etherscan.d.ts.map +1 -1
- package/dist/block-explorer/etherscan.js +42 -30
- package/dist/block-explorer/etherscan.js.map +1 -1
- package/dist/ccip/consts.d.ts.map +1 -1
- package/dist/ccip/consts.js +0 -80
- package/dist/ccip/consts.js.map +1 -1
- package/dist/consts/multisigIsm.d.ts.map +1 -1
- package/dist/consts/multisigIsm.js +0 -118
- package/dist/consts/multisigIsm.js.map +1 -1
- package/dist/core/types.d.ts +136 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/deploy/proxy.d.ts +41 -4
- package/dist/deploy/proxy.d.ts.map +1 -1
- package/dist/deploy/proxy.js +38 -8
- package/dist/deploy/proxy.js.map +1 -1
- package/dist/deploy/warp.d.ts.map +1 -1
- package/dist/deploy/warp.js +29 -3
- package/dist/deploy/warp.js.map +1 -1
- package/dist/ica/types.d.ts +80 -0
- package/dist/ica/types.d.ts.map +1 -1
- package/dist/ism/EvmIsmModule.d.ts +2 -0
- package/dist/ism/EvmIsmModule.d.ts.map +1 -1
- package/dist/ism/EvmIsmModule.hardhat-test.js +162 -9
- package/dist/ism/EvmIsmModule.hardhat-test.js.map +1 -1
- package/dist/ism/EvmIsmModule.js +35 -8
- package/dist/ism/EvmIsmModule.js.map +1 -1
- package/dist/ism/EvmIsmModule.test.d.ts +2 -0
- package/dist/ism/EvmIsmModule.test.d.ts.map +1 -0
- package/dist/ism/EvmIsmModule.test.js +200 -0
- package/dist/ism/EvmIsmModule.test.js.map +1 -0
- package/dist/ism/EvmIsmReader.d.ts +12 -0
- package/dist/ism/EvmIsmReader.d.ts.map +1 -1
- package/dist/ism/EvmIsmReader.js +29 -12
- package/dist/ism/EvmIsmReader.js.map +1 -1
- package/dist/ism/EvmIsmReader.test.js +227 -8
- package/dist/ism/EvmIsmReader.test.js.map +1 -1
- package/dist/ism/HyperlaneIsmFactory.d.ts.map +1 -1
- package/dist/ism/HyperlaneIsmFactory.hardhat-test.js +166 -2
- package/dist/ism/HyperlaneIsmFactory.hardhat-test.js.map +1 -1
- package/dist/ism/HyperlaneIsmFactory.js +3 -2
- package/dist/ism/HyperlaneIsmFactory.js.map +1 -1
- package/dist/ism/blacklist.d.ts +62 -0
- package/dist/ism/blacklist.d.ts.map +1 -0
- package/dist/ism/blacklist.js +98 -0
- package/dist/ism/blacklist.js.map +1 -0
- package/dist/ism/types.test.js +20 -1
- package/dist/ism/types.test.js.map +1 -1
- package/dist/ism/utils.d.ts.map +1 -1
- package/dist/ism/utils.js +26 -8
- package/dist/ism/utils.js.map +1 -1
- package/dist/metadata/ChainMetadataManager.d.ts +6 -0
- package/dist/metadata/ChainMetadataManager.d.ts.map +1 -1
- package/dist/metadata/ChainMetadataManager.js +21 -16
- package/dist/metadata/ChainMetadataManager.js.map +1 -1
- package/dist/metadata/ChainMetadataManager.test.js +30 -0
- package/dist/metadata/ChainMetadataManager.test.js.map +1 -1
- package/dist/metadata/warpRouteConfig.d.ts +10 -8
- package/dist/metadata/warpRouteConfig.d.ts.map +1 -1
- package/dist/middleware/account/InterchainAccount.d.ts.map +1 -1
- package/dist/middleware/account/InterchainAccount.js +38 -10
- package/dist/middleware/account/InterchainAccount.js.map +1 -1
- package/dist/middleware/account/InterchainAccount.test.js +182 -2
- package/dist/middleware/account/InterchainAccount.test.js.map +1 -1
- package/dist/providers/SmartProvider/HyperlaneEtherscanProvider.d.ts.map +1 -1
- package/dist/providers/SmartProvider/HyperlaneEtherscanProvider.js +21 -6
- package/dist/providers/SmartProvider/HyperlaneEtherscanProvider.js.map +1 -1
- package/dist/providers/SmartProvider/SmartProvider.d.ts +4 -0
- package/dist/providers/SmartProvider/SmartProvider.d.ts.map +1 -1
- package/dist/providers/SmartProvider/SmartProvider.js +1 -1
- package/dist/providers/SmartProvider/SmartProvider.js.map +1 -1
- package/dist/providers/SmartProvider/SmartProvider.test.js +82 -0
- package/dist/providers/SmartProvider/SmartProvider.test.js.map +1 -1
- package/dist/providers/transactionFeeEstimators.d.ts.map +1 -1
- package/dist/providers/transactionFeeEstimators.js +16 -10
- package/dist/providers/transactionFeeEstimators.js.map +1 -1
- package/dist/providers/transactionFeeEstimators.test.js +66 -1
- package/dist/providers/transactionFeeEstimators.test.js.map +1 -1
- package/dist/router/ProxiedRouterDeployer.d.ts.map +1 -1
- package/dist/router/ProxiedRouterDeployer.js +9 -0
- package/dist/router/ProxiedRouterDeployer.js.map +1 -1
- package/dist/router/types.d.ts +80 -0
- package/dist/router/types.d.ts.map +1 -1
- package/dist/router/types.js +4 -1
- package/dist/router/types.js.map +1 -1
- package/dist/router/types.test.js +76 -0
- package/dist/router/types.test.js.map +1 -1
- package/dist/rpc/evm/EvmEventLogsReader.d.ts +14 -0
- package/dist/rpc/evm/EvmEventLogsReader.d.ts.map +1 -1
- package/dist/rpc/evm/EvmEventLogsReader.hardhat-test.js +209 -3
- package/dist/rpc/evm/EvmEventLogsReader.hardhat-test.js.map +1 -1
- package/dist/rpc/evm/EvmEventLogsReader.js +96 -11
- package/dist/rpc/evm/EvmEventLogsReader.js.map +1 -1
- package/dist/rpc/evm/utils.d.ts +7 -11
- package/dist/rpc/evm/utils.d.ts.map +1 -1
- package/dist/rpc/evm/utils.hardhat-test.js +34 -9
- package/dist/rpc/evm/utils.hardhat-test.js.map +1 -1
- package/dist/rpc/evm/utils.js +10 -20
- package/dist/rpc/evm/utils.js.map +1 -1
- package/dist/test/contractDouble.d.ts +8 -0
- package/dist/test/contractDouble.d.ts.map +1 -0
- package/dist/test/contractDouble.js +12 -0
- package/dist/test/contractDouble.js.map +1 -0
- package/dist/timelock/evm/constants.d.ts +1 -0
- package/dist/timelock/evm/constants.d.ts.map +1 -1
- package/dist/timelock/evm/constants.js +1 -0
- package/dist/timelock/evm/constants.js.map +1 -1
- package/dist/timelock/evm/errors.d.ts +2 -0
- package/dist/timelock/evm/errors.d.ts.map +1 -0
- package/dist/timelock/evm/errors.js +19 -0
- package/dist/timelock/evm/errors.js.map +1 -0
- package/dist/timelock/evm/errors.test.d.ts +2 -0
- package/dist/timelock/evm/errors.test.d.ts.map +1 -0
- package/dist/timelock/evm/errors.test.js +33 -0
- package/dist/timelock/evm/errors.test.js.map +1 -0
- package/dist/token/EvmWarpModule.d.ts +17 -0
- package/dist/token/EvmWarpModule.d.ts.map +1 -1
- package/dist/token/EvmWarpModule.hardhat-test.js +144 -0
- package/dist/token/EvmWarpModule.hardhat-test.js.map +1 -1
- package/dist/token/EvmWarpModule.js +191 -6
- package/dist/token/EvmWarpModule.js.map +1 -1
- package/dist/token/EvmWarpModule.test.js +232 -8
- package/dist/token/EvmWarpModule.test.js.map +1 -1
- package/dist/token/EvmWarpRouteReader.d.ts +1 -0
- package/dist/token/EvmWarpRouteReader.d.ts.map +1 -1
- package/dist/token/EvmWarpRouteReader.hardhat-test.js +68 -3
- package/dist/token/EvmWarpRouteReader.hardhat-test.js.map +1 -1
- package/dist/token/EvmWarpRouteReader.js +83 -6
- package/dist/token/EvmWarpRouteReader.js.map +1 -1
- package/dist/token/ITokenMetadata.d.ts +3 -2
- package/dist/token/ITokenMetadata.d.ts.map +1 -1
- package/dist/token/Token.d.ts.map +1 -1
- package/dist/token/Token.js +4 -0
- package/dist/token/Token.js.map +1 -1
- package/dist/token/Token.test.js +16 -0
- package/dist/token/Token.test.js.map +1 -1
- package/dist/token/TokenStandard.d.ts +3 -1
- package/dist/token/TokenStandard.d.ts.map +1 -1
- package/dist/token/TokenStandard.js +6 -0
- package/dist/token/TokenStandard.js.map +1 -1
- package/dist/token/config.d.ts +2 -0
- package/dist/token/config.d.ts.map +1 -1
- package/dist/token/config.js +4 -0
- package/dist/token/config.js.map +1 -1
- package/dist/token/configUtils.d.ts +5 -0
- package/dist/token/configUtils.d.ts.map +1 -1
- package/dist/token/configUtils.js +30 -6
- package/dist/token/configUtils.js.map +1 -1
- package/dist/token/configUtils.test.js +21 -1
- package/dist/token/configUtils.test.js.map +1 -1
- package/dist/token/contracts.d.ts +3 -1
- package/dist/token/contracts.d.ts.map +1 -1
- package/dist/token/contracts.js +3 -1
- package/dist/token/contracts.js.map +1 -1
- package/dist/token/deploy.d.ts +3 -1
- package/dist/token/deploy.d.ts.map +1 -1
- package/dist/token/deploy.hardhat-test.js +111 -3
- package/dist/token/deploy.hardhat-test.js.map +1 -1
- package/dist/token/deploy.js +52 -3
- package/dist/token/deploy.js.map +1 -1
- package/dist/token/tokenMetadataUtils.d.ts.map +1 -1
- package/dist/token/tokenMetadataUtils.js +20 -2
- package/dist/token/tokenMetadataUtils.js.map +1 -1
- package/dist/token/types.d.ts +9807 -5533
- package/dist/token/types.d.ts.map +1 -1
- package/dist/token/types.js +49 -3
- package/dist/token/types.js.map +1 -1
- package/dist/token/types.test.js +21 -0
- package/dist/token/types.test.js.map +1 -1
- package/dist/token/warpCheck.d.ts.map +1 -1
- package/dist/token/warpCheck.js +100 -2
- package/dist/token/warpCheck.js.map +1 -1
- package/dist/token/warpCheck.test.js +101 -1
- package/dist/token/warpCheck.test.js.map +1 -1
- package/dist/warp/types.d.ts +5 -4
- package/dist/warp/types.d.ts.map +1 -1
- package/package.json +11 -11
package/dist/router/types.d.ts
CHANGED
|
@@ -724,6 +724,32 @@ export declare const RouterConfigSchema: z.ZodObject<{
|
|
|
724
724
|
interchainSecurityModule: z.ZodOptional<z.ZodType<import("../ism/types.js").IsmConfig, z.ZodTypeDef, unknown>>;
|
|
725
725
|
} & {
|
|
726
726
|
foreignDeployment: z.ZodOptional<z.ZodString>;
|
|
727
|
+
} & {
|
|
728
|
+
timelock: z.ZodOptional<z.ZodObject<{
|
|
729
|
+
delay: z.ZodEffects<z.ZodNumber, number, number>;
|
|
730
|
+
roles: z.ZodObject<{
|
|
731
|
+
executor: z.ZodEffects<z.ZodString, string, string>;
|
|
732
|
+
proposer: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
733
|
+
}, "strip", z.ZodTypeAny, {
|
|
734
|
+
executor: string;
|
|
735
|
+
proposer: string;
|
|
736
|
+
}, {
|
|
737
|
+
executor: string;
|
|
738
|
+
proposer: string;
|
|
739
|
+
}>;
|
|
740
|
+
}, "strip", z.ZodTypeAny, {
|
|
741
|
+
delay: number;
|
|
742
|
+
roles: {
|
|
743
|
+
executor: string;
|
|
744
|
+
proposer: string;
|
|
745
|
+
};
|
|
746
|
+
}, {
|
|
747
|
+
delay: number;
|
|
748
|
+
roles: {
|
|
749
|
+
executor: string;
|
|
750
|
+
proposer: string;
|
|
751
|
+
};
|
|
752
|
+
}>>;
|
|
727
753
|
} & {
|
|
728
754
|
remoteRouters: z.ZodOptional<z.ZodRecord<z.ZodUnion<[z.ZodString, z.ZodNumber]>, z.ZodObject<{
|
|
729
755
|
address: z.ZodString;
|
|
@@ -972,6 +998,13 @@ export declare const RouterConfigSchema: z.ZodObject<{
|
|
|
972
998
|
}, "strip", z.ZodTypeAny, {
|
|
973
999
|
owner: string;
|
|
974
1000
|
ownerOverrides?: Record<string, string> | undefined;
|
|
1001
|
+
timelock?: {
|
|
1002
|
+
delay: number;
|
|
1003
|
+
roles: {
|
|
1004
|
+
executor: string;
|
|
1005
|
+
proposer: string;
|
|
1006
|
+
};
|
|
1007
|
+
} | undefined;
|
|
975
1008
|
mailbox: string;
|
|
976
1009
|
hook?: string | import("../hook/types.js").AggregationHookConfig | import("../hook/types.js").AmountRoutingHookConfig | import("../hook/types.js").ArbL2ToL1HookConfig | {
|
|
977
1010
|
owner: string;
|
|
@@ -1089,6 +1122,13 @@ export declare const RouterConfigSchema: z.ZodObject<{
|
|
|
1089
1122
|
}, {
|
|
1090
1123
|
owner: string;
|
|
1091
1124
|
ownerOverrides?: Record<string, string> | undefined;
|
|
1125
|
+
timelock?: {
|
|
1126
|
+
delay: number;
|
|
1127
|
+
roles: {
|
|
1128
|
+
executor: string;
|
|
1129
|
+
proposer: string;
|
|
1130
|
+
};
|
|
1131
|
+
} | undefined;
|
|
1092
1132
|
mailbox: string;
|
|
1093
1133
|
hook?: unknown;
|
|
1094
1134
|
interchainSecurityModule?: unknown;
|
|
@@ -1421,6 +1461,32 @@ export declare const GasRouterConfigSchema: z.ZodObject<{
|
|
|
1421
1461
|
interchainSecurityModule: z.ZodOptional<z.ZodType<import("../ism/types.js").IsmConfig, z.ZodTypeDef, unknown>>;
|
|
1422
1462
|
} & {
|
|
1423
1463
|
foreignDeployment: z.ZodOptional<z.ZodString>;
|
|
1464
|
+
} & {
|
|
1465
|
+
timelock: z.ZodOptional<z.ZodObject<{
|
|
1466
|
+
delay: z.ZodEffects<z.ZodNumber, number, number>;
|
|
1467
|
+
roles: z.ZodObject<{
|
|
1468
|
+
executor: z.ZodEffects<z.ZodString, string, string>;
|
|
1469
|
+
proposer: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
1470
|
+
}, "strip", z.ZodTypeAny, {
|
|
1471
|
+
executor: string;
|
|
1472
|
+
proposer: string;
|
|
1473
|
+
}, {
|
|
1474
|
+
executor: string;
|
|
1475
|
+
proposer: string;
|
|
1476
|
+
}>;
|
|
1477
|
+
}, "strip", z.ZodTypeAny, {
|
|
1478
|
+
delay: number;
|
|
1479
|
+
roles: {
|
|
1480
|
+
executor: string;
|
|
1481
|
+
proposer: string;
|
|
1482
|
+
};
|
|
1483
|
+
}, {
|
|
1484
|
+
delay: number;
|
|
1485
|
+
roles: {
|
|
1486
|
+
executor: string;
|
|
1487
|
+
proposer: string;
|
|
1488
|
+
};
|
|
1489
|
+
}>>;
|
|
1424
1490
|
} & {
|
|
1425
1491
|
remoteRouters: z.ZodOptional<z.ZodRecord<z.ZodUnion<[z.ZodString, z.ZodNumber]>, z.ZodObject<{
|
|
1426
1492
|
address: z.ZodString;
|
|
@@ -1673,6 +1739,13 @@ export declare const GasRouterConfigSchema: z.ZodObject<{
|
|
|
1673
1739
|
}, "strip", z.ZodTypeAny, {
|
|
1674
1740
|
owner: string;
|
|
1675
1741
|
ownerOverrides?: Record<string, string> | undefined;
|
|
1742
|
+
timelock?: {
|
|
1743
|
+
delay: number;
|
|
1744
|
+
roles: {
|
|
1745
|
+
executor: string;
|
|
1746
|
+
proposer: string;
|
|
1747
|
+
};
|
|
1748
|
+
} | undefined;
|
|
1676
1749
|
mailbox: string;
|
|
1677
1750
|
hook?: string | import("../hook/types.js").AggregationHookConfig | import("../hook/types.js").AmountRoutingHookConfig | import("../hook/types.js").ArbL2ToL1HookConfig | {
|
|
1678
1751
|
owner: string;
|
|
@@ -1793,6 +1866,13 @@ export declare const GasRouterConfigSchema: z.ZodObject<{
|
|
|
1793
1866
|
}, {
|
|
1794
1867
|
owner: string;
|
|
1795
1868
|
ownerOverrides?: Record<string, string> | undefined;
|
|
1869
|
+
timelock?: {
|
|
1870
|
+
delay: number;
|
|
1871
|
+
roles: {
|
|
1872
|
+
executor: string;
|
|
1873
|
+
proposer: string;
|
|
1874
|
+
};
|
|
1875
|
+
} | undefined;
|
|
1796
1876
|
mailbox: string;
|
|
1797
1877
|
hook?: unknown;
|
|
1798
1878
|
interchainSecurityModule?: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/router/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,MAAM,EACN,2BAA2B,EAC5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,cAAc,EAAa,MAAM,sBAAsB,CAAC;AAE1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/router/types.ts"],"names":[],"mappings":"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"}
|
package/dist/router/types.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { ProxyAdmin__factory, TimelockController__factory, } from '@hyperlane-xyz/core';
|
|
3
3
|
import { isNumeric } from '@hyperlane-xyz/utils';
|
|
4
|
+
import { UpgradeConfigSchema } from '../deploy/proxy.js';
|
|
4
5
|
import { TokenFeeConfigInputSchema } from '../fee/types.js';
|
|
5
6
|
import { HookConfigSchema } from '../hook/types.js';
|
|
6
7
|
import { IsmConfigSchema } from '../ism/types.js';
|
|
@@ -44,7 +45,9 @@ export const RemoteRouterRouter = z.object({
|
|
|
44
45
|
address: z.string().startsWith('0x'),
|
|
45
46
|
});
|
|
46
47
|
export const RemoteRoutersSchema = z.record(RemoteRouterDomainOrChainNameSchema, RemoteRouterRouter);
|
|
47
|
-
export const RouterConfigSchema = MailboxClientConfigSchema.merge(ForeignDeploymentConfigSchema)
|
|
48
|
+
export const RouterConfigSchema = MailboxClientConfigSchema.merge(ForeignDeploymentConfigSchema)
|
|
49
|
+
.merge(UpgradeConfigSchema.partial())
|
|
50
|
+
.merge(z.object({
|
|
48
51
|
remoteRouters: RemoteRoutersSchema.optional(),
|
|
49
52
|
proxyAdmin: DeployedOwnableSchema.optional(),
|
|
50
53
|
tokenFee: TokenFeeConfigInputSchema.optional(),
|
package/dist/router/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/router/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAEL,mBAAmB,EAEnB,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAA2B,SAAS,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/router/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,15 @@ import { expect } from 'chai';
|
|
|
2
2
|
import { ethers } from 'ethers';
|
|
3
3
|
import { GasRouterConfigSchema } from './types.js';
|
|
4
4
|
const SOME_ADDRESS = ethers.Wallet.createRandom().address;
|
|
5
|
+
const EXECUTOR_ADDRESS = ethers.Wallet.createRandom().address;
|
|
6
|
+
const PROPOSER_ADDRESS = ethers.Wallet.createRandom().address;
|
|
7
|
+
const VALID_TIMELOCK = {
|
|
8
|
+
delay: 259200,
|
|
9
|
+
roles: {
|
|
10
|
+
executor: EXECUTOR_ADDRESS,
|
|
11
|
+
proposer: PROPOSER_ADDRESS,
|
|
12
|
+
},
|
|
13
|
+
};
|
|
5
14
|
describe('GasRouterConfigSchema', () => {
|
|
6
15
|
const baseConfig = {
|
|
7
16
|
owner: SOME_ADDRESS,
|
|
@@ -28,5 +37,72 @@ describe('GasRouterConfigSchema', () => {
|
|
|
28
37
|
});
|
|
29
38
|
expect(result.success).to.be.false;
|
|
30
39
|
});
|
|
40
|
+
it('should accept config with timelock', () => {
|
|
41
|
+
const result = GasRouterConfigSchema.safeParse({
|
|
42
|
+
...baseConfig,
|
|
43
|
+
timelock: VALID_TIMELOCK,
|
|
44
|
+
});
|
|
45
|
+
expect(result.success).to.be.true;
|
|
46
|
+
if (result.success) {
|
|
47
|
+
expect(result.data.timelock?.delay).to.equal(259200);
|
|
48
|
+
expect(result.data.timelock?.roles.executor).to.equal(EXECUTOR_ADDRESS);
|
|
49
|
+
expect(result.data.timelock?.roles.proposer).to.equal(PROPOSER_ADDRESS);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
for (const [name, timelock] of [
|
|
53
|
+
[
|
|
54
|
+
'non-EVM executor hash',
|
|
55
|
+
{
|
|
56
|
+
...VALID_TIMELOCK,
|
|
57
|
+
roles: {
|
|
58
|
+
...VALID_TIMELOCK.roles,
|
|
59
|
+
executor: '0x1111111111111111111111111111111111111111111111111111111111111111',
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
[
|
|
64
|
+
'invalid executor checksum',
|
|
65
|
+
{
|
|
66
|
+
...VALID_TIMELOCK,
|
|
67
|
+
roles: {
|
|
68
|
+
...VALID_TIMELOCK.roles,
|
|
69
|
+
executor: '0x8Ba1f109551bD432803012645Ac136ddd64DBA72',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
['unsafe delay', { ...VALID_TIMELOCK, delay: Number.MAX_SAFE_INTEGER + 1 }],
|
|
74
|
+
[
|
|
75
|
+
'zero-address proposer',
|
|
76
|
+
{
|
|
77
|
+
...VALID_TIMELOCK,
|
|
78
|
+
roles: {
|
|
79
|
+
...VALID_TIMELOCK.roles,
|
|
80
|
+
proposer: ethers.constants.AddressZero,
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
['zero delay', { ...VALID_TIMELOCK, delay: 0 }],
|
|
85
|
+
]) {
|
|
86
|
+
it(`should reject timelock with ${name}`, () => {
|
|
87
|
+
const result = GasRouterConfigSchema.safeParse({
|
|
88
|
+
...baseConfig,
|
|
89
|
+
timelock,
|
|
90
|
+
});
|
|
91
|
+
expect(result.success).to.be.false;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
it('should accept timelock with zero-address executor', () => {
|
|
95
|
+
const result = GasRouterConfigSchema.safeParse({
|
|
96
|
+
...baseConfig,
|
|
97
|
+
timelock: {
|
|
98
|
+
...VALID_TIMELOCK,
|
|
99
|
+
roles: {
|
|
100
|
+
...VALID_TIMELOCK.roles,
|
|
101
|
+
executor: ethers.constants.AddressZero,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
expect(result.success).to.be.true;
|
|
106
|
+
});
|
|
31
107
|
});
|
|
32
108
|
//# sourceMappingURL=types.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.test.js","sourceRoot":"","sources":["../../src/router/types.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.test.js","sourceRoot":"","sources":["../../src/router/types.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,7 @@ export type EvmEventLogsReaderConfig = {
|
|
|
9
9
|
chain: ChainNameOrId;
|
|
10
10
|
useRPC?: boolean;
|
|
11
11
|
paginationBlockRange?: number;
|
|
12
|
+
explorerFallback?: ExplorerFallbackConfig;
|
|
12
13
|
};
|
|
13
14
|
export declare const GetLogByTopicOptionsSchema: z.ZodObject<{
|
|
14
15
|
eventTopic: z.ZodEffects<z.ZodString, string, string>;
|
|
@@ -48,6 +49,7 @@ interface IEvmEventLogsReaderStrategy {
|
|
|
48
49
|
getContractDeploymentBlockNumber(address: Address): Promise<number>;
|
|
49
50
|
getContractLogs(address: RequiredGetLogByTopicOptions): Promise<GetEventLogsResponse[]>;
|
|
50
51
|
}
|
|
52
|
+
export type ExplorerFallbackConfig = Partial<Record<keyof IEvmEventLogsReaderStrategy, boolean>>;
|
|
51
53
|
export declare class EvmEtherscanLikeEventLogsReader implements IEvmEventLogsReaderStrategy {
|
|
52
54
|
protected readonly chain: ChainNameOrId;
|
|
53
55
|
protected readonly config: Awaited<ReturnType<ChainMetadataManager['getExplorerApi']>>;
|
|
@@ -68,6 +70,16 @@ export declare class EvmRpcEventLogsReader implements IEvmEventLogsReaderStrateg
|
|
|
68
70
|
getContractDeploymentBlockNumber(address: string): Promise<number>;
|
|
69
71
|
getContractLogs(options: RequiredGetLogByTopicOptions): Promise<GetEventLogsResponse[]>;
|
|
70
72
|
}
|
|
73
|
+
export declare class FallbackEvmEventLogsReader implements IEvmEventLogsReaderStrategy {
|
|
74
|
+
protected readonly chain: ChainNameOrId;
|
|
75
|
+
protected readonly readers: EvmEtherscanLikeEventLogsReader[];
|
|
76
|
+
protected readonly logger: Logger;
|
|
77
|
+
protected readonly config: ExplorerFallbackConfig;
|
|
78
|
+
constructor(chain: ChainNameOrId, readers: EvmEtherscanLikeEventLogsReader[], logger: Logger, config?: ExplorerFallbackConfig);
|
|
79
|
+
private executeWithFallback;
|
|
80
|
+
getContractDeploymentBlockNumber(address: Address): Promise<number>;
|
|
81
|
+
getContractLogs(options: RequiredGetLogByTopicOptions): Promise<GetEventLogsResponse[]>;
|
|
82
|
+
}
|
|
71
83
|
export declare class EvmEventLogsReader {
|
|
72
84
|
protected readonly config: EvmEventLogsReaderConfig;
|
|
73
85
|
protected readonly multiProvider: MultiProvider;
|
|
@@ -75,8 +87,10 @@ export declare class EvmEventLogsReader {
|
|
|
75
87
|
protected readonly logger: Logger;
|
|
76
88
|
protected fallbackLogReaderStrategy?: IEvmEventLogsReaderStrategy | undefined;
|
|
77
89
|
private deploymentBlockCache;
|
|
90
|
+
private explorerDeploymentBlockCache;
|
|
78
91
|
protected constructor(config: EvmEventLogsReaderConfig, multiProvider: MultiProvider, logReaderStrategy: IEvmEventLogsReaderStrategy, logger: Logger, fallbackLogReaderStrategy?: IEvmEventLogsReaderStrategy | undefined);
|
|
79
92
|
static fromConfig(config: EvmEventLogsReaderConfig, multiProvider: MultiProvider, logger?: Logger): EvmEventLogsReader;
|
|
93
|
+
getContractDeploymentBlockFromExplorer(contractAddress: Address): Promise<number>;
|
|
80
94
|
getLogsByTopic(options: GetLogByTopicOptions): Promise<GetEventLogsResponse[]>;
|
|
81
95
|
private getDeploymentBlock;
|
|
82
96
|
private getLogsByTopicWithStrategy;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EvmEventLogsReader.d.ts","sourceRoot":"","sources":["../../../src/rpc/evm/EvmEventLogsReader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EACL,OAAO,EAKR,MAAM,sBAAsB,CAAC;AAO9B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAEnF,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGlD,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,EAAE,aAAa,CAAC;IAGrB,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,oBAAoB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"EvmEventLogsReader.d.ts","sourceRoot":"","sources":["../../../src/rpc/evm/EvmEventLogsReader.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,10 +5,11 @@ import hre from 'hardhat';
|
|
|
5
5
|
import sinon from 'sinon';
|
|
6
6
|
import { ERC20Test__factory } from '@hyperlane-xyz/core';
|
|
7
7
|
import { assert } from '@hyperlane-xyz/utils';
|
|
8
|
-
import { KNOWN_ETHEREUM_TIMELOCK_CONTRACT, TestChainName, ethereumTestChain, } from '../../consts/testChains.js';
|
|
8
|
+
import { KNOWN_ETHEREUM_TIMELOCK_CONTRACT, TestChainName, ethereumTestChain, test1, } from '../../consts/testChains.js';
|
|
9
|
+
import { ExplorerFamily } from '../../metadata/chainMetadataTypes.js';
|
|
9
10
|
import { MultiProvider } from '../../providers/MultiProvider.js';
|
|
10
11
|
import { randomAddress, randomInt } from '../../test/testUtils.js';
|
|
11
|
-
import { EvmEtherscanLikeEventLogsReader, EvmEventLogsReader, EvmRpcEventLogsReader, } from './EvmEventLogsReader.js';
|
|
12
|
+
import { EvmEtherscanLikeEventLogsReader, EvmEventLogsReader, EvmRpcEventLogsReader, FallbackEvmEventLogsReader, } from './EvmEventLogsReader.js';
|
|
12
13
|
chai.use(chaiAsPromised);
|
|
13
14
|
describe('EvmEventLogsReader', () => {
|
|
14
15
|
let contractOwner;
|
|
@@ -33,6 +34,7 @@ describe('EvmEventLogsReader', () => {
|
|
|
33
34
|
// Get contract factory for ERC20Test
|
|
34
35
|
erc20Factory = new ERC20Test__factory(contractOwner);
|
|
35
36
|
});
|
|
37
|
+
afterEach(() => sinon.restore());
|
|
36
38
|
async function deployTestErc20() {
|
|
37
39
|
testContract = await erc20Factory.deploy('TestToken', 'TST', ethers.utils.parseEther('1000000'), 18);
|
|
38
40
|
await testContract.deployed();
|
|
@@ -51,7 +53,7 @@ describe('EvmEventLogsReader', () => {
|
|
|
51
53
|
chain: TestChainName.test1,
|
|
52
54
|
}, multiProvider);
|
|
53
55
|
// Access the private property indirectly
|
|
54
|
-
expect(readerWithRpc['logReaderStrategy']).to.be.instanceOf(
|
|
56
|
+
expect(readerWithRpc['logReaderStrategy']).to.be.instanceOf(FallbackEvmEventLogsReader);
|
|
55
57
|
});
|
|
56
58
|
it('should initialize with RPC strategy when useRPC is true', async () => {
|
|
57
59
|
const readerWithRpc = EvmEventLogsReader.fromConfig({
|
|
@@ -72,6 +74,34 @@ describe('EvmEventLogsReader', () => {
|
|
|
72
74
|
// Access the private property indirectly
|
|
73
75
|
expect(reader['logReaderStrategy']).to.be.instanceOf(EvmRpcEventLogsReader);
|
|
74
76
|
});
|
|
77
|
+
it('should allow explorer fallback to be enabled per method', async () => {
|
|
78
|
+
const firstReader = new EvmEtherscanLikeEventLogsReader(TestChainName.test1, {
|
|
79
|
+
apiKey: 'first-key',
|
|
80
|
+
apiUrl: 'https://first.example.com/api',
|
|
81
|
+
family: ExplorerFamily.Etherscan,
|
|
82
|
+
}, multiProvider);
|
|
83
|
+
const secondReader = new EvmEtherscanLikeEventLogsReader(TestChainName.test1, {
|
|
84
|
+
apiUrl: 'https://second.example.com/api',
|
|
85
|
+
family: ExplorerFamily.Blockscout,
|
|
86
|
+
}, multiProvider);
|
|
87
|
+
const firstGetLogs = sinon
|
|
88
|
+
.stub(firstReader, 'getContractLogs')
|
|
89
|
+
.rejects(new Error('first explorer failed'));
|
|
90
|
+
const secondGetLogs = sinon
|
|
91
|
+
.stub(secondReader, 'getContractLogs')
|
|
92
|
+
.resolves([]);
|
|
93
|
+
const reader = new FallbackEvmEventLogsReader(TestChainName.test1, [firstReader, secondReader], multiProvider.logger, {
|
|
94
|
+
getContractLogs: true,
|
|
95
|
+
});
|
|
96
|
+
expect(await reader.getContractLogs({
|
|
97
|
+
contractAddress: randomAddress(),
|
|
98
|
+
eventTopic: ethers.constants.HashZero,
|
|
99
|
+
fromBlock: 0,
|
|
100
|
+
toBlock: 0,
|
|
101
|
+
})).to.deep.equal([]);
|
|
102
|
+
expect(firstGetLogs.calledOnce).to.be.true;
|
|
103
|
+
expect(secondGetLogs.calledOnce).to.be.true;
|
|
104
|
+
});
|
|
75
105
|
});
|
|
76
106
|
describe(`${EvmEventLogsReader.prototype.getLogsByTopic.name} (rpc)`, () => {
|
|
77
107
|
let reader;
|
|
@@ -259,6 +289,34 @@ describe('EvmEventLogsReader', () => {
|
|
|
259
289
|
});
|
|
260
290
|
});
|
|
261
291
|
describe('retry before fallback', () => {
|
|
292
|
+
it('should keep the explorer deployment block when logs fall back to RPC', async () => {
|
|
293
|
+
await deployTestErc20();
|
|
294
|
+
const reader = EvmEventLogsReader.fromConfig({ chain: TestChainName.test1 }, multiProvider);
|
|
295
|
+
const primaryStrategy = reader['logReaderStrategy'];
|
|
296
|
+
const fallbackStrategy = reader['fallbackLogReaderStrategy'];
|
|
297
|
+
assert(primaryStrategy instanceof FallbackEvmEventLogsReader, 'Expected a fallback explorer log reader');
|
|
298
|
+
assert(fallbackStrategy, 'Expected an RPC fallback log reader');
|
|
299
|
+
const [explorerReader] = primaryStrategy['readers'];
|
|
300
|
+
sinon
|
|
301
|
+
.stub(explorerReader, 'getContractDeploymentBlockNumber')
|
|
302
|
+
.resolves(deploymentBlockNumber);
|
|
303
|
+
const explorerGetLogs = sinon
|
|
304
|
+
.stub(explorerReader, 'getContractLogs')
|
|
305
|
+
.rejects(Object.assign(new Error('explorer logs unavailable'), {
|
|
306
|
+
isRecoverable: false,
|
|
307
|
+
}));
|
|
308
|
+
const fallbackGetLogs = sinon.spy(fallbackStrategy, 'getContractLogs');
|
|
309
|
+
const fromBlock = await reader.getContractDeploymentBlockFromExplorer(testContract.address);
|
|
310
|
+
const logs = await reader.getLogsByTopic({
|
|
311
|
+
eventTopic: transferTopic,
|
|
312
|
+
contractAddress: testContract.address,
|
|
313
|
+
fromBlock,
|
|
314
|
+
});
|
|
315
|
+
expect(logs).to.have.length(1);
|
|
316
|
+
expect(explorerGetLogs.calledOnce).to.be.true;
|
|
317
|
+
expect(fallbackGetLogs.calledOnce).to.be.true;
|
|
318
|
+
expect(fallbackGetLogs.firstCall.args[0].fromBlock).to.equal(deploymentBlockNumber);
|
|
319
|
+
});
|
|
262
320
|
it('should succeed on retry without hitting fallback', async () => {
|
|
263
321
|
await deployTestErc20();
|
|
264
322
|
const reader = EvmEventLogsReader.fromConfig({ chain: TestChainName.test1, useRPC: true }, multiProvider);
|
|
@@ -307,8 +365,119 @@ describe('EvmEventLogsReader', () => {
|
|
|
307
365
|
expect(logs.length).to.be.greaterThan(0);
|
|
308
366
|
expect(fallbackSpy.callCount).to.equal(1);
|
|
309
367
|
});
|
|
368
|
+
it('should use the same toBlock for primary and fallback reads', async () => {
|
|
369
|
+
await deployTestErc20();
|
|
370
|
+
const reader = EvmEventLogsReader.fromConfig({ chain: TestChainName.test1, useRPC: true }, multiProvider);
|
|
371
|
+
const snapshotBlock = deploymentBlockNumber + 100;
|
|
372
|
+
const getBlockNumber = sinon
|
|
373
|
+
.stub(providerChainTest1, 'getBlockNumber')
|
|
374
|
+
.onFirstCall()
|
|
375
|
+
.resolves(snapshotBlock)
|
|
376
|
+
.onSecondCall()
|
|
377
|
+
.resolves(snapshotBlock + 1);
|
|
378
|
+
const primaryGetLogs = sinon.stub().rejects(Object.assign(new Error('primary failed'), {
|
|
379
|
+
isRecoverable: false,
|
|
380
|
+
}));
|
|
381
|
+
const fallbackGetLogs = sinon.stub().resolves([]);
|
|
382
|
+
reader['logReaderStrategy'] = {
|
|
383
|
+
getContractDeploymentBlockNumber: async () => deploymentBlockNumber,
|
|
384
|
+
getContractLogs: primaryGetLogs,
|
|
385
|
+
};
|
|
386
|
+
reader['fallbackLogReaderStrategy'] = {
|
|
387
|
+
getContractDeploymentBlockNumber: async () => deploymentBlockNumber,
|
|
388
|
+
getContractLogs: fallbackGetLogs,
|
|
389
|
+
};
|
|
390
|
+
await reader.getLogsByTopic({
|
|
391
|
+
eventTopic: transferTopic,
|
|
392
|
+
contractAddress: testContract.address,
|
|
393
|
+
fromBlock: deploymentBlockNumber,
|
|
394
|
+
});
|
|
395
|
+
expect(getBlockNumber.callCount).to.equal(1);
|
|
396
|
+
expect(primaryGetLogs.firstCall.args[0].toBlock).to.equal(snapshotBlock);
|
|
397
|
+
expect(fallbackGetLogs.firstCall.args[0].toBlock).to.equal(snapshotBlock);
|
|
398
|
+
});
|
|
310
399
|
});
|
|
311
400
|
describe('deployment block cache', () => {
|
|
401
|
+
it('falls back between explorers for deployment blocks and logs', async () => {
|
|
402
|
+
await deployTestErc20();
|
|
403
|
+
const multiExplorerProvider = new MultiProvider({
|
|
404
|
+
[TestChainName.test1]: {
|
|
405
|
+
...test1,
|
|
406
|
+
blockExplorers: [
|
|
407
|
+
{
|
|
408
|
+
apiKey: 'first-key',
|
|
409
|
+
apiUrl: 'https://first.example.com/api',
|
|
410
|
+
family: ExplorerFamily.Etherscan,
|
|
411
|
+
name: 'First explorer',
|
|
412
|
+
url: 'https://first.example.com',
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
apiUrl: 'https://second.example.com/api',
|
|
416
|
+
family: ExplorerFamily.Blockscout,
|
|
417
|
+
name: 'Second explorer',
|
|
418
|
+
url: 'https://second.example.com',
|
|
419
|
+
},
|
|
420
|
+
],
|
|
421
|
+
},
|
|
422
|
+
});
|
|
423
|
+
multiExplorerProvider.setProvider(TestChainName.test1, providerChainTest1);
|
|
424
|
+
const reader = EvmEventLogsReader.fromConfig({ chain: TestChainName.test1 }, multiExplorerProvider);
|
|
425
|
+
const fallbackExplorerReader = reader['logReaderStrategy'];
|
|
426
|
+
assert(fallbackExplorerReader instanceof FallbackEvmEventLogsReader, 'Expected a fallback explorer log reader');
|
|
427
|
+
const [firstExplorer, secondExplorer] = fallbackExplorerReader['readers'];
|
|
428
|
+
const firstError = Object.assign(new Error('first explorer failed'), {
|
|
429
|
+
isRecoverable: false,
|
|
430
|
+
});
|
|
431
|
+
const firstLookup = sinon
|
|
432
|
+
.stub(firstExplorer, 'getContractDeploymentBlockNumber')
|
|
433
|
+
.rejects(firstError);
|
|
434
|
+
const secondLookup = sinon
|
|
435
|
+
.stub(secondExplorer, 'getContractDeploymentBlockNumber')
|
|
436
|
+
.resolves(deploymentBlockNumber);
|
|
437
|
+
const firstGetLogs = sinon
|
|
438
|
+
.stub(firstExplorer, 'getContractLogs')
|
|
439
|
+
.rejects(firstError);
|
|
440
|
+
const secondGetLogs = sinon
|
|
441
|
+
.stub(secondExplorer, 'getContractLogs')
|
|
442
|
+
.resolves([]);
|
|
443
|
+
const rpcReader = reader['fallbackLogReaderStrategy'];
|
|
444
|
+
assert(rpcReader, 'Expected an RPC fallback log reader');
|
|
445
|
+
const rpcGetLogs = sinon.stub(rpcReader, 'getContractLogs').resolves([]);
|
|
446
|
+
expect(await reader.getContractDeploymentBlockFromExplorer(testContract.address)).to.equal(deploymentBlockNumber);
|
|
447
|
+
expect(firstLookup.calledOnce).to.be.true;
|
|
448
|
+
expect(secondLookup.calledOnce).to.be.true;
|
|
449
|
+
expect(await reader.getLogsByTopic({
|
|
450
|
+
contractAddress: testContract.address,
|
|
451
|
+
eventTopic: transferTopic,
|
|
452
|
+
fromBlock: deploymentBlockNumber,
|
|
453
|
+
toBlock: deploymentBlockNumber,
|
|
454
|
+
})).to.deep.equal([]);
|
|
455
|
+
expect(firstGetLogs.calledOnce).to.be.true;
|
|
456
|
+
expect(secondGetLogs.calledOnce).to.be.true;
|
|
457
|
+
expect(rpcGetLogs.notCalled).to.be.true;
|
|
458
|
+
});
|
|
459
|
+
it('should reject an explorer deployment lookup for an RPC-only reader', async () => {
|
|
460
|
+
await deployTestErc20();
|
|
461
|
+
const reader = EvmEventLogsReader.fromConfig({ chain: TestChainName.test1, useRPC: true }, multiProvider);
|
|
462
|
+
const deploymentSpy = sinon.spy(reader['logReaderStrategy'], 'getContractDeploymentBlockNumber');
|
|
463
|
+
await expect(reader.getContractDeploymentBlockFromExplorer(testContract.address)).to.be.rejectedWith(`No block explorer is configured for chain ${TestChainName.test1}`);
|
|
464
|
+
expect(deploymentSpy.notCalled).to.be.true;
|
|
465
|
+
});
|
|
466
|
+
it('should not use a cached RPC deployment block as an explorer block', async () => {
|
|
467
|
+
await deployTestErc20();
|
|
468
|
+
const reader = EvmEventLogsReader.fromConfig({ chain: TestChainName.test1 }, multiProvider);
|
|
469
|
+
const primaryStrategy = reader['logReaderStrategy'];
|
|
470
|
+
assert(primaryStrategy instanceof FallbackEvmEventLogsReader, 'Expected a fallback explorer log reader');
|
|
471
|
+
const [explorerReader] = primaryStrategy['readers'];
|
|
472
|
+
reader['deploymentBlockCache'].set(testContract.address, deploymentBlockNumber + 1);
|
|
473
|
+
const deploymentStub = sinon
|
|
474
|
+
.stub(explorerReader, 'getContractDeploymentBlockNumber')
|
|
475
|
+
.resolves(deploymentBlockNumber);
|
|
476
|
+
expect(await reader.getContractDeploymentBlockFromExplorer(testContract.address)).to.equal(deploymentBlockNumber);
|
|
477
|
+
expect(await reader.getContractDeploymentBlockFromExplorer(testContract.address)).to.equal(deploymentBlockNumber);
|
|
478
|
+
expect(deploymentStub.calledOnce).to.be.true;
|
|
479
|
+
expect(reader['deploymentBlockCache'].get(testContract.address)).to.equal(deploymentBlockNumber);
|
|
480
|
+
});
|
|
312
481
|
it('should only look up deployment block once for the same contract', async () => {
|
|
313
482
|
await deployTestErc20();
|
|
314
483
|
const reader = EvmEventLogsReader.fromConfig({ chain: TestChainName.test1, useRPC: true }, multiProvider);
|
|
@@ -377,6 +546,43 @@ describe('EvmEventLogsReader', () => {
|
|
|
377
546
|
fromBlock: deploymentBlockNumber,
|
|
378
547
|
})).to.be.rejectedWith();
|
|
379
548
|
});
|
|
549
|
+
it('should reject a log outside the requested range', async () => {
|
|
550
|
+
const toBlock = deploymentBlockNumber + 10;
|
|
551
|
+
const outOfRangeLog = {
|
|
552
|
+
address: testContract.address,
|
|
553
|
+
blockNumber: toBlock + 1,
|
|
554
|
+
data: '0x',
|
|
555
|
+
logIndex: 0,
|
|
556
|
+
topics: [transferTopic],
|
|
557
|
+
transactionHash: ethers.constants.HashZero,
|
|
558
|
+
transactionIndex: 0,
|
|
559
|
+
};
|
|
560
|
+
reader['logReaderStrategy'] = {
|
|
561
|
+
getContractDeploymentBlockNumber: async () => deploymentBlockNumber,
|
|
562
|
+
getContractLogs: async () => [outOfRangeLog],
|
|
563
|
+
};
|
|
564
|
+
await expect(reader.getLogsByTopic({
|
|
565
|
+
eventTopic: transferTopic,
|
|
566
|
+
contractAddress: testContract.address,
|
|
567
|
+
fromBlock: deploymentBlockNumber,
|
|
568
|
+
toBlock,
|
|
569
|
+
})).to.be.rejectedWith(`Log block ${toBlock + 1} is outside requested range ${deploymentBlockNumber}-${toBlock}`);
|
|
570
|
+
});
|
|
571
|
+
it('should reject a deployment block above the snapshotted head', async () => {
|
|
572
|
+
const headBlock = deploymentBlockNumber;
|
|
573
|
+
const deploymentBlock = headBlock + 1;
|
|
574
|
+
sinon.stub(providerChainTest1, 'getBlockNumber').resolves(headBlock);
|
|
575
|
+
const getContractLogs = sinon.stub().resolves([]);
|
|
576
|
+
reader['logReaderStrategy'] = {
|
|
577
|
+
getContractDeploymentBlockNumber: async () => deploymentBlock,
|
|
578
|
+
getContractLogs,
|
|
579
|
+
};
|
|
580
|
+
await expect(reader.getLogsByTopic({
|
|
581
|
+
eventTopic: transferTopic,
|
|
582
|
+
contractAddress: testContract.address,
|
|
583
|
+
})).to.be.rejectedWith(`Log range start ${deploymentBlock} exceeds end ${headBlock}`);
|
|
584
|
+
expect(getContractLogs.notCalled).to.be.true;
|
|
585
|
+
});
|
|
380
586
|
});
|
|
381
587
|
});
|
|
382
588
|
//# sourceMappingURL=EvmEventLogsReader.hardhat-test.js.map
|