Skip to content

Commit 038c3e0

Browse files
committed
Check membership of checkpoint correctly and log huge warning if ISS module cannot locally check (for now, see consensus-shipyard#402)
1 parent 5ef68d4 commit 038c3e0

File tree

1 file changed

+25
-13
lines changed

1 file changed

+25
-13
lines changed

pkg/iss/iss.go

+25-13
Original file line numberDiff line numberDiff line change
@@ -417,12 +417,31 @@ func New(
417417
Cert: cert,
418418
}
419419
chkp := checkpoint.StableCheckpointFromPb(_chkp.Pb())
420-
// TODO: Technically this is wrong.
421-
// The memberhips information in the checkpint is used to verify the checkpoint itself.
422-
// This makes it possible to construct an arbitrary valid checkpoint.
423-
// Use an independent local source of memberhip information instead.
424-
if err := chkp.VerifyCert(iss.hashImpl, iss.chkpVerifier, chkp.PreviousMembership()); err != nil {
425-
iss.logger.Log(logging.LevelWarn, "Ignoring stable checkpoint. Certificate don walid.",
420+
chkpMembershipOffset := int(chkp.Epoch()) - 1 - int(iss.epoch.Nr())
421+
422+
// Check how far the received stable checkpoint is ahead of the local node's state.
423+
if chkpMembershipOffset <= 0 {
424+
// Ignore stable checkpoints that are not far enough
425+
// ahead of the current state of the local node.
426+
return nil
427+
}
428+
429+
chkpMembership := chkp.PreviousMembership() // TODO this is wrong and it is a vulnerability, come back to fix after discussion (issue #384)
430+
if chkpMembershipOffset > iss.Params.ConfigOffset {
431+
// cannot verify checkpoint signatures, too far ahead
432+
// TODO here we should externalize verification/decision to dedicated module (issue #402)
433+
iss.logger.Log(logging.LevelWarn, "-----------------------------------------------------\n",
434+
"ATTENTION: cannot verify membership of checkpoint, too far ahead, proceed with caution\n",
435+
"-----------------------------------------------------\n",
436+
"localEpoch", iss.epoch.Nr(),
437+
"chkpEpoch", chkp.Epoch(),
438+
"configOffset", iss.Params.ConfigOffset,
439+
)
440+
} else {
441+
chkpMembership = iss.memberships[chkpMembershipOffset]
442+
}
443+
if err := chkp.VerifyCert(iss.hashImpl, iss.chkpVerifier, chkpMembership); err != nil {
444+
iss.logger.Log(logging.LevelWarn, "Ignoring stable checkpoint. Certificate not valid.",
426445
"localEpoch", iss.epoch.Nr(),
427446
"chkpEpoch", chkp.Epoch(),
428447
)
@@ -437,13 +456,6 @@ func New(
437456
return nil
438457
}
439458

440-
// Check how far the received stable checkpoint is ahead of the local node's state.
441-
if chkp.Epoch() <= iss.epoch.Nr()+1 {
442-
// Ignore stable checkpoints that are not far enough
443-
// ahead of the current state of the local node.
444-
return nil
445-
}
446-
447459
// Deserialize received leader selection policy. If deserialization fails, ignore the whole message.
448460
result, err := lsp.LeaderPolicyFromBytes(chkp.Snapshot.EpochData.LeaderPolicy)
449461
if err != nil {

0 commit comments

Comments
 (0)