PrepareProposal/ProcessProposal: Dealing with block data exposed to App (#9219)

* [cherrypicked] abci++: only include meaningful header fields in data passed-through to application (#8216)

* make proto-gen

* Fix kvstore tests

* Small changes to abci protobufs taken from v0.36.x

* make proto-gen (again)

* [Partial cherrypick] Restore `Commit` to the ABCI++ spec, and other late modifications (backport #8796) (#8936)

* Restore `Commit` to the ABCI++ spec, and other late modifications (#8796)

* Added VoteExtensionsEnableHeight

* Fix reference to `modified`

* Removed old pseudo-code, now included in spec

* Removed markdown warnings in abci++_basic_concepts_002_draft.md

* Restored `Commit` in the Methods section

* Addressed remaining markdown warnings

* Revisited intro and basic concepts section

* Extra pass at all spec sections to recover Commit, and other ABCI++ spec modifications

* Fixed links

* make proto-gen

* Remove _primes_ from spec notation

* Update proto/tendermint/abci/types.proto

Co-authored-by: Callum Waters <cmwaters19@gmail.com>

* Update spec/abci++/abci++_tmint_expected_behavior_002_draft.md

Co-authored-by: Callum Waters <cmwaters19@gmail.com>

* Addressed @cmwaters' comments

* Addressed @angbrav's and @mpoke's comments on spec

* make proto-gen

* Fix MD anchor reference

* Clarify throughout the spec when `ProcessProposal` and `VerifyVoteExtension` are called

* Update spec/abci++/abci++_app_requirements_002_draft.md

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>

* Update spec/abci++/abci++_app_requirements_002_draft.md

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>

* Update spec/abci++/abci++_app_requirements_002_draft.md

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Update spec/abci++/abci++_basic_concepts_002_draft.md

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Update spec/abci++/abci++_basic_concepts_002_draft.md

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>

* Update spec/abci++/abci++_basic_concepts_002_draft.md

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Update spec/abci++/abci++_methods_002_draft.md

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>

* Update spec/abci++/abci++_tmint_expected_behavior_002_draft.md

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>

* Addresed comments

* Renamed 'draft' files

* Adatped links to new filenames

* Fixed links and minor cosmetic changes

* Renamed 'byzantine_validators' to 'misbehavior' in ABCI++ spec and protobufs

* make proto-gen

* Renamed 'byzantine_validators' to 'misbehavior' in the code

* Fixed link

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_basic_concepts.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Update spec/abci++/abci++_methods.md

Co-authored-by: Daniel <daniel.cason@usi.ch>

* Addressed @cason's comments

* Clarified conditions for `ProcessProposal` call at proposer

Co-authored-by: Callum Waters <cmwaters19@gmail.com>
Co-authored-by: M. J. Fromberger <fromberger@interchain.io>
Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>
Co-authored-by: Daniel <daniel.cason@usi.ch>
(cherry picked from commit 331860c2a8)

* Fixed merge conflicts

Co-authored-by: Sergio Mena <sergio@informal.systems>

* make proto-gen (and again)

* make build

* fix UTs

Co-authored-by: William Banfield <4561443+williambanfield@users.noreply.github.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
Sergio Mena
2022-08-11 11:21:43 +02:00
committed by GitHub
parent f861062ee2
commit 25b0c7c78e
8 changed files with 514 additions and 419 deletions

View File

@@ -130,7 +130,7 @@ func (app *PersistentKVStoreApplication) BeginBlock(req types.RequestBeginBlock)
// Punish validators who committed equivocation.
for _, ev := range req.ByzantineValidators {
if ev.Type == types.EvidenceType_DUPLICATE_VOTE {
if ev.Type == types.MisbehaviorType_DUPLICATE_VOTE {
addr := string(ev.Validator.Address)
if pubKey, ok := app.valAddrToPubKeyMap[addr]; ok {
app.updateValidator(types.ValidatorUpdate{

File diff suppressed because it is too large Load Diff

View File

@@ -80,7 +80,7 @@ message RequestBeginBlock {
bytes hash = 1;
tendermint.types.Header header = 2 [(gogoproto.nullable) = false];
CommitInfo last_commit_info = 3 [(gogoproto.nullable) = false];
repeated Evidence byzantine_validators = 4 [(gogoproto.nullable) = false];
repeated Misbehavior byzantine_validators = 4 [(gogoproto.nullable) = false];
}
enum CheckTxType {
@@ -127,21 +127,24 @@ message RequestApplySnapshotChunk {
}
message RequestPrepareProposal {
bytes hash = 1;
tendermint.types.Header header = 2 [(gogoproto.nullable) = false];
// the modified transactions cannot exceed this size.
int64 max_tx_bytes = 1;
// txs is an array of transactions that will be included in a block,
// sent to the app for possible modifications.
repeated bytes txs = 3;
ExtendedCommitInfo local_last_commit = 4 [(gogoproto.nullable) = false];
repeated Evidence byzantine_validators = 5 [(gogoproto.nullable) = false];
// the modified transactions cannot exceed this size.
int64 max_tx_bytes = 6;
repeated bytes txs = 2;
ExtendedCommitInfo local_last_commit = 3 [(gogoproto.nullable) = false];
repeated Misbehavior misbehavior = 4 [(gogoproto.nullable) = false];
int64 height = 5;
google.protobuf.Timestamp time = 6 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
bytes next_validators_hash = 7;
// address of the public key of the validator proposing the block.
bytes proposer_address = 8;
}
message RequestProcessProposal {
repeated bytes txs = 1;
CommitInfo proposed_last_commit = 2 [(gogoproto.nullable) = false];
repeated Evidence misbehavior = 3 [(gogoproto.nullable) = false];
repeated bytes txs = 1;
CommitInfo proposed_last_commit = 2 [(gogoproto.nullable) = false];
repeated Misbehavior misbehavior = 3 [(gogoproto.nullable) = false];
// hash is the merkle root hash of the fields of the proposed block.
bytes hash = 4;
int64 height = 5;
@@ -351,7 +354,10 @@ message CommitInfo {
}
message ExtendedCommitInfo {
int32 round = 1;
// The round at which the block proposer decided in the previous height.
int32 round = 1;
// List of validators' addresses in the last validator set with their voting
// information, including vote extensions.
repeated ExtendedVoteInfo votes = 2 [(gogoproto.nullable) = false];
}
@@ -416,8 +422,6 @@ message ValidatorUpdate {
message VoteInfo {
Validator validator = 1 [(gogoproto.nullable) = false];
bool signed_last_block = 2;
reserved 3; // Placeholder for tendermint_signed_extension in v0.37
reserved 4; // Placeholder for app_signed_extension in v0.37
}
message ExtendedVoteInfo {
@@ -426,14 +430,14 @@ message ExtendedVoteInfo {
bytes vote_extension = 3; // Reserved for future use
}
enum EvidenceType {
enum MisbehaviorType {
UNKNOWN = 0;
DUPLICATE_VOTE = 1;
LIGHT_CLIENT_ATTACK = 2;
}
message Evidence {
EvidenceType type = 1;
message Misbehavior {
MisbehaviorType type = 1;
// The offending validator
Validator validator = 2 [(gogoproto.nullable) = false];
// The height when the offense occurred

View File

@@ -115,12 +115,14 @@ func (blockExec *BlockExecutor) CreateProposalBlock(
localLastCommit := buildLastCommitInfo(block, blockExec.store, state.InitialHeight)
rpp, err := blockExec.proxyApp.PrepareProposalSync(
abci.RequestPrepareProposal{
Hash: block.Hash(),
Header: *block.Header.ToProto(),
Txs: block.Txs.ToSliceOfBytes(),
LocalLastCommit: extendedCommitInfo(localLastCommit, votes),
ByzantineValidators: block.Evidence.Evidence.ToABCI(),
MaxTxBytes: maxDataBytes,
MaxTxBytes: maxDataBytes,
Txs: block.Txs.ToSliceOfBytes(),
LocalLastCommit: extendedCommitInfo(localLastCommit, votes),
Misbehavior: block.Evidence.Evidence.ToABCI(),
Height: block.Height,
Time: block.Time,
NextValidatorsHash: block.NextValidatorsHash,
ProposerAddress: block.ProposerAddress,
},
)
if err != nil {

View File

@@ -193,16 +193,16 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
ev := []types.Evidence{dve, lcae}
abciEv := []abci.Evidence{
abciMb := []abci.Misbehavior{
{
Type: abci.EvidenceType_DUPLICATE_VOTE,
Type: abci.MisbehaviorType_DUPLICATE_VOTE,
Height: 3,
Time: defaultEvidenceTime,
Validator: types.TM2PB.Validator(state.Validators.Validators[0]),
TotalVotingPower: 10,
},
{
Type: abci.EvidenceType_LIGHT_CLIENT_ATTACK,
Type: abci.MisbehaviorType_LIGHT_CLIENT_ATTACK,
Height: 8,
Time: defaultEvidenceTime,
Validator: types.TM2PB.Validator(state.Validators.Validators[0]),
@@ -242,7 +242,7 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
assert.EqualValues(t, retainHeight, 1)
// TODO check state and mempool
assert.Equal(t, abciEv, app.ByzantineValidators)
assert.Equal(t, abciMb, app.Misbehavior)
}
func TestProcessProposal(t *testing.T) {

View File

@@ -224,9 +224,9 @@ func randomGenesisDoc() *types.GenesisDoc {
type testApp struct {
abci.BaseApplication
CommitVotes []abci.VoteInfo
ByzantineValidators []abci.Evidence
ValidatorUpdates []abci.ValidatorUpdate
CommitVotes []abci.VoteInfo
Misbehavior []abci.Misbehavior
ValidatorUpdates []abci.ValidatorUpdate
}
var _ abci.Application = (*testApp)(nil)
@@ -237,7 +237,7 @@ func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) {
func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock {
app.CommitVotes = req.LastCommitInfo.Votes
app.ByzantineValidators = req.ByzantineValidators
app.Misbehavior = req.ByzantineValidators
return abci.ResponseBeginBlock{}
}

View File

@@ -246,7 +246,7 @@ func TestValidateBlockEvidence(t *testing.T) {
evpool.On("CheckEvidence", mock.AnythingOfType("types.EvidenceList")).Return(nil)
evpool.On("Update", mock.AnythingOfType("state.State"), mock.AnythingOfType("types.EvidenceList")).Return()
evpool.On("ABCIEvidence", mock.AnythingOfType("int64"), mock.AnythingOfType("[]types.Evidence")).Return(
[]abci.Evidence{})
[]abci.Misbehavior{})
mp := &mpmocks.Mempool{}
mp.On("Lock").Return()

View File

@@ -20,13 +20,13 @@ import (
// Evidence represents any provable malicious activity by a validator.
// Verification logic for each evidence is part of the evidence module.
type Evidence interface {
ABCI() []abci.Evidence // forms individual evidence to be sent to the application
Bytes() []byte // bytes which comprise the evidence
Hash() []byte // hash of the evidence
Height() int64 // height of the infraction
String() string // string format of the evidence
Time() time.Time // time of the infraction
ValidateBasic() error // basic consistency check
ABCI() []abci.Misbehavior // forms individual evidence to be sent to the application
Bytes() []byte // bytes which comprise the evidence
Hash() []byte // hash of the evidence
Height() int64 // height of the infraction
String() string // string format of the evidence
Time() time.Time // time of the infraction
ValidateBasic() error // basic consistency check
}
//--------------------------------------------------------------------------------------
@@ -73,9 +73,9 @@ func NewDuplicateVoteEvidence(vote1, vote2 *Vote, blockTime time.Time, valSet *V
}
// ABCI returns the application relevant representation of the evidence
func (dve *DuplicateVoteEvidence) ABCI() []abci.Evidence {
return []abci.Evidence{{
Type: abci.EvidenceType_DUPLICATE_VOTE,
func (dve *DuplicateVoteEvidence) ABCI() []abci.Misbehavior {
return []abci.Misbehavior{{
Type: abci.MisbehaviorType_DUPLICATE_VOTE,
Validator: abci.Validator{
Address: dve.VoteA.ValidatorAddress,
Power: dve.ValidatorPower,
@@ -199,12 +199,12 @@ type LightClientAttackEvidence struct {
var _ Evidence = &LightClientAttackEvidence{}
// ABCI forms an array of abci evidence for each byzantine validator
func (l *LightClientAttackEvidence) ABCI() []abci.Evidence {
abciEv := make([]abci.Evidence, len(l.ByzantineValidators))
// ABCI forms an array of abci.Misbehavior for each byzantine validator
func (l *LightClientAttackEvidence) ABCI() []abci.Misbehavior {
abciEv := make([]abci.Misbehavior, len(l.ByzantineValidators))
for idx, val := range l.ByzantineValidators {
abciEv[idx] = abci.Evidence{
Type: abci.EvidenceType_LIGHT_CLIENT_ATTACK,
abciEv[idx] = abci.Misbehavior{
Type: abci.MisbehaviorType_LIGHT_CLIENT_ATTACK,
Validator: TM2PB.Validator(val),
Height: l.Height(),
Time: l.Timestamp,
@@ -461,8 +461,8 @@ func (evl EvidenceList) Has(evidence Evidence) bool {
// ToABCI converts the evidence list to a slice of the ABCI protobuf messages
// for use when communicating the evidence to an application.
func (evl EvidenceList) ToABCI() []abci.Evidence {
var el []abci.Evidence
func (evl EvidenceList) ToABCI() []abci.Misbehavior {
var el []abci.Misbehavior
for _, e := range evl {
el = append(el, e.ABCI()...)
}