Skip to content

Commit 925b4d3

Browse files
committed
Panic when own checkpoint differs from weak cert
Change-Id: I4ce07658b1ee63756fdd113c1713d9cf411180ff Signed-off-by: Kostas Christidis <[email protected]>
1 parent ce13868 commit 925b4d3

File tree

2 files changed

+22
-31
lines changed

2 files changed

+22
-31
lines changed

consensus/pbft/pbft-core.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,14 @@ func (instance *pbftCore) recvCheckpoint(chkpt *Checkpoint) events.Event {
11701170
instance.id, matching, chkpt.SequenceNumber, chkpt.Id)
11711171

11721172
if matching == instance.f+1 {
1173-
// We do have a weak cert
1173+
// We have a weak cert
1174+
// If we have generated a checkpoint for this seqNo, make sure we have a match
1175+
if ownChkptID, ok := instance.chkpts[chkpt.SequenceNumber]; ok {
1176+
if ownChkptID != chkpt.Id {
1177+
logger.Panicf("Own checkpoint for seqNo %d (%s) different from weak checkpoint certificate (%s)",
1178+
chkpt.SequenceNumber, ownChkptID, chkpt.Id)
1179+
}
1180+
}
11741181
instance.witnessCheckpointWeakCert(chkpt)
11751182
}
11761183

@@ -1187,8 +1194,7 @@ func (instance *pbftCore) recvCheckpoint(chkpt *Checkpoint) events.Event {
11871194
// we have reached this checkpoint
11881195
// Note, this is not divergent from the paper, as the paper requires that
11891196
// the quorum certificate must contain 2f+1 messages, including its own
1190-
chkptID, ok := instance.chkpts[chkpt.SequenceNumber]
1191-
if !ok {
1197+
if _, ok := instance.chkpts[chkpt.SequenceNumber]; !ok {
11921198
logger.Debugf("Replica %d found checkpoint quorum for seqNo %d, digest %s, but it has not reached this checkpoint itself yet",
11931199
instance.id, chkpt.SequenceNumber, chkpt.Id)
11941200
if instance.skipInProgress {
@@ -1206,12 +1212,6 @@ func (instance *pbftCore) recvCheckpoint(chkpt *Checkpoint) events.Event {
12061212
logger.Debugf("Replica %d found checkpoint quorum for seqNo %d, digest %s",
12071213
instance.id, chkpt.SequenceNumber, chkpt.Id)
12081214

1209-
if chkptID != chkpt.Id {
1210-
logger.Criticalf("Replica %d generated a checkpoint of %s, but a quorum of the network agrees on %s. This is almost definitely non-deterministic chaincode.",
1211-
instance.id, chkptID, chkpt.Id)
1212-
instance.stateTransfer(nil)
1213-
}
1214-
12151215
instance.moveWatermarks(chkpt.SequenceNumber)
12161216

12171217
return instance.processNewView()

consensus/pbft/pbft-core_test.go

+13-22
Original file line numberDiff line numberDiff line change
@@ -1751,42 +1751,33 @@ func TestStateNetworkMovesOnDuringSlowStateTransfer(t *testing.T) {
17511751
}
17521752
}
17531753

1754-
// This test is designed to ensure state transfer occurs if our checkpoint does not match a quorum cert
1755-
func TestCheckpointDiffersFromQuorum(t *testing.T) {
1756-
invalidated := false
1757-
skipped := false
1758-
instance := newPbftCore(3, loadConfig(), &omniProto{
1759-
invalidateStateImpl: func() { invalidated = true },
1760-
skipToImpl: func(s uint64, id []byte, replicas []uint64) { skipped = true },
1761-
}, &inertTimerFactory{})
1754+
// This test is designed to ensure the peer panics if the value of the weak cert is different from its own checkpoint
1755+
func TestCheckpointDiffersFromWeakCert(t *testing.T) {
1756+
defer func() {
1757+
if r := recover(); r == nil {
1758+
t.Errorf("Weak checkpoint certificate different from own, should have panicked.")
1759+
}
1760+
}()
17621761

1763-
seqNo := uint64(10)
1762+
instance := newPbftCore(3, loadConfig(), &omniProto{}, &inertTimerFactory{})
17641763

17651764
badChkpt := &Checkpoint{
17661765
SequenceNumber: 10,
17671766
Id: base64.StdEncoding.EncodeToString([]byte("WRONG")),
1768-
ReplicaId: 0,
1767+
ReplicaId: 3,
17691768
}
1770-
instance.chkpts[seqNo] = badChkpt.Id // This is done via the exec path, shortcut it here
1769+
instance.chkpts[10] = badChkpt.Id // This is done via the exec path, shortcut it here
17711770
events.SendEvent(instance, badChkpt)
17721771

1773-
for i := uint64(1); i <= 3; i++ {
1772+
for i := uint64(0); i < 2; i++ {
17741773
events.SendEvent(instance, &Checkpoint{
17751774
SequenceNumber: 10,
17761775
Id: base64.StdEncoding.EncodeToString([]byte("CORRECT")),
17771776
ReplicaId: i,
17781777
})
17791778
}
17801779

1781-
if instance.h != 10 {
1782-
t.Fatalf("Replica should have moved its watermarks but did not")
1783-
}
1784-
1785-
if !instance.skipInProgress {
1786-
t.Fatalf("Replica should be attempting state transfer")
1787-
}
1788-
1789-
if !invalidated || !skipped {
1790-
t.Fatalf("Replica should have invalidated its state and skipped")
1780+
if instance.highStateTarget != nil {
1781+
t.Fatalf("State target should not have been updated")
17911782
}
17921783
}

0 commit comments

Comments
 (0)