{"record":{"id":"50ccf3bbc29a6698","repo":"datahaven-xyz/datahaven","slug":"synccommitteeparticipantsnotsupermajority","errorCode":"SyncCommitteeParticipantsNotSupermajority","errorMessage":"SyncCommitteeParticipantsNotSupermajority","messagePattern":"SyncCommitteeParticipantsNotSupermajority","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"operator/pallets/ethereum-client/src/lib.rs","lineNumber":637,"sourceCode":"        ) -> Result<H256, DispatchError> {\n            let hash_root = ForkData {\n                current_version,\n                genesis_validators_root: genesis_validators_root.into(),\n            }\n            .hash_tree_root()\n            .map_err(|_| Error::<T>::ForkDataHashTreeRootFailed)?;\n\n            Ok(hash_root)\n        }\n\n        /// Checks that the sync committee bits (the votes of the sync committee members,\n        /// represented by bits 0 and 1) is more than a supermajority (2/3 of the votes are\n        /// positive).\n        pub(super) fn sync_committee_participation_is_supermajority(\n            sync_committee_bits: &[u8],\n        ) -> DispatchResult {\n            let sync_committee_sum = sync_committee_sum(sync_committee_bits);\n            ensure!(\n                ((sync_committee_sum * 3) as usize) >= sync_committee_bits.len() * 2,\n                Error::<T>::SyncCommitteeParticipantsNotSupermajority\n            );\n\n            Ok(())\n        }\n\n        /// Returns the fork version based on the current epoch. The hard fork versions\n        /// are defined in pallet config.\n        pub(super) fn compute_fork_version(epoch: u64) -> ForkVersion {\n            Self::select_fork_version(&T::ForkVersions::get(), epoch)\n        }\n\n        /// Returns the fork version based on the current epoch.\n        pub(super) fn select_fork_version(fork_versions: &ForkVersions, epoch: u64) -> ForkVersion {\n            if epoch >= fork_versions.fulu.epoch {\n                return fork_versions.fulu.version;\n            }","sourceCodeStart":619,"sourceCodeEnd":655,"githubUrl":"https://github.com/datahaven-xyz/datahaven/blob/edcb13dbbcd3c29489eaa2480a6f60ee4cb1f3ec/operator/pallets/ethereum-client/src/lib.rs#L619-L655","documentation":"Thrown by `sync_committee_participation_is_supermajority` when the sync-aggregate bitfield has fewer than 2/3 of its bits set. Ethereum consensus requires a 2/3 supermajority of sync committee participants for an update signature to be valid; without it the attestation cannot be trusted.","triggerScenarios":"Submitting a light-client update whose `sync_aggregate.sync_committee_bits` produce `sync_committee_sum * 3 < bits.len() * 2` — i.e. a weakly signed update from the beacon chain.","commonSituations":"Replaying an update that was later superseded by one with higher participation, relayer picking malformed/edge-case aggregates, or an actual network liveness problem on the beacon chain.","solutions":["Wait for and submit a later update with ≥2/3 participation; finalized updates typically have near-full participation.","Verify the relayer does not truncate or corrupt the `sync_committee_bits` bitfield during serialization.","Check beacon chain finality health; prolonged low participation indicates upstream liveness issues.","Re-fetch the aggregate from a full node rather than a cached/derived copy."],"exampleFix":"// before: submit any fetched update\nsubmit(update);\n// after: pre-check participation on the relayer\nlet bits = count_bits(update.sync_aggregate.sync_committee_bits);\nrequire!(bits * 3 >= SYNC_COMMITTEE_SIZE * 2);\nsubmit(update);","handlingStrategy":"validation","validationCode":"const sum = countBits(update.sync_aggregate.sync_committee_bits);\nif (sum * 3 < SYNC_COMMITTEE_SIZE * 2) {\n  throw new Error('sync aggregate lacks 2/3 supermajority');\n}","typeGuard":"function hasSupermajority(bits, committeeSize) {\n  return bits.reduce((a, b) => a + b, 0) * 3 >= committeeSize * 2;\n}","tryCatchPattern":"try {\n  await submit(update);\n} catch (e) {\n  if (String(e).includes('SyncCommitteeParticipantsNotSupermajority')) {\n    await waitForNextUpdateWithFullParticipation();\n  }\n}","preventionTips":["Pre-check bitfield weight on the relayer before submission","Prefer finalized updates, which normally carry near-full participation","Monitor beacon chain liveness; alert when participation drops persistently"],"tags":["blockchain","consensus","signature","liveness"],"backgroundTag":"invalid-argument-value","analyzedSha":"edcb13dbbcd3c29489eaa2480a6f60ee4cb1f3ec","analyzedAt":"2026-09-13T19:19:32.206Z","contentChangedAt":"2026-09-13T19:19:32.206Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}