docs: Update ADR 064 (#16885)
This commit is contained in:
parent
5aaadf74b5
commit
864ce72b79
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -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")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user