Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: add code documentation #39

Merged
merged 11 commits into from
Sep 20, 2024
3 changes: 3 additions & 0 deletions chainclient/broadcast_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/vitwit/avail-da-module/types"
)

// GetBinPath returns the path to the Avail SDK home directory within the user's home directory.
func GetBinPath(daemon string) string {
homeDir, err := os.UserHomeDir()
if err != nil {
Expand All @@ -25,6 +26,8 @@ func GetBinPath(daemon string) string {
return availdHomePath
}

// ExecuteTX handles the creation and submission of a transaction to update blob status on the chain.
// It uses keyring and RPC client configurations to interact with the network.
func ExecuteTX(ctx sdk.Context, msg types.MsgUpdateBlobStatusRequest, cdc codec.BinaryCodec, config types.AvailConfiguration, nodeDir string) error {
// Define keyring and RPC client configuration
// homePath := "/home/vitwit/.simapp"
Expand Down
3 changes: 2 additions & 1 deletion chainclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ const (
KeyringBackendTest = "test"
)

// ChainClient is client to interact with SPN.
// ChainClient represents a client used for interacting with a network.
// It contains configurations and credentials necessary for broadcasting transactions and interacting with the chain.
NagaTulasi marked this conversation as resolved.
Show resolved Hide resolved
type ChainClient struct {
Address string `json:"address"`
AddressPrefix string `json:"account_address_prefix"`
Expand Down
2 changes: 2 additions & 0 deletions client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/vitwit/avail-da-module/types"
)

// GetQueryCmd returns the root query command for the avail-da module.
func GetQueryCmd() *cobra.Command {
cmd := &cobra.Command{
Use: availblob.ModuleName,
Expand All @@ -22,6 +23,7 @@ func GetQueryCmd() *cobra.Command {
return cmd
}

// GetLatestBlobStatusInfo returns a command to query the latest status of blob submissions.
func GetLatestBlobStatusInfo() *cobra.Command {
cmd := &cobra.Command{
Use: "get-da-status",
Expand Down
5 changes: 3 additions & 2 deletions client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/vitwit/avail-da-module/types"
)

// NewTxCmd
// NewTxCmd creates and returns a Cobra command for transaction subcommands related to the availblob module.
func NewTxCmd(_ *keeper.Keeper) *cobra.Command {
txCmd := &cobra.Command{
Use: availblob.ModuleName,
Expand All @@ -29,7 +29,7 @@ func NewTxCmd(_ *keeper.Keeper) *cobra.Command {
return txCmd
}

// update status
// NewUpdateBlobStatusCmd creates and returns a Cobra command to update the status of a blob within a specified range of blocks.
func NewUpdateBlobStatusCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "update-blob [from_block] [to_block] [status] [avail_height]",
Expand Down Expand Up @@ -80,6 +80,7 @@ func NewUpdateBlobStatusCmd() *cobra.Command {
return cmd
}

// ParseStatus converts a string status to a boolean value indicating success or failure.
func ParseStatus(status string) (bool, error) {
status = strings.ToUpper(status)
if status == "SUCCESS" {
Expand Down
27 changes: 26 additions & 1 deletion keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,26 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

// ProofOfBlobProposalHandler manages the proposal and vote extension logic related to
// blob transactions in the consensus process.
type ProofOfBlobProposalHandler struct {
keeper *Keeper

// prepareProposalHandler is responsible for preparing proposals. This is called
// during the proposal preparation phase to adjust or validate the proposal before
// it's broadcast to other validators.
prepareProposalHandler sdk.PrepareProposalHandler

// processProposalHandler processes proposals during the consensus. It verifies
// the validity of the received proposal and determines whether it should be accepted or rejected.
processProposalHandler sdk.ProcessProposalHandler
VoteExtHandler VoteExtHandler

// VoteExtHandler handles vote extensions, allowing validators to submit additional information
// like avail height along with their votes during the consensus process.
VoteExtHandler VoteExtHandler
}

// NewProofOfBlobProposalHandler creates a new instance of the ProofOfBlobProposalHandler.
func NewProofOfBlobProposalHandler(
k *Keeper,
prepareProposalHandler sdk.PrepareProposalHandler,
Expand All @@ -32,6 +44,8 @@ func NewProofOfBlobProposalHandler(
}
}

// PrepareProposal is responsible for preparing a proposal by aggregating vote extensions
// and injecting them into the list of transactions for the proposal.
func (h *ProofOfBlobProposalHandler) PrepareProposal(ctx sdk.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) {
h.keeper.ProposerAddress = req.ProposerAddress
proposalTxs := req.Txs
Expand All @@ -57,6 +71,9 @@ func (h *ProofOfBlobProposalHandler) PrepareProposal(ctx sdk.Context, req *abci.
}, nil
}

// ProcessProposal handles the validation and processing of a proposed block during the consensus process.
// It checks if the proposal contains any transactions, attempts to decode the injected vote extension
// transaction, and performs necessary validations before deciding to accept or reject the proposal.
func (h *ProofOfBlobProposalHandler) ProcessProposal(_ sdk.Context, req *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) {
if len(req.Txs) == 0 {
return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil
Expand All @@ -73,6 +90,8 @@ func (h *ProofOfBlobProposalHandler) ProcessProposal(_ sdk.Context, req *abci.Re
return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil
}

// PreBlocker runs before finalizing each block, responsible for handling vote extensions
// and managing the posting of blocks to the Avail light client.
NagaTulasi marked this conversation as resolved.
Show resolved Hide resolved
func (k *Keeper) PreBlocker(ctx sdk.Context, req *abci.RequestFinalizeBlock) error {
votingEndHeight := k.GetVotingEndHeightFromStore(ctx, false)
blobStatus := k.GetBlobStatus(ctx)
Expand Down Expand Up @@ -131,6 +150,8 @@ func (k *Keeper) PreBlocker(ctx sdk.Context, req *abci.RequestFinalizeBlock) err
return nil
}

// IsValidBlockToPostTODA checks if the given block height is valid for posting data.
// The block is considered valid if it meets the defined interval for posting.
func (k *Keeper) IsValidBlockToPostTODA(height uint64) bool {
if height <= uint64(1) {
return false
Expand All @@ -143,6 +164,10 @@ func (k *Keeper) IsValidBlockToPostTODA(height uint64) bool {
return true
}

// For each vote, it decodes the `VoteExtension`, which contains the vote information for
// specific block ranges.
// If the vote extension contains a vote for the pending range, it sums the voting power
// of validators.
NagaTulasi marked this conversation as resolved.
Show resolved Hide resolved
func (h *ProofOfBlobProposalHandler) aggregateVotes(ctx sdk.Context, ci abci.ExtendedCommitInfo) (map[string]int64, error) {
from := h.keeper.GetStartHeightFromStore(ctx)
to := h.keeper.GetEndHeightFromStore(ctx)
Expand Down
9 changes: 8 additions & 1 deletion keeper/abciTypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ package keeper

import abci "github.com/cometbft/cometbft/abci/types"

// StakeWeightedVotes stores the stake-weighted votes from validators and the commit info
// for a consensus round.
NagaTulasi marked this conversation as resolved.
Show resolved Hide resolved
type StakeWeightedVotes struct {
Votes map[string]int64
// A map where the key is the range of pending blocks(e.g. "1 10"), and the value is the
// validator's voting power.
Votes map[string]int64

// ExtendedCommitInfo Contains additional information about the commit phase, including
// vote extensions and details about the current consensus round.
ExtendedCommitInfo abci.ExtendedCommitInfo
}
2 changes: 2 additions & 0 deletions keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,12 @@ func NewKeeper(
}
}

// SetRelayer sets the relayer instance for the Keeper.
func (k *Keeper) SetRelayer(r *relayer.Relayer) {
k.relayer = r
}

// GetBlobStatus retrieves the current status of the blob from the store.
func (k *Keeper) GetBlobStatus(ctx sdk.Context) uint32 {
store := ctx.KVStore(k.storeKey)
return GetStatusFromStore(store)
Expand Down
3 changes: 3 additions & 0 deletions keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ func NewMsgServerImpl(keeper *Keeper) types.MsgServer {
return &msgServer{k: keeper}
}

// UpdateBlobStatus updates the status of the blob.
// This method verifies the blocks range and updates the status to either Voting or Failure,
// depending on the request's success flag.
func (s msgServer) UpdateBlobStatus(ctx context.Context, req *types.MsgUpdateBlobStatusRequest) (*types.MsgUpdateBlobStatusResponse, error) {
sdkCtx := sdk.UnwrapSDKContext(ctx)

Expand Down
1 change: 1 addition & 0 deletions keeper/query_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type queryServer struct {
k *Keeper
}

// SubmittedBlobStatus handles a request to query and return the current status of a blob.
func (qs queryServer) SubmittedBlobStatus(ctx context.Context, _ *types.QuerySubmittedBlobStatusRequest) (*types.QuerySubmittedBlobStatusResponse, error) {
sdkCtx := sdk.UnwrapSDKContext(ctx)

Expand Down
4 changes: 4 additions & 0 deletions keeper/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

// SetBlobStatusPending sets the status of a blob to "pending" and updates its height range.
// This method ensures that the status can be updated to pending before making the changes
// and sets the start and end heights for the blob.
func (k *Keeper) SetBlobStatusPending(ctx sdk.Context, startHeight, endHeight uint64) bool {
store := ctx.KVStore(k.storeKey)

Expand All @@ -17,6 +20,7 @@ func (k *Keeper) SetBlobStatusPending(ctx sdk.Context, startHeight, endHeight ui
return true
}

// SetBlobStatus updates the status of the blob
func (k *Keeper) SetBlobStatus(ctx sdk.Context, state uint32) error {
store := ctx.KVStore(k.storeKey)

Expand Down
17 changes: 17 additions & 0 deletions keeper/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,16 @@ func ParseStatus(status uint32, startHeight, endHeight uint64) string {
}
}

// ParseVotingEndHeight converts a given voting end height from uint64 to a string format.
func ParseVotingEndHeight(height uint64) string {
if height == 0 {
return ""
}
return fmt.Sprintln(height)
}

// CanUpdateStatusToPending checks if the blob status can be updated to "pending".
// This function verifies whether the current status allows transitioning to the "pending" state.
func CanUpdateStatusToPending(store storetypes2.KVStore) bool {
statusBytes := store.Get(availblob1.BlobStatusKey)
if len(statusBytes) == 0 {
Expand All @@ -54,6 +57,7 @@ func CanUpdateStatusToPending(store storetypes2.KVStore) bool {
return status == ReadyState || status == FailureState
}

// GetStatusFromStore retrieves the current status of the blob from the store.
func GetStatusFromStore(store storetypes2.KVStore) uint32 {
statusBytes := store.Get(availblob1.BlobStatusKey)

Expand All @@ -66,6 +70,7 @@ func GetStatusFromStore(store storetypes2.KVStore) uint32 {
return status
}

// UpdateBlobStatus updates the blob status in the KV store.
func UpdateBlobStatus(_ sdk.Context, store storetypes2.KVStore, status uint32) error {
statusBytes := make([]byte, 4)

Expand All @@ -75,22 +80,27 @@ func UpdateBlobStatus(_ sdk.Context, store storetypes2.KVStore, status uint32) e
return nil
}

// UpdateStartHeight updates the start height in the KV store.
func UpdateStartHeight(_ sdk.Context, store storetypes2.KVStore, startHeight uint64) error {
return updateHeight(store, availblob1.PrevHeightKey, startHeight)
}

// UpdateEndHeight updates the end height in the KV store.
func UpdateEndHeight(_ sdk.Context, store storetypes2.KVStore, endHeight uint64) error {
return updateHeight(store, availblob1.NextHeightKey, endHeight)
}

// UpdateProvenHeight updates the proven height in the KV store.
func UpdateProvenHeight(_ sdk.Context, store storetypes2.KVStore, provenHeight uint64) error {
return updateHeight(store, availblob1.ProvenHeightKey, provenHeight)
}

// UpdateAvailHeight updates the avail height in the store
func UpdateAvailHeight(_ sdk.Context, store storetypes2.KVStore, availHeight uint64) error {
return updateHeight(store, availblob1.AvailHeightKey, availHeight)
}

// UpdateVotingEndHeight updates the voting end height in the KV store.
func UpdateVotingEndHeight(_ sdk.Context, store storetypes2.KVStore, votingEndHeight uint64, isLastVoting bool) error {
key := availblob1.VotingEndHeightKey
if isLastVoting {
Expand All @@ -99,6 +109,7 @@ func UpdateVotingEndHeight(_ sdk.Context, store storetypes2.KVStore, votingEndHe
return updateHeight(store, key, votingEndHeight)
}

// updateHeight encodes and stores a height value in the KV store.
func updateHeight(store storetypes2.KVStore, key collections.Prefix, height uint64) error {
heightBytes := make([]byte, 8)

Expand All @@ -108,14 +119,17 @@ func updateHeight(store storetypes2.KVStore, key collections.Prefix, height uint
return nil
}

// GetProvenHeightFromStore retrieves the proven height from the KV store.
func (k *Keeper) GetProvenHeightFromStore(ctx sdk.Context) uint64 {
return k.getHeight(ctx, availblob1.ProvenHeightKey)
}

// GetAvailHeightFromStore retrieves the avail height from the KV store.
func (k *Keeper) GetAvailHeightFromStore(ctx sdk.Context) uint64 {
return k.getHeight(ctx, availblob1.AvailHeightKey)
}

// GetVotingEndHeightFromStore retrieves the ending vote height from store
func (k *Keeper) GetVotingEndHeightFromStore(ctx sdk.Context, isLastVoting bool) uint64 {
key := availblob1.VotingEndHeightKey
if isLastVoting {
Expand All @@ -124,14 +138,17 @@ func (k *Keeper) GetVotingEndHeightFromStore(ctx sdk.Context, isLastVoting bool)
return k.getHeight(ctx, key)
}

// GetStartHeightFromStore retrieves the start height from store
func (k *Keeper) GetStartHeightFromStore(ctx sdk.Context) uint64 {
return k.getHeight(ctx, availblob1.PrevHeightKey)
}

// GetEndHeightFromStore retrieves the end height from store
func (k *Keeper) GetEndHeightFromStore(ctx sdk.Context) uint64 {
return k.getHeight(ctx, availblob1.NextHeightKey)
}

// getHeight retrieves and decodes a height value from the KV store.
func (k *Keeper) getHeight(ctx sdk.Context, key collections.Prefix) uint64 {
store := ctx.KVStore(k.storeKey)
heightBytes := store.Get(key)
Expand Down
4 changes: 4 additions & 0 deletions keeper/vote_extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ type VoteExtension struct {
Votes map[string]bool
}

// ExtendVoteHandler handles the extension of votes by providing a vote extension for the given block.
// This function is used to extend the voting information with the necessary vote extensions based on the current blockchain state.
func (h *VoteExtHandler) ExtendVoteHandler() sdk.ExtendVoteHandler {
return func(ctx sdk.Context, _ *abci.RequestExtendVote) (*abci.ResponseExtendVote, error) {
from := h.Keeper.GetStartHeightFromStore(ctx)
Expand Down Expand Up @@ -93,6 +95,8 @@ func (h *VoteExtHandler) ExtendVoteHandler() sdk.ExtendVoteHandler {
}
}

// VerifyVoteExtensionHandler handles the verification of vote extensions by validating the provided vote extension data.
// This function is used to verify the correctness and validity of the vote extensions submitted during the voting process.
func (h *VoteExtHandler) VerifyVoteExtensionHandler() sdk.VerifyVoteExtensionHandler {
return func(_ sdk.Context, _ *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) {
// TODO: write proper validation for the votes
Expand Down
4 changes: 4 additions & 0 deletions keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ const (
QuerierRoute = ModuleName
)

// PendingBlobsStoreKey generates a store key for pending blobs based on the given block range.
// The key is constructed by appending the byte-encoded 'From' and 'To' values from the `blocksRange`
// to a base key (`PendingBlobsKey`). This unique key is used to store and retrieve pending blob data
// in a key-value store.
func PendingBlobsStoreKey(blocksRange types.Range) []byte {
fromBytes := make([]byte, 8)
binary.BigEndian.PutUint64(fromBytes, blocksRange.From)
Expand Down
9 changes: 7 additions & 2 deletions proto/sdk/avail/v1beta1/abci.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@ import "gogoproto/gogo.proto";

option go_package = "github.com/vitwit/avail-da-module/types";

// InjectedData represents a message containing data that has been injected.
message InjectedData {

// PendingBlocks contains information about blocks that are pending.
PendingBlocks pending_blocks = 1 [ (gogoproto.nullable) = false ];
}

// The PendingBlocks message includes a list of block heights that are currently pending.
message PendingBlocks {
repeated int64 block_heights = 1;
}

message UnprovenBlock {
// UnprovenBlock represents a message containing data about a block that has not yet been proven.
message UnprovenBlock { // TODO: depreacate this not using anymore
int64 height = 1;
bytes block = 2;
}
}
4 changes: 2 additions & 2 deletions proto/sdk/avail/v1beta1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import "sdk/avail/v1beta1/validator.proto";

option go_package = "github.com/vitwit/avail-da-module/types";

// GenesisState defines the auth module's genesis state.
// GenesisState defines the avail da module's genesis state.
message GenesisState {
repeated Validator validators = 1 [ (gogoproto.nullable) = false ];

// the height of the last block that was proven to be posted to Avail.
// increment only, never skipping heights.
uint64 proven_height = 2;
}
}
Loading
Loading