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

docs: update ADR-064 #15771

Merged
merged 9 commits into from
Apr 11, 2023
42 changes: 14 additions & 28 deletions docs/architecture/adr-064-abci-2.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@

* 2023-01-17: Initial Draft (@alexanderbez)
* 2023-04-06: Add upgrading section (@alexanderbez)
* 2023-04-10: Simplify vote extension state persistence (@alexanderbez)

## Status

PROPOSED
ACCEPTED

## Abstract

Expand Down Expand Up @@ -277,22 +278,14 @@ decision based on the vote extensions.

#### Vote Extension Persistence

In order to make any data derived from vote extensions persistent, we propose to
allow application developers to "merge" the `processProposalState` into the
`finalizeState`, such that when processing transactions during `FinalizeBlock`,
the base state includes any state changes from processing votes extensions
(see [`FinalizeBlock`](#finalizeblock-1) below).

However, we DO NOT want to pollute `finalizeState` with any state changes from
verifying transactions during `ProcessProposal`, so we will introduce a new API,
`ResetProcessProposalState`, that will allow applications to essentially reset
the `ProcessProposal` state, effectively allowing any state transitions after to
be committed.

What this means is that any explicit state changes in a `ProcessProposal` handler
using the injected `processProposalState.Context` will be written to state! An
application must be careful to execute `ResetProcessProposalState` where and when
appropriate.
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`.

A `ProcessProposal` handler could look like the following:

Expand All @@ -306,17 +299,10 @@ func (h MyHandler) ProcessProposalHandler() sdk.ProcessProposalHandler {
}
}

// Reset the ProposalProposal state, which, up to this point, has accumulated
// possible state transitions from transaction verification and processing.
// Any subsequent state transitions after this will be merged into the
// FinalizeState before processing Begin/EndBlock and transactions.
//
// NOTE: Applications must call this to ensure no state transactions up to now
// are committed!
h.app.ResetProcessProposalState()

// Any state changes that occur on the provided ctx WILL be written to state!
h.myKeeper.SetVoteExtResult(ctx, ...)
fCtx := h.app.GetFinalizeState()

// Any state changes that occur on the provided fCtx WILL be written to state!
h.myKeeper.SetVoteExtResult(fCtx, ...)

return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}
}
Expand Down