consensus: include evidence in proposed block parts. fixes #2050
This commit is contained in:
parent
359898dcac
commit
6046b99197
|
@ -156,7 +156,7 @@ func makeTxs(height int64) (txs []types.Tx) {
|
|||
}
|
||||
|
||||
func makeBlock(height int64, state sm.State) *types.Block {
|
||||
block, _ := state.MakeBlock(height, makeTxs(height), new(types.Commit))
|
||||
block, _ := state.MakeBlock(height, makeTxs(height), new(types.Commit), nil)
|
||||
return block
|
||||
}
|
||||
|
||||
|
|
|
@ -907,6 +907,8 @@ func (cs *ConsensusState) isProposalComplete() bool {
|
|||
}
|
||||
|
||||
// Create the next block to propose and return it.
|
||||
// We really only need to return the parts, but the block
|
||||
// is returned for convenience so we can log the proposal block.
|
||||
// Returns nil block upon error.
|
||||
// NOTE: keep it side-effect free for clarity.
|
||||
func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts *types.PartSet) {
|
||||
|
@ -926,9 +928,8 @@ func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts
|
|||
|
||||
// Mempool validated transactions
|
||||
txs := cs.mempool.Reap(cs.state.ConsensusParams.BlockSize.MaxTxs)
|
||||
block, parts := cs.state.MakeBlock(cs.Height, txs, commit)
|
||||
evidence := cs.evpool.PendingEvidence()
|
||||
block.AddEvidence(evidence)
|
||||
block, parts := cs.state.MakeBlock(cs.Height, txs, commit, evidence)
|
||||
return block, parts
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ func TestBeginBlockValidators(t *testing.T) {
|
|||
lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: tc.lastCommitPrecommits}
|
||||
|
||||
// block for height 2
|
||||
block, _ := state.MakeBlock(2, makeTxs(2), lastCommit)
|
||||
block, _ := state.MakeBlock(2, makeTxs(2), lastCommit, nil)
|
||||
_, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators, stateDB)
|
||||
require.Nil(t, err, tc.desc)
|
||||
|
||||
|
@ -138,7 +138,7 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
|
|||
lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: votes}
|
||||
for _, tc := range testCases {
|
||||
|
||||
block, _ := state.MakeBlock(10, makeTxs(2), lastCommit)
|
||||
block, _ := state.MakeBlock(10, makeTxs(2), lastCommit, nil)
|
||||
block.Time = now
|
||||
block.Evidence.Evidence = tc.evidence
|
||||
_, 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 {
|
||||
block, _ := state.MakeBlock(height, makeTxs(state.LastBlockHeight), new(types.Commit))
|
||||
block, _ := state.MakeBlock(height, makeTxs(state.LastBlockHeight), new(types.Commit), nil)
|
||||
return block
|
||||
}
|
||||
|
||||
|
|
|
@ -101,18 +101,26 @@ func (state State) GetValidators() (last *types.ValidatorSet, current *types.Val
|
|||
//------------------------------------------------------------------------
|
||||
// Create a block from the latest state
|
||||
|
||||
// MakeBlock builds a block with the given txs and commit from the current state.
|
||||
func (state State) MakeBlock(height int64, txs []types.Tx, commit *types.Commit) (*types.Block, *types.PartSet) {
|
||||
// build base block
|
||||
block := types.MakeBlock(height, txs, commit)
|
||||
// MakeBlock builds a block from the current state with the given txs, commit, and evidence.
|
||||
func (state State) MakeBlock(
|
||||
height int64,
|
||||
txs []types.Tx,
|
||||
commit *types.Commit,
|
||||
evidence []types.Evidence,
|
||||
) (*types.Block, *types.PartSet) {
|
||||
|
||||
// fill header with state data
|
||||
// Build base block with block data.
|
||||
block := types.MakeBlock(height, txs, commit, evidence)
|
||||
|
||||
// Fill rest of header with state data.
|
||||
block.ChainID = state.ChainID
|
||||
block.TotalTxs = state.LastBlockTotalTx + block.NumTxs
|
||||
|
||||
block.LastBlockID = state.LastBlockID
|
||||
block.TotalTxs = state.LastBlockTotalTx + block.NumTxs
|
||||
|
||||
block.ValidatorsHash = state.Validators.Hash()
|
||||
block.AppHash = state.AppHash
|
||||
block.ConsensusHash = state.ConsensusParams.Hash()
|
||||
block.AppHash = state.AppHash
|
||||
block.LastResultsHash = state.LastResultsHash
|
||||
|
||||
return block, block.MakePartSet(state.ConsensusParams.BlockGossip.BlockPartSizeBytes)
|
||||
|
|
|
@ -25,7 +25,7 @@ type Block struct {
|
|||
|
||||
// MakeBlock returns a new block with an empty header, except what can be computed from itself.
|
||||
// It populates the same set of fields validated by ValidateBasic
|
||||
func MakeBlock(height int64, txs []Tx, commit *Commit) *Block {
|
||||
func MakeBlock(height int64, txs []Tx, commit *Commit, evidence []Evidence) *Block {
|
||||
block := &Block{
|
||||
Header: Header{
|
||||
Height: height,
|
||||
|
@ -35,20 +35,13 @@ func MakeBlock(height int64, txs []Tx, commit *Commit) *Block {
|
|||
Data: Data{
|
||||
Txs: txs,
|
||||
},
|
||||
Evidence: EvidenceData{Evidence: evidence},
|
||||
LastCommit: commit,
|
||||
}
|
||||
block.fillHeader()
|
||||
return block
|
||||
}
|
||||
|
||||
// AddEvidence appends the given evidence to the block
|
||||
func (b *Block) AddEvidence(evidence []Evidence) {
|
||||
if b == nil {
|
||||
return
|
||||
}
|
||||
b.Evidence.Evidence = append(b.Evidence.Evidence, evidence...)
|
||||
}
|
||||
|
||||
// ValidateBasic performs basic validation that doesn't involve state data.
|
||||
// It checks the internal consistency of the block.
|
||||
func (b *Block) ValidateBasic() error {
|
||||
|
|
|
@ -19,11 +19,13 @@ func TestBlockAddEvidence(t *testing.T) {
|
|||
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
|
||||
require.NoError(t, err)
|
||||
|
||||
block := MakeBlock(h, txs, commit)
|
||||
require.NotNil(t, block)
|
||||
|
||||
ev := NewMockGoodEvidence(h, 0, valSet.Validators[0].Address)
|
||||
block.AddEvidence([]Evidence{ev})
|
||||
evList := []Evidence{ev}
|
||||
|
||||
block := MakeBlock(h, txs, commit, evList)
|
||||
require.NotNil(t, block)
|
||||
require.Equal(t, 1, len(block.Evidence.Evidence))
|
||||
require.NotNil(t, block.EvidenceHash)
|
||||
}
|
||||
|
||||
func TestBlockValidateBasic(t *testing.T) {
|
||||
|
@ -33,11 +35,14 @@ func TestBlockValidateBasic(t *testing.T) {
|
|||
lastID := makeBlockIDRandom()
|
||||
h := int64(3)
|
||||
|
||||
voteSet, _, vals := randVoteSet(h-1, 1, VoteTypePrecommit, 10, 1)
|
||||
voteSet, valSet, vals := randVoteSet(h-1, 1, VoteTypePrecommit, 10, 1)
|
||||
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
|
||||
require.NoError(t, err)
|
||||
|
||||
block := MakeBlock(h, txs, commit)
|
||||
ev := NewMockGoodEvidence(h, 0, valSet.Validators[0].Address)
|
||||
evList := []Evidence{ev}
|
||||
|
||||
block := MakeBlock(h, txs, commit, evList)
|
||||
require.NotNil(t, block)
|
||||
|
||||
// proper block must pass
|
||||
|
@ -45,39 +50,39 @@ func TestBlockValidateBasic(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// tamper with NumTxs
|
||||
block = MakeBlock(h, txs, commit)
|
||||
block = MakeBlock(h, txs, commit, evList)
|
||||
block.NumTxs++
|
||||
err = block.ValidateBasic()
|
||||
require.Error(t, err)
|
||||
|
||||
// remove 1/2 the commits
|
||||
block = MakeBlock(h, txs, commit)
|
||||
block = MakeBlock(h, txs, commit, evList)
|
||||
block.LastCommit.Precommits = commit.Precommits[:commit.Size()/2]
|
||||
block.LastCommit.hash = nil // clear hash or change wont be noticed
|
||||
err = block.ValidateBasic()
|
||||
require.Error(t, err)
|
||||
|
||||
// tamper with LastCommitHash
|
||||
block = MakeBlock(h, txs, commit)
|
||||
block = MakeBlock(h, txs, commit, evList)
|
||||
block.LastCommitHash = []byte("something else")
|
||||
err = block.ValidateBasic()
|
||||
require.Error(t, err)
|
||||
|
||||
// tamper with data
|
||||
block = MakeBlock(h, txs, commit)
|
||||
block = MakeBlock(h, txs, commit, evList)
|
||||
block.Data.Txs[0] = Tx("something else")
|
||||
block.Data.hash = nil // clear hash or change wont be noticed
|
||||
err = block.ValidateBasic()
|
||||
require.Error(t, err)
|
||||
|
||||
// tamper with DataHash
|
||||
block = MakeBlock(h, txs, commit)
|
||||
block = MakeBlock(h, txs, commit, evList)
|
||||
block.DataHash = cmn.RandBytes(len(block.DataHash))
|
||||
err = block.ValidateBasic()
|
||||
require.Error(t, err)
|
||||
|
||||
// tamper with evidence
|
||||
block = MakeBlock(h, txs, commit)
|
||||
block = MakeBlock(h, txs, commit, evList)
|
||||
block.EvidenceHash = []byte("something else")
|
||||
err = block.ValidateBasic()
|
||||
require.Error(t, err)
|
||||
|
@ -85,13 +90,13 @@ func TestBlockValidateBasic(t *testing.T) {
|
|||
|
||||
func TestBlockHash(t *testing.T) {
|
||||
assert.Nil(t, (*Block)(nil).Hash())
|
||||
assert.Nil(t, MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil).Hash())
|
||||
assert.Nil(t, MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil, nil).Hash())
|
||||
}
|
||||
|
||||
func TestBlockMakePartSet(t *testing.T) {
|
||||
assert.Nil(t, (*Block)(nil).MakePartSet(2))
|
||||
|
||||
partSet := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil).MakePartSet(1024)
|
||||
partSet := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil, nil).MakePartSet(1024)
|
||||
assert.NotNil(t, partSet)
|
||||
assert.Equal(t, 1, partSet.Total())
|
||||
}
|
||||
|
@ -105,7 +110,10 @@ func TestBlockHashesTo(t *testing.T) {
|
|||
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
|
||||
require.NoError(t, err)
|
||||
|
||||
block := MakeBlock(h, []Tx{Tx("Hello World")}, commit)
|
||||
ev := NewMockGoodEvidence(h, 0, valSet.Validators[0].Address)
|
||||
evList := []Evidence{ev}
|
||||
|
||||
block := MakeBlock(h, []Tx{Tx("Hello World")}, commit, evList)
|
||||
block.ValidatorsHash = valSet.Hash()
|
||||
assert.False(t, block.HashesTo([]byte{}))
|
||||
assert.False(t, block.HashesTo([]byte("something else")))
|
||||
|
@ -113,7 +121,7 @@ func TestBlockHashesTo(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestBlockSize(t *testing.T) {
|
||||
size := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil).Size()
|
||||
size := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil, nil).Size()
|
||||
if size <= 0 {
|
||||
t.Fatal("Size of the block is zero or negative")
|
||||
}
|
||||
|
@ -124,7 +132,7 @@ func TestBlockString(t *testing.T) {
|
|||
assert.Equal(t, "nil-Block", (*Block)(nil).StringIndented(""))
|
||||
assert.Equal(t, "nil-Block", (*Block)(nil).StringShort())
|
||||
|
||||
block := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil)
|
||||
block := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil, nil)
|
||||
assert.NotEqual(t, "nil-Block", block.String())
|
||||
assert.NotEqual(t, "nil-Block", block.StringIndented(""))
|
||||
assert.NotEqual(t, "nil-Block", block.StringShort())
|
||||
|
|
Loading…
Reference in New Issue