Skip to content

Commit

Permalink
docs: Update ADR 064 (cosmos#16885)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexanderbez committed Jul 7, 2023
1 parent 5aaadf7 commit 864ce72
Showing 1 changed file with 21 additions and 25 deletions.
46 changes: 21 additions & 25 deletions docs/architecture/adr-064-abci-2.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2023-01-17: Initial Draft (@alexanderbez)
* 2023-04-06: Add upgrading section (@alexanderbez)
* 2023-04-10: Simplify vote extension state persistence (@alexanderbez)
* 2023-07-07: Revise vote extension state persistence (@alexanderbez)

## Status

Expand Down Expand Up @@ -279,32 +280,22 @@ decision based on the vote extensions.
#### Vote Extension Persistence

In certain contexts, it may be useful or necessary for applications to persist
data derived from vote extensions. In order to facilitate this use case, we
propose to allow application developers to manually retrieve the `finalizeState`
context (see [`FinalizeBlock`](#finalizeblock-1) below). Using this context,
state can be directly written to `finalizeState`, which will be used during
`FinalizeBlock` and eventually committed to the application state. Note, since
`ProcessProposal` can timeout and thus require another round of consensus, we
will reset `finalizeState` in the beginning of `ProcessProposal`.
data derived from vote extensions. In order to facilitate this use case, we propose
to allow app developers to define a pre-FinalizeBlock hook which will be called
at the very beginning of `FinalizeBlock`, i.e. before `BeginBlock` (see below).

A `ProcessProposal` handler could look like the following:
Note, we cannot allow applications to directly write to the application state
during `ProcessProposal` because during replay, CometBFT will NOT call `ProcessProposal`,
which would result in an incomplete state view.

```go
func (h MyHandler) ProcessProposalHandler() sdk.ProcessProposalHandler {
return func(ctx sdk.Context, req abci.RequestProcessProposal) abci.ResponseProcessProposal {
for _, txBytes := range req.Txs {
_, err := h.app.ProcessProposalVerifyTx(txBytes)
if err != nil {
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}
}
}

fCtx := h.app.GetFinalizeState()

// Any state changes that occur on the provided fCtx WILL be written to state!
h.myKeeper.SetVoteExtResult(fCtx, ...)
func (a MyApp) PreFinalizeBlockHook(ctx sdk.Context, req.RequestFinalizeBlock) error {
voteExts := GetVoteExtensions(ctx, req.Txs)

return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}
// Process and perform some compute on vote extensions, storing any resulting
// state.
if err a.processVoteExtensions(ctx, voteExts); if err != nil {
return err
}
}
```
Expand Down Expand Up @@ -347,9 +338,14 @@ legacy ABCI types, e.g. `LegacyBeginBlockRequest` and `LegacyEndBlockRequest`. O
we can come up with new types and names altogether.

```go
func (app *BaseApp) FinalizeBlock(req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock {
// merge any state changes from ProcessProposal into the FinalizeBlock state
app.MergeProcessProposalState()
func (app *BaseApp) FinalizeBlock(req abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) {
ctx := ...

if app.preFinalizeBlockHook != nil {
if err := app.preFinalizeBlockHook(ctx, req); err != nil {
return nil, err
}
}

beginBlockResp := app.beginBlock(ctx, req)
appendBlockEventAttr(beginBlockResp.Events, "begin_block")
Expand Down

0 comments on commit 864ce72

Please sign in to comment.