Skip to content

Commit 3cefcdd

Browse files
committed
checkIsLeader should consider OCert validity
This commit adds a verification, during our leader check, that we have an operational cert which is valid for the current KES period. Previously, if the OCert was not valid, two things could happen (depending on the crypto implementation): - An error would be thrown during signing, or - A block would be generated and subsequently rejected by the validation logic. Now instead we skip any slots where we would otherwise be the leader but for an invalid operational certificiate. It would probably be nice to log this in the future.
1 parent deda980 commit 3cefcdd

File tree

1 file changed

+18
-2
lines changed
  • ouroboros-consensus-shelley/src/Ouroboros/Consensus/Shelley

1 file changed

+18
-2
lines changed

ouroboros-consensus-shelley/src/Ouroboros/Consensus/Shelley/Protocol.hs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ import qualified Cardano.Crypto.VRF.Class as VRF
5757
import Cardano.Prelude (Natural, NoUnexpectedThunks (..))
5858
import Cardano.Slotting.EpochInfo
5959

60-
import Ouroboros.Network.Block (pointSlot)
60+
import Ouroboros.Network.Block (pointSlot, unSlotNo)
6161

6262
import Ouroboros.Consensus.Ledger.Abstract
6363
import qualified Ouroboros.Consensus.Node.State as NodeState
@@ -334,6 +334,19 @@ instance TPraosCrypto c => ConsensusProtocol (TPraos c) where
334334
TPraosIsNotACoreNode -> return Nothing
335335
TPraosIsACoreNode isACoreNode -> go isACoreNode
336336
where
337+
338+
-- | Check whether we have an operational certificate valid for the
339+
-- current KES period.
340+
hasValidOCert :: TPraosIsCoreNode c -> Bool
341+
hasValidOCert TPraosIsCoreNode{tpraosIsCoreNodeOpCert} =
342+
kesPeriod > c0 && kesPeriod < c1
343+
where
344+
SL.OCert _ _ (SL.KESPeriod c0) _ = tpraosIsCoreNodeOpCert
345+
c1 = c0 + fromIntegral (tpraosMaxKESEvo tpraosParams)
346+
-- The current KES period
347+
kesPeriod = fromIntegral $
348+
unSlotNo slot `div` tpraosSlotsPerKESPeriod tpraosParams
349+
337350
go :: MonadRandom m => TPraosIsCoreNode c -> m (Maybe (TPraosProof c))
338351
go icn = do
339352
let TPraosIsCoreNode {
@@ -351,6 +364,7 @@ instance TPraosCrypto c => ConsensusProtocol (TPraos c) where
351364
return $ case Map.lookup slot (SL.lvOverlaySched lv) of
352365
Nothing
353366
| meetsLeaderThreshold cfg lv (SL.coerceKeyRole vkhCold) y
367+
, hasValidOCert icn
354368
-- Slot isn't in the overlay schedule, so we're in Praos
355369
-> Just TPraosProof {
356370
tpraosEta = coerce rho
@@ -366,7 +380,9 @@ instance TPraosCrypto c => ConsensusProtocol (TPraos c) where
366380
-- The given genesis key has authority to produce a block in this
367381
-- slot. Check whether we're its delegate.
368382
Just (SL.ActiveSlot gkhash) -> case Map.lookup gkhash dlgMap of
369-
Just dlgHash | SL.coerceKeyRole dlgHash == vkhCold
383+
Just dlgHash
384+
| SL.coerceKeyRole dlgHash == vkhCold
385+
, hasValidOCert icn
370386
-> Just TPraosProof {
371387
tpraosEta = coerce rho
372388
-- Note that this leader value is not checked for slots in

0 commit comments

Comments
 (0)