Fix Smart Provider e2e test (#3150)

### Description

Remove hard-coding of min block number and topic1 value.

### Drive-by changes

Add convenience `isAddress` util function

### Related issues

https://github.com/hyperlane-xyz/hyperlane-monorepo/pull/3148

### Backward compatibility

Yes
avious00-typo-patch
J M Rossy 10 months ago committed by GitHub
parent 493c160b2e
commit 3c298d0646
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      .changeset/fast-pillows-wash.md
  2. 2
      typescript/sdk/package.json
  3. 63
      typescript/sdk/src/providers/SmartProvider/SmartProvider.test.ts
  4. 1
      typescript/utils/index.ts
  5. 4
      typescript/utils/src/addresses.ts

@ -0,0 +1,5 @@
---
'@hyperlane-xyz/utils': patch
---
Add isAddress function to check if string matches EVM, Cosmos, or Solana address formats

@ -61,7 +61,7 @@
"prepublishOnly": "yarn build", "prepublishOnly": "yarn build",
"prettier": "prettier --write ./src", "prettier": "prettier --write ./src",
"test": "yarn test:unit && yarn test:hardhat && yarn test:foundry", "test": "yarn test:unit && yarn test:hardhat && yarn test:foundry",
"test:ci": "yarn test:unit --exclude './src/**/SmartProvider.test.ts' && yarn test:hardhat && yarn test:foundry", "test:ci": "yarn test",
"test:unit": "mocha --config .mocharc.json './src/**/*.test.ts' --exit", "test:unit": "mocha --config .mocharc.json './src/**/*.test.ts' --exit",
"test:hardhat": "hardhat test $(find ./src -name \"*.hardhat-test.ts\")", "test:hardhat": "hardhat test $(find ./src -name \"*.hardhat-test.ts\")",
"test:metadata": "ts-node ./src/test/metadata-check.ts", "test:metadata": "ts-node ./src/test/metadata-check.ts",

@ -10,37 +10,30 @@ import { ChainMetadata } from '../../metadata/chainMetadataTypes';
import { ProviderMethod } from './ProviderMethods'; import { ProviderMethod } from './ProviderMethods';
import { HyperlaneSmartProvider } from './SmartProvider'; import { HyperlaneSmartProvider } from './SmartProvider';
const MIN_BLOCK_NUM = 10200000;
const DEFAULT_ACCOUNT = '0x9d525E28Fe5830eE92d7Aa799c4D21590567B595'; const DEFAULT_ACCOUNT = '0x9d525E28Fe5830eE92d7Aa799c4D21590567B595';
const WETH_CONTRACT = '0xb4fbf271143f4fbf7b91a5ded31805e42b2208d6'; const WETH_CONTRACT = '0xb4fbf271143f4fbf7b91a5ded31805e42b2208d6';
const WETH_TRANSFER_TOPIC0 = const WETH_TRANSFER_TOPIC0 =
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'; '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';
const WETH_TRANSFER_TOPIC1 =
'0x00000000000000000000000022a9af161b9660f3dc1b996bf1e622a2c58b8558';
const WETH_CALL_DATA = const WETH_CALL_DATA =
'0x70a082310000000000000000000000004f7a67464b5976d7547c860109e4432d50afb38e'; '0x70a082310000000000000000000000004f7a67464b5976d7547c860109e4432d50afb38e';
const TRANSFER_TX_HASH = const TRANSFER_TX_HASH =
'0x45a586f90ffd5d0f8e618f0f3703b14c2c9e4611af6231d6fed32c62776b6c1b'; '0x45a586f90ffd5d0f8e618f0f3703b14c2c9e4611af6231d6fed32c62776b6c1b';
const goerliRpcConfig = { const pagination = { maxBlockRange: 1000 };
...chainMetadata.goerli.rpcUrls[0], const goerliRpcConfig1 = { ...chainMetadata.goerli.rpcUrls[0], pagination };
pagination: { const goerliRpcConfig2 = { ...chainMetadata.goerli.rpcUrls[1], pagination };
maxBlockRange: 1000,
minBlockNumber: MIN_BLOCK_NUM,
},
};
const justExplorersConfig: ChainMetadata = { const justExplorersConfig: ChainMetadata = {
...chainMetadata.goerli, ...chainMetadata.goerli,
rpcUrls: [] as any, rpcUrls: [] as any,
}; };
const justRpcsConfig: ChainMetadata = { const justRpcsConfig: ChainMetadata = {
...chainMetadata.goerli, ...chainMetadata.goerli,
rpcUrls: [goerliRpcConfig], rpcUrls: [goerliRpcConfig1, goerliRpcConfig2],
blockExplorers: [], blockExplorers: [],
}; };
const combinedConfig: ChainMetadata = { const combinedConfig: ChainMetadata = {
...chainMetadata.goerli, ...chainMetadata.goerli,
rpcUrls: [goerliRpcConfig], rpcUrls: [goerliRpcConfig1],
}; };
const configs: [string, ChainMetadata][] = [ const configs: [string, ChainMetadata][] = [
['Just Explorers', justExplorersConfig], ['Just Explorers', justExplorersConfig],
@ -56,19 +49,22 @@ describe('SmartProvider', () => {
if (provider.supportedMethods.includes(method)) { if (provider.supportedMethods.includes(method)) {
return fn(); return fn();
} }
}).timeout(20_000); }).timeout(30_000);
}; };
for (const [description, config] of configs) { for (const [description, config] of configs) {
describe(description, () => { describe(description, () => {
provider = HyperlaneSmartProvider.fromChainMetadata(config, { provider = HyperlaneSmartProvider.fromChainMetadata(config, {
debug: true, debug: true,
baseRetryDelayMs: 1000,
fallbackStaggerMs: 3000,
maxRetries: 3,
}); });
itDoesIfSupported(ProviderMethod.GetBlock, async () => { itDoesIfSupported(ProviderMethod.GetBlock, async () => {
const latestBlock = await provider.getBlock('latest'); const latestBlock = await provider.getBlock('latest');
console.debug('Latest block #', latestBlock.number); console.debug('Latest block #', latestBlock.number);
expect(latestBlock.number).to.be.greaterThan(MIN_BLOCK_NUM); expect(latestBlock.number).to.be.greaterThan(0);
expect(latestBlock.timestamp).to.be.greaterThan( expect(latestBlock.timestamp).to.be.greaterThan(
Date.now() / 1000 - 60 * 60 * 24, Date.now() / 1000 - 60 * 60 * 24,
); );
@ -79,7 +75,7 @@ describe('SmartProvider', () => {
itDoesIfSupported(ProviderMethod.GetBlockNumber, async () => { itDoesIfSupported(ProviderMethod.GetBlockNumber, async () => {
const result = await provider.getBlockNumber(); const result = await provider.getBlockNumber();
console.debug('Latest block #', result); console.debug('Latest block #', result);
expect(result).to.be.greaterThan(MIN_BLOCK_NUM); expect(result).to.be.greaterThan(0);
}); });
itDoesIfSupported(ProviderMethod.GetGasPrice, async () => { itDoesIfSupported(ProviderMethod.GetGasPrice, async () => {
@ -130,34 +126,28 @@ describe('SmartProvider', () => {
}); });
itDoesIfSupported(ProviderMethod.GetLogs, async () => { itDoesIfSupported(ProviderMethod.GetLogs, async () => {
console.debug('Testing logs with no from/to range'); const latestBlockNumber = await provider.getBlockNumber();
const minBlockNumber = latestBlockNumber - 10_000;
console.debug('Testing logs with small from/to range');
const result1 = await provider.getLogs({ const result1 = await provider.getLogs({
address: WETH_CONTRACT, address: WETH_CONTRACT,
topics: [WETH_TRANSFER_TOPIC0, WETH_TRANSFER_TOPIC1], topics: [WETH_TRANSFER_TOPIC0],
fromBlock: minBlockNumber,
toBlock: minBlockNumber + 100,
}); });
console.debug('Logs found', result1.length);
expect(result1.length).to.be.greaterThan(0); expect(result1.length).to.be.greaterThan(0);
expect(eqAddress(result1[0].address, WETH_CONTRACT)).to.be.true; expect(eqAddress(result1[0].address, WETH_CONTRACT)).to.be.true;
console.debug('Testing logs with small from/to range'); console.debug('Testing logs with large from/to range');
const result2 = await provider.getLogs({ const result2 = await provider.getLogs({
address: WETH_CONTRACT, address: WETH_CONTRACT,
topics: [WETH_TRANSFER_TOPIC0], topics: [WETH_TRANSFER_TOPIC0],
fromBlock: MIN_BLOCK_NUM, fromBlock: minBlockNumber,
toBlock: MIN_BLOCK_NUM + 100, toBlock: 'latest',
}); });
expect(result2.length).to.be.greaterThan(0); expect(result2.length).to.be.greaterThan(0);
expect(eqAddress(result2[0].address, WETH_CONTRACT)).to.be.true; expect(eqAddress(result2[0].address, WETH_CONTRACT)).to.be.true;
console.debug('Testing logs with large from/to range');
const result3 = await provider.getLogs({
address: WETH_CONTRACT,
topics: [WETH_TRANSFER_TOPIC0, WETH_TRANSFER_TOPIC1],
fromBlock: MIN_BLOCK_NUM,
toBlock: 'latest',
});
expect(result3.length).to.be.greaterThan(0);
expect(eqAddress(result3[0].address, WETH_CONTRACT)).to.be.true;
}); });
itDoesIfSupported(ProviderMethod.EstimateGas, async () => { itDoesIfSupported(ProviderMethod.EstimateGas, async () => {
@ -181,11 +171,10 @@ describe('SmartProvider', () => {
}); });
it('Handles parallel requests', async () => { it('Handles parallel requests', async () => {
const result1Promise = provider.getLogs({ const result1Promise = provider.call({
address: WETH_CONTRACT, to: WETH_CONTRACT,
topics: [WETH_TRANSFER_TOPIC0], from: DEFAULT_ACCOUNT,
fromBlock: MIN_BLOCK_NUM, data: WETH_CALL_DATA,
toBlock: MIN_BLOCK_NUM + 100,
}); });
const result2Promise = provider.getBlockNumber(); const result2Promise = provider.getBlockNumber();
const result3Promise = provider.getTransaction(TRANSFER_TX_HASH); const result3Promise = provider.getTransaction(TRANSFER_TX_HASH);
@ -197,7 +186,7 @@ describe('SmartProvider', () => {
expect(result1.length).to.be.greaterThan(0); expect(result1.length).to.be.greaterThan(0);
expect(result2).to.be.greaterThan(0); expect(result2).to.be.greaterThan(0);
expect(!!result3).to.be.true; expect(!!result3).to.be.true;
}).timeout(10_000); }).timeout(15_000);
}); });
it('Reports as healthy', async () => { it('Reports as healthy', async () => {

@ -18,6 +18,7 @@ export {
eqAddressEvm, eqAddressEvm,
eqAddressSol, eqAddressSol,
getAddressProtocolType, getAddressProtocolType,
isAddress,
isAddressCosmos, isAddressCosmos,
isAddressEvm, isAddressEvm,
isAddressSealevel, isAddressSealevel,

@ -53,6 +53,10 @@ export function getAddressProtocolType(address: Address) {
} }
} }
export function isAddress(address: Address) {
return !!getAddressProtocolType(address);
}
function routeAddressUtil<T>( function routeAddressUtil<T>(
fns: Partial<Record<ProtocolType, (param: string) => T>>, fns: Partial<Record<ProtocolType, (param: string) => T>>,
param: string, param: string,

Loading…
Cancel
Save