ChainSafe / ChainSafe/canton-extending-mainnet
Scan ingestion throws on an unparseable MemberTraffic synchronizerId
- 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