Skip to content

Commit 134292d

Browse files
authored
prevCommitSignatures is added to the prePrepare message only when leader rotation is on (#599)
Signed-off-by: Fedor Partanskiy <[email protected]>
1 parent 2aa7f87 commit 134292d

File tree

2 files changed

+95
-1
lines changed

2 files changed

+95
-1
lines changed

internal/bft/view.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,10 @@ func (v *View) metadataWithUpdatedBlacklist(metadata *protos.ViewMetadata, verif
949949

950950
// Propose broadcasts a prePrepare message with the given proposal
951951
func (v *View) Propose(proposal types.Proposal) {
952-
_, prevSigs := v.RetrieveCheckpoint()
952+
var prevSigs []*protos.Signature
953+
if v.DecisionsPerLeader > 0 {
954+
_, prevSigs = v.RetrieveCheckpoint()
955+
}
953956

954957
seq := v.ProposalSequence
955958
msg := &protos.Message{

internal/bft/view_test.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,97 @@ func TestViewBasic(t *testing.T) {
145145
view.Abort()
146146
}
147147

148+
func TestPrePrepareAndPrevCommits(t *testing.T) {
149+
for _, testCase := range []struct {
150+
description string
151+
decisionsPerLeader uint64
152+
expectedCall int
153+
}{
154+
{
155+
description: "sent with leaderRotation is off",
156+
decisionsPerLeader: 0,
157+
expectedCall: 0,
158+
},
159+
{
160+
description: "sent with leaderRotation is on",
161+
decisionsPerLeader: 1,
162+
expectedCall: 3,
163+
},
164+
} {
165+
t.Run(testCase.description, func(t *testing.T) {
166+
basicLog, err := zap.NewDevelopment()
167+
assert.NoError(t, err)
168+
log := basicLog.Sugar()
169+
comm := &mocks.CommMock{}
170+
commWG := sync.WaitGroup{}
171+
comm.On("BroadcastConsensus", mock.Anything).Run(func(args mock.Arguments) {
172+
commWG.Done()
173+
})
174+
decider := &mocks.Decider{}
175+
deciderWG := sync.WaitGroup{}
176+
decidedProposal := make(chan types.Proposal)
177+
decidedSigs := make(chan []types.Signature)
178+
decider.On("Decide", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
179+
deciderWG.Done()
180+
proposal, _ := args.Get(0).(types.Proposal)
181+
decidedProposal <- proposal
182+
sigs, _ := args.Get(1).([]types.Signature)
183+
decidedSigs <- sigs
184+
})
185+
verifier := &mocks.VerifierMock{}
186+
verifier.On("VerificationSequence").Return(uint64(1))
187+
verifier.On("VerifyProposal", mock.Anything, mock.Anything).Return(nil, nil)
188+
verifier.On("VerifyConsenterSig", mock.Anything, mock.Anything).Return(nil, nil)
189+
verifier.On("VerifySignature", mock.Anything).Return(nil)
190+
verifier.On("AuxiliaryData", mock.Anything).Return(nil)
191+
signer := &mocks.SignerMock{}
192+
signer.On("SignProposal", mock.Anything, mock.Anything).Return(&types.Signature{
193+
ID: 4,
194+
Value: []byte{4},
195+
})
196+
viewSeq := &atomic.Value{}
197+
state := &bft.StateRecorder{}
198+
cp := &types.Checkpoint{}
199+
view := &bft.View{
200+
RetrieveCheckpoint: cp.Get,
201+
DecisionsPerLeader: testCase.decisionsPerLeader,
202+
State: state,
203+
Logger: log,
204+
N: 4,
205+
NodesList: []uint64{1, 2, 3, 4},
206+
LeaderID: 1,
207+
SelfID: 1,
208+
Quorum: 3,
209+
Number: 1,
210+
ProposalSequence: 0,
211+
Comm: comm,
212+
Decider: decider,
213+
Verifier: verifier,
214+
Signer: signer,
215+
ViewSequences: viewSeq,
216+
InMsgQSize: 40,
217+
MetricsView: api.NewMetricsView(&disabled.Provider{}),
218+
MetricsBlacklist: api.NewMetricsBlacklist(&disabled.Provider{}),
219+
}
220+
view.Start()
221+
222+
commWG.Add(2)
223+
proposal1 := proposal
224+
proposal1.Metadata = bft.MarshalOrPanic(&protos.ViewMetadata{
225+
LatestSequence: 0,
226+
ViewId: 1,
227+
PrevCommitSignatureDigest: bft.CommitSignaturesDigest([]*protos.Signature{{Signer: 1}, {Signer: 2}, {Signer: 3}}),
228+
})
229+
cp.Set(proposal1, []types.Signature{{ID: 1}, {ID: 2}, {ID: 3}})
230+
view.Propose(proposal1)
231+
commWG.Wait()
232+
233+
verifier.AssertNumberOfCalls(t, "VerifyConsenterSig", testCase.expectedCall)
234+
view.Abort()
235+
})
236+
}
237+
}
238+
148239
func TestBadPrePrepare(t *testing.T) {
149240
// Ensure that a prePrepare with a wrong view number sent by the leader causes a view abort,
150241
// and that if the same message is from a follower then it is simply ignored.

0 commit comments

Comments
 (0)