-
Notifications
You must be signed in to change notification settings - Fork 197
Description
Describe the feature
Summary
Tempo currently does not expose BLS finalization signatures or consensus proofs via any API, making it impossible to build trustless light clients or cross-chain bridges. This feature request proposes adding a consensus API (similar to Ethereum's Beacon API) to expose finality proofs.
Motivation
Use Cases
- Cross-chain bridges: Bridges need cryptographic proof that blocks were finalized by the validator set to trustlessly relay state to other chains
- Light clients: SPV-style clients need to verify finality without running a full consensus node
- Block explorers: Displaying finality status and validator signatures
- Audit and verification: Independent verification of chain finality
Current Limitation
While Tempo generates BLS threshold signatures for notarization and finalization internally, these signatures are:
- ✅ Created during consensus
- ✅ Verified by validators
- ❌ Never stored or exposed
- ❌ Discarded after verification
This means:
- External observers cannot verify historical finality
- Light clients must trust RPC providers
- Bridges cannot prove finality cryptographically
--followmode nodes have zero verification
Comparison: Ethereum Beacon API
Ethereum solved this with dedicated light client endpoints on the Beacon Chain API:
# Get finality checkpoint
GET /eth/v1/beacon/states/{state_id}/finality_checkpoints
# Light client finality update (includes BLS signatures)
GET /eth/v1/beacon/light_client/finality_update
# Light client bootstrap
GET /eth/v1/beacon/light_client/bootstrap/{block_root}Response includes:
- Finalized block header
- BLS aggregate signature proving finality
- Sync committee participation bits
- Merkle proofs for verification
Additional context
Proposed Solution
1. Store Finalization Certificates
Uncomment and implement the existing skeleton in crates/commonware-node/src/consensus/block.rs:140-250:
pub struct Finalized {
proof: Finalization, // BLS signature
block: Block,
}
impl Finalized {
pub fn verify(&self, namespace: &[u8], identity: &BlsPublicKey) -> bool {
self.proof.verify(namespace, identity)
}
}Store certificates in:
- In-memory: Recent N blocks (for active bridges/light clients)
- Database/Indexer: Historical proofs (for full verification)
2. Add Consensus RPC Namespace
Create tempo_consensus namespace with methods:
#[rpc(server, namespace = "tempo_consensus")]
pub trait TempoConsensusApi {
/// Get BLS finalization signature for a block
#[method(name = "getBlockFinalization")]
async fn get_block_finalization(
&self,
block_hash: B256,
) -> RpcResult<Option<FinalizationCertificate>>;
/// Get notarization certificate for a block
#[method(name = "getBlockNotarization")]
async fn get_block_notarization(
&self,
block_hash: B256,
) -> RpcResult<Option<NotarizationCertificate>>;
/// Get validator set for an epoch
#[method(name = "getEpochValidators")]
async fn get_epoch_validators(
&self,
epoch: u64,
) -> RpcResult<ValidatorSet>;
/// Get BLS public key for verification (from genesis/DKG)
#[method(name = "getEpochPublicKey")]
async fn get_epoch_public_key(
&self,
epoch: u64,
) -> RpcResult<BlsPublicKey>;
}3. Response Format
interface FinalizationCertificate {
blockHash: string; // Block being finalized
epoch: number; // Epoch number
round: number; // Consensus round
signature: string; // BLS threshold signature (hex)
participantBits: string; // Bitfield of validators who signed
publicKey: string; // BLS public key for verification
}4. Verification Flow
// Bridge verification example
const cert = await rpc.call('tempo_consensus_getBlockFinalization', [blockHash]);
const publicKey = await rpc.call('tempo_consensus_getEpochPublicKey', [cert.epoch]);
// Verify BLS signature cryptographically
const isValid = verifyBLS(cert.signature, blockHash, publicKey);Implementation Notes
Minimal Implementation (Phase 1)
- Store finalization certificates in
subblocks.rsactor (LruCache<BlockHash, Certificate>) - Add RPC method to query from cache
- Expose last ~1000 finalized blocks
Full Implementation (Phase 2)
- Implement indexer that stores all historical certificates
- Add light client sync protocol (like Ethereum's)
- Support for merkle proofs and state verification
References
- Existing code:
crates/commonware-node/src/consensus/block.rs:140-250(commented out) - Consensus signatures: Already created in
crates/commonware-node/src/subblocks.rs:243-250 - Ethereum Beacon API: https://ethereum.github.io/beacon-APIs/
- BLS Public Key: Already stored in
genesis.config.publicPolynomial(pre-allegretto) orboundary_block.extraData(post-allegretto)
Impact
Without this feature:
- ❌ No trustless bridges possible
- ❌ No light client support
- ❌ Nodes in
--followmode cannot verify finality - ❌ External observers must trust RPC providers
With this feature:
- ✅ Trustless cross-chain bridges
- ✅ Light client protocols
- ✅ Independent finality verification
- ✅ Production-ready bridge infrastructure
Related
This addresses the TODO comment in the codebase about implementing an indexer for consensus proofs.