Continuity Proving for Query
The Creditcoin Decentralized Oracle uses Continuity proving to determine whether a block is part of certified source chain. It is the first of two key proofs that certify oracle results.
Overview
Continuity proofs for queries are cryptographic proofs that link the queried source chain block to an on-chain attestation or checkpoint, establishing that the block is part of the finalized source chain. This is essential for trustless cross-chain verification because it proves that the block containing the queried transaction has been attested to by the Creditcoin Oracle and cannot be reverted.
Note: Continuity proof generation for queries differs from continuity proofs used in attestation generation (see Continuity Proving for Attestation). This section focuses specifically on query continuity proofs.
Continuity Proof
A continuity proof for a query cryptographically links the queried block to an attestation or checkpoint stored on Creditcoin. The proof structure contains:
lowerEndpointDigest: The digest of the block before the query (queryHeight - 1), retrieved from indexed attestation data on Creditcoinroots[]: An array of Merkle roots for blocks fromqueryHeightto the attestation/checkpoint block
Digests are computed on-chain from these roots using this formula, which creates an unbroken cryptographic chain: digest[i] = hash(blockNumber[i], merkleRoot[i], digest[i-1])
Why Continuity Proofs Are Needed
Without continuity proofs, a malicious prover could:
Present fake Merkle roots for non-existent blocks
Claim transactions exist in blocks that were never finalized
Use outdated or reorganized blocks
Continuity proofs solve this by:
Linking to On-Chain Attestations by proving the queried block is part of a client source chain that has been attested to on Creditcoin
Creating Cryptographic Guarantees through the digest chain that provides cryptographic proof that blocks form an unbroken, tamper-proof sequence from the lower endpoint to the attestation/checkpoint
Query Types
The Proof Generation API supports two types of continuity proof queries:
1. Query Between Attestations:
The query block falls between two regular attestations
The API queries indexed attestation data on Creditcoin
Constructs a continuity proof using computed roots and digests from the indexed attestations
The proof links from the lower attestation to the upper attestation
2. Query Between Checkpoints:
The query block falls between two checkpoints (which are filtered attestations)
The API queries all attestations in that range from the indexed data on Creditcoin
Creates the continuity proof based on all attestations in the checkpoint interval
The proof ends in a checkpoint, providing stronger finality guarantees
In both cases, the API queries indexed data stored on Creditcoin (attestations and checkpoints) and constructs the continuity proof using the computed roots and digests from this indexed data.
Continuity Proof Construction
When an off-chain worker needs to query a transaction at a specific block height, the Proof Generation API constructs a continuity proof through the following steps:
1. Determine Interval Endpoints
The API first identifies the attestation/checkpoint boundaries around the query:
Find the Highest Attestation/Checkpoint Before the Query
Queries indexed attestation/checkpoint data stored on Creditcoin
Identifies the most recent attestation or checkpoint with a block number less than
queryHeightRetrieves the computed digest from the indexed data to use as
lowerEndpointDigest
Find the Lowest Attestation/Checkpoint After the Query
Queries indexed attestation/checkpoint data on Creditcoin for the earliest attestation or checkpoint with a block number greater than or equal to
queryHeightThe proof must link to this attestation/checkpoint's digest
This serves as the upper endpoint of the continuity proof
For queries between checkpoints, this will be a checkpoint (ending in a checkpoint)
Example:
Query height: 145
Last attestation before query: Block 140 (digest:
0xabc...)Next attestation after query: Block 150 (digest:
0xdef...)Continuity proof must link blocks 145-150 to attestation at block 150
2. Query Indexed Data and Fetch Source Chain Blocks
The API queries indexed attestation data on Creditcoin and fetches source chain blocks:
Query Indexed Attestation Data:
For queries between attestations: Retrieves the specific attestations from indexed data
For queries between checkpoints: Queries all attestations in the checkpoint interval range from indexed data
Uses the computed roots and digests from the indexed attestation data
Fetch Block Headers
Requests block headers from the source chain RPC node
Needs blocks from
queryHeightto the next attestation/checkpoint blockEach block header contains: block number, Merkle root, previous block hash
Verify Block Integrity
Validates that blocks form a continuous chain
Ensures each block's
previousBlockHashmatches the previous block's hashThis ensures blocks haven't been tampered with or reorganized
Example (continuing from above):
Queries indexed attestation data on Creditcoin for blocks 140-150
Fetches blocks: 144, 145, 146, 147, 148, 149, 150
Blocks 145-150 form the chain to the attestation
3. Construct Digest Chain
The API constructs the digest chain using the computed roots and digests from the indexed attestation data on Creditcoin:
Digest Calculation Formula:
Where:
blockNumber[i]is the block number (e.g., 145)merkleRoot[i]is the Merkle root from the block headerdigest[i-1]is the digest of the previous block
Process:
Start with the digest of the block before the query (
queryHeight - 1)This digest should match the
prev_digestfrom the attestation/checkpoint before the queryIf no previous attestation exists, use genesis digest
For each block from
queryHeightto the attestation/checkpoint block, compute using roots from indexed data:The final digest (
digest[150]) must match the digest stored in the indexed attestation/checkpoint data on Creditcoin at block 150.
4. Build Continuity Proof Structure
The continuity proof structure is simplified and only stores Merkle roots (digests are computed on-chain):
Continuity Proof Structure:
lowerEndpointDigest: The digest of the block before the query (queryHeight - 1)This is the
prev_digestthat the first block in the continuity chain referencesMust match the digest from the attestation/checkpoint before the query
roots[]: Array of Merkle roots for blocks fromqueryHeightto the attestation/checkpoint blockBlock numbers are derived:
blockNumber = queryHeight + indexDigests are computed on-chain from these roots (not submitted in proof)
Security
The fundamental security property of continuity proofs is the cascading effect of digest changes:
If any block in the continuity proof is modified:
The digest of that block changes (because it includes the block's Merkle root)
All subsequent block digests change (because each digest includes the previous digest)
The final digest will not match the on-chain attestation/checkpoint digest
This mismatch can be detected during verification, causing the proof to be rejected
Example Attack Scenario:
Last updated