|
1 | 1 | import { describe, expect, test } from 'vitest';
|
| 2 | +import EthereumABI from '../protocols/ethereum/abi.js'; |
2 | 3 | import { ContractService } from './contracts.js';
|
3 | 4 | import { loadRegistry } from './registry.js';
|
4 | 5 |
|
@@ -85,19 +86,89 @@ const TEST_CONTRACT_START_BLOCKS = {
|
85 | 86 | // },
|
86 | 87 | };
|
87 | 88 |
|
88 |
| -describe('getStartBlockForContract', { sequential: true }, async () => { |
| 89 | +const TEST_SOURCIFY_CONTRACT_INFO = { |
| 90 | + mainnet: { |
| 91 | + '0xc2EdaD668740f1aA35E4D8f227fB8E17dcA888Cd': { |
| 92 | + name: 'MasterChef', |
| 93 | + startBlock: 10_736_242, |
| 94 | + }, |
| 95 | + }, |
| 96 | + optimism: { |
| 97 | + '0xc35DADB65012eC5796536bD9864eD8773aBc74C4': { |
| 98 | + name: 'BentoBoxV1', |
| 99 | + startBlock: 7_019_815, |
| 100 | + }, |
| 101 | + }, |
| 102 | + wax: { |
| 103 | + account: { |
| 104 | + name: null, |
| 105 | + startBlock: null, |
| 106 | + }, |
| 107 | + }, |
| 108 | + 'non-existing chain': { |
| 109 | + '0x0000000000000000000000000000000000000000': { |
| 110 | + name: null, |
| 111 | + startBlock: null, |
| 112 | + }, |
| 113 | + }, |
| 114 | +}; |
| 115 | + |
| 116 | +// Retry helper with configurable number of retries |
| 117 | +async function retry<T>(operation: () => Promise<T>, maxRetries = 3, sleepMs = 5000): Promise<T> { |
| 118 | + let lastError: Error | undefined; |
| 119 | + for (let attempt = 0; attempt < maxRetries; attempt++) { |
| 120 | + try { |
| 121 | + return await operation(); |
| 122 | + } catch (error) { |
| 123 | + lastError = error as Error; |
| 124 | + if (attempt < maxRetries - 1) { |
| 125 | + await new Promise(resolve => setTimeout(resolve, sleepMs)); |
| 126 | + } |
| 127 | + } |
| 128 | + } |
| 129 | + throw lastError; |
| 130 | +} |
| 131 | + |
| 132 | +describe('getStartBlockForContract', { concurrent: true }, async () => { |
89 | 133 | const registry = await loadRegistry();
|
90 | 134 | const contractService = new ContractService(registry);
|
91 | 135 | for (const [network, contracts] of Object.entries(TEST_CONTRACT_START_BLOCKS)) {
|
92 | 136 | for (const [contract, startBlockExp] of Object.entries(contracts)) {
|
93 | 137 | test(
|
94 | 138 | `Returns the start block ${network} ${contract} ${startBlockExp}`,
|
95 |
| - async () => { |
96 |
| - //loop through the TEST_CONTRACT_START_BLOCKS object and test each network |
97 |
| - const startBlock = await contractService.getStartBlock(network, contract); |
| 139 | + { timeout: 50_000 }, |
| 140 | + async ({ expect }) => { |
| 141 | + const startBlock = await retry( |
| 142 | + () => contractService.getStartBlock(network, contract), |
| 143 | + 10, |
| 144 | + ); |
98 | 145 | expect(parseInt(startBlock)).toBe(startBlockExp);
|
99 | 146 | },
|
100 |
| - { timeout: 10_000 }, |
| 147 | + ); |
| 148 | + } |
| 149 | + } |
| 150 | +}); |
| 151 | + |
| 152 | +describe('getFromSourcifyForContract', { concurrent: true }, async () => { |
| 153 | + const registry = await loadRegistry(); |
| 154 | + const contractService = new ContractService(registry); |
| 155 | + for (const [networkId, contractInfo] of Object.entries(TEST_SOURCIFY_CONTRACT_INFO)) { |
| 156 | + for (const [contract, t] of Object.entries(contractInfo)) { |
| 157 | + test( |
| 158 | + `Returns contract information ${networkId} ${contract} ${t.name} ${t.startBlock}`, |
| 159 | + { timeout: 50_000 }, |
| 160 | + async () => { |
| 161 | + const result = await retry(() => |
| 162 | + contractService.getFromSourcify(EthereumABI, networkId, contract), |
| 163 | + ); |
| 164 | + if (t.name === null && t.startBlock === null) { |
| 165 | + expect(result).toBeNull(); |
| 166 | + } else { |
| 167 | + // Only check name and startBlock, omit API property from Sourcify results |
| 168 | + const { name, startBlock } = result!; |
| 169 | + expect(t).toEqual({ name, startBlock: parseInt(startBlock) }); |
| 170 | + } |
| 171 | + }, |
101 | 172 | );
|
102 | 173 | }
|
103 | 174 | }
|
|
0 commit comments