Browse Source

types: remove panic from block methods (#7501)

pull/7504/head
Sam Kleinman 3 years ago
committed by GitHub
parent
commit
430817d9e9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 413 additions and 192 deletions
  1. +9
    -3
      internal/blocksync/reactor.go
  2. +4
    -2
      internal/blocksync/reactor_test.go
  3. +2
    -1
      internal/consensus/byzantine_test.go
  4. +3
    -1
      internal/consensus/common_test.go
  5. +56
    -33
      internal/consensus/replay_test.go
  6. +5
    -4
      internal/consensus/state.go
  7. +96
    -45
      internal/consensus/state_test.go
  8. +3
    -1
      internal/eventbus/event_bus_test.go
  9. +16
    -6
      internal/evidence/pool_test.go
  10. +7
    -2
      internal/state/execution.go
  11. +23
    -9
      internal/state/execution_test.go
  12. +21
    -11
      internal/state/helpers_test.go
  13. +7
    -2
      internal/state/state.go
  14. +64
    -23
      internal/state/state_test.go
  15. +23
    -11
      internal/state/test/factory/block.go
  16. +14
    -8
      internal/state/validation_test.go
  17. +32
    -13
      internal/store/store_test.go
  18. +10
    -5
      node/node_test.go
  19. +5
    -5
      types/block.go
  20. +11
    -4
      types/block_test.go
  21. +2
    -3
      types/evidence_test.go

+ 9
- 3
internal/blocksync/reactor.go View File

@ -513,8 +513,15 @@ FOR_LOOP:
didProcessCh <- struct{}{} didProcessCh <- struct{}{}
} }
firstParts, err := first.MakePartSet(types.BlockPartSizeBytes)
if err != nil {
r.logger.Error("failed to make ",
"height", first.Height,
"err", err.Error())
break FOR_LOOP
}
var ( var (
firstParts = first.MakePartSet(types.BlockPartSizeBytes)
firstPartSetHeader = firstParts.Header() firstPartSetHeader = firstParts.Header()
firstID = types.BlockID{Hash: first.Hash(), PartSetHeader: firstPartSetHeader} firstID = types.BlockID{Hash: first.Hash(), PartSetHeader: firstPartSetHeader}
) )
@ -524,8 +531,7 @@ FOR_LOOP:
// NOTE: We can probably make this more efficient, but note that calling // NOTE: We can probably make this more efficient, but note that calling
// first.Hash() doesn't verify the tx contents, so MakePartSet() is // first.Hash() doesn't verify the tx contents, so MakePartSet() is
// currently necessary. // currently necessary.
err := state.Validators.VerifyCommitLight(chainID, firstID, first.Height, second.LastCommit)
if err != nil {
if err = state.Validators.VerifyCommitLight(chainID, firstID, first.Height, second.LastCommit); err != nil {
err = fmt.Errorf("invalid last commit: %w", err) err = fmt.Errorf("invalid last commit: %w", err)
r.logger.Error( r.logger.Error(
err.Error(), err.Error(),


+ 4
- 2
internal/blocksync/reactor_test.go View File

@ -152,8 +152,10 @@ func (rts *reactorTestSuite) addNode(
) )
} }
thisBlock := sf.MakeBlock(state, blockHeight, lastCommit)
thisParts := thisBlock.MakePartSet(types.BlockPartSizeBytes)
thisBlock, err := sf.MakeBlock(state, blockHeight, lastCommit)
require.NoError(t, err)
thisParts, err := thisBlock.MakePartSet(types.BlockPartSizeBytes)
require.NoError(t, err)
blockID := types.BlockID{Hash: thisBlock.Hash(), PartSetHeader: thisParts.Header()} blockID := types.BlockID{Hash: thisBlock.Hash(), PartSetHeader: thisParts.Header()}
state, err = blockExec.ApplyBlock(ctx, state, blockID, thisBlock) state, err = blockExec.ApplyBlock(ctx, state, blockID, thisBlock)


+ 2
- 1
internal/consensus/byzantine_test.go View File

@ -201,9 +201,10 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
} }
proposerAddr := lazyNodeState.privValidatorPubKey.Address() proposerAddr := lazyNodeState.privValidatorPubKey.Address()
block, blockParts := lazyNodeState.blockExec.CreateProposalBlock(
block, blockParts, err := lazyNodeState.blockExec.CreateProposalBlock(
lazyNodeState.Height, lazyNodeState.state, commit, proposerAddr, lazyNodeState.Height, lazyNodeState.state, commit, proposerAddr,
) )
require.NoError(t, err)
// Flush the WAL. Otherwise, we may not recompute the same proposal to sign, // Flush the WAL. Otherwise, we may not recompute the same proposal to sign,
// and the privValidator will refuse to sign anything. // and the privValidator will refuse to sign anything.


+ 3
- 1
internal/consensus/common_test.go View File

@ -231,13 +231,15 @@ func startTestRound(ctx context.Context, cs *State, height int64, round int32) {
// Create proposal block from cs1 but sign it with vs. // Create proposal block from cs1 but sign it with vs.
func decideProposal( func decideProposal(
ctx context.Context, ctx context.Context,
t *testing.T,
cs1 *State, cs1 *State,
vs *validatorStub, vs *validatorStub,
height int64, height int64,
round int32, round int32,
) (proposal *types.Proposal, block *types.Block) { ) (proposal *types.Proposal, block *types.Block) {
cs1.mtx.Lock() cs1.mtx.Lock()
block, blockParts := cs1.createProposalBlock()
block, blockParts, err := cs1.createProposalBlock()
require.NoError(t, err)
validRound := cs1.ValidRound validRound := cs1.ValidRound
chainID := cs1.state.ChainID chainID := cs1.state.ChainID
cs1.mtx.Unlock() cs1.mtx.Unlock()


+ 56
- 33
internal/consensus/replay_test.go View File

@ -381,8 +381,10 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
newValidatorTx1 := kvstore.MakeValSetChangeTx(valPubKey1ABCI, testMinPower) newValidatorTx1 := kvstore.MakeValSetChangeTx(valPubKey1ABCI, testMinPower)
err = assertMempool(css[0].txNotifier).CheckTx(ctx, newValidatorTx1, nil, mempool.TxInfo{}) err = assertMempool(css[0].txNotifier).CheckTx(ctx, newValidatorTx1, nil, mempool.TxInfo{})
assert.Nil(t, err) assert.Nil(t, err)
propBlock, _ := css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
propBlockParts := propBlock.MakePartSet(partSize)
propBlock, _, err := css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
require.NoError(t, err)
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
blockID := types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()} blockID := types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()}
proposal := types.NewProposal(vss[1].Height, round, -1, blockID) proposal := types.NewProposal(vss[1].Height, round, -1, blockID)
@ -413,8 +415,10 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
updateValidatorTx1 := kvstore.MakeValSetChangeTx(updatePubKey1ABCI, 25) updateValidatorTx1 := kvstore.MakeValSetChangeTx(updatePubKey1ABCI, 25)
err = assertMempool(css[0].txNotifier).CheckTx(ctx, updateValidatorTx1, nil, mempool.TxInfo{}) err = assertMempool(css[0].txNotifier).CheckTx(ctx, updateValidatorTx1, nil, mempool.TxInfo{})
assert.Nil(t, err) assert.Nil(t, err)
propBlock, _ = css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
propBlockParts = propBlock.MakePartSet(partSize)
propBlock, _, err = css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
require.NoError(t, err)
propBlockParts, err = propBlock.MakePartSet(partSize)
require.NoError(t, err)
blockID = types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()} blockID = types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()}
proposal = types.NewProposal(vss[2].Height, round, -1, blockID) proposal = types.NewProposal(vss[2].Height, round, -1, blockID)
@ -452,8 +456,10 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
newValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, testMinPower) newValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, testMinPower)
err = assertMempool(css[0].txNotifier).CheckTx(ctx, newValidatorTx3, nil, mempool.TxInfo{}) err = assertMempool(css[0].txNotifier).CheckTx(ctx, newValidatorTx3, nil, mempool.TxInfo{})
assert.Nil(t, err) assert.Nil(t, err)
propBlock, _ = css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
propBlockParts = propBlock.MakePartSet(partSize)
propBlock, _, err = css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
require.NoError(t, err)
propBlockParts, err = propBlock.MakePartSet(partSize)
require.NoError(t, err)
blockID = types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()} blockID = types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()}
newVss := make([]*validatorStub, nVals+1) newVss := make([]*validatorStub, nVals+1)
copy(newVss, vss[:nVals+1]) copy(newVss, vss[:nVals+1])
@ -531,8 +537,10 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
removeValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, 0) removeValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, 0)
err = assertMempool(css[0].txNotifier).CheckTx(ctx, removeValidatorTx3, nil, mempool.TxInfo{}) err = assertMempool(css[0].txNotifier).CheckTx(ctx, removeValidatorTx3, nil, mempool.TxInfo{})
assert.Nil(t, err) assert.Nil(t, err)
propBlock, _ = css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
propBlockParts = propBlock.MakePartSet(partSize)
propBlock, _, err = css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
require.NoError(t, err)
propBlockParts, err = propBlock.MakePartSet(partSize)
require.NoError(t, err)
blockID = types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()} blockID = types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()}
newVss = make([]*validatorStub, nVals+3) newVss = make([]*validatorStub, nVals+3)
copy(newVss, vss[:nVals+3]) copy(newVss, vss[:nVals+3])
@ -740,7 +748,7 @@ func testHandshakeReplay(
cfg = sim.Config cfg = sim.Config
chain = append([]*types.Block{}, sim.Chain...) // copy chain chain = append([]*types.Block{}, sim.Chain...) // copy chain
commits = sim.Commits commits = sim.Commits
store = newMockBlockStore(cfg, genesisState.ConsensusParams)
store = newMockBlockStore(t, cfg, genesisState.ConsensusParams)
} else { // test single node } else { // test single node
testConfig, err := ResetConfig(fmt.Sprintf("%s_%v_s", t.Name(), mode)) testConfig, err := ResetConfig(fmt.Sprintf("%s_%v_s", t.Name(), mode))
require.NoError(t, err) require.NoError(t, err)
@ -762,7 +770,7 @@ func testHandshakeReplay(
require.NoError(t, err) require.NoError(t, err)
pubKey, err := privVal.GetPubKey(ctx) pubKey, err := privVal.GetPubKey(ctx)
require.NoError(t, err) require.NoError(t, err)
stateDB, genesisState, store = stateAndStore(cfg, pubKey, kvstore.ProtocolVersion)
stateDB, genesisState, store = stateAndStore(t, cfg, pubKey, kvstore.ProtocolVersion)
} }
stateStore := sm.NewStore(stateDB) stateStore := sm.NewStore(stateDB)
@ -773,6 +781,7 @@ func testHandshakeReplay(
// run the chain through state.ApplyBlock to build up the tendermint state // run the chain through state.ApplyBlock to build up the tendermint state
state = buildTMStateFromChain( state = buildTMStateFromChain(
ctx, ctx,
t,
cfg, cfg,
logger, logger,
sim.Mempool, sim.Mempool,
@ -800,7 +809,7 @@ func testHandshakeReplay(
stateStore := sm.NewStore(stateDB1) stateStore := sm.NewStore(stateDB1)
err := stateStore.Save(genesisState) err := stateStore.Save(genesisState)
require.NoError(t, err) require.NoError(t, err)
buildAppStateFromChain(ctx, proxyApp, stateStore, sim.Mempool, sim.Evpool, genesisState, chain, nBlocks, mode, store)
buildAppStateFromChain(ctx, t, proxyApp, stateStore, sim.Mempool, sim.Evpool, genesisState, chain, nBlocks, mode, store)
} }
// Prune block store if requested // Prune block store if requested
@ -858,6 +867,7 @@ func testHandshakeReplay(
func applyBlock( func applyBlock(
ctx context.Context, ctx context.Context,
t *testing.T,
stateStore sm.Store, stateStore sm.Store,
mempool mempool.Mempool, mempool mempool.Mempool,
evpool sm.EvidencePool, evpool sm.EvidencePool,
@ -869,16 +879,17 @@ func applyBlock(
testPartSize := types.BlockPartSizeBytes testPartSize := types.BlockPartSizeBytes
blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), mempool, evpool, blockStore) blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), mempool, evpool, blockStore)
blkID := types.BlockID{Hash: blk.Hash(), PartSetHeader: blk.MakePartSet(testPartSize).Header()}
bps, err := blk.MakePartSet(testPartSize)
require.NoError(t, err)
blkID := types.BlockID{Hash: blk.Hash(), PartSetHeader: bps.Header()}
newState, err := blockExec.ApplyBlock(ctx, st, blkID, blk) newState, err := blockExec.ApplyBlock(ctx, st, blkID, blk)
if err != nil {
panic(err)
}
require.NoError(t, err)
return newState return newState
} }
func buildAppStateFromChain( func buildAppStateFromChain(
ctx context.Context, ctx context.Context,
t *testing.T,
proxyApp proxy.AppConns, proxyApp proxy.AppConns,
stateStore sm.Store, stateStore sm.Store,
mempool mempool.Mempool, mempool mempool.Mempool,
@ -908,18 +919,18 @@ func buildAppStateFromChain(
case 0: case 0:
for i := 0; i < nBlocks; i++ { for i := 0; i < nBlocks; i++ {
block := chain[i] block := chain[i]
state = applyBlock(ctx, stateStore, mempool, evpool, state, block, proxyApp, blockStore)
state = applyBlock(ctx, t, stateStore, mempool, evpool, state, block, proxyApp, blockStore)
} }
case 1, 2, 3: case 1, 2, 3:
for i := 0; i < nBlocks-1; i++ { for i := 0; i < nBlocks-1; i++ {
block := chain[i] block := chain[i]
state = applyBlock(ctx, stateStore, mempool, evpool, state, block, proxyApp, blockStore)
state = applyBlock(ctx, t, stateStore, mempool, evpool, state, block, proxyApp, blockStore)
} }
if mode == 2 || mode == 3 { if mode == 2 || mode == 3 {
// update the kvstore height and apphash // update the kvstore height and apphash
// as if we ran commit but not // as if we ran commit but not
state = applyBlock(ctx, stateStore, mempool, evpool, state, chain[nBlocks-1], proxyApp, blockStore)
state = applyBlock(ctx, t, stateStore, mempool, evpool, state, chain[nBlocks-1], proxyApp, blockStore)
} }
default: default:
panic(fmt.Sprintf("unknown mode %v", mode)) panic(fmt.Sprintf("unknown mode %v", mode))
@ -929,6 +940,7 @@ func buildAppStateFromChain(
func buildTMStateFromChain( func buildTMStateFromChain(
ctx context.Context, ctx context.Context,
t *testing.T,
cfg *config.Config, cfg *config.Config,
logger log.Logger, logger log.Logger,
mempool mempool.Mempool, mempool mempool.Mempool,
@ -965,19 +977,19 @@ func buildTMStateFromChain(
case 0: case 0:
// sync right up // sync right up
for _, block := range chain { for _, block := range chain {
state = applyBlock(ctx, stateStore, mempool, evpool, state, block, proxyApp, blockStore)
state = applyBlock(ctx, t, stateStore, mempool, evpool, state, block, proxyApp, blockStore)
} }
case 1, 2, 3: case 1, 2, 3:
// sync up to the penultimate as if we stored the block. // sync up to the penultimate as if we stored the block.
// whether we commit or not depends on the appHash // whether we commit or not depends on the appHash
for _, block := range chain[:len(chain)-1] { for _, block := range chain[:len(chain)-1] {
state = applyBlock(ctx, stateStore, mempool, evpool, state, block, proxyApp, blockStore)
state = applyBlock(ctx, t, stateStore, mempool, evpool, state, block, proxyApp, blockStore)
} }
// apply the final block to a state copy so we can // apply the final block to a state copy so we can
// get the right next appHash but keep the state back // get the right next appHash but keep the state back
applyBlock(ctx, stateStore, mempool, evpool, state, chain[len(chain)-1], proxyApp, blockStore)
applyBlock(ctx, t, stateStore, mempool, evpool, state, chain[len(chain)-1], proxyApp, blockStore)
default: default:
panic(fmt.Sprintf("unknown mode %v", mode)) panic(fmt.Sprintf("unknown mode %v", mode))
} }
@ -1002,12 +1014,14 @@ func TestHandshakePanicsIfAppReturnsWrongAppHash(t *testing.T) {
const appVersion = 0x0 const appVersion = 0x0
pubKey, err := privVal.GetPubKey(ctx) pubKey, err := privVal.GetPubKey(ctx)
require.NoError(t, err) require.NoError(t, err)
stateDB, state, store := stateAndStore(cfg, pubKey, appVersion)
stateDB, state, store := stateAndStore(t, cfg, pubKey, appVersion)
stateStore := sm.NewStore(stateDB) stateStore := sm.NewStore(stateDB)
genDoc, _ := sm.MakeGenesisDocFromFile(cfg.GenesisFile()) genDoc, _ := sm.MakeGenesisDocFromFile(cfg.GenesisFile())
state.LastValidators = state.Validators.Copy() state.LastValidators = state.Validators.Copy()
// mode = 0 for committing all the blocks // mode = 0 for committing all the blocks
blocks := sf.MakeBlocks(3, &state, privVal)
blocks, err := sf.MakeBlocks(3, &state, privVal)
require.NoError(t, err)
store.chain = blocks store.chain = blocks
logger := log.TestingLogger() logger := log.TestingLogger()
@ -1204,17 +1218,19 @@ func readPieceFromWAL(msg *TimedWALMessage) interface{} {
// fresh state and mock store // fresh state and mock store
func stateAndStore( func stateAndStore(
t *testing.T,
cfg *config.Config, cfg *config.Config,
pubKey crypto.PubKey, pubKey crypto.PubKey,
appVersion uint64) (dbm.DB, sm.State, *mockBlockStore) {
appVersion uint64,
) (dbm.DB, sm.State, *mockBlockStore) {
stateDB := dbm.NewMemDB() stateDB := dbm.NewMemDB()
stateStore := sm.NewStore(stateDB) stateStore := sm.NewStore(stateDB)
state, _ := sm.MakeGenesisStateFromFile(cfg.GenesisFile())
state, err := sm.MakeGenesisStateFromFile(cfg.GenesisFile())
require.NoError(t, err)
state.Version.Consensus.App = appVersion state.Version.Consensus.App = appVersion
store := newMockBlockStore(cfg, state.ConsensusParams)
if err := stateStore.Save(state); err != nil {
panic(err)
}
store := newMockBlockStore(t, cfg, state.ConsensusParams)
require.NoError(t, stateStore.Save(state))
return stateDB, state, store return stateDB, state, store
} }
@ -1227,11 +1243,16 @@ type mockBlockStore struct {
chain []*types.Block chain []*types.Block
commits []*types.Commit commits []*types.Commit
base int64 base int64
t *testing.T
} }
// TODO: NewBlockStore(db.NewMemDB) ... // TODO: NewBlockStore(db.NewMemDB) ...
func newMockBlockStore(cfg *config.Config, params types.ConsensusParams) *mockBlockStore {
return &mockBlockStore{cfg, params, nil, nil, 0}
func newMockBlockStore(t *testing.T, cfg *config.Config, params types.ConsensusParams) *mockBlockStore {
return &mockBlockStore{
cfg: cfg,
params: params,
t: t,
}
} }
func (bs *mockBlockStore) Height() int64 { return int64(len(bs.chain)) } func (bs *mockBlockStore) Height() int64 { return int64(len(bs.chain)) }
@ -1245,8 +1266,10 @@ func (bs *mockBlockStore) LoadBlockByHash(hash []byte) *types.Block {
func (bs *mockBlockStore) LoadBlockMetaByHash(hash []byte) *types.BlockMeta { return nil } func (bs *mockBlockStore) LoadBlockMetaByHash(hash []byte) *types.BlockMeta { return nil }
func (bs *mockBlockStore) LoadBlockMeta(height int64) *types.BlockMeta { func (bs *mockBlockStore) LoadBlockMeta(height int64) *types.BlockMeta {
block := bs.chain[height-1] block := bs.chain[height-1]
bps, err := block.MakePartSet(types.BlockPartSizeBytes)
require.NoError(bs.t, err)
return &types.BlockMeta{ return &types.BlockMeta{
BlockID: types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(types.BlockPartSizeBytes).Header()},
BlockID: types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()},
Header: block.Header, Header: block.Header,
} }
} }
@ -1291,7 +1314,7 @@ func TestHandshakeUpdatesValidators(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
pubKey, err := privVal.GetPubKey(ctx) pubKey, err := privVal.GetPubKey(ctx)
require.NoError(t, err) require.NoError(t, err)
stateDB, state, store := stateAndStore(cfg, pubKey, 0x0)
stateDB, state, store := stateAndStore(t, cfg, pubKey, 0x0)
stateStore := sm.NewStore(stateDB) stateStore := sm.NewStore(stateDB)
oldValAddr := state.Validators.Validators[0].Address oldValAddr := state.Validators.Validators[0].Address


+ 5
- 4
internal/consensus/state.go View File

@ -1230,8 +1230,9 @@ func (cs *State) defaultDecideProposal(ctx context.Context, height int64, round
block, blockParts = cs.ValidBlock, cs.ValidBlockParts block, blockParts = cs.ValidBlock, cs.ValidBlockParts
} else { } else {
// Create a new proposal block from state/txs from the mempool. // Create a new proposal block from state/txs from the mempool.
block, blockParts = cs.createProposalBlock()
if block == nil {
var err error
block, blockParts, err = cs.createProposalBlock()
if block == nil || err != nil {
return return
} }
} }
@ -1290,9 +1291,9 @@ func (cs *State) isProposalComplete() bool {
// //
// NOTE: keep it side-effect free for clarity. // NOTE: keep it side-effect free for clarity.
// CONTRACT: cs.privValidator is not nil. // CONTRACT: cs.privValidator is not nil.
func (cs *State) createProposalBlock() (block *types.Block, blockParts *types.PartSet) {
func (cs *State) createProposalBlock() (block *types.Block, blockParts *types.PartSet, err error) {
if cs.privValidator == nil { if cs.privValidator == nil {
panic("entered createProposalBlock with privValidator being nil")
return nil, nil, errors.New("entered createProposalBlock with privValidator being nil")
} }
var commit *types.Commit var commit *types.Commit


+ 96
- 45
internal/consensus/state_test.go View File

@ -227,7 +227,8 @@ func TestStateBadProposal(t *testing.T) {
proposalCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryCompleteProposal) proposalCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryCompleteProposal)
voteCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryVote) voteCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryVote)
propBlock, _ := cs1.createProposalBlock() // changeProposer(t, cs1, vs2)
propBlock, _, err := cs1.createProposalBlock() // changeProposer(t, cs1, vs2)
require.NoError(t, err)
// make the second validator the proposer by incrementing round // make the second validator the proposer by incrementing round
round++ round++
@ -240,7 +241,8 @@ func TestStateBadProposal(t *testing.T) {
} }
stateHash[0] = (stateHash[0] + 1) % 255 stateHash[0] = (stateHash[0] + 1) % 255
propBlock.AppHash = stateHash propBlock.AppHash = stateHash
propBlockParts := propBlock.MakePartSet(partSize)
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
blockID := types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()} blockID := types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()}
proposal := types.NewProposal(vs2.Height, round, -1, blockID) proposal := types.NewProposal(vs2.Height, round, -1, blockID)
p := proposal.ToProto() p := proposal.ToProto()
@ -266,13 +268,19 @@ func TestStateBadProposal(t *testing.T) {
validatePrevote(ctx, t, cs1, round, vss[0], nil) validatePrevote(ctx, t, cs1, round, vss[0], nil)
// add bad prevote from vs2 and wait for it // add bad prevote from vs2 and wait for it
signAddVotes(ctx, config, cs1, tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2)
bps, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
signAddVotes(ctx, config, cs1, tmproto.PrevoteType, propBlock.Hash(), bps.Header(), vs2)
ensurePrevote(voteCh, height, round) ensurePrevote(voteCh, height, round)
// wait for precommit // wait for precommit
ensurePrecommit(voteCh, height, round) ensurePrecommit(voteCh, height, round)
validatePrecommit(ctx, t, cs1, round, -1, vss[0], nil, nil) validatePrecommit(ctx, t, cs1, round, -1, vss[0], nil, nil)
signAddVotes(ctx, config, cs1, tmproto.PrecommitType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2)
bps2, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
signAddVotes(ctx, config, cs1, tmproto.PrecommitType, propBlock.Hash(), bps2.Header(), vs2)
} }
func TestStateOversizedBlock(t *testing.T) { func TestStateOversizedBlock(t *testing.T) {
@ -291,7 +299,8 @@ func TestStateOversizedBlock(t *testing.T) {
timeoutProposeCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryTimeoutPropose) timeoutProposeCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryTimeoutPropose)
voteCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryVote) voteCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryVote)
propBlock, _ := cs1.createProposalBlock()
propBlock, _, err := cs1.createProposalBlock()
require.NoError(t, err)
propBlock.Data.Txs = []types.Tx{tmrand.Bytes(2001)} propBlock.Data.Txs = []types.Tx{tmrand.Bytes(2001)}
propBlock.Header.DataHash = propBlock.Data.Hash() propBlock.Header.DataHash = propBlock.Data.Hash()
@ -299,7 +308,8 @@ func TestStateOversizedBlock(t *testing.T) {
round++ round++
incrementRound(vss[1:]...) incrementRound(vss[1:]...)
propBlockParts := propBlock.MakePartSet(partSize)
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
blockID := types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()} blockID := types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()}
proposal := types.NewProposal(height, round, -1, blockID) proposal := types.NewProposal(height, round, -1, blockID)
p := proposal.ToProto() p := proposal.ToProto()
@ -331,11 +341,18 @@ func TestStateOversizedBlock(t *testing.T) {
// precommit on it // precommit on it
ensurePrevote(voteCh, height, round) ensurePrevote(voteCh, height, round)
validatePrevote(ctx, t, cs1, round, vss[0], nil) validatePrevote(ctx, t, cs1, round, vss[0], nil)
signAddVotes(ctx, config, cs1, tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2)
bps, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
signAddVotes(ctx, config, cs1, tmproto.PrevoteType, propBlock.Hash(), bps.Header(), vs2)
ensurePrevote(voteCh, height, round) ensurePrevote(voteCh, height, round)
ensurePrecommit(voteCh, height, round) ensurePrecommit(voteCh, height, round)
validatePrecommit(ctx, t, cs1, round, -1, vss[0], nil, nil) validatePrecommit(ctx, t, cs1, round, -1, vss[0], nil, nil)
signAddVotes(ctx, config, cs1, tmproto.PrecommitType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2)
bps2, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
signAddVotes(ctx, config, cs1, tmproto.PrecommitType, propBlock.Hash(), bps2.Header(), vs2)
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
@ -528,9 +545,7 @@ func TestStateLockNoPOL(t *testing.T) {
rs := cs1.GetRoundState() rs := cs1.GetRoundState()
if rs.ProposalBlock != nil {
panic("Expected proposal block to be nil")
}
require.Nil(t, rs.ProposalBlock, "Expected proposal block to be nil")
// wait to finish prevote // wait to finish prevote
ensurePrevote(voteCh, height, round) ensurePrevote(voteCh, height, round)
@ -538,7 +553,10 @@ func TestStateLockNoPOL(t *testing.T) {
validatePrevote(ctx, t, cs1, round, vss[0], rs.LockedBlock.Hash()) validatePrevote(ctx, t, cs1, round, vss[0], rs.LockedBlock.Hash())
// add a conflicting prevote from the other validator // add a conflicting prevote from the other validator
signAddVotes(ctx, config, cs1, tmproto.PrevoteType, hash, rs.LockedBlock.MakePartSet(partSize).Header(), vs2)
bps, err := rs.LockedBlock.MakePartSet(partSize)
require.NoError(t, err)
signAddVotes(ctx, config, cs1, tmproto.PrevoteType, hash, bps.Header(), vs2)
ensurePrevote(voteCh, height, round) ensurePrevote(voteCh, height, round)
// now we're going to enter prevote again, but with invalid args // now we're going to enter prevote again, but with invalid args
@ -551,7 +569,9 @@ func TestStateLockNoPOL(t *testing.T) {
validatePrecommit(ctx, t, cs1, round, 0, vss[0], nil, theBlockHash) validatePrecommit(ctx, t, cs1, round, 0, vss[0], nil, theBlockHash)
// add conflicting precommit from vs2 // add conflicting precommit from vs2
signAddVotes(ctx, config, cs1, tmproto.PrecommitType, hash, rs.LockedBlock.MakePartSet(partSize).Header(), vs2)
bps2, err := rs.LockedBlock.MakePartSet(partSize)
require.NoError(t, err)
signAddVotes(ctx, config, cs1, tmproto.PrecommitType, hash, bps2.Header(), vs2)
ensurePrecommit(voteCh, height, round) ensurePrecommit(voteCh, height, round)
// (note we're entering precommit for a second time this round, but with invalid args // (note we're entering precommit for a second time this round, but with invalid args
@ -581,7 +601,9 @@ func TestStateLockNoPOL(t *testing.T) {
ensurePrevote(voteCh, height, round) // prevote ensurePrevote(voteCh, height, round) // prevote
validatePrevote(ctx, t, cs1, round, vss[0], rs.LockedBlock.Hash()) validatePrevote(ctx, t, cs1, round, vss[0], rs.LockedBlock.Hash())
signAddVotes(ctx, config, cs1, tmproto.PrevoteType, hash, rs.ProposalBlock.MakePartSet(partSize).Header(), vs2)
bps0, err := rs.ProposalBlock.MakePartSet(partSize)
require.NoError(t, err)
signAddVotes(ctx, config, cs1, tmproto.PrevoteType, hash, bps0.Header(), vs2)
ensurePrevote(voteCh, height, round) ensurePrevote(voteCh, height, round)
ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Prevote(round).Nanoseconds()) ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Prevote(round).Nanoseconds())
@ -589,13 +611,15 @@ func TestStateLockNoPOL(t *testing.T) {
validatePrecommit(ctx, t, cs1, round, 0, vss[0], nil, theBlockHash) // precommit nil but be locked on proposal validatePrecommit(ctx, t, cs1, round, 0, vss[0], nil, theBlockHash) // precommit nil but be locked on proposal
bps1, err := rs.ProposalBlock.MakePartSet(partSize)
require.NoError(t, err)
signAddVotes( signAddVotes(
ctx, ctx,
config, config,
cs1, cs1,
tmproto.PrecommitType, tmproto.PrecommitType,
hash, hash,
rs.ProposalBlock.MakePartSet(partSize).Header(),
bps1.Header(),
vs2) // NOTE: conflicting precommits at same height vs2) // NOTE: conflicting precommits at same height
ensurePrecommit(voteCh, height, round) ensurePrecommit(voteCh, height, round)
@ -605,7 +629,7 @@ func TestStateLockNoPOL(t *testing.T) {
cs2, _, err := randState(ctx, config, log.TestingLogger(), 2) cs2, _, err := randState(ctx, config, log.TestingLogger(), 2)
require.NoError(t, err) require.NoError(t, err)
// before we time out into new round, set next proposal block // before we time out into new round, set next proposal block
prop, propBlock := decideProposal(ctx, cs2, vs2, vs2.Height, vs2.Round+1)
prop, propBlock := decideProposal(ctx, t, cs2, vs2, vs2.Height, vs2.Round+1)
if prop == nil || propBlock == nil { if prop == nil || propBlock == nil {
t.Fatal("Failed to create proposal block with vs2") t.Fatal("Failed to create proposal block with vs2")
} }
@ -621,7 +645,9 @@ func TestStateLockNoPOL(t *testing.T) {
// now we're on a new round and not the proposer // now we're on a new round and not the proposer
// so set the proposal block // so set the proposal block
if err := cs1.SetProposalAndBlock(ctx, prop, propBlock, propBlock.MakePartSet(partSize), ""); err != nil {
bps3, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
if err := cs1.SetProposalAndBlock(ctx, prop, propBlock, bps3, ""); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -631,20 +657,25 @@ func TestStateLockNoPOL(t *testing.T) {
validatePrevote(ctx, t, cs1, 3, vss[0], cs1.LockedBlock.Hash()) validatePrevote(ctx, t, cs1, 3, vss[0], cs1.LockedBlock.Hash())
// prevote for proposed block // prevote for proposed block
signAddVotes(ctx, config, cs1, tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2)
bps4, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
signAddVotes(ctx, config, cs1, tmproto.PrevoteType, propBlock.Hash(), bps4.Header(), vs2)
ensurePrevote(voteCh, height, round) ensurePrevote(voteCh, height, round)
ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Prevote(round).Nanoseconds()) ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Prevote(round).Nanoseconds())
ensurePrecommit(voteCh, height, round) ensurePrecommit(voteCh, height, round)
validatePrecommit(ctx, t, cs1, round, 0, vss[0], nil, theBlockHash) // precommit nil but locked on proposal validatePrecommit(ctx, t, cs1, round, 0, vss[0], nil, theBlockHash) // precommit nil but locked on proposal
bps5, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
signAddVotes( signAddVotes(
ctx, ctx,
config, config,
cs1, cs1,
tmproto.PrecommitType, tmproto.PrecommitType,
propBlock.Hash(), propBlock.Hash(),
propBlock.MakePartSet(partSize).Header(),
bps5.Header(),
vs2) // NOTE: conflicting precommits at same height vs2) // NOTE: conflicting precommits at same height
ensurePrecommit(voteCh, height, round) ensurePrecommit(voteCh, height, round)
} }
@ -708,11 +739,13 @@ func TestStateLockPOLRelock(t *testing.T) {
cs2, err := newState(ctx, logger, cs1.state, vs2, kvstore.NewApplication()) cs2, err := newState(ctx, logger, cs1.state, vs2, kvstore.NewApplication())
require.NoError(t, err) require.NoError(t, err)
prop, propBlock := decideProposal(ctx, cs2, vs2, vs2.Height, vs2.Round+1)
prop, propBlock := decideProposal(ctx, t, cs2, vs2, vs2.Height, vs2.Round+1)
if prop == nil || propBlock == nil { if prop == nil || propBlock == nil {
t.Fatal("Failed to create proposal block with vs2") t.Fatal("Failed to create proposal block with vs2")
} }
propBlockParts := propBlock.MakePartSet(partSize)
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
propBlockHash := propBlock.Hash() propBlockHash := propBlock.Hash()
require.NotEqual(t, propBlockHash, theBlockHash) require.NotEqual(t, propBlockHash, theBlockHash)
@ -810,8 +843,9 @@ func TestStateLockPOLUnlock(t *testing.T) {
signAddVotes(ctx, config, cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs3) signAddVotes(ctx, config, cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs3)
// before we time out into new round, set next proposal block // before we time out into new round, set next proposal block
prop, propBlock := decideProposal(ctx, cs1, vs2, vs2.Height, vs2.Round+1)
propBlockParts := propBlock.MakePartSet(partSize)
prop, propBlock := decideProposal(ctx, t, cs1, vs2, vs2.Height, vs2.Round+1)
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
// timeout to new round // timeout to new round
ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Precommit(round).Nanoseconds()) ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Precommit(round).Nanoseconds())
@ -905,11 +939,13 @@ func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) {
// before we timeout to the new round set the new proposal // before we timeout to the new round set the new proposal
cs2, err := newState(ctx, logger, cs1.state, vs2, kvstore.NewApplication()) cs2, err := newState(ctx, logger, cs1.state, vs2, kvstore.NewApplication())
require.NoError(t, err) require.NoError(t, err)
prop, propBlock := decideProposal(ctx, cs2, vs2, vs2.Height, vs2.Round+1)
prop, propBlock := decideProposal(ctx, t, cs2, vs2, vs2.Height, vs2.Round+1)
if prop == nil || propBlock == nil { if prop == nil || propBlock == nil {
t.Fatal("Failed to create proposal block with vs2") t.Fatal("Failed to create proposal block with vs2")
} }
secondBlockParts := propBlock.MakePartSet(partSize)
secondBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
secondBlockHash := propBlock.Hash() secondBlockHash := propBlock.Hash()
require.NotEqual(t, secondBlockHash, firstBlockHash) require.NotEqual(t, secondBlockHash, firstBlockHash)
@ -950,11 +986,12 @@ func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) {
// before we timeout to the new round set the new proposal // before we timeout to the new round set the new proposal
cs3, err := newState(ctx, logger, cs1.state, vs3, kvstore.NewApplication()) cs3, err := newState(ctx, logger, cs1.state, vs3, kvstore.NewApplication())
require.NoError(t, err) require.NoError(t, err)
prop, propBlock = decideProposal(ctx, cs3, vs3, vs3.Height, vs3.Round+1)
prop, propBlock = decideProposal(ctx, t, cs3, vs3, vs3.Height, vs3.Round+1)
if prop == nil || propBlock == nil { if prop == nil || propBlock == nil {
t.Fatal("Failed to create proposal block with vs2") t.Fatal("Failed to create proposal block with vs2")
} }
thirdPropBlockParts := propBlock.MakePartSet(partSize)
thirdPropBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
thirdPropBlockHash := propBlock.Hash() thirdPropBlockHash := propBlock.Hash()
require.NotEqual(t, secondBlockHash, thirdPropBlockHash) require.NotEqual(t, secondBlockHash, thirdPropBlockHash)
@ -1023,8 +1060,11 @@ func TestStateLockPOLSafety1(t *testing.T) {
validatePrevote(ctx, t, cs1, round, vss[0], propBlock.Hash()) validatePrevote(ctx, t, cs1, round, vss[0], propBlock.Hash())
// the others sign a polka but we don't see it // the others sign a polka but we don't see it
bps, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
prevotes := signVotes(ctx, config, tmproto.PrevoteType, prevotes := signVotes(ctx, config, tmproto.PrevoteType,
propBlock.Hash(), propBlock.MakePartSet(partSize).Header(),
propBlock.Hash(), bps.Header(),
vs2, vs3, vs4) vs2, vs3, vs4)
t.Logf("old prop hash %v", fmt.Sprintf("%X", propBlock.Hash())) t.Logf("old prop hash %v", fmt.Sprintf("%X", propBlock.Hash()))
@ -1038,9 +1078,10 @@ func TestStateLockPOLSafety1(t *testing.T) {
t.Log("### ONTO ROUND 1") t.Log("### ONTO ROUND 1")
prop, propBlock := decideProposal(ctx, cs1, vs2, vs2.Height, vs2.Round+1)
prop, propBlock := decideProposal(ctx, t, cs1, vs2, vs2.Height, vs2.Round+1)
propBlockHash := propBlock.Hash() propBlockHash := propBlock.Hash()
propBlockParts := propBlock.MakePartSet(partSize)
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
incrementRound(vs2, vs3, vs4) incrementRound(vs2, vs3, vs4)
@ -1139,18 +1180,20 @@ func TestStateLockPOLSafety2(t *testing.T) {
// the block for R0: gets polkad but we miss it // the block for R0: gets polkad but we miss it
// (even though we signed it, shhh) // (even though we signed it, shhh)
_, propBlock0 := decideProposal(ctx, cs1, vss[0], height, round)
_, propBlock0 := decideProposal(ctx, t, cs1, vss[0], height, round)
propBlockHash0 := propBlock0.Hash() propBlockHash0 := propBlock0.Hash()
propBlockParts0 := propBlock0.MakePartSet(partSize)
propBlockParts0, err := propBlock0.MakePartSet(partSize)
require.NoError(t, err)
propBlockID0 := types.BlockID{Hash: propBlockHash0, PartSetHeader: propBlockParts0.Header()} propBlockID0 := types.BlockID{Hash: propBlockHash0, PartSetHeader: propBlockParts0.Header()}
// the others sign a polka but we don't see it // the others sign a polka but we don't see it
prevotes := signVotes(ctx, config, tmproto.PrevoteType, propBlockHash0, propBlockParts0.Header(), vs2, vs3, vs4) prevotes := signVotes(ctx, config, tmproto.PrevoteType, propBlockHash0, propBlockParts0.Header(), vs2, vs3, vs4)
// the block for round 1 // the block for round 1
prop1, propBlock1 := decideProposal(ctx, cs1, vs2, vs2.Height, vs2.Round+1)
prop1, propBlock1 := decideProposal(ctx, t, cs1, vs2, vs2.Height, vs2.Round+1)
propBlockHash1 := propBlock1.Hash() propBlockHash1 := propBlock1.Hash()
propBlockParts1 := propBlock1.MakePartSet(partSize)
propBlockParts1, err := propBlock1.MakePartSet(partSize)
require.NoError(t, err)
incrementRound(vs2, vs3, vs4) incrementRound(vs2, vs3, vs4)
@ -1253,8 +1296,10 @@ func TestProposeValidBlock(t *testing.T) {
validatePrevote(ctx, t, cs1, round, vss[0], propBlockHash) validatePrevote(ctx, t, cs1, round, vss[0], propBlockHash)
// the others sign a polka // the others sign a polka
bps, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
signAddVotes(ctx, config, cs1, tmproto.PrevoteType, signAddVotes(ctx, config, cs1, tmproto.PrevoteType,
propBlockHash, propBlock.MakePartSet(partSize).Header(), vs2,
propBlockHash, bps.Header(), vs2,
vs3, vs4) vs3, vs4)
ensurePrecommit(voteCh, height, round) ensurePrecommit(voteCh, height, round)
@ -1344,7 +1389,8 @@ func TestSetValidBlockOnDelayedPrevote(t *testing.T) {
rs := cs1.GetRoundState() rs := cs1.GetRoundState()
propBlock := rs.ProposalBlock propBlock := rs.ProposalBlock
propBlockHash := propBlock.Hash() propBlockHash := propBlock.Hash()
propBlockParts := propBlock.MakePartSet(partSize)
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
ensurePrevote(voteCh, height, round) ensurePrevote(voteCh, height, round)
validatePrevote(ctx, t, cs1, round, vss[0], propBlockHash) validatePrevote(ctx, t, cs1, round, vss[0], propBlockHash)
@ -1415,9 +1461,10 @@ func TestSetValidBlockOnDelayedProposal(t *testing.T) {
ensurePrevote(voteCh, height, round) ensurePrevote(voteCh, height, round)
validatePrevote(ctx, t, cs1, round, vss[0], nil) validatePrevote(ctx, t, cs1, round, vss[0], nil)
prop, propBlock := decideProposal(ctx, cs1, vs2, vs2.Height, vs2.Round+1)
prop, propBlock := decideProposal(ctx, t, cs1, vs2, vs2.Height, vs2.Round+1)
propBlockHash := propBlock.Hash() propBlockHash := propBlock.Hash()
propBlockParts := propBlock.MakePartSet(partSize)
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
// vs2, vs3 and vs4 send prevote for propBlock // vs2, vs3 and vs4 send prevote for propBlock
signAddVotes(ctx, config, cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) signAddVotes(ctx, config, cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4)
@ -1601,9 +1648,10 @@ func TestEmitNewValidBlockEventOnCommitWithoutBlock(t *testing.T) {
newRoundCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryNewRound) newRoundCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryNewRound)
validBlockCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryValidBlock) validBlockCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryValidBlock)
_, propBlock := decideProposal(ctx, cs1, vs2, vs2.Height, vs2.Round)
_, propBlock := decideProposal(ctx, t, cs1, vs2, vs2.Height, vs2.Round)
propBlockHash := propBlock.Hash() propBlockHash := propBlock.Hash()
propBlockParts := propBlock.MakePartSet(partSize)
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
// start round in which PO is not proposer // start round in which PO is not proposer
startTestRound(ctx, cs1, height, round) startTestRound(ctx, cs1, height, round)
@ -1639,9 +1687,10 @@ func TestCommitFromPreviousRound(t *testing.T) {
validBlockCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryValidBlock) validBlockCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryValidBlock)
proposalCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryCompleteProposal) proposalCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryCompleteProposal)
prop, propBlock := decideProposal(ctx, cs1, vs2, vs2.Height, vs2.Round)
prop, propBlock := decideProposal(ctx, t, cs1, vs2, vs2.Height, vs2.Round)
propBlockHash := propBlock.Hash() propBlockHash := propBlock.Hash()
propBlockParts := propBlock.MakePartSet(partSize)
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
// start round in which PO is not proposer // start round in which PO is not proposer
startTestRound(ctx, cs1, height, round) startTestRound(ctx, cs1, height, round)
@ -1794,8 +1843,9 @@ func TestResetTimeoutPrecommitUponNewHeight(t *testing.T) {
ensureNewBlockHeader(newBlockHeader, height, theBlockHash) ensureNewBlockHeader(newBlockHeader, height, theBlockHash)
prop, propBlock := decideProposal(ctx, cs1, vs2, height+1, 0)
propBlockParts := propBlock.MakePartSet(partSize)
prop, propBlock := decideProposal(ctx, t, cs1, vs2, height+1, 0)
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
if err := cs1.SetProposalAndBlock(ctx, prop, propBlock, propBlockParts, "some peer"); err != nil { if err := cs1.SetProposalAndBlock(ctx, prop, propBlock, propBlockParts, "some peer"); err != nil {
t.Fatal(err) t.Fatal(err)
@ -1921,7 +1971,8 @@ func TestStateHalt1(t *testing.T) {
ensureNewProposal(proposalCh, height, round) ensureNewProposal(proposalCh, height, round)
rs := cs1.GetRoundState() rs := cs1.GetRoundState()
propBlock := rs.ProposalBlock propBlock := rs.ProposalBlock
propBlockParts := propBlock.MakePartSet(partSize)
propBlockParts, err := propBlock.MakePartSet(partSize)
require.NoError(t, err)
ensurePrevote(voteCh, height, round) ensurePrevote(voteCh, height, round)


+ 3
- 1
internal/eventbus/event_bus_test.go View File

@ -80,7 +80,9 @@ func TestEventBusPublishEventNewBlock(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
block := types.MakeBlock(0, []types.Tx{}, nil, []types.Evidence{}) block := types.MakeBlock(0, []types.Tx{}, nil, []types.Evidence{})
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(types.BlockPartSizeBytes).Header()}
bps, err := block.MakePartSet(types.BlockPartSizeBytes)
require.NoError(t, err)
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
resultBeginBlock := abci.ResponseBeginBlock{ resultBeginBlock := abci.ResponseBeginBlock{
Events: []abci.Event{ Events: []abci.Event{
{Type: "testType", Attributes: []abci.EventAttribute{{Key: "baz", Value: "1"}}}, {Type: "testType", Attributes: []abci.EventAttribute{{Key: "baz", Value: "1"}}},


+ 16
- 6
internal/evidence/pool_test.go View File

@ -335,7 +335,8 @@ func TestRecoverPendingEvidence(t *testing.T) {
state, err := stateStore.Load() state, err := stateStore.Load()
require.NoError(t, err) require.NoError(t, err)
blockStore := initializeBlockStore(dbm.NewMemDB(), state, valAddress)
blockStore, err := initializeBlockStore(dbm.NewMemDB(), state, valAddress)
require.NoError(t, err)
// create previous pool and populate it // create previous pool and populate it
pool, err := evidence.NewPool(log.TestingLogger(), evidenceDB, stateStore, blockStore) pool, err := evidence.NewPool(log.TestingLogger(), evidenceDB, stateStore, blockStore)
@ -434,22 +435,29 @@ func initializeValidatorState(t *testing.T, privVal types.PrivValidator, height
// initializeBlockStore creates a block storage and populates it w/ a dummy // initializeBlockStore creates a block storage and populates it w/ a dummy
// block at +height+. // block at +height+.
func initializeBlockStore(db dbm.DB, state sm.State, valAddr []byte) *store.BlockStore {
func initializeBlockStore(db dbm.DB, state sm.State, valAddr []byte) (*store.BlockStore, error) {
blockStore := store.NewBlockStore(db) blockStore := store.NewBlockStore(db)
for i := int64(1); i <= state.LastBlockHeight; i++ { for i := int64(1); i <= state.LastBlockHeight; i++ {
lastCommit := makeCommit(i-1, valAddr) lastCommit := makeCommit(i-1, valAddr)
block := sf.MakeBlock(state, i, lastCommit)
block, err := sf.MakeBlock(state, i, lastCommit)
if err != nil {
return nil, err
}
block.Header.Time = defaultEvidenceTime.Add(time.Duration(i) * time.Minute) block.Header.Time = defaultEvidenceTime.Add(time.Duration(i) * time.Minute)
block.Header.Version = version.Consensus{Block: version.BlockProtocol, App: 1} block.Header.Version = version.Consensus{Block: version.BlockProtocol, App: 1}
const parts = 1 const parts = 1
partSet := block.MakePartSet(parts)
partSet, err := block.MakePartSet(parts)
if err != nil {
return nil, err
}
seenCommit := makeCommit(i, valAddr) seenCommit := makeCommit(i, valAddr)
blockStore.SaveBlock(block, partSet, seenCommit) blockStore.SaveBlock(block, partSet, seenCommit)
} }
return blockStore
return blockStore, nil
} }
func makeCommit(height int64, valAddr []byte) *types.Commit { func makeCommit(height int64, valAddr []byte) *types.Commit {
@ -464,12 +472,14 @@ func makeCommit(height int64, valAddr []byte) *types.Commit {
} }
func defaultTestPool(t *testing.T, height int64) (*evidence.Pool, types.MockPV) { func defaultTestPool(t *testing.T, height int64) (*evidence.Pool, types.MockPV) {
t.Helper()
val := types.NewMockPV() val := types.NewMockPV()
valAddress := val.PrivKey.PubKey().Address() valAddress := val.PrivKey.PubKey().Address()
evidenceDB := dbm.NewMemDB() evidenceDB := dbm.NewMemDB()
stateStore := initializeValidatorState(t, val, height) stateStore := initializeValidatorState(t, val, height)
state, _ := stateStore.Load() state, _ := stateStore.Load()
blockStore := initializeBlockStore(dbm.NewMemDB(), state, valAddress)
blockStore, err := initializeBlockStore(dbm.NewMemDB(), state, valAddress)
require.NoError(t, err)
pool, err := evidence.NewPool(log.TestingLogger(), evidenceDB, stateStore, blockStore) pool, err := evidence.NewPool(log.TestingLogger(), evidenceDB, stateStore, blockStore)
require.NoError(t, err, "test evidence pool could not be created") require.NoError(t, err, "test evidence pool could not be created")


+ 7
- 2
internal/state/execution.go View File

@ -104,7 +104,7 @@ func (blockExec *BlockExecutor) CreateProposalBlock(
height int64, height int64,
state State, commit *types.Commit, state State, commit *types.Commit,
proposerAddr []byte, proposerAddr []byte,
) (*types.Block, *types.PartSet) {
) (*types.Block, *types.PartSet, error) {
maxBytes := state.ConsensusParams.Block.MaxBytes maxBytes := state.ConsensusParams.Block.MaxBytes
maxGas := state.ConsensusParams.Block.MaxGas maxGas := state.ConsensusParams.Block.MaxGas
@ -603,7 +603,12 @@ func ExecCommitBlock(
return nil, err return nil, err
} }
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(types.BlockPartSizeBytes).Header()}
bps, err := block.MakePartSet(types.BlockPartSizeBytes)
if err != nil {
return nil, err
}
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
fireEvents(ctx, be.logger, be.eventBus, block, blockID, abciResponses, validatorUpdates) fireEvents(ctx, be.logger, be.eventBus, block, blockID, abciResponses, validatorUpdates)
} }


+ 23
- 9
internal/state/execution_test.go View File

@ -53,8 +53,11 @@ func TestApplyBlock(t *testing.T) {
blockExec := sm.NewBlockExecutor(stateStore, logger, proxyApp.Consensus(), blockExec := sm.NewBlockExecutor(stateStore, logger, proxyApp.Consensus(),
mmock.Mempool{}, sm.EmptyEvidencePool{}, blockStore) mmock.Mempool{}, sm.EmptyEvidencePool{}, blockStore)
block := sf.MakeBlock(state, 1, new(types.Commit))
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()}
block, err := sf.MakeBlock(state, 1, new(types.Commit))
require.NoError(t, err)
bps, err := block.MakePartSet(testPartSize)
require.NoError(t, err)
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
state, err = blockExec.ApplyBlock(ctx, state, blockID, block) state, err = blockExec.ApplyBlock(ctx, state, blockID, block)
require.Nil(t, err) require.Nil(t, err)
@ -109,7 +112,8 @@ func TestBeginBlockValidators(t *testing.T) {
lastCommit := types.NewCommit(1, 0, prevBlockID, tc.lastCommitSigs) lastCommit := types.NewCommit(1, 0, prevBlockID, tc.lastCommitSigs)
// block for height 2 // block for height 2
block := sf.MakeBlock(state, 2, lastCommit)
block, err := sf.MakeBlock(state, 2, lastCommit)
require.NoError(t, err)
_, err = sm.ExecCommitBlock(ctx, nil, proxyApp.Consensus(), block, log.TestingLogger(), stateStore, 1, state) _, err = sm.ExecCommitBlock(ctx, nil, proxyApp.Consensus(), block, log.TestingLogger(), stateStore, 1, state)
require.Nil(t, err, tc.desc) require.Nil(t, err, tc.desc)
@ -214,10 +218,14 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(),
mmock.Mempool{}, evpool, blockStore) mmock.Mempool{}, evpool, blockStore)
block := sf.MakeBlock(state, 1, new(types.Commit))
block, err := sf.MakeBlock(state, 1, new(types.Commit))
require.NoError(t, err)
block.Evidence = types.EvidenceData{Evidence: ev} block.Evidence = types.EvidenceData{Evidence: ev}
block.Header.EvidenceHash = block.Evidence.Hash() block.Header.EvidenceHash = block.Evidence.Hash()
blockID = types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()}
bps, err := block.MakePartSet(testPartSize)
require.NoError(t, err)
blockID = types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
_, err = blockExec.ApplyBlock(ctx, state, blockID, block) _, err = blockExec.ApplyBlock(ctx, state, blockID, block)
require.Nil(t, err) require.Nil(t, err)
@ -394,8 +402,11 @@ func TestEndBlockValidatorUpdates(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
block := sf.MakeBlock(state, 1, new(types.Commit))
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()}
block, err := sf.MakeBlock(state, 1, new(types.Commit))
require.NoError(t, err)
bps, err := block.MakePartSet(testPartSize)
require.NoError(t, err)
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
pubkey := ed25519.GenPrivKey().PubKey() pubkey := ed25519.GenPrivKey().PubKey()
pk, err := encoding.PubKeyToProto(pubkey) pk, err := encoding.PubKeyToProto(pubkey)
@ -452,8 +463,11 @@ func TestEndBlockValidatorUpdatesResultingInEmptySet(t *testing.T) {
blockStore, blockStore,
) )
block := sf.MakeBlock(state, 1, new(types.Commit))
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()}
block, err := sf.MakeBlock(state, 1, new(types.Commit))
require.NoError(t, err)
bps, err := block.MakePartSet(testPartSize)
require.NoError(t, err)
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
vp, err := encoding.PubKeyToProto(state.Validators.Validators[0].PubKey) vp, err := encoding.PubKeyToProto(state.Validators.Validators[0].PubKey)
require.NoError(t, err) require.NoError(t, err)


+ 21
- 11
internal/state/helpers_test.go View File

@ -4,8 +4,10 @@ import (
"bytes" "bytes"
"context" "context"
"fmt" "fmt"
"testing"
"time" "time"
"github.com/stretchr/testify/require"
dbm "github.com/tendermint/tm-db" dbm "github.com/tendermint/tm-db"
abciclient "github.com/tendermint/tendermint/abci/client" abciclient "github.com/tendermint/tendermint/abci/client"
@ -69,13 +71,17 @@ func makeAndApplyGoodBlock(
blockExec *sm.BlockExecutor, blockExec *sm.BlockExecutor,
evidence []types.Evidence, evidence []types.Evidence,
) (sm.State, types.BlockID, error) { ) (sm.State, types.BlockID, error) {
block, _ := state.MakeBlock(height, factory.MakeTenTxs(height), lastCommit, evidence, proposerAddr)
block, _, err := state.MakeBlock(height, factory.MakeTenTxs(height), lastCommit, evidence, proposerAddr)
if err != nil {
return state, types.BlockID{}, err
}
if err := blockExec.ValidateBlock(state, block); err != nil { if err := blockExec.ValidateBlock(state, block); err != nil {
return state, types.BlockID{}, err return state, types.BlockID{}, err
} }
blockID := types.BlockID{Hash: block.Hash(), blockID := types.BlockID{Hash: block.Hash(),
PartSetHeader: types.PartSetHeader{Total: 3, Hash: tmrand.Bytes(32)}} PartSetHeader: types.PartSetHeader{Total: 3, Hash: tmrand.Bytes(32)}}
state, err := blockExec.ApplyBlock(ctx, state, blockID, block)
state, err = blockExec.ApplyBlock(ctx, state, blockID, block)
if err != nil { if err != nil {
return state, types.BlockID{}, err return state, types.BlockID{}, err
} }
@ -147,11 +153,13 @@ func genValSet(size int) *types.ValidatorSet {
} }
func makeHeaderPartsResponsesValPubKeyChange( func makeHeaderPartsResponsesValPubKeyChange(
t *testing.T,
state sm.State, state sm.State,
pubkey crypto.PubKey, pubkey crypto.PubKey,
) (types.Header, types.BlockID, *tmstate.ABCIResponses) { ) (types.Header, types.BlockID, *tmstate.ABCIResponses) {
block := sf.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit))
block, err := sf.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit))
require.NoError(t, err)
abciResponses := &tmstate.ABCIResponses{ abciResponses := &tmstate.ABCIResponses{
BeginBlock: &abci.ResponseBeginBlock{}, BeginBlock: &abci.ResponseBeginBlock{},
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
@ -160,13 +168,10 @@ func makeHeaderPartsResponsesValPubKeyChange(
_, val := state.NextValidators.GetByIndex(0) _, val := state.NextValidators.GetByIndex(0)
if !bytes.Equal(pubkey.Bytes(), val.PubKey.Bytes()) { if !bytes.Equal(pubkey.Bytes(), val.PubKey.Bytes()) {
vPbPk, err := encoding.PubKeyToProto(val.PubKey) vPbPk, err := encoding.PubKeyToProto(val.PubKey)
if err != nil {
panic(err)
}
require.NoError(t, err)
pbPk, err := encoding.PubKeyToProto(pubkey) pbPk, err := encoding.PubKeyToProto(pubkey)
if err != nil {
panic(err)
}
require.NoError(t, err)
abciResponses.EndBlock = &abci.ResponseEndBlock{ abciResponses.EndBlock = &abci.ResponseEndBlock{
ValidatorUpdates: []abci.ValidatorUpdate{ ValidatorUpdates: []abci.ValidatorUpdate{
{PubKey: vPbPk, Power: 0}, {PubKey: vPbPk, Power: 0},
@ -179,11 +184,14 @@ func makeHeaderPartsResponsesValPubKeyChange(
} }
func makeHeaderPartsResponsesValPowerChange( func makeHeaderPartsResponsesValPowerChange(
t *testing.T,
state sm.State, state sm.State,
power int64, power int64,
) (types.Header, types.BlockID, *tmstate.ABCIResponses) { ) (types.Header, types.BlockID, *tmstate.ABCIResponses) {
block := sf.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit))
block, err := sf.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit))
require.NoError(t, err)
abciResponses := &tmstate.ABCIResponses{ abciResponses := &tmstate.ABCIResponses{
BeginBlock: &abci.ResponseBeginBlock{}, BeginBlock: &abci.ResponseBeginBlock{},
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
@ -207,11 +215,13 @@ func makeHeaderPartsResponsesValPowerChange(
} }
func makeHeaderPartsResponsesParams( func makeHeaderPartsResponsesParams(
t *testing.T,
state sm.State, state sm.State,
params *types.ConsensusParams, params *types.ConsensusParams,
) (types.Header, types.BlockID, *tmstate.ABCIResponses) { ) (types.Header, types.BlockID, *tmstate.ABCIResponses) {
block := sf.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit))
block, err := sf.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit))
require.NoError(t, err)
pbParams := params.ToProto() pbParams := params.ToProto()
abciResponses := &tmstate.ABCIResponses{ abciResponses := &tmstate.ABCIResponses{
BeginBlock: &abci.ResponseBeginBlock{}, BeginBlock: &abci.ResponseBeginBlock{},


+ 7
- 2
internal/state/state.go View File

@ -258,7 +258,7 @@ func (state State) MakeBlock(
commit *types.Commit, commit *types.Commit,
evidence []types.Evidence, evidence []types.Evidence,
proposerAddress []byte, proposerAddress []byte,
) (*types.Block, *types.PartSet) {
) (*types.Block, *types.PartSet, error) {
// Build base block with block data. // Build base block with block data.
block := types.MakeBlock(height, txs, commit, evidence) block := types.MakeBlock(height, txs, commit, evidence)
@ -280,7 +280,12 @@ func (state State) MakeBlock(
proposerAddress, proposerAddress,
) )
return block, block.MakePartSet(types.BlockPartSizeBytes)
bps, err := block.MakePartSet(types.BlockPartSizeBytes)
if err != nil {
return nil, nil, err
}
return block, bps, nil
} }
// MedianTime computes a median time for a given Commit (based on Timestamp field of votes messages) and the // MedianTime computes a median time for a given Commit (based on Timestamp field of votes messages) and the


+ 64
- 23
internal/state/state_test.go View File

@ -107,7 +107,8 @@ func TestABCIResponsesSaveLoad1(t *testing.T) {
state.LastBlockHeight++ state.LastBlockHeight++
// Build mock responses. // Build mock responses.
block := statefactory.MakeBlock(state, 2, new(types.Commit))
block, err := statefactory.MakeBlock(state, 2, new(types.Commit))
require.NoError(t, err)
abciResponses := new(tmstate.ABCIResponses) abciResponses := new(tmstate.ABCIResponses)
dtxs := make([]*abci.ResponseDeliverTx, 2) dtxs := make([]*abci.ResponseDeliverTx, 2)
@ -275,7 +276,7 @@ func TestOneValidatorChangesSaveLoad(t *testing.T) {
changeIndex++ changeIndex++
power++ power++
} }
header, blockID, responses := makeHeaderPartsResponsesValPowerChange(state, power)
header, blockID, responses := makeHeaderPartsResponsesValPowerChange(t, state, power)
validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates) validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates)
require.NoError(t, err) require.NoError(t, err)
state, err = sm.UpdateState(state, blockID, &header, responses, validatorUpdates) state, err = sm.UpdateState(state, blockID, &header, responses, validatorUpdates)
@ -451,8 +452,11 @@ func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) {
// NewValidatorSet calls IncrementProposerPriority but uses on a copy of val1 // NewValidatorSet calls IncrementProposerPriority but uses on a copy of val1
assert.EqualValues(t, 0, val1.ProposerPriority) assert.EqualValues(t, 0, val1.ProposerPriority)
block := statefactory.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit))
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()}
block, err := statefactory.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit))
require.NoError(t, err)
bps, err := block.MakePartSet(testPartSize)
require.NoError(t, err)
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
abciResponses := &tmstate.ABCIResponses{ abciResponses := &tmstate.ABCIResponses{
BeginBlock: &abci.ResponseBeginBlock{}, BeginBlock: &abci.ResponseBeginBlock{},
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
@ -565,8 +569,11 @@ func TestProposerPriorityProposerAlternates(t *testing.T) {
// we only have one validator: // we only have one validator:
assert.Equal(t, val1PubKey.Address(), state.Validators.Proposer.Address) assert.Equal(t, val1PubKey.Address(), state.Validators.Proposer.Address)
block := statefactory.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit))
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()}
block, err := statefactory.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit))
require.NoError(t, err)
bps, err := block.MakePartSet(testPartSize)
require.NoError(t, err)
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
// no updates: // no updates:
abciResponses := &tmstate.ABCIResponses{ abciResponses := &tmstate.ABCIResponses{
BeginBlock: &abci.ResponseBeginBlock{}, BeginBlock: &abci.ResponseBeginBlock{},
@ -752,8 +759,11 @@ func TestLargeGenesisValidator(t *testing.T) {
validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
require.NoError(t, err) require.NoError(t, err)
block := statefactory.MakeBlock(oldState, oldState.LastBlockHeight+1, new(types.Commit))
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()}
block, err := statefactory.MakeBlock(oldState, oldState.LastBlockHeight+1, new(types.Commit))
require.NoError(t, err)
bps, err := block.MakePartSet(testPartSize)
require.NoError(t, err)
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
updatedState, err := sm.UpdateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates) updatedState, err := sm.UpdateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates)
require.NoError(t, err) require.NoError(t, err)
@ -781,8 +791,13 @@ func TestLargeGenesisValidator(t *testing.T) {
BeginBlock: &abci.ResponseBeginBlock{}, BeginBlock: &abci.ResponseBeginBlock{},
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{firstAddedVal}}, EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{firstAddedVal}},
} }
block := statefactory.MakeBlock(oldState, oldState.LastBlockHeight+1, new(types.Commit))
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()}
block, err := statefactory.MakeBlock(oldState, oldState.LastBlockHeight+1, new(types.Commit))
require.NoError(t, err)
bps, err := block.MakePartSet(testPartSize)
require.NoError(t, err)
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
updatedState, err := sm.UpdateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates) updatedState, err := sm.UpdateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates)
require.NoError(t, err) require.NoError(t, err)
@ -796,8 +811,13 @@ func TestLargeGenesisValidator(t *testing.T) {
validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
require.NoError(t, err) require.NoError(t, err)
block := statefactory.MakeBlock(lastState, lastState.LastBlockHeight+1, new(types.Commit))
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()}
block, err := statefactory.MakeBlock(lastState, lastState.LastBlockHeight+1, new(types.Commit))
require.NoError(t, err)
bps, err = block.MakePartSet(testPartSize)
require.NoError(t, err)
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
updatedStateInner, err := sm.UpdateState(lastState, blockID, &block.Header, abciResponses, validatorUpdates) updatedStateInner, err := sm.UpdateState(lastState, blockID, &block.Header, abciResponses, validatorUpdates)
require.NoError(t, err) require.NoError(t, err)
@ -829,8 +849,12 @@ func TestLargeGenesisValidator(t *testing.T) {
BeginBlock: &abci.ResponseBeginBlock{}, BeginBlock: &abci.ResponseBeginBlock{},
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{addedVal}}, EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{addedVal}},
} }
block := statefactory.MakeBlock(oldState, oldState.LastBlockHeight+1, new(types.Commit))
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()}
block, err := statefactory.MakeBlock(oldState, oldState.LastBlockHeight+1, new(types.Commit))
require.NoError(t, err)
bps, err := block.MakePartSet(testPartSize)
require.NoError(t, err)
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
state, err = sm.UpdateState(state, blockID, &block.Header, abciResponses, validatorUpdates) state, err = sm.UpdateState(state, blockID, &block.Header, abciResponses, validatorUpdates)
require.NoError(t, err) require.NoError(t, err)
} }
@ -844,8 +868,14 @@ func TestLargeGenesisValidator(t *testing.T) {
BeginBlock: &abci.ResponseBeginBlock{}, BeginBlock: &abci.ResponseBeginBlock{},
EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{removeGenesisVal}}, EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{removeGenesisVal}},
} }
block = statefactory.MakeBlock(oldState, oldState.LastBlockHeight+1, new(types.Commit))
blockID = types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()}
block, err = statefactory.MakeBlock(oldState, oldState.LastBlockHeight+1, new(types.Commit))
require.NoError(t, err)
bps, err = block.MakePartSet(testPartSize)
require.NoError(t, err)
blockID = types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
require.NoError(t, err) require.NoError(t, err)
updatedState, err = sm.UpdateState(state, blockID, &block.Header, abciResponses, validatorUpdates) updatedState, err = sm.UpdateState(state, blockID, &block.Header, abciResponses, validatorUpdates)
@ -865,8 +895,13 @@ func TestLargeGenesisValidator(t *testing.T) {
} }
validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
require.NoError(t, err) require.NoError(t, err)
block = statefactory.MakeBlock(curState, curState.LastBlockHeight+1, new(types.Commit))
blockID = types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()}
block, err = statefactory.MakeBlock(curState, curState.LastBlockHeight+1, new(types.Commit))
require.NoError(t, err)
bps, err := block.MakePartSet(testPartSize)
require.NoError(t, err)
blockID = types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
curState, err = sm.UpdateState(curState, blockID, &block.Header, abciResponses, validatorUpdates) curState, err = sm.UpdateState(curState, blockID, &block.Header, abciResponses, validatorUpdates)
require.NoError(t, err) require.NoError(t, err)
if !bytes.Equal(curState.Validators.Proposer.Address, curState.NextValidators.Proposer.Address) { if !bytes.Equal(curState.Validators.Proposer.Address, curState.NextValidators.Proposer.Address) {
@ -890,8 +925,13 @@ func TestLargeGenesisValidator(t *testing.T) {
validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
require.NoError(t, err) require.NoError(t, err)
block := statefactory.MakeBlock(updatedState, updatedState.LastBlockHeight+1, new(types.Commit))
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()}
block, err := statefactory.MakeBlock(updatedState, updatedState.LastBlockHeight+1, new(types.Commit))
require.NoError(t, err)
bps, err := block.MakePartSet(testPartSize)
require.NoError(t, err)
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
updatedState, err = sm.UpdateState(updatedState, blockID, &block.Header, abciResponses, validatorUpdates) updatedState, err = sm.UpdateState(updatedState, blockID, &block.Header, abciResponses, validatorUpdates)
require.NoError(t, err) require.NoError(t, err)
@ -946,7 +986,7 @@ func TestManyValidatorChangesSaveLoad(t *testing.T) {
pubkey := ed25519.GenPrivKey().PubKey() pubkey := ed25519.GenPrivKey().PubKey()
// Swap the first validator with a new one (validator set size stays the same). // Swap the first validator with a new one (validator set size stays the same).
header, blockID, responses := makeHeaderPartsResponsesValPubKeyChange(state, pubkey)
header, blockID, responses := makeHeaderPartsResponsesValPubKeyChange(t, state, pubkey)
// Save state etc. // Save state etc.
var validatorUpdates []*types.Validator var validatorUpdates []*types.Validator
@ -985,7 +1025,8 @@ func TestStateMakeBlock(t *testing.T) {
proposerAddress := state.Validators.GetProposer().Address proposerAddress := state.Validators.GetProposer().Address
stateVersion := state.Version.Consensus stateVersion := state.Version.Consensus
block := statefactory.MakeBlock(state, 2, new(types.Commit))
block, err := statefactory.MakeBlock(state, 2, new(types.Commit))
require.NoError(t, err)
// test we set some fields // test we set some fields
assert.Equal(t, stateVersion, block.Version) assert.Equal(t, stateVersion, block.Version)
@ -1026,7 +1067,7 @@ func TestConsensusParamsChangesSaveLoad(t *testing.T) {
changeIndex++ changeIndex++
cp = params[changeIndex] cp = params[changeIndex]
} }
header, blockID, responses := makeHeaderPartsResponsesParams(state, &cp)
header, blockID, responses := makeHeaderPartsResponsesParams(t, state, &cp)
validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates) validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates)
require.NoError(t, err) require.NoError(t, err)
state, err = sm.UpdateState(state, blockID, &header, responses, validatorUpdates) state, err = sm.UpdateState(state, blockID, &header, responses, validatorUpdates)


+ 23
- 11
internal/state/test/factory/block.go View File

@ -8,8 +8,8 @@ import (
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
) )
func MakeBlocks(n int, state *sm.State, privVal types.PrivValidator) []*types.Block {
blocks := make([]*types.Block, 0)
func MakeBlocks(n int, state *sm.State, privVal types.PrivValidator) ([]*types.Block, error) {
blocks := make([]*types.Block, n)
var ( var (
prevBlock *types.Block prevBlock *types.Block
@ -20,8 +20,12 @@ func MakeBlocks(n int, state *sm.State, privVal types.PrivValidator) []*types.Bl
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
height := int64(i + 1) height := int64(i + 1)
block, parts := makeBlockAndPartSet(*state, prevBlock, prevBlockMeta, privVal, height)
blocks = append(blocks, block)
block, parts, err := makeBlockAndPartSet(*state, prevBlock, prevBlockMeta, privVal, height)
if err != nil {
return nil, err
}
blocks[i] = block
prevBlock = block prevBlock = block
prevBlockMeta = types.NewBlockMeta(block, parts) prevBlockMeta = types.NewBlockMeta(block, parts)
@ -32,23 +36,31 @@ func MakeBlocks(n int, state *sm.State, privVal types.PrivValidator) []*types.Bl
state.LastBlockHeight = height state.LastBlockHeight = height
} }
return blocks
return blocks, nil
} }
func MakeBlock(state sm.State, height int64, c *types.Commit) *types.Block {
block, _ := state.MakeBlock(
func MakeBlock(state sm.State, height int64, c *types.Commit) (*types.Block, error) {
block, _, err := state.MakeBlock(
height, height,
factory.MakeTenTxs(state.LastBlockHeight), factory.MakeTenTxs(state.LastBlockHeight),
c, c,
nil, nil,
state.Validators.GetProposer().Address, state.Validators.GetProposer().Address,
) )
return block
}
if err != nil {
return nil, err
}
func makeBlockAndPartSet(state sm.State, lastBlock *types.Block, lastBlockMeta *types.BlockMeta,
privVal types.PrivValidator, height int64) (*types.Block, *types.PartSet) {
return block, nil
}
func makeBlockAndPartSet(
state sm.State,
lastBlock *types.Block,
lastBlockMeta *types.BlockMeta,
privVal types.PrivValidator,
height int64,
) (*types.Block, *types.PartSet, error) {
lastCommit := types.NewCommit(height-1, 0, types.BlockID{}, nil) lastCommit := types.NewCommit(height-1, 0, types.BlockID{}, nil)
if height > 1 { if height > 1 {
vote, _ := factory.MakeVote( vote, _ := factory.MakeVote(


+ 14
- 8
internal/state/validation_test.go View File

@ -92,9 +92,10 @@ func TestValidateBlockHeader(t *testing.T) {
Invalid blocks don't pass Invalid blocks don't pass
*/ */
for _, tc := range testCases { for _, tc := range testCases {
block := statefactory.MakeBlock(state, height, lastCommit)
block, err := statefactory.MakeBlock(state, height, lastCommit)
require.NoError(t, err)
tc.malleateBlock(block) tc.malleateBlock(block)
err := blockExec.ValidateBlock(state, block)
err = blockExec.ValidateBlock(state, block)
t.Logf("%s: %v", tc.name, err) t.Logf("%s: %v", tc.name, err)
require.Error(t, err, tc.name) require.Error(t, err, tc.name)
} }
@ -109,9 +110,10 @@ func TestValidateBlockHeader(t *testing.T) {
} }
nextHeight := validationTestsStopHeight nextHeight := validationTestsStopHeight
block := statefactory.MakeBlock(state, nextHeight, lastCommit)
block, err := statefactory.MakeBlock(state, nextHeight, lastCommit)
require.NoError(t, err)
state.InitialHeight = nextHeight + 1 state.InitialHeight = nextHeight + 1
err := blockExec.ValidateBlock(state, block)
err = blockExec.ValidateBlock(state, block)
require.Error(t, err, "expected an error when state is ahead of block") require.Error(t, err, "expected an error when state is ahead of block")
assert.Contains(t, err.Error(), "lower than initial height") assert.Contains(t, err.Error(), "lower than initial height")
} }
@ -162,7 +164,8 @@ func TestValidateBlockCommit(t *testing.T) {
state.LastBlockID, state.LastBlockID,
[]types.CommitSig{wrongHeightVote.CommitSig()}, []types.CommitSig{wrongHeightVote.CommitSig()},
) )
block := statefactory.MakeBlock(state, height, wrongHeightCommit)
block, err := statefactory.MakeBlock(state, height, wrongHeightCommit)
require.NoError(t, err)
err = blockExec.ValidateBlock(state, block) err = blockExec.ValidateBlock(state, block)
_, isErrInvalidCommitHeight := err.(types.ErrInvalidCommitHeight) _, isErrInvalidCommitHeight := err.(types.ErrInvalidCommitHeight)
require.True(t, isErrInvalidCommitHeight, "expected ErrInvalidCommitHeight at height %d but got: %v", height, err) require.True(t, isErrInvalidCommitHeight, "expected ErrInvalidCommitHeight at height %d but got: %v", height, err)
@ -170,7 +173,8 @@ func TestValidateBlockCommit(t *testing.T) {
/* /*
#2589: test len(block.LastCommit.Signatures) == state.LastValidators.Size() #2589: test len(block.LastCommit.Signatures) == state.LastValidators.Size()
*/ */
block = statefactory.MakeBlock(state, height, wrongSigsCommit)
block, err = statefactory.MakeBlock(state, height, wrongSigsCommit)
require.NoError(t, err)
err = blockExec.ValidateBlock(state, block) err = blockExec.ValidateBlock(state, block)
_, isErrInvalidCommitSignatures := err.(types.ErrInvalidCommitSignatures) _, isErrInvalidCommitSignatures := err.(types.ErrInvalidCommitSignatures)
require.True(t, isErrInvalidCommitSignatures, require.True(t, isErrInvalidCommitSignatures,
@ -285,8 +289,10 @@ func TestValidateBlockEvidence(t *testing.T) {
evidence = append(evidence, newEv) evidence = append(evidence, newEv)
currentBytes += int64(len(newEv.Bytes())) currentBytes += int64(len(newEv.Bytes()))
} }
block, _ := state.MakeBlock(height, testfactory.MakeTenTxs(height), lastCommit, evidence, proposerAddr)
err := blockExec.ValidateBlock(state, block)
block, _, err := state.MakeBlock(height, testfactory.MakeTenTxs(height), lastCommit, evidence, proposerAddr)
require.NoError(t, err)
err = blockExec.ValidateBlock(state, block)
if assert.Error(t, err) { if assert.Error(t, err) {
_, ok := err.(*types.ErrEvidenceOverflow) _, ok := err.(*types.ErrEvidenceOverflow)
require.True(t, ok, "expected error to be of type ErrEvidenceOverflow at height %d but got %v", height, err) require.True(t, ok, "expected error to be of type ErrEvidenceOverflow at height %d but got %v", height, err)


+ 32
- 13
internal/store/store_test.go View File

@ -2,6 +2,7 @@ package store
import ( import (
"fmt" "fmt"
stdlog "log"
"os" "os"
"runtime/debug" "runtime/debug"
"strings" "strings"
@ -75,9 +76,17 @@ var (
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
var cleanup cleanupFunc var cleanup cleanupFunc
var err error
state, _, cleanup = makeStateAndBlockStore(log.NewNopLogger()) state, _, cleanup = makeStateAndBlockStore(log.NewNopLogger())
block = factory.MakeBlock(state, 1, new(types.Commit))
partSet = block.MakePartSet(2)
block, err = factory.MakeBlock(state, 1, new(types.Commit))
if err != nil {
stdlog.Fatal(err)
}
partSet, err = block.MakePartSet(2)
if err != nil {
stdlog.Fatal(err)
}
part1 = partSet.GetPart(0) part1 = partSet.GetPart(0)
part2 = partSet.GetPart(1) part2 = partSet.GetPart(1)
seenCommit1 = makeTestCommit(10, tmtime.Now()) seenCommit1 = makeTestCommit(10, tmtime.Now())
@ -102,8 +111,10 @@ func TestBlockStoreSaveLoadBlock(t *testing.T) {
} }
// save a block // save a block
block := factory.MakeBlock(state, bs.Height()+1, new(types.Commit))
validPartSet := block.MakePartSet(2)
block, err := factory.MakeBlock(state, bs.Height()+1, new(types.Commit))
require.NoError(t, err)
validPartSet, err := block.MakePartSet(2)
require.NoError(t, err)
seenCommit := makeTestCommit(10, tmtime.Now()) seenCommit := makeTestCommit(10, tmtime.Now())
bs.SaveBlock(block, partSet, seenCommit) bs.SaveBlock(block, partSet, seenCommit)
require.EqualValues(t, 1, bs.Base(), "expecting the new height to be changed") require.EqualValues(t, 1, bs.Base(), "expecting the new height to be changed")
@ -111,7 +122,7 @@ func TestBlockStoreSaveLoadBlock(t *testing.T) {
incompletePartSet := types.NewPartSetFromHeader(types.PartSetHeader{Total: 2}) incompletePartSet := types.NewPartSetFromHeader(types.PartSetHeader{Total: 2})
uncontiguousPartSet := types.NewPartSetFromHeader(types.PartSetHeader{Total: 0}) uncontiguousPartSet := types.NewPartSetFromHeader(types.PartSetHeader{Total: 0})
_, err := uncontiguousPartSet.AddPart(part2)
_, err = uncontiguousPartSet.AddPart(part2)
require.Error(t, err) require.Error(t, err)
header1 := types.Header{ header1 := types.Header{
@ -305,8 +316,10 @@ func TestLoadBaseMeta(t *testing.T) {
bs := NewBlockStore(dbm.NewMemDB()) bs := NewBlockStore(dbm.NewMemDB())
for h := int64(1); h <= 10; h++ { for h := int64(1); h <= 10; h++ {
block := factory.MakeBlock(state, h, new(types.Commit))
partSet := block.MakePartSet(2)
block, err := factory.MakeBlock(state, h, new(types.Commit))
require.NoError(t, err)
partSet, err := block.MakePartSet(2)
require.NoError(t, err)
seenCommit := makeTestCommit(h, tmtime.Now()) seenCommit := makeTestCommit(h, tmtime.Now())
bs.SaveBlock(block, partSet, seenCommit) bs.SaveBlock(block, partSet, seenCommit)
} }
@ -371,8 +384,10 @@ func TestPruneBlocks(t *testing.T) {
// make more than 1000 blocks, to test batch deletions // make more than 1000 blocks, to test batch deletions
for h := int64(1); h <= 1500; h++ { for h := int64(1); h <= 1500; h++ {
block := factory.MakeBlock(state, h, new(types.Commit))
partSet := block.MakePartSet(2)
block, err := factory.MakeBlock(state, h, new(types.Commit))
require.NoError(t, err)
partSet, err := block.MakePartSet(2)
require.NoError(t, err)
seenCommit := makeTestCommit(h, tmtime.Now()) seenCommit := makeTestCommit(h, tmtime.Now())
bs.SaveBlock(block, partSet, seenCommit) bs.SaveBlock(block, partSet, seenCommit)
} }
@ -476,9 +491,11 @@ func TestBlockFetchAtHeight(t *testing.T) {
state, bs, cleanup := makeStateAndBlockStore(log.NewNopLogger()) state, bs, cleanup := makeStateAndBlockStore(log.NewNopLogger())
defer cleanup() defer cleanup()
require.Equal(t, bs.Height(), int64(0), "initially the height should be zero") require.Equal(t, bs.Height(), int64(0), "initially the height should be zero")
block := factory.MakeBlock(state, bs.Height()+1, new(types.Commit))
block, err := factory.MakeBlock(state, bs.Height()+1, new(types.Commit))
require.NoError(t, err)
partSet := block.MakePartSet(2)
partSet, err := block.MakePartSet(2)
require.NoError(t, err)
seenCommit := makeTestCommit(10, tmtime.Now()) seenCommit := makeTestCommit(10, tmtime.Now())
bs.SaveBlock(block, partSet, seenCommit) bs.SaveBlock(block, partSet, seenCommit)
require.Equal(t, bs.Height(), block.Header.Height, "expecting the new height to be changed") require.Equal(t, bs.Height(), block.Header.Height, "expecting the new height to be changed")
@ -517,8 +534,10 @@ func TestSeenAndCanonicalCommit(t *testing.T) {
// are persisted. // are persisted.
for h := int64(3); h <= 5; h++ { for h := int64(3); h <= 5; h++ {
blockCommit := makeTestCommit(h-1, tmtime.Now()) blockCommit := makeTestCommit(h-1, tmtime.Now())
block := factory.MakeBlock(state, h, blockCommit)
partSet := block.MakePartSet(2)
block, err := factory.MakeBlock(state, h, blockCommit)
require.NoError(t, err)
partSet, err := block.MakePartSet(2)
require.NoError(t, err)
seenCommit := makeTestCommit(h, tmtime.Now()) seenCommit := makeTestCommit(h, tmtime.Now())
bs.SaveBlock(block, partSet, seenCommit) bs.SaveBlock(block, partSet, seenCommit)
c3 := bs.LoadSeenCommit() c3 := bs.LoadSeenCommit()


+ 10
- 5
node/node_test.go View File

@ -316,14 +316,16 @@ func TestCreateProposalBlock(t *testing.T) {
) )
commit := types.NewCommit(height-1, 0, types.BlockID{}, nil) commit := types.NewCommit(height-1, 0, types.BlockID{}, nil)
block, _ := blockExec.CreateProposalBlock(
block, _, err := blockExec.CreateProposalBlock(
height, height,
state, commit, state, commit,
proposerAddr, proposerAddr,
) )
require.NoError(t, err)
// check that the part set does not exceed the maximum block size // check that the part set does not exceed the maximum block size
partSet := block.MakePartSet(partSize)
partSet, err := block.MakePartSet(partSize)
require.NoError(t, err)
assert.Less(t, partSet.ByteSize(), int64(maxBytes)) assert.Less(t, partSet.ByteSize(), int64(maxBytes))
partSetFromHeader := types.NewPartSetFromHeader(partSet.Header()) partSetFromHeader := types.NewPartSetFromHeader(partSet.Header())
@ -387,18 +389,20 @@ func TestMaxTxsProposalBlockSize(t *testing.T) {
) )
commit := types.NewCommit(height-1, 0, types.BlockID{}, nil) commit := types.NewCommit(height-1, 0, types.BlockID{}, nil)
block, _ := blockExec.CreateProposalBlock(
block, _, err := blockExec.CreateProposalBlock(
height, height,
state, commit, state, commit,
proposerAddr, proposerAddr,
) )
require.NoError(t, err)
pb, err := block.ToProto() pb, err := block.ToProto()
require.NoError(t, err) require.NoError(t, err)
assert.Less(t, int64(pb.Size()), maxBytes) assert.Less(t, int64(pb.Size()), maxBytes)
// check that the part set does not exceed the maximum block size // check that the part set does not exceed the maximum block size
partSet := block.MakePartSet(partSize)
partSet, err := block.MakePartSet(partSize)
require.NoError(t, err)
assert.EqualValues(t, partSet.ByteSize(), int64(pb.Size())) assert.EqualValues(t, partSet.ByteSize(), int64(pb.Size()))
} }
@ -494,11 +498,12 @@ func TestMaxProposalBlockSize(t *testing.T) {
commit.Signatures = append(commit.Signatures, cs) commit.Signatures = append(commit.Signatures, cs)
} }
block, partSet := blockExec.CreateProposalBlock(
block, partSet, err := blockExec.CreateProposalBlock(
math.MaxInt64, math.MaxInt64,
state, commit, state, commit,
proposerAddr, proposerAddr,
) )
require.NoError(t, err)
// this ensures that the header is at max size // this ensures that the header is at max size
block.Header.Time = timestamp block.Header.Time = timestamp


+ 5
- 5
types/block.go View File

@ -126,22 +126,22 @@ func (b *Block) Hash() tmbytes.HexBytes {
// MakePartSet returns a PartSet containing parts of a serialized block. // MakePartSet returns a PartSet containing parts of a serialized block.
// This is the form in which the block is gossipped to peers. // This is the form in which the block is gossipped to peers.
// CONTRACT: partSize is greater than zero. // CONTRACT: partSize is greater than zero.
func (b *Block) MakePartSet(partSize uint32) *PartSet {
func (b *Block) MakePartSet(partSize uint32) (*PartSet, error) {
if b == nil { if b == nil {
return nil
return nil, errors.New("nil block")
} }
b.mtx.Lock() b.mtx.Lock()
defer b.mtx.Unlock() defer b.mtx.Unlock()
pbb, err := b.ToProto() pbb, err := b.ToProto()
if err != nil { if err != nil {
panic(err)
return nil, err
} }
bz, err := proto.Marshal(pbb) bz, err := proto.Marshal(pbb)
if err != nil { if err != nil {
panic(err)
return nil, err
} }
return NewPartSetFromData(bz, partSize)
return NewPartSetFromData(bz, partSize), nil
} }
// HashesTo is a convenience function that checks if a block hashes to the given argument. // HashesTo is a convenience function that checks if a block hashes to the given argument.


+ 11
- 4
types/block_test.go View File

@ -123,15 +123,20 @@ func TestBlockHash(t *testing.T) {
} }
func TestBlockMakePartSet(t *testing.T) { func TestBlockMakePartSet(t *testing.T) {
assert.Nil(t, (*Block)(nil).MakePartSet(2))
bps, err := (*Block)(nil).MakePartSet(2)
assert.Error(t, err)
assert.Nil(t, bps)
partSet := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil, nil).MakePartSet(1024)
partSet, err := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil, nil).MakePartSet(1024)
require.NoError(t, err)
assert.NotNil(t, partSet) assert.NotNil(t, partSet)
assert.EqualValues(t, 1, partSet.Total()) assert.EqualValues(t, 1, partSet.Total())
} }
func TestBlockMakePartSetWithEvidence(t *testing.T) { func TestBlockMakePartSetWithEvidence(t *testing.T) {
assert.Nil(t, (*Block)(nil).MakePartSet(2))
bps, err := (*Block)(nil).MakePartSet(2)
assert.Error(t, err)
assert.Nil(t, bps)
lastID := makeBlockIDRandom() lastID := makeBlockIDRandom()
h := int64(3) h := int64(3)
@ -143,7 +148,9 @@ func TestBlockMakePartSetWithEvidence(t *testing.T) {
ev := NewMockDuplicateVoteEvidenceWithValidator(h, time.Now(), vals[0], "block-test-chain") ev := NewMockDuplicateVoteEvidenceWithValidator(h, time.Now(), vals[0], "block-test-chain")
evList := []Evidence{ev} evList := []Evidence{ev}
partSet := MakeBlock(h, []Tx{Tx("Hello World")}, commit, evList).MakePartSet(512)
partSet, err := MakeBlock(h, []Tx{Tx("Hello World")}, commit, evList).MakePartSet(512)
require.NoError(t, err)
assert.NotNil(t, partSet) assert.NotNil(t, partSet)
assert.EqualValues(t, 4, partSet.Total()) assert.EqualValues(t, 4, partSet.Total())
} }


+ 2
- 3
types/evidence_test.go View File

@ -249,9 +249,8 @@ func makeVote(
vpb := v.ToProto() vpb := v.ToProto()
err = val.SignVote(context.Background(), chainID, vpb) err = val.SignVote(context.Background(), chainID, vpb)
if err != nil {
panic(err)
}
require.NoError(t, err)
v.Signature = vpb.Signature v.Signature = vpb.Signature
return v return v
} }


Loading…
Cancel
Save