Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

abci++: Propagate vote extensions (RFC 017) #8433

Merged
merged 94 commits into from
May 11, 2022
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
d651cd5
Add protos for ExtendedCommit
sergio-mena Apr 10, 2022
98ea839
make proto-gen
thanethomson Apr 28, 2022
f18f1cb
BlockStore holds extended commit
sergio-mena Apr 10, 2022
23d4d6f
Reshuffle ExtendedCommit and ExtendedCommitSig
thanethomson Apr 28, 2022
9cd356d
Fix exit condition in blocksync
sergio-mena Apr 10, 2022
49a6b2f
Merge branch 'master' into thane/8272-propagate-vote-extensions
thanethomson Apr 29, 2022
bb4a1c7
Merge branch 'master' into thane/8272-propagate-vote-extensions
thanethomson Apr 29, 2022
adfdfca
Add note to remove TxResult proto
thanethomson Apr 28, 2022
82dd779
Lift termination condition into for loop
thanethomson Apr 29, 2022
c5db2e9
Enforce vote extension signature requirement
thanethomson Apr 29, 2022
dc6a208
Expand on comment for PeekTwoBlocks for posterity
thanethomson Apr 29, 2022
fba6848
Isolate TODO more clearly
thanethomson Apr 29, 2022
91d076a
Merge changes from master and resolve conflicts
thanethomson Apr 30, 2022
4037fcd
Merge branch 'master' into thane/8272-propagate-vote-extensions
thanethomson May 2, 2022
61d5837
Merge branch 'master' into thane/8272-propagate-vote-extensions
thanethomson May 3, 2022
583d5fc
make mockery
thanethomson May 2, 2022
b3f3c32
Fix comment
thanethomson May 2, 2022
5c81f7a
Make panic output from BlockStore.SaveBlock more readable
thanethomson May 3, 2022
056aa98
Add helper methods to ExtendedCommitSig and ExtendedCommit
thanethomson May 3, 2022
656d2d0
Fix most tests except TestHandshake*
thanethomson May 3, 2022
ce70167
Fix store prefix collision
thanethomson May 3, 2022
e503d74
Fix TestBlockFetchAtHeight
thanethomson May 3, 2022
6396abd
Remove global state from store tests
thanethomson May 3, 2022
51f87b6
Apply suggestions from code review
thanethomson May 4, 2022
a327736
Merge branch 'master' into thane/8272-propagate-vote-extensions
thanethomson May 4, 2022
e3bfd43
Merge branch 'master' into thane/8272-propagate-vote-extensions
thanethomson May 4, 2022
1378900
blocksync: Just return error
thanethomson May 4, 2022
421a12b
make format
thanethomson May 4, 2022
4aed18a
types: Remove unused/commented-out code
thanethomson May 4, 2022
dd5c23d
blocksync: Change pool AddBlock function signature to return errors
thanethomson May 4, 2022
2febbb2
types: Improve legibility of switch statements
thanethomson May 4, 2022
a8adf63
blocksync: Expand on extended commit requirement in AddBlock description
thanethomson May 4, 2022
86f942a
blocksync: Return error without also logging it
thanethomson May 4, 2022
fce052d
consensus: Rename short-lived local variable
thanethomson May 4, 2022
1667ed2
consensus: Allocate TODO to Sergio
thanethomson May 4, 2022
0e8fc8e
evidence/pool_test: Inline slice construction
thanethomson May 4, 2022
9fcab60
state: Rename LoadBlockExtCommit to LoadBlockExtendedCommit
thanethomson May 4, 2022
b9fe2d7
proto: Remove TODO on TxResult
thanethomson May 4, 2022
24d1e6d
types: Minor format
thanethomson May 4, 2022
a3b3415
types: Reformat ExtendedCommitSig.BlockID
thanethomson May 4, 2022
b5a94bb
types: Remove NewExtendedCommit constructor
thanethomson May 4, 2022
59434d8
types: Remove NewCommit constructor
thanethomson May 4, 2022
386cdef
types: Shorten receiver names for ExtendedCommit
thanethomson May 4, 2022
0a31afe
types: Convert ExtendedCommit.Copy to a deep clone
thanethomson May 4, 2022
d0102e6
types: Assign TODO to Sergio
thanethomson May 4, 2022
2ef2733
types: Fix legibility nits
thanethomson May 4, 2022
3377d61
Merge branch 'master' into thane/8272-propagate-vote-extensions
thanethomson May 4, 2022
c9deedf
types: Improve legibility
thanethomson May 4, 2022
6a69e88
store/state: Add TODO to move prefixes to common package
thanethomson May 5, 2022
bce2c7c
Merge branch 'master' into thane/8272-propagate-vote-extensions
thanethomson May 7, 2022
a20a485
Propagate validator info to PrepareProposal
thanethomson May 7, 2022
408cc4c
Rename local var for clarity
thanethomson May 7, 2022
e43e72c
Fix TestMaxProposalBlockSize
thanethomson May 7, 2022
0dd7ce3
Rename local var for clarity
thanethomson May 7, 2022
630ec25
Remove debug log
thanethomson May 7, 2022
accba47
Remove CommigSig.ForBlock helper
thanethomson May 7, 2022
08bf156
Remove CommigSig.Absent helper
thanethomson May 7, 2022
a27365b
Remove ExtendedCommitSig.ForBlock helper
thanethomson May 7, 2022
e7e7da3
Remove ExtendedCommitSig.Absent helper
thanethomson May 7, 2022
5217349
There are no extended commits below the initial height
thanethomson May 7, 2022
739e60e
Fix comment grammar
thanethomson May 7, 2022
fe5220b
Remove JSON encoding from ExtendedCommit
thanethomson May 7, 2022
6389f2f
Embed CommitSig into ExtendedCommitSig instead of duplicating fields
thanethomson May 7, 2022
595377f
Rename ExtendedCommit vote_extension field to extension for consisten…
thanethomson May 7, 2022
9483b42
blocksync: Panic if we peek a block without an extended commit
thanethomson May 7, 2022
b1896eb
Apply suggestions from code review
thanethomson May 9, 2022
db91461
Merge branch 'master' into thane/8272-propagate-vote-extensions
thanethomson May 9, 2022
2cbaa35
Remove Sergio from TODO
thanethomson May 9, 2022
8922ae4
Increase hard-coded vote extension max size to 1MB
thanethomson May 9, 2022
d688cf0
state: Remove unnecessary comment
thanethomson May 9, 2022
ecb523c
state: Ensure no of commit sigs equals validator set length
thanethomson May 9, 2022
7b1f36d
make format
thanethomson May 9, 2022
20fadb6
types: Minor legibility improvements
thanethomson May 9, 2022
d53d11d
Improve legibility
thanethomson May 9, 2022
4f5f158
types: Remove unused GetVotes function on VoteSet
thanethomson May 9, 2022
8cc7776
Refactor TestMaxProposalBlockSize to construct more realistic extende…
thanethomson May 9, 2022
acb3723
Refactor buildExtendedCommitInfo to resemble buildLastCommitInfo
thanethomson May 9, 2022
2668f19
Apply suggestions from code review
thanethomson May 9, 2022
a0742ce
abci++: Disable VerifyVoteExtension call on nil precommits (#8491)
thanethomson May 10, 2022
e000d1c
Merge branch 'master' into thane/8272-propagate-vote-extensions
thanethomson May 10, 2022
68013b8
Merge branch 'master' into thane/8272-propagate-vote-extensions
thanethomson May 10, 2022
15220bb
types: Require vote extensions on non-nil precommits and not otherwise
thanethomson May 10, 2022
d90b0f3
Merge from master and fix conflict from #8493
thanethomson May 10, 2022
2146a7f
Merge changes from master and resolve conflicts
thanethomson May 10, 2022
6fffbf9
Disable lint
thanethomson May 10, 2022
af51493
Increase timeout for TestReactorVotingPowerChange to counter flakiness
thanethomson May 10, 2022
76e36fc
Only sign and verify vote extensions in non-nil precommits
thanethomson May 10, 2022
585ba6a
Revert "Disable lint"
thanethomson May 10, 2022
efd1313
Add missing non-nil check uncovered non-deterministically in TestHand…
thanethomson May 10, 2022
c278eb1
Merge branch 'master' into thane/8272-propagate-vote-extensions
thanethomson May 10, 2022
84bf76e
Expand error message for accuracy
thanethomson May 10, 2022
74ddd7a
Only call ExtendVote when we make non-nil precommits
thanethomson May 10, 2022
aa7fbc8
Revert "Increase timeout for TestReactorVotingPowerChange to counter …
thanethomson May 10, 2022
9350ceb
Refactor ValidateBasic for ExtendedCommitSig for legibility
thanethomson May 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 31 additions & 11 deletions internal/blocksync/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,16 +200,20 @@ func (pool *BlockPool) IsCaughtUp() bool {
return pool.height >= (pool.maxPeerHeight - 1)
}

// PeekTwoBlocks returns blocks at pool.height and pool.height+1.
// We need to see the second block's Commit to validate the first block.
// So we peek two blocks at a time.
// PeekTwoBlocks returns blocks at pool.height and pool.height+1. We need to
// see the second block's Commit to validate the first block. So we peek two
// blocks at a time. We return an extended commit, containing vote extensions
// and their associated signatures, as this is critical to consensus in ABCI++
// as we switch from block sync to consensus mode.
//
// The caller will verify the commit.
func (pool *BlockPool) PeekTwoBlocks() (first *types.Block, second *types.Block) {
func (pool *BlockPool) PeekTwoBlocks() (first, second *types.Block, firstExtCommit *types.ExtendedCommit) {
pool.mtx.RLock()
defer pool.mtx.RUnlock()

if r := pool.requesters[pool.height]; r != nil {
first = r.getBlock()
firstExtCommit = r.getExtendedCommit()
}
if r := pool.requesters[pool.height+1]; r != nil {
second = r.getBlock()
Expand All @@ -218,7 +222,8 @@ func (pool *BlockPool) PeekTwoBlocks() (first *types.Block, second *types.Block)
}

// PopRequest pops the first block at pool.height.
// It must have been validated by 'second'.Commit from PeekTwoBlocks().
// It must have been validated by the second Commit from PeekTwoBlocks.
// TODO(thane): (?) and its corresponding ExtendedCommit.
func (pool *BlockPool) PopRequest() {
pool.mtx.Lock()
defer pool.mtx.Unlock()
Expand Down Expand Up @@ -264,10 +269,15 @@ func (pool *BlockPool) RedoRequest(height int64) types.NodeID {

// AddBlock validates that the block comes from the peer it was expected from and calls the requester to store it.
thanethomson marked this conversation as resolved.
Show resolved Hide resolved
// TODO: ensure that blocks come in order for each peer.
func (pool *BlockPool) AddBlock(peerID types.NodeID, block *types.Block, blockSize int) {
func (pool *BlockPool) AddBlock(peerID types.NodeID, block *types.Block, extCommit *types.ExtendedCommit, blockSize int) {
pool.mtx.Lock()
defer pool.mtx.Unlock()

if block.Height != extCommit.Height {
pool.logger.Error("heights don't match, not adding block", "block_height", block.Height, "commit_height", extCommit.Height)
thanethomson marked this conversation as resolved.
Show resolved Hide resolved
return
}

requester := pool.requesters[block.Height]
if requester == nil {
pool.logger.Error("peer sent us a block we didn't expect",
Expand All @@ -282,7 +292,7 @@ func (pool *BlockPool) AddBlock(peerID types.NodeID, block *types.Block, blockSi
return
}

if requester.setBlock(block, peerID) {
if requester.setBlock(block, extCommit, peerID) {
atomic.AddInt32(&pool.numPending, -1)
peer := pool.peers[peerID]
if peer != nil {
Expand Down Expand Up @@ -456,6 +466,7 @@ func (pool *BlockPool) debug() string {
} else {
str += fmt.Sprintf("H(%v):", h)
str += fmt.Sprintf("B?(%v) ", pool.requesters[h].block != nil)
str += fmt.Sprintf("C?(%v) ", pool.requesters[h].extCommit != nil)
}
}
return str
Expand Down Expand Up @@ -544,9 +555,10 @@ type bpRequester struct {
gotBlockCh chan struct{}
redoCh chan types.NodeID // redo may send multitime, add peerId to identify repeat

mtx sync.Mutex
peerID types.NodeID
block *types.Block
mtx sync.Mutex
peerID types.NodeID
block *types.Block
extCommit *types.ExtendedCommit
}

func newBPRequester(logger log.Logger, pool *BlockPool, height int64) *bpRequester {
Expand All @@ -572,13 +584,14 @@ func (bpr *bpRequester) OnStart(ctx context.Context) error {
func (*bpRequester) OnStop() {}

// Returns true if the peer matches and block doesn't already exist.
func (bpr *bpRequester) setBlock(block *types.Block, peerID types.NodeID) bool {
func (bpr *bpRequester) setBlock(block *types.Block, extCommit *types.ExtendedCommit, peerID types.NodeID) bool {
bpr.mtx.Lock()
if bpr.block != nil || bpr.peerID != peerID {
bpr.mtx.Unlock()
return false
}
bpr.block = block
bpr.extCommit = extCommit
bpr.mtx.Unlock()

select {
Expand All @@ -594,6 +607,12 @@ func (bpr *bpRequester) getBlock() *types.Block {
return bpr.block
}

func (bpr *bpRequester) getExtendedCommit() *types.ExtendedCommit {
bpr.mtx.Lock()
defer bpr.mtx.Unlock()
return bpr.extCommit
}

func (bpr *bpRequester) getPeerID() types.NodeID {
bpr.mtx.Lock()
defer bpr.mtx.Unlock()
Expand All @@ -611,6 +630,7 @@ func (bpr *bpRequester) reset() {

bpr.peerID = ""
bpr.block = nil
bpr.extCommit = nil
}

// Tells bpRequester to pick another peer and try again.
Expand Down
9 changes: 6 additions & 3 deletions internal/blocksync/pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ func (p testPeer) runInputRoutine() {
// Request desired, pretend like we got the block immediately.
func (p testPeer) simulateInput(input inputData) {
block := &types.Block{Header: types.Header{Height: input.request.Height}}
input.pool.AddBlock(input.request.PeerID, block, 123)
var blockID types.BlockID
var extCommitSigs []types.ExtendedCommitSig
extCommit := types.NewExtendedCommit(input.request.Height, 0, blockID, extCommitSigs)
input.pool.AddBlock(input.request.PeerID, block, extCommit, 123)
// TODO: uncommenting this creates a race which is detected by:
// https://github.com/golang/go/blob/2bd767b1022dd3254bcec469f0ee164024726486/src/testing/testing.go#L854-L856
// see: https://github.com/tendermint/tendermint/issues/3390#issue-418379890
Expand Down Expand Up @@ -110,7 +113,7 @@ func TestBlockPoolBasic(t *testing.T) {
if !pool.IsRunning() {
return
}
first, second := pool.PeekTwoBlocks()
first, second, _ := pool.PeekTwoBlocks()
thanethomson marked this conversation as resolved.
Show resolved Hide resolved
if first != nil && second != nil {
pool.PopRequest()
} else {
Expand Down Expand Up @@ -164,7 +167,7 @@ func TestBlockPoolTimeout(t *testing.T) {
if !pool.IsRunning() {
return
}
first, second := pool.PeekTwoBlocks()
first, second, _ := pool.PeekTwoBlocks()
if first != nil && second != nil {
pool.PopRequest()
} else {
Expand Down
50 changes: 41 additions & 9 deletions internal/blocksync/reactor.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ type Reactor struct {
stateStore sm.Store

blockExec *sm.BlockExecutor
store *store.BlockStore
store sm.BlockStore
thanethomson marked this conversation as resolved.
Show resolved Hide resolved
pool *BlockPool
consReactor consensusReactor
blockSync *atomicBool
Expand Down Expand Up @@ -186,15 +186,23 @@ func (r *Reactor) OnStop() {
func (r *Reactor) respondToPeer(ctx context.Context, msg *bcproto.BlockRequest, peerID types.NodeID, blockSyncCh *p2p.Channel) error {
block := r.store.LoadBlock(msg.Height)
if block != nil {
extCommit := r.store.LoadBlockExtCommit(msg.Height)
if extCommit == nil {
r.logger.Error("peer requesting a block; we have the block but not its extended commit (%v)", block)
thanethomson marked this conversation as resolved.
Show resolved Hide resolved
return fmt.Errorf("blockstore has block but not extended commit %v", block)
}
blockProto, err := block.ToProto()
if err != nil {
r.logger.Error("failed to convert msg to protobuf", "err", err)
r.logger.Error("failed to convert block to protobuf", "err", err)
thanethomson marked this conversation as resolved.
Show resolved Hide resolved
return err
}

return blockSyncCh.Send(ctx, p2p.Envelope{
To: peerID,
Message: &bcproto.BlockResponse{Block: blockProto},
To: peerID,
Message: &bcproto.BlockResponse{
Block: blockProto,
ExtCommit: extCommit.ToProto(),
},
})
}

Expand Down Expand Up @@ -236,8 +244,15 @@ func (r *Reactor) handleMessage(ctx context.Context, envelope *p2p.Envelope, blo
"err", err)
return err
}
extCommit, err := types.ExtendedCommitFromProto(msg.ExtCommit)
if err != nil {
r.logger.Error("failed to convert extended commit from proto",
"peer", envelope.From,
"err", err)
return err
}

r.pool.AddBlock(envelope.From, block, block.Size())
r.pool.AddBlock(envelope.From, block, extCommit, block.Size())

case *bcproto.StatusRequest:
return blockSyncCh.Send(ctx, p2p.Envelope{
Expand Down Expand Up @@ -448,6 +463,19 @@ func (r *Reactor) poolRoutine(ctx context.Context, stateSynced bool, blockSyncCh
)

switch {
//case state.LastBlockHeight > 0 && r.store.LoadBlockExtCommit(state.LastBlockHeight) == nil:
thanethomson marked this conversation as resolved.
Show resolved Hide resolved
case state.LastBlockHeight > 0 && blocksSynced == 0:
//If we have state-synced, we need to blocksync at least one block
thanethomson marked this conversation as resolved.
Show resolved Hide resolved
r.logger.Info(
"no seen commit yet",
"height", height,
"last_block_height", state.LastBlockHeight,
"initial_height", state.InitialHeight,
"max_peer_height", r.pool.MaxPeerHeight(),
"timeout_in", syncTimeout-time.Since(lastAdvance),
)
continue

case r.pool.IsCaughtUp():
r.logger.Info("switching to consensus reactor", "height", height)

Expand Down Expand Up @@ -490,9 +518,12 @@ func (r *Reactor) poolRoutine(ctx context.Context, stateSynced bool, blockSyncCh
// TODO: Uncouple from request routine.

// see if there are any blocks to sync
first, second := r.pool.PeekTwoBlocks()
if first == nil || second == nil {
// we need both to sync the first block
first, second, extCommit := r.pool.PeekTwoBlocks()
if first == nil || second == nil || extCommit == nil {
if first != nil && extCommit == nil {
r.logger.Error("peeked a block without extended commit", "height", first.Height)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this really an error?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is in the current version of the solution. A received block in block sync interactions must always contain an extended commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that we should always have extended commits, should there not be some consequence somewhere for this? Or is logging the issue sufficient? I suppose it makes sense to have this as informational if some other routine will pick up on the fact that the relevant extended commit is missing and panic/error out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we hit this line, there is obviously a bug somewhere else in this reactor (probably in PeekTwoBlocks). I decided to just log an error an not panic because we can recover from this, but I wouldn't be against a panic since the values we get from PeekTwoBlocks are totally under our control.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, not having the first or the second is not an error (we simply might not have yet received a block at that height). However, having a block and no extended commit is an error. PeekTwoBlocks is supposed to just read whatever is in the store. So if there is an error here, it should be in incorrectly stored blocks, not a bug. What will happen here is still ok, we will try to read the same block again. But I also think that, if we end up in this situation, there is something wrong with Tendermint or there are inconsistencies in the data, no?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jmalicevic, I think I agree with you.
Are you suggesting panic'ing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think panicing is the right option. Or we ask another peer for that same block. But in that case we still have a node with corrupted data. In my opinion we either panic or find a way to fix this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated this to panic instead of just logging the error: 9483b42

}
// we need all to sync the first block
continue
} else {
// try again quickly next loop
Expand All @@ -517,6 +548,7 @@ func (r *Reactor) poolRoutine(ctx context.Context, stateSynced bool, blockSyncCh
// NOTE: We can probably make this more efficient, but note that calling
// first.Hash() doesn't verify the tx contents, so MakePartSet() is
// currently necessary.
// TODO Should we also validate against the extended commit?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The light client verification doesn't rely on the extended commits, so I don't see this being necessary. Maybe I'm missing something?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The point of that TODO is that, now, we have two commits we can use for verification:

  • the commit inside second
  • the extended commit that came along with first
    So we could be extra-careful and validate against both, by calling VerifyCommitLight twice: once with each commit that we have. This is for the über-anxious like myself :-)
    I would like to have @jmalicevic's input here, as she's the one really looking into this aspect.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@williambanfield are you saying that we do not really care about whether the extended commit provided to us passes validation as we will not need it? If so, if this block is the last one before we switch to consensus, we do want to verify it, no? If you agree with my first sentence, then maybe it is not necessary to verify every extended commit but I somehow feel we do want to verify it before switching back to consensus (except, right now we do not now this at the point of verification here, so we'd have to introduce a check elsewhere).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh! I see, then I misunderstood. I was thinking this meant we should use the ExtendedCommit to validate the header, (which didn't seem necessary since we already do the call to VerifyLightCommit) but it seems like the intent is sort of the reverse, use the validated header (and LastCommit) to ensure that the ExtendedCommit is correct. That seems great to me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jmalicevic, would you agree on taking on this TODO on your side? (which also means deciding how to tackle it)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sergio-mena sure, I think it makes sense to include it as part of the verification work

if err = state.Validators.VerifyCommitLight(chainID, firstID, first.Height, second.LastCommit); err != nil {
err = fmt.Errorf("invalid last commit: %w", err)
r.logger.Error(
Expand Down Expand Up @@ -549,7 +581,7 @@ func (r *Reactor) poolRoutine(ctx context.Context, stateSynced bool, blockSyncCh
r.pool.PopRequest()

// TODO: batch saves so we do not persist to disk every block
r.store.SaveBlock(first, firstParts, second.LastCommit)
r.store.SaveBlock(first, firstParts, extCommit)

var err error

Expand Down
52 changes: 28 additions & 24 deletions internal/blocksync/reactor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,39 +147,43 @@ func (rts *reactorTestSuite) addNode(
sm.NopMetrics(),
)

var lastExtCommit *types.ExtendedCommit

// The commit we are building for the current height.
seenExtCommit := types.NewExtendedCommit(0, 0, types.BlockID{}, nil)

for blockHeight := int64(1); blockHeight <= maxBlockHeight; blockHeight++ {
lastCommit := types.NewCommit(blockHeight-1, 0, types.BlockID{}, nil)

if blockHeight > 1 {
lastBlockMeta := blockStore.LoadBlockMeta(blockHeight - 1)
lastBlock := blockStore.LoadBlock(blockHeight - 1)

vote, err := factory.MakeVote(
ctx,
privVal,
lastBlock.Header.ChainID, 0,
lastBlock.Header.Height, 0, 2,
lastBlockMeta.BlockID,
time.Now(),
)
require.NoError(t, err)
lastCommit = types.NewCommit(
vote.Height,
vote.Round,
lastBlockMeta.BlockID,
[]types.CommitSig{vote.CommitSig()},
)
}
lastExtCommit = seenExtCommit.Copy()

thisBlock := sf.MakeBlock(state, blockHeight, lastCommit)
thisBlock := sf.MakeBlock(state, blockHeight, lastExtCommit.StripExtensions())
thisParts, err := thisBlock.MakePartSet(types.BlockPartSizeBytes)
require.NoError(t, err)
blockID := types.BlockID{Hash: thisBlock.Hash(), PartSetHeader: thisParts.Header()}

// Simulate a commit for the current height
vote, err := factory.MakeVote(
ctx,
privVal,
thisBlock.Header.ChainID,
0,
thisBlock.Header.Height,
0,
2,
blockID,
time.Now(),
)
require.NoError(t, err)
seenExtCommit = types.NewExtendedCommit(
vote.Height,
vote.Round,
blockID,
[]types.ExtendedCommitSig{vote.ExtendedCommitSig()},
)
thanethomson marked this conversation as resolved.
Show resolved Hide resolved

state, err = blockExec.ApplyBlock(ctx, state, blockID, thisBlock)
require.NoError(t, err)

blockStore.SaveBlock(thisBlock, thisParts, lastCommit)
blockStore.SaveBlock(thisBlock, thisParts, seenExtCommit)
thanethomson marked this conversation as resolved.
Show resolved Hide resolved
thanethomson marked this conversation as resolved.
Show resolved Hide resolved
}

rts.peerChans[nodeID] = make(chan p2p.PeerUpdate)
Expand Down
10 changes: 5 additions & 5 deletions internal/consensus/byzantine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,22 +178,22 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
lazyNodeState.decideProposal = func(ctx context.Context, height int64, round int32) {
require.NotNil(t, lazyNodeState.privValidator)

var commit *types.Commit
var commit *types.ExtendedCommit
switch {
case lazyNodeState.Height == lazyNodeState.state.InitialHeight:
// We're creating a proposal for the first block.
// The commit is empty, but not nil.
commit = types.NewCommit(0, 0, types.BlockID{}, nil)
commit = types.NewExtendedCommit(0, 0, types.BlockID{}, nil)
case lazyNodeState.LastCommit.HasTwoThirdsMajority():
// Make the commit from LastCommit
commit = lazyNodeState.LastCommit.MakeCommit()
commit = lazyNodeState.LastCommit.MakeExtendedCommit()
default: // This shouldn't happen.
lazyNodeState.logger.Error("enterPropose: Cannot propose anything: No commit for the previous block")
return
}

// omit the last signature in the commit
commit.Signatures[len(commit.Signatures)-1] = types.NewCommitSigAbsent()
commit.ExtendedSignatures[len(commit.ExtendedSignatures)-1] = types.NewExtendedCommitSigAbsent()

if lazyNodeState.privValidatorPubKey == nil {
// If this node is a validator & proposer in the current round, it will
Expand All @@ -204,7 +204,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
proposerAddr := lazyNodeState.privValidatorPubKey.Address()

block, err := lazyNodeState.blockExec.CreateProposalBlock(
ctx, lazyNodeState.Height, lazyNodeState.state, commit, proposerAddr, lazyNodeState.LastCommit.GetVotes())
ctx, lazyNodeState.Height, lazyNodeState.state, commit, proposerAddr)
require.NoError(t, err)
blockParts, err := block.MakePartSet(types.BlockPartSizeBytes)
require.NoError(t, err)
Expand Down
6 changes: 3 additions & 3 deletions internal/consensus/reactor.go
Original file line number Diff line number Diff line change
Expand Up @@ -794,10 +794,10 @@ func (r *Reactor) gossipVotesRoutine(ctx context.Context, ps *PeerState, voteCh
// catchup logic -- if peer is lagging by more than 1, send Commit
blockStoreBase := r.state.blockStore.Base()
if blockStoreBase > 0 && prs.Height != 0 && rs.Height >= prs.Height+2 && prs.Height >= blockStoreBase {
// Load the block commit for prs.Height, which contains precommit
// Load the block's extended commit for prs.Height, which contains precommit
// signatures for prs.Height.
if commit := r.state.blockStore.LoadBlockCommit(prs.Height); commit != nil {
if ok, err := r.pickSendVote(ctx, ps, commit, voteCh); err != nil {
if extCommit := r.state.blockStore.LoadBlockExtCommit(prs.Height); extCommit != nil {
if ok, err := r.pickSendVote(ctx, ps, extCommit, voteCh); err != nil {
thanethomson marked this conversation as resolved.
Show resolved Hide resolved
return
} else if ok {
logger.Debug("picked Catchup commit to send", "height", prs.Height)
Expand Down
Loading