Skip to content

refactor: return SourcifyChainMap from initializeSourcifyChains#2749

Merged
kuzdogan merged 8 commits intofeat/remote-chain-config-v2from
refactor/return-sourcify-chains-map
Apr 16, 2026
Merged

refactor: return SourcifyChainMap from initializeSourcifyChains#2749
kuzdogan merged 8 commits intofeat/remote-chain-config-v2from
refactor/return-sourcify-chains-map

Conversation

@kuzdogan
Copy link
Copy Markdown
Member

Summary

Addresses Manuel's review comment on #2709 (cli.ts:99):

I tend to say that this function should return the sourcifyChainsMap instead of modifying a shared object. The current pattern seems error-prone to me.

And the follow-up on sourcify-chains.ts:277:

not necessary when you return an object from this function and not write to a shared one. (referring to the map-clearing loop)

What changed

  • src/sourcify-chains.ts: Remove the exported sourcifyChainsMap singleton. initializeSourcifyChains() now returns Promise<SourcifyChainMap>. The map-clearing loop is gone (each call builds a fresh local map). The unusual if (!chainsExtensions!) non-null assertion is cleaned up to let chainsExtensions: ... | undefined + if (!chainsExtensions). All chainId keys are now consistently strings (chainId.toString()).
  • src/server/cli.ts: Capture the returned map with const sourcifyChainsMap = await initializeSourcifyChains(). getEtherscanApiKeyForEachChain now accepts the map as a parameter rather than closing over the module-level export.
  • test/helpers/ServerFixture.ts: Store the returned map on this.sourcifyChainsMap (public field). Integration tests access it via serverFixture.sourcifyChainsMap[...].
  • Unit tests (sourcify-chains.spec.ts, verificationWorker.spec.ts, contract-creation-util.spec.ts): Use the returned value; remove the beforeEach map-clearing loop; rewrite the re-initialization test as two independent-map assertions.
  • Chain tests (chain-tests.spec.ts, etherscan-instances.spec.ts): Use the returned value in the async IIFEs. Add .catch() to both IIFEs so a chain-init failure exits instead of hanging Mocha's --delay mode. etherscan-instances.spec.ts is now wrapped in the same --delay/run() pattern as chain-tests.spec.ts (was previously relying on synchronous access to the old module-level map).
  • test/chains/deployContracts.ts: Call initializeSourcifyChains() inside main() and use the returned map.

Out of scope

Other review comments from #2709 (GCP-hosted URL, not importing config in sourcify-chains.ts, Dockerfile dedup, etc.) will be addressed separately.

🤖 Generated with Claude Code

Instead of mutating a module-level `sourcifyChainsMap` singleton,
`initializeSourcifyChains()` now returns a fresh `SourcifyChainMap`.

Key changes:
- `sourcify-chains.ts`: remove exported `sourcifyChainsMap` const; return
  a local map from the function; drop the map-clearing loop; clean up
  the non-null assertion on `chainsExtensions`; use consistent string
  keys for all chainId lookups
- `cli.ts`: capture the returned map in the async IIFE; make
  `getEtherscanApiKeyForEachChain` accept the map as a parameter
- `ServerFixture`: store the returned map on `this.sourcifyChainsMap`;
  integration tests access it via the fixture instead of a module import
- `chain-tests.spec.ts` / `etherscan-instances.spec.ts`: use the
  returned value directly; add `.catch()` to async IIFEs so failures
  exit instead of hanging Mocha with --delay
- Unit tests: use returned value for assertions; remove the beforeEach
  map-clearing loop; rewrite the re-initialization test as two
  independent-map assertion

Addresses Manuel's review comment on #2709.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
kuzdogan and others added 5 commits April 15, 2026 08:27
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… chain map

The async IIFE + run() pattern relied on Mocha's --delay flag which was
never set in the test scripts, making test registration order a race
condition. Replace it with a plain synchronous describe loop that uses
only chainId at registration time.

Chain names are recovered inside before() once serverFixture has
initialized its sourcifyChainsMap, then written back onto the suite title
so reporters (spec, mochawesome) still show the human-readable name.
The supported-chain guard also moves into before() for the same reason.

The "Double check" section now builds sourcifyChainsArray inside the it()
block from serverFixture.sourcifyChainsMap, eliminating the last
describe-time dependency on the chain map.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… beforeEach

it() titles are registered synchronously like describe() titles, so the
chain name cannot be embedded at registration time. Store chainName in a
closure variable (set by before()), then patch this.currentTest.title in
beforeEach() by replacing the chainId placeholder with the full name.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e bug

`chainId` is declared with `let` outside the for..in loop, so all
describe/before/beforeEach/it closures that run asynchronously share the
same variable and see the last iteration's value. Only the final chain
(11155420) got the correct title replacement; all others saw the wrong
chainId in the replace() call.

Fix: capture the current value in `const id = chainId` at the top of
each describe callback. All closures inside that describe now close over
their own immutable `id`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ServerFixture: comment that sourcifyChainsMap is assigned in before()
  and safe to read inside it/beforeEach
- sourcify-chains.spec.ts: assert the two returned maps are distinct
  object references, not just disjoint in keys

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@kuzdogan kuzdogan marked this pull request as ready for review April 15, 2026 06:28
@kuzdogan kuzdogan requested a review from manuelwedler April 15, 2026 06:29
Comment thread services/server/test/unit/verificationWorker.spec.ts
Comment thread services/server/test/helpers/ServerFixture.ts Outdated
maxFileSize: config.get<number>("server.maxFileSize"),
corsAllowedOrigins: config.get<string[]>("corsAllowedOrigins"),
chains: fixtureOptions_?.chains || sourcifyChainsMap,
chains: fixtureOptions_?.chains || this.sourcifyChainsMap,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a problem of this PR, but a problem in general:

below we always pass the this.sourcifyChainsMap to the verification service, but it should also prioritize the fixtureOptions.chains.

I think in general it would be better to remove the sourcifyChainMap from the VerificationServiceOptions and instead pass a separate argument from the Server constructor to the VerificationService in order to avoid such mistakes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it should be in this PR? The change should be straightforward?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See c16794e about prioritizing fixtureOptions.chains

Above comment for removing the sourcifyChainMap from VerificationServiceOptions

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't have to be in this PR, but should be straight forward, yes. I would simply add the chain map as a separate argument to the VerificationService constructor.

Comment thread services/server/test/unit/utils/contract-creation-util.spec.ts Outdated
kuzdogan and others added 2 commits April 16, 2026 11:37
…+ fix fixtureOptions priority

- Replace the `sourcifyChainsMap!` instance field with a getter that
  delegates to `this.server.chainRepository.sourcifyChainMap` — the
  field was redundant since the server already owns the chain map.
- Create a local `sourcifyChainsMap` const in before() that respects
  `fixtureOptions_?.chains` first, then falls back to
  `initializeSourcifyChains()`. Both `serverOptions.chains` and
  `sourcifyChainMap` in VerificationServiceOptions now use the same
  value, fixing the inconsistency where the override was only applied
  to one of them.
- Replace all `serverFixture.server.chainRepository.sourcifyChainMap`
  call sites across integration tests with `serverFixture.sourcifyChainsMap`
  for consistency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@kuzdogan kuzdogan merged commit 32428d5 into feat/remote-chain-config-v2 Apr 16, 2026
18 checks passed
@github-project-automation github-project-automation bot moved this from Triage to Sprint - Done in Sourcify Public Apr 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Sprint - Done

Development

Successfully merging this pull request may close these issues.

2 participants