fixes for ProposerAddress
- state.MakeBlock takes a proposerAddr - validateBlock only checks that the ProposerAddress is in the validator set - fix raceyness from bad proposer test: - use privValidator to get the proposer address (instead of racy state) - note we had to remove the test that checked the correct proposer was included for higher rounds because we don't have a good way to test this with multiple consensus states and not using the privValidator.Address while calling createProposalBlock was a hack!
This commit is contained in:
parent
4d998b7c03
commit
e1062a657f
|
@ -156,7 +156,7 @@ func makeTxs(height int64) (txs []types.Tx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeBlock(height int64, state sm.State) *types.Block {
|
func makeBlock(height int64, state sm.State) *types.Block {
|
||||||
block, _ := state.MakeBlock(height, makeTxs(height), new(types.Commit), nil)
|
block, _ := state.MakeBlock(height, makeTxs(height), new(types.Commit), nil, state.Validators.GetProposer().Address)
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -949,7 +949,8 @@ func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts
|
||||||
// Mempool validated transactions
|
// Mempool validated transactions
|
||||||
txs := cs.mempool.Reap(cs.state.ConsensusParams.BlockSize.MaxTxs)
|
txs := cs.mempool.Reap(cs.state.ConsensusParams.BlockSize.MaxTxs)
|
||||||
evidence := cs.evpool.PendingEvidence()
|
evidence := cs.evpool.PendingEvidence()
|
||||||
block, parts := cs.state.MakeBlock(cs.Height, txs, commit, evidence)
|
proposerAddr := cs.privValidator.GetAddress()
|
||||||
|
block, parts := cs.state.MakeBlock(cs.Height, txs, commit, evidence, proposerAddr)
|
||||||
return block, parts
|
return block, parts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,10 +108,6 @@ func TestStateProposerSelection2(t *testing.T) {
|
||||||
if !bytes.Equal(prop.Address, correctProposer) {
|
if !bytes.Equal(prop.Address, correctProposer) {
|
||||||
panic(cmn.Fmt("expected RoundState.Validators.GetProposer() to be validator %d. Got %X", (i+2)%len(vss), prop.Address))
|
panic(cmn.Fmt("expected RoundState.Validators.GetProposer() to be validator %d. Got %X", (i+2)%len(vss), prop.Address))
|
||||||
}
|
}
|
||||||
block, _ := cs1.createProposalBlock()
|
|
||||||
if !bytes.Equal(block.ProposerAddress, correctProposer) {
|
|
||||||
panic(cmn.Fmt("expected block.ProposerAddress to be validator %d. Got %X", (i+2)%len(vss), block.ProposerAddress))
|
|
||||||
}
|
|
||||||
|
|
||||||
rs := cs1.GetRoundState()
|
rs := cs1.GetRoundState()
|
||||||
signAddVotes(cs1, types.VoteTypePrecommit, nil, rs.ProposalBlockParts.Header(), vss[1:]...)
|
signAddVotes(cs1, types.VoteTypePrecommit, nil, rs.ProposalBlockParts.Header(), vss[1:]...)
|
||||||
|
|
|
@ -79,7 +79,7 @@ func TestBeginBlockValidators(t *testing.T) {
|
||||||
lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: tc.lastCommitPrecommits}
|
lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: tc.lastCommitPrecommits}
|
||||||
|
|
||||||
// block for height 2
|
// block for height 2
|
||||||
block, _ := state.MakeBlock(2, makeTxs(2), lastCommit, nil)
|
block, _ := state.MakeBlock(2, makeTxs(2), lastCommit, nil, state.Validators.GetProposer().Address)
|
||||||
_, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators, stateDB)
|
_, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators, stateDB)
|
||||||
require.Nil(t, err, tc.desc)
|
require.Nil(t, err, tc.desc)
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
|
||||||
lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: votes}
|
lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: votes}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
|
|
||||||
block, _ := state.MakeBlock(10, makeTxs(2), lastCommit, nil)
|
block, _ := state.MakeBlock(10, makeTxs(2), lastCommit, nil, state.Validators.GetProposer().Address)
|
||||||
block.Time = now
|
block.Time = now
|
||||||
block.Evidence.Evidence = tc.evidence
|
block.Evidence.Evidence = tc.evidence
|
||||||
_, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators, stateDB)
|
_, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators, stateDB)
|
||||||
|
@ -269,7 +269,7 @@ func state(nVals, height int) (State, dbm.DB) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeBlock(state State, height int64) *types.Block {
|
func makeBlock(state State, height int64) *types.Block {
|
||||||
block, _ := state.MakeBlock(height, makeTxs(state.LastBlockHeight), new(types.Commit), nil)
|
block, _ := state.MakeBlock(height, makeTxs(state.LastBlockHeight), new(types.Commit), nil, state.Validators.GetProposer().Address)
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,12 +99,14 @@ func (state State) IsEmpty() bool {
|
||||||
// Create a block from the latest state
|
// Create a block from the latest state
|
||||||
|
|
||||||
// MakeBlock builds a block from the current state with the given txs, commit,
|
// MakeBlock builds a block from the current state with the given txs, commit,
|
||||||
// and evidence.
|
// and evidence. Note it also takes a proposerAddress because the state does not
|
||||||
|
// track rounds, and hence doesn't know the correct proposer. TODO: alleviate this!
|
||||||
func (state State) MakeBlock(
|
func (state State) MakeBlock(
|
||||||
height int64,
|
height int64,
|
||||||
txs []types.Tx,
|
txs []types.Tx,
|
||||||
commit *types.Commit,
|
commit *types.Commit,
|
||||||
evidence []types.Evidence,
|
evidence []types.Evidence,
|
||||||
|
proposerAddress []byte,
|
||||||
) (*types.Block, *types.PartSet) {
|
) (*types.Block, *types.PartSet) {
|
||||||
|
|
||||||
// Build base block with block data.
|
// Build base block with block data.
|
||||||
|
@ -122,7 +124,9 @@ func (state State) MakeBlock(
|
||||||
block.AppHash = state.AppHash
|
block.AppHash = state.AppHash
|
||||||
block.LastResultsHash = state.LastResultsHash
|
block.LastResultsHash = state.LastResultsHash
|
||||||
|
|
||||||
block.ProposerAddress = state.Validators.GetProposer().Address
|
// NOTE: we can't use the state.Validators because we don't
|
||||||
|
// IncrementAccum for rounds there.
|
||||||
|
block.ProposerAddress = proposerAddress
|
||||||
|
|
||||||
return block, block.MakePartSet(state.ConsensusParams.BlockGossip.BlockPartSizeBytes)
|
return block, block.MakePartSet(state.ConsensusParams.BlockGossip.BlockPartSizeBytes)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/tendermint/go-crypto/tmhash"
|
||||||
dbm "github.com/tendermint/tendermint/libs/db"
|
dbm "github.com/tendermint/tendermint/libs/db"
|
||||||
"github.com/tendermint/tendermint/types"
|
"github.com/tendermint/tendermint/types"
|
||||||
)
|
)
|
||||||
|
@ -121,10 +122,13 @@ func validateBlock(stateDB dbm.DB, state State, block *types.Block) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal(block.ProposerAddress, state.Validators.GetProposer().Address) {
|
// NOTE: We can't actually verify it's the right proposer because we dont
|
||||||
|
// know what round the block was first proposed. So just check that it's
|
||||||
|
// a legit address and a known validator.
|
||||||
|
if len(block.ProposerAddress) != tmhash.Size ||
|
||||||
|
!state.Validators.HasAddress(block.ProposerAddress) {
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"Wrong Block.Header.ProposerAddress. Expected %X, got %v",
|
"Block.Header.ProposerAddress, %X, is not a validator",
|
||||||
state.Validators.GetProposer().Address,
|
|
||||||
block.ProposerAddress,
|
block.ProposerAddress,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,4 +72,7 @@ func TestValidateBlock(t *testing.T) {
|
||||||
block.ProposerAddress = ed25519.GenPrivKey().PubKey().Address()
|
block.ProposerAddress = ed25519.GenPrivKey().PubKey().Address()
|
||||||
err = blockExec.ValidateBlock(state, block)
|
err = blockExec.ValidateBlock(state, block)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
block.ProposerAddress = []byte("wrong size")
|
||||||
|
err = blockExec.ValidateBlock(state, block)
|
||||||
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue