Skip to content

Commit

Permalink
docs: add specs (#34)
Browse files Browse the repository at this point in the history
* feat: added transactions

* feat: implement client

* fix tx issue

* feat: pause previous code

* adding client injection

* custom txclient

* fix: client issue debug

* new chain client

* debug client init

* update create client

* import mnemonic

* docs

* Update README.md

* update docs

* execute submit tx through client

* fix keyring issue

* import key

* fix

* refactor

* update submitblob tx

* new query

* feat: changes

* handle error

* post data to da

* execute update tx after da submission

* fix

* query and tx

* update msg

* feat: fixed range errors

* feat: vote extensions

* refactor core lgic

* feat: enable vote extensions

* feat: enable vote extensions

* feat: fix vote extensions bug

* feat: fix vote extensions bug

* fix: config script for vote extension height

* fix typo

* fix client

* feat: enable vote extensions

* remove deadcode

* feat: light client data verification

* feat: enable light client verification

* fix

* docs: add specs

* feat: docs: add abstract

* Update README.md

* feat: add specs

* feat: spec

* feat: update docs

* docs: update specs

* Update README.md

* Update README.md

* Update README.md

* nit: small changes

* chore: conflicts

* Update 07_vote_extension.md

* docs: add requirements

* Update README.md

---------

Co-authored-by: PrathyushaLakkireddy <[email protected]>
Co-authored-by: Prathyusha Lakkireddy <[email protected]>
  • Loading branch information
3 people authored Sep 19, 2024
1 parent 664aebd commit 6ab8d2b
Show file tree
Hide file tree
Showing 9 changed files with 440 additions and 49 deletions.
53 changes: 4 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,12 @@ CADA is a module designed to connect Cosmos sovereign chains with the Avail netw

For example:
Let blobInterval = 10,

- At height `11`, blocks from `1` to `10` are posted.
- At height `21`, blocks from `11` to `20` are posted.

#### Relayer
The `Relayer` acts as the transport layer, responsible for handling requests from the `prepareBlocker` and facilitating transactions between the Cosmos chain and the Avail DA network. It performs key functions such as submitting block data to Avail and updating block status on the Cosmos chain. Every validator in the network is required to run the relayer process.

#### Proven Height
The `Proven Height` signifies the most recent block height of the Cosmos chain where data has been successfully transmitted to Avail and validated by the network.

## Architecture

![Screenshot from 2024-08-27 11-35-01](https://github.com/user-attachments/assets/1a8657f6-4c1b-418a-8295-05c039baa6d0)


1. **Block Interval Trigger**:
- At each block interval, a request is sent from `PrepareProposal` abci method to the relayer, specifying the range of block heights to be posted to the Avail DA network. This request should be made by the block proposer only.

2. **MsgSubmitBlobRequest Transaction**:
- The relayer submits a `MsgSubmitBlobRequest` transaction on the Cosmos chain, signaling that the block data for the specified range is pending:
```
status[range] = pending
```
- The relayer monitors the transaction to confirm its successful inclusion and processing on the chain.
3. **Data Submission to Avail DA**:
- Once the `MsgSubmitBlobRequest` transaction is confirmed, the relayer fetches the block data for the specified range and submits it to the Avail DA layer.
4. **MsgUpdateBlobStatusRequest Transaction**:
- After confirming that the data is available on Avail, the relayer submits a `MsgUpdateBlobStatusRequest` transaction on the Cosmos chain, updating the block status to pre-verification:
```
status[range] = IN_VOTING
```
5. **Validator Confirmation**:
- Within a preconfigured block limit, all validators are required to verify the data's availability on the Avail network using their Avail light clients and cast their votes.
we could use voteExtension to cast the votes
6. **Consensus and Proven Height Update**:
- If the number of votes exceeds the consensus threshold, the status of the block range is updated to success, and the `Proven Height` is advanced:
```
status[range] = success
// Update the proven height
if range.from == provenHeight + 1 {
provenHeight = range.to
}
```
Refer to the module specification available [here](./specs/README.md) for more detailed information.

7. **Failure Handling**:
- In case of any failures or expiration of the verification window, the data will be reposted following the same procedure.
Note: Use the latest maintained [Go](https://go.dev/dl/) version to work with this module.

---
For detailed instructions on how to integrate the module with a spawn generated application, please refer to the [integration guide](./docs/spawn.md).
Ensure that the Avail light client URL is correctly configured for the module to function as expected. For instructions on running Avail locally, refer to [this documentation](https://github.com/rollkit/avail-da?tab=readme-ov-file#avail-da).
32 changes: 32 additions & 0 deletions specs/01_concepts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!--
order: 1
-->

# Concepts

### MaxBlocksLimitForBlob

- The `maxBlocksLimitForBlob` defines the maximum number blobs to be posted to Avail DA at once (in on Avail Transaction).

### Blob Interval

- The `Blob Interval` defines the frequency at which block data is posted to the Avail Network.
- For example, if the interval is set to `5`, data will be submitted at block heights `6`, `11`, `16`, and so on.
- At each of these intervals, the block data from the proven height to min(current height, proven height + maxBlocksLimitForBlob) will be posted.

Example:
For Blob Interval = 5 and Maximum Blocks Limit for Blob = 10 :-

- At height `6` and provenHeight = `0`, blocks from `1` to `5` are posted.

- At height `11` and provenHeight still `0`, blocks from `1` to `10` are posted.

### Relayer

- The `Relayer` acts as the transport layer, responsible for handling requests from the `preBlocker` and facilitating transactions between the Cosmos chain and the Avail DA network.
- It performs key functions such as submitting block data to Avail and updating block status on the Cosmos chain. Every validator in the network is required to run the relayer process.
- Relayer should initialized with a chain account so that the validator can use this account to sign `MsgUpdateStatusBlob` transaction.

### Voting Interval

- The `Voting Interval` is the period before validators verify whether data is truly included in Avail and confirm it with the network using vote extensions.
64 changes: 64 additions & 0 deletions specs/02_state.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<!--
order: 2
-->

# State

The module keeps state of the following primary objects:

## Blocks Range

Tracks the start and end of the current blocks range being posted to `Avail`.

### Blocks Range Start Height

Stores the start height of the range of current blocks being posted to `Avail`.

It is stored in the state as follows:

- PrevHeightKey `0x07` -> Start Height (Uint64)

### Blocks Range End Height

Stores the end height of the range of current blocks being posted to `Avail`.

It is stored in the state as follows:

- NextHeightKey `0x08` -> End Height (Uint64)

## Blocks Submission Status

Indicates the status of the current blocks submission (`READY`, `PENDING`, `IN_VOTING`, `FAILURE`).

** PENDING ** : Blocks data submission has been initiated and is awaiting confirmation
** IN_VOTING ** : Blocks data has been posted to `Avail` and is now pending validators' verification
** FAILURE ** : Blocks data submission or verification has failed and needs to be resubmitted
** READY ** : blocks data submission is successful; the next set of blocks is ready to be posted

It is stored in the state as follows:

- BlobStatusKey `0x06` : status (uint32)

## Voting End Height

The block height at which the voting for the current blocks should conclude.

It is stored in the state as follows:

- VotingEndHeightKey `0x09` : voting end block height (uint64)

## Avail Height

The Avail block height at which the latest blocks data is made available.

It is stored in the state as follows:

AvailHeightKey `0x0A` : avail block height (uint64)

## Proven Height

The latest block height of the Cosmos chain for which data has been successfully posted to Avail and verified by the network.

It is stored in the state as follows:

ProvenHeightKey `0x02` : proven block height (uint64)
14 changes: 14 additions & 0 deletions specs/03_msg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!--
order: 3
-->

# Messages

## UpdateBlobStatus

The `MsgUpdateBlobStatus` is used to update the status of blocks submission from `PENDING` to either `IN_VOTING` if the submission is successful, or `FAILURE` if it fails. The responsibility for executing this transaction lies with the individual who originally submitted the blocks data to `Avail` (the proposer of the block where the blocks data submission was initiated).

This message will fail under the following conditions:

If the status is nil, meaning it is neither true nor false.
If the status is true but the Avail height is not a valid number.
35 changes: 35 additions & 0 deletions specs/04_client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!--
order: 4
-->

# Client

A user can query and interact with the `cada` module using the CLI.


## Query

The `query` commands allows users to query `cada` state.


```sh
simd query cada --help
```

#### Query the Status
The `get-da-status` command enables users to retrieve comprehensive information, including the range of blocks currently being posted to Avail, the current status, the last proven height, the Avail height where the data is made available, and the voting block height by which voting should conclude.

```sh
$ simd query cada get-da-status
```

Output:

```yml
last_blob_voting_ends_at: "23"
proven_height: "0"
range:
from: "1"
to: "5"
status: IN_VOTING
```
59 changes: 59 additions & 0 deletions specs/05_prepare_proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<!--
order: 5
-->

# ProofOfBlobProposalHandler: PrepareProposal Method

This documentation provides an overview of the `PrepareProposal` method within the `ProofOfBlobProposalHandler`. This method is critical for preparing a block proposal by aggregating and injecting vote information into the proposal transactions.

## Method Overview

The `PrepareProposal` method performs the following key steps:

### 1. Proposer Address Initialization

The method starts by setting the `proposerAddress` in the keeper with the address provided in the `RequestPrepareProposal`. This address represents the proposer of the current block. Since the `PrepareProposal` ABCI method is exclusively executed by the block proposer, this address can later be used for posting block data to `Avail`.

```go
h.keeper.proposerAddress = req.ProposerAddress
```


### 2. Vote Aggregation

The method then aggregates votes by calling the `aggregateVotes` function, which takes in the current context and the `LocalLastCommit` from the request. This function collects votes from the last commit, which are essential for the consensus process for da verification.

```go
votes, err := h.aggregateVotes(ctx, req.LocalLastCommit)
if err != nil {
fmt.Println("error while aggregating votes", err)
return nil, err
}
```



### 3. Injection of Aggregated Votes

The method creates a new structure, `StakeWeightedVotes`, to hold the aggregated votes and the extended commit information (`ExtendedCommitInfo`).

```go
injectedVoteExtTx := StakeWeightedVotes{
Votes: votes,
ExtendedCommitInfo: req.LocalLastCommit,
}
bz, err := json.Marshal(injectedVoteExtTx)
if err != nil {
fmt.Println("failed to encode injected vote extension tx", "err", err)
}
```

The serialized vote information (`injectedVoteExtTx`) is appended to the list of proposal transactions, which can be later processed in `PreBlocker` abci method.

```go
proposalTxs = append(proposalTxs, bz)

return &abci.ResponsePrepareProposal{
Txs: proposalTxs,
}, nil
```
83 changes: 83 additions & 0 deletions specs/06_preblocker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<!--
order: 6
-->

# ProofOfBlobProposalHandler: PreBlocker Method

This documentation provides a detailed overview of the `PreBlocker` method within the `ProofOfBlobProposalHandler`. This method is crucial for processing vote extensions, updating statuses, and initiating block data submissions to Avail.

## Method Overview

The `PreBlocker` method is responsible for two primary tasks: processing votes from vote extensions to update the status and initiating the submission of blocks' data to Avail. Below is a step-by-step explanation of how this method works.

### 1. Process Votes from Vote Extensions and Update the Status

When the current block height matches the voting end height and the status is `IN_VOTING`, the method processes the voting results and updates the state accordingly.

- **Success Condition:** If the collective voting power exceeds 66%, the status is updated to `READY`, and the `provenHeight` is set to the end of the current block range.
- **Failure Condition:** If the voting power is 66% or less, the status is updated to `FAILURE`.

```go
if len(req.Txs) > 0 && currentHeight == int64(votingEndHeight) && blobStatus == IN_VOTING_STATE {
var injectedVoteExtTx StakeWeightedVotes
if err := json.Unmarshal(req.Txs[0], &injectedVoteExtTx); err != nil {
fmt.Println("preblocker failed to decode injected vote extension tx", "err", err)
} else {
from := k.GetStartHeightFromStore(ctx)
to := k.GetEndHeightFromStore(ctx)

pendingRangeKey := Key(from, to)
votingPower := injectedVoteExtTx.Votes[pendingRangeKey]

if votingPower > 66 { // Voting power is greater than 66%
k.setBlobStatusSuccess(ctx)
} else {
k.SetBlobStatusFailure(ctx)
}
}
}
```

### 2. Initiate Block Data Availability (DA) Submission

If the current block height aligns with a voting interval and the status is either `READY` or `FAILURE`, the method updates the block range and sets the status to `PENDING` for the next round of blocks data submission.

- **Range Calculation:** The pending block range to be submitted is calculated based on the last proven height and the current block height.
- **Status Update:** The status is set to `PENDING` to mark the start of the data submission process.

```go
// The following code is executed at block heights that are multiples of the voteInterval,
// i.e., voteInterval+1, 2*voteInterval+1, 3*voteInterval+1, etc.
if !k.IsValidBlockToPostTODA(uint64(currentBlockHeight)) {
return nil
}

provenHeight := k.GetProvenHeightFromStore(ctx)
fromHeight := provenHeight + 1 // Calculate pending range of blocks to post data
endHeight := min(fromHeight+uint64(k.MaxBlocksForBlob), uint64(ctx.BlockHeight())) // Exclusive range i.e., [fromHeight, endHeight)

sdkCtx := sdk.UnwrapSDKContext(ctx)
ok := k.SetBlobStatusPending(sdkCtx, fromHeight, endHeight-1)
if !ok {
return nil
}
```

### 3. Proposer Submits Block Data to Avail DA

If the node running this method is the proposer of the block, it takes responsibility for submitting the blocks data to Avail DA.

- **Block Data Submission:** The proposer gathers the blocks within the calculated range and posts them to Avail DA.

```go
var blocksToSubmit []int64

for i := fromHeight; i < endHeight; i++ {
blocksToSubmit = append(blocksToSubmit, int64(i))
}

// Only the proposer should execute the following code
if bytes.Equal(req.ProposerAddress, k.proposerAddress) {
k.relayer.PostBlocks(ctx, blocksToSubmit, k.cdc, req.ProposerAddress)
}
```
Loading

0 comments on commit 6ab8d2b

Please sign in to comment.