ChainSafe / ChainSafe/canton-extending-mainnet

Scan ingestion throws on an unparseable MemberTraffic synchronizerId

Open
#117 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Shell
Stars
0
Forks
0
Avg merge
14d 10h
Merged PRs (30d)
2

Description

`ScanStore.scala:397` parses the synchronizer id on the `MemberTraffic` filter with an unguarded
`SynchronizerId.tryFromString`. The `memberId` immediately above it is guarded with a fold, whose
comment says the intent is "to avoid killing the entire ingestion pipeline as a result". The
synchronizer id has no such guard.

That was safe while traffic could only be bought for the global synchronizer, because
`validateBuyMemberTrafficInputs` requires the id to be in
`configUsd.decentralizedSynchronizer.requiredSynchronizers` (`AmuletRules.daml:1832`), which is a
config-provided set of real ids.

It is no longer safe on the dedicated path. There the only check is a Text comparison against the
disclosed registration (`AmuletRules.daml:1836`), and `DsoRules_RegisterSynchronizer` validates
only that the id is non-empty (`DsoRules.daml:1714`). The choice then creates `MemberTraffic with
synchronizerId` from that same argument (`AmuletRules.daml:308`). So a governance typo in a
registration produces a `MemberTraffic` whose synchronizer id does not parse, and every Scan that
ingests it throws.

Not introduced by any one PR: the dedicated buy path and the unguarded parse are both already on
main. Surfaced while reworking the Scan registration query for
canton-network/splice-multi-sync#29, which does not touch either.

Worth deciding what the right behaviour is rather than copying the memberId fold blindly: silently
dropping the row hides a governance mistake, and `memberTrafficDomain` is used by
`getTotalPurchasedMemberTraffic`.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start at the unguarded parse in ScanStore.scala:397, then read the guarded memberId handling immediately above it. Trace the related validation and construction in AmuletRules.daml:1832, 1836, and 308, plus DsoRules.daml:1714. Done means the team has chosen and implemented behavior for an unparseable synchronizer id without silently hiding a governance mistake or breaking getTotalPurchasedMemberTraffic.

Written by the indexing model from the issue text.

Assessment

Tech stack
scala
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.