> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cosmos.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Vote Extensions

<Note>
  **Synopsis**
  This section describes how the application can define and use vote extensions
  defined in ABCI++.
</Note>

## Extend Vote

ABCI++ allows an application to extend a pre-commit vote with arbitrary data. This
process does NOT have to be deterministic, and the data returned can be unique to the
validator process. The Cosmos SDK defines `baseapp.ExtendVoteHandler`:

```go theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
type ExtendVoteHandler func(Context, *abci.RequestExtendVote) (*abci.ResponseExtendVote, error)
```

An application can set this handler in `app.go` via the `baseapp.SetExtendVoteHandler`
`BaseApp` option function. The `sdk.ExtendVoteHandler`, if defined, is called during
the `ExtendVote` ABCI method. Note, if an application decides to implement
`baseapp.ExtendVoteHandler`, it MUST return a non-nil `VoteExtension`. However, the vote
extension can be empty. See [here](https://github.com/cometbft/cometbft/blob/v0.38.0-rc1/spec/abci/abci++_methods.md#extendvote)
for more details.

There are many decentralized censorship-resistant use cases for vote extensions.
For example, a validator may want to submit prices for a price oracle or encryption
shares for an encrypted transaction mempool. Note, an application should be careful
to consider the size of the vote extensions as they could increase latency in block
production. See [here](https://github.com/cometbft/cometbft/blob/v0.38.0-rc1/docs/qa/CometBFT-QA-38.md#vote-extensions-testbed)
for more details.

## Verify Vote Extension

Similar to extending a vote, an application can also verify vote extensions from
other validators when validating their pre-commits. For a given vote extension,
this process MUST be deterministic. The Cosmos SDK defines `sdk.VerifyVoteExtensionHandler`:

```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
package types

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

// InitChainer initializes application state at genesis
type InitChainer func(ctx Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error)

// PrepareCheckStater runs code during commit after the block has been committed, and the `checkState`
// has been branched for the new block.
type PrepareCheckStater func(ctx Context)

// Precommiter runs code during commit immediately before the `deliverState` is written to the `rootMultiStore`.
type Precommiter func(ctx Context)

// PeerFilter responds to p2p filtering queries from Tendermint
type PeerFilter func(info string) *abci.ResponseQuery

// ProcessProposalHandler defines a function type alias for processing a proposer
type ProcessProposalHandler func(Context, *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error)

// PrepareProposalHandler defines a function type alias for preparing a proposal
type PrepareProposalHandler func(Context, *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error)

// ExtendVoteHandler defines a function type alias for extending a pre-commit vote.
type ExtendVoteHandler func(Context, *abci.RequestExtendVote) (*abci.ResponseExtendVote, error)

// VerifyVoteExtensionHandler defines a function type alias for verifying a
// pre-commit vote extension.
type VerifyVoteExtensionHandler func(Context, *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error)

// BeginBlocker defines a function type alias for executing application
// business logic before transactions are executed.
//
// Note: The BeginBlock ABCI method no longer exists in the ABCI specification
// as of CometBFT v0.38.0. This function type alias is provided for backwards
// compatibility with applications that still use the BeginBlock ABCI method
// and allows for existing BeginBlock functionality within applications.
type BeginBlocker func(Context) (BeginBlock, error)

// EndBlocker defines a function type alias for executing application
// business logic after transactions are executed but before committing.
//
// Note: The EndBlock ABCI method no longer exists in the ABCI specification
// as of CometBFT v0.38.0. This function type alias is provided for backwards
// compatibility with applications that still use the EndBlock ABCI method
// and allows for existing EndBlock functionality within applications.
type EndBlocker func(Context) (EndBlock, error)

// EndBlock defines a type which contains endblock events and validator set updates
type EndBlock struct {
    ValidatorUpdates []abci.ValidatorUpdate
	Events           []abci.Event
}

// BeginBlock defines a type which contains beginBlock events
type BeginBlock struct {
    Events []abci.Event
}
```

An application can set this handler in `app.go` via the `baseapp.SetVerifyVoteExtensionHandler`
`BaseApp` option function. The `sdk.VerifyVoteExtensionHandler`, if defined, is called
during the `VerifyVoteExtension` ABCI method. If an application defines a vote
extension handler, it should also define a verification handler. Note, not all
validators will share the same view of what vote extensions they verify depending
on how votes are propagated. See [here](https://github.com/cometbft/cometbft/blob/v0.38.0-rc1/spec/abci/abci++_methods.md#verifyvoteextension)
for more details.

## Vote Extension Propagation

The agreed upon vote extensions at height `H` are provided to the proposing validator
at height `H+1` during `PrepareProposal`. As a result, the vote extensions are
not natively provided or exposed to the remaining validators during `ProcessProposal`.
As a result, if an application requires that the agreed upon vote extensions from
height `H` are available to all validators at `H+1`, the application must propagate
these vote extensions manually in the block proposal itself. This can be done by
"injecting" them into the block proposal, since the `Txs` field in `PrepareProposal`
is just a slice of byte slices.

`FinalizeBlock` will ignore any byte slice that doesn't implement an `sdk.Tx`, so
any injected vote extensions will safely be ignored in `FinalizeBlock`. For more
details on propagation, see the [ABCI++ 2.0 ADR](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-064-abci-2.0.md#vote-extension-propagation--verification).

### Recovery of injected Vote Extensions

As stated before, vote extensions can be injected into a block proposal (along with
other transactions in the `Txs` field). The Cosmos SDK provides a pre-FinalizeBlock
hook to allow applications to recover vote extensions, perform any necessary
computation on them, and then store the results in the cached store. These results
will be available to the application during the subsequent `FinalizeBlock` call.

An example of how a pre-FinalizeBlock hook could look like is shown below:

```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
app.SetPreBlocker(func(ctx sdk.Context, req *abci.RequestFinalizeBlock)

error {
    allVEs := []VE{
} // store all parsed vote extensions here
    for _, tx := range req.Txs {
        // define a custom function that tries to parse the tx as a vote extension
        ve, ok := parseVoteExtension(tx)
    if !ok {
    continue
}

allVEs = append(allVEs, ve)
}

    // perform any necessary computation on the vote extensions and store the result
    // in the cached store
    result := compute(allVEs)
    err := storeVEResult(ctx, result)
    if err != nil {
    return err
}

return nil
})
```

Then, in an app's module, the application can retrieve the result of the computation
of vote extensions from the cached store:

```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
func (k Keeper)

BeginBlocker(ctx context.Context)

error {
    // retrieve the result of the computation of vote extensions from the cached store
    result, err := k.GetVEResult(ctx)
    if err != nil {
    return err
}

    // use the result of the computation of vote extensions
    k.setSomething(result)

return nil
}
```
