> For the complete documentation index, see [llms.txt](https://docs.creditcoin.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.creditcoin.org/usc/creditcoin-oracle-subsystems/readability/step-1-attestation/continuity-proving-for-attestation.md).

# Continuity Proving for Attestation

## **Overview**

A continuity proof is one of two key proofs the Creditcoin Decentralized Oracle needs to securely move data from one chain to another. It organizes source chain blocks into a segment so that each block hash links to the next. Together these hashes/digests ensure that attestation `n + 1` is always a valid descendant of attestation `n`

Why do we need continuity proofs? Why can't attestors simply record consensus about every block? The answer has two parts:\
**1. On-chain Storage:** Storing attestations for every source chain block on our Creditcoin chain would be too expensive—especially for chains like <img src="/files/Y5Dxqajg40K2KnM2wvwo" alt="" data-size="line"> `Solana` that produce blocks frequently. \
**2. Attestor Network Load:** The attestor network must perform expensive signing, hashing, p2p gossip, and tx submission for every attestation it produces. We make the attestor networks more resiliant and efficient by not attesting to every block.\
\
To solve both problems, we produce attestations at larger intervals (e.g., every 10 or 100 source chain blocks). Each attestation links to the previous one via digests. When there's a gap between attestations, a continuity proof fills it. This proof is a chain of digests of intermediate source chain blocks that:

* Starts from the block immediately after the last finalized attestation
* Ends at the block immediately before the new attestation
* Proves each intermediate block links to the previous one via digests

This lets the oracle handle queries for any source chain block—even if it wasn't explicitly stored—by proving continuity through the intermediate blocks. The continuity proof ensures that even though we only store attestations at intervals, we can still verify the integrity of the entire source chain.

## **Key Terms:**

📝 **Hash:** A cryptographic hash is a deterministic mathematical function that takes an input of arbitrary size and produces a fixed-size output, called a hash value.

***

📝 **Merkle Tree**: A Merkle tree is a balanced binary tree of cryptographic hashes that enables efficient and secure verification of integrity of large data sets. With the tree’s Merkle root and a small subset of hashes (a Merkle proof), one can efficiently verify whether a given piece of data is included in the set without revealing or re-hashing all the data. This property allows us to efficiently determine whether a part of a transaction is contained in the Merkle tree for a given block.

***

📝 **Root (Merkle Root)**: A Merkle root is the single cryptographic hash at the top of a Merkle tree. It uniquely summarizes all the data beneath it, allowing us to rapidly verify the integrity of all the data stored in that tree.

{% code title="Root in code" %}

```rust
let root = eth::starknet_pedersen_mmr(&block_data);
```

{% endcode %}

***

📝 **Digest:** Another term for any output from a hash function. In the context of the Creditcoin oracle, a digest usually describes the hash output uniquely identifying a block or attestation. The digest of a block is derived by hashing its block number, Merkle root, and previous digest.&#x20;

<pre class="language-rust" data-title="Digest in code"><code class="lang-rust"><strong>let digest = Self::hash_payload(&#x26;block_number.into(), &#x26;root, &#x26;prev_digest);
</strong></code></pre>

***

📝 **Previous Digest:** The previous digest of a block is just the digest of the block before it. We generate each new block digest using the previous digest. <br>

## **How Hashing "Chains" Blocks Together**

Continuity proving relies on one of the key properties of blockchains. Namely, that the digest of each block is generated using both the contents of that block and the digest of the previous block. Since each block uses part of the previous block, the blocks are said to form a *chain*. This gives us a very important property:

> <mark style="color:$info;">If the contents of block</mark> <mark style="color:$info;"></mark><mark style="color:$info;">`x`</mark> <mark style="color:$info;"></mark><mark style="color:$info;">are changed, then the digests of blocks</mark> <mark style="color:$info;"></mark><mark style="color:$info;">`x, x+1, ... x+n`</mark> <mark style="color:$info;"></mark><mark style="color:$info;">are</mark> <mark style="color:$info;"></mark>*<mark style="color:$info;">all changed</mark>* <mark style="color:$info;"></mark><mark style="color:$info;">as a result. This allows us to cheaply verify whether any part of the chain was changed using only the most recent block.</mark>

## **Generating  Attestations**

An attestation is generated using the following process:

### 1. Determine which source chain blocks to attest to

This is calculated as:

```rust
let next_attestation_block = latest_attestation_block + attestation_interval;
```

The attestation interval determines how frequently attestations are created on Creditcoin relative to source chain blocks. For example, if the attestation interval for Ethereum is 10, a new attestation is produced on Creditcoin for every 10 blocks on Ethereum. More specifically, if the `attestation_interval` is `10` and the last attestation was at block `100`, attestors will fetch blocks   `101-110`  and generate new attestation at height `110`.

### 2. Fetch source chain blocks from source chain RPC nodes.&#x20;

Attestors either monitor the source chain directly or query an external trusted endpoint of their choice. As long as the attestor population represents a sufficiently diverse and distributed set of endpoints, rather than relying on just a few sources, it doesn't matter if individual attestors use external RPC endpoints.

### 3. Construct an attestation fragment

Attestors fetch source chain blocks to build a continuity proof, a sequence of digests that bridges from one attestation to the next. As digests are added, each new digest is calculated as:

<pre class="language-rust"><code class="lang-rust"><strong>let digest = Self::hash_payload(&#x26;block_number.into(), &#x26;root, &#x26;prev_digest);
</strong></code></pre>

Each block's digest integrates the previous block's digest, forming a verifiable chain. At the end, the new attestation's `prev_digest` is set to the digest of the continuity proof's head block. The attestation itself has its own digest, calculated from the attestation's `root` and `prev_digest`. This allows the attestation to be verified against the entire chain of intermediate digests, proving continuity even when blocks weren't explicitly stored.\
The following visual shows how digests bridge one attestation to the next.

<figure><img src="/files/27Zv3s3oF1WTl6bymNLi" alt=""><figcaption></figcaption></figure>

### 4. Sign and submit to gossip network

Each eligible attestor signs their attestation with both a *SR25519* signature (for attestor identity) and a *BLS* signature (for aggregation). The signed attestation (including the continuity proof) is then submitted to the P2P gossip network, where it is validated, coordinated with other attestors' votes, and aggregated by other attestors on that same network before on-chain submission.

## **Proving Continuity for Attestations**

{% hint style="info" %}
**Note:** Continuity proof generation for attestations differs from continuity proofs generated for queries (see [Continuity Proving for Queries](/usc/creditcoin-oracle-subsystems/readability/step-2-transaction-proving/continuity-proving-for-queries.md)). This section focuses specifically on attestation continuity proofs.
{% endhint %}

When generating attestations, attestors construct a continuity proof chain linking blocks from the last finalized attestation (or checkpoint) to the current attestation height. The process:

* Determines the interval endpoints by finding the last finalized attestation/checkpoint on-chain and identifying the current attestation height
* Fetches source chain blocks between these endpoints and constructs the continuity proof. For attestations, the continuity proof starts from the block after the last finalized attestation and extends to the current attestation height
* Computes block digests using the formula: `digest = hash(block_number, merkle_root, prev_digest)`, creating an unbroken cryptographic chain
* Returns the continuity proof verifying that hashing was done correctly on the input blocks

The attestation includes this continuity proof and a `prev_digest` field. For a continuity proof to be valid, the `prev_digest` of the prospective attestation must match the digest of the last continuity block.

When the attestation is submitted to Creditcoin, the runtime verifies the validity of the continuity proof by reconstructing the digest chain and checking if the final digest matches the attestation's `prev_digest`. If verification succeeds, the attestation is stored on-chain.

#### **Security**

If a malicious attestor creates an internally consistent attestation with bogus blocks; the primary defense is consensus - since honest attestors will not be using the bogus block, their final digest will be different, thus preventing the malicious attestation from reaching quorum. The following visual shows how a faulty attestation is rejected:

<figure><img src="/files/UGhyoAwECN8ffujVGmDH" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.creditcoin.org/usc/creditcoin-oracle-subsystems/readability/step-1-attestation/continuity-proving-for-attestation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
