Skip to content

Commit

Permalink
resolve merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
NagaTulasi committed Sep 19, 2024
2 parents 78eb55b + 6ab8d2b commit 96c05e4
Show file tree
Hide file tree
Showing 19 changed files with 521 additions and 117 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).
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ require (
cosmossdk.io/log v1.3.1
cosmossdk.io/store v1.1.0
cosmossdk.io/x/upgrade v0.1.4
github.com/99designs/keyring v1.2.1
github.com/centrifuge/go-substrate-rpc-client/v4 v4.0.12
github.com/cometbft/cometbft v0.38.10
github.com/cosmos/cosmos-proto v1.0.0-beta.5
Expand All @@ -31,6 +30,7 @@ require (
)

require (
github.com/99designs/keyring v1.2.1 // indirect
github.com/btcsuite/btcd/btcutil v1.1.5 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
github.com/golang/mock v1.6.0 // indirect
Expand Down
4 changes: 3 additions & 1 deletion keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (h *ProofOfBlobProposalHandler) ProcessProposal(_ sdk.Context, req *abci.Re
// PreBlocker runs before finalizing each block, responsible for handling vote extensions
// and managing the posting of blocks to the Avail light client.
func (k *Keeper) PreBlocker(ctx sdk.Context, req *abci.RequestFinalizeBlock) error {
votingEndHeight := k.GetVotingEndHeightFromStore(ctx)
votingEndHeight := k.GetVotingEndHeightFromStore(ctx, false)
blobStatus := k.GetBlobStatus(ctx)
currentHeight := ctx.BlockHeight()

Expand All @@ -114,6 +114,8 @@ func (k *Keeper) PreBlocker(ctx sdk.Context, req *abci.RequestFinalizeBlock) err
state = ReadyState
}

store := ctx.KVStore(k.storeKey)
UpdateVotingEndHeight(ctx, store, 0, false)
k.SetBlobStatus(ctx, state)
}
}
Expand Down
4 changes: 3 additions & 1 deletion keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ func (s msgServer) UpdateBlobStatus(ctx context.Context, req *types.MsgUpdateBlo
} else {
currentHeight := sdkCtx.BlockHeight()
UpdateAvailHeight(sdkCtx, store, req.AvailHeight) // updates avail height at which the blocks got submitted to DA
UpdateVotingEndHeight(sdkCtx, store, uint64(currentHeight)+s.k.VotingInterval)
lastVotingEndHeight := s.k.GetVotingEndHeightFromStore(sdkCtx, false)
UpdateVotingEndHeight(sdkCtx, store, uint64(currentHeight)+s.k.VotingInterval, false)
UpdateVotingEndHeight(sdkCtx, store, lastVotingEndHeight, true)
}

UpdateBlobStatus(sdkCtx, store, newStatus)
Expand Down
10 changes: 5 additions & 5 deletions keeper/query_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ func (qs queryServer) SubmittedBlobStatus(ctx context.Context, _ *types.QuerySub
status := GetStatusFromStore(store)
blobStatus := ParseStatus(status)
provenHeight := qs.k.GetProvenHeightFromStore(sdkCtx)
votingEndHeight := qs.k.GetVotingEndHeightFromStore(sdkCtx)
votingEndHeight := qs.k.GetVotingEndHeightFromStore(sdkCtx, false)

return &types.QuerySubmittedBlobStatusResponse{
Range: &types.Range{From: startHeight, To: endHeight},
Status: blobStatus,
ProvenHeight: provenHeight,
LastBlobVotingEndsAt: votingEndHeight,
Range: &types.Range{From: startHeight, To: endHeight},
Status: blobStatus,
ProvenHeight: provenHeight,
VotingEndsAt: votingEndHeight,
}, nil
}
16 changes: 12 additions & 4 deletions keeper/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,12 @@ func UpdateAvailHeight(_ sdk.Context, store storetypes2.KVStore, availHeight uin
}

// UpdateVotingEndHeight updates the voting end height in the KV store.
func UpdateVotingEndHeight(_ sdk.Context, store storetypes2.KVStore, votingEndHeight uint64) error {
return updateHeight(store, availblob1.VotingEndHeightKey, votingEndHeight)
func UpdateVotingEndHeight(_ sdk.Context, store storetypes2.KVStore, votingEndHeight uint64, isLastVoting bool) error {
key := availblob1.VotingEndHeightKey
if isLastVoting {
key = availblob1.LastVotingEndHeightKey
}
return updateHeight(store, key, votingEndHeight)
}

// updateHeight encodes and stores a height value in the KV store.
Expand All @@ -113,8 +117,12 @@ func (k *Keeper) GetAvailHeightFromStore(ctx sdk.Context) uint64 {
}

// GetVotingEndHeightFromStore retrieves the ending vote height from store
func (k *Keeper) GetVotingEndHeightFromStore(ctx sdk.Context) uint64 {
return k.getHeight(ctx, availblob1.VotingEndHeightKey)
func (k *Keeper) GetVotingEndHeightFromStore(ctx sdk.Context, isLastVoting bool) uint64 {
key := availblob1.VotingEndHeightKey
if isLastVoting {
key = availblob1.LastVotingEndHeightKey
}
return k.getHeight(ctx, key)
}

// GetStartHeightFromStore retrieves the start height from store
Expand Down
2 changes: 1 addition & 1 deletion keeper/vote_extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (h *VoteExtHandler) ExtendVoteHandler() sdk.ExtendVoteHandler {

blobStatus := h.Keeper.GetBlobStatus(ctx)
currentHeight := ctx.BlockHeight()
voteEndHeight := h.Keeper.GetVotingEndHeightFromStore(ctx)
voteEndHeight := h.Keeper.GetVotingEndHeightFromStore(ctx, false)
Votes := make(map[string]bool, 1)

abciResponseVoteExt := &abci.ResponseExtendVote{}
Expand Down
4 changes: 3 additions & 1 deletion keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ var (

VotingEndHeightKey = collections.NewPrefix(9)

AvailHeightKey = collections.NewPrefix(10)
LastVotingEndHeightKey = collections.NewPrefix(10)

AvailHeightKey = collections.NewPrefix(11)
)

const (
Expand Down
4 changes: 2 additions & 2 deletions proto/sdk/avail/v1beta1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ message QuerySubmittedBlobStatusResponse {
// This height indicates the extent of posted data to avail light client.
uint64 proven_height = 3;

// last_blob_voting_ends_at denotes the block height at which the last voting on the blob ended.
// voting_ends_at denotes the block height at which the last voting on the blob ended.
// This provides information on when the last voting period for the blob concluded.
uint64 last_blob_voting_ends_at = 4;
uint64 voting_ends_at = 4;
}

// Query defines the gRPC querier service.
Expand Down
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
```
Loading

0 comments on commit 96c05e4

Please sign in to comment.