Skip to content

Commit

Permalink
consensus: store EBB header hash bytes in PBFT ChainState
Browse files Browse the repository at this point in the history
  • Loading branch information
nfrisby committed Jan 6, 2020
1 parent 40d70cb commit 36c8ab2
Show file tree
Hide file tree
Showing 12 changed files with 419 additions and 185 deletions.
1 change: 1 addition & 0 deletions ouroboros-consensus/ouroboros-consensus.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ library
Ouroboros.Consensus.Protocol.ModChainSel
Ouroboros.Consensus.Protocol.PBFT
Ouroboros.Consensus.Protocol.PBFT.ChainState
Ouroboros.Consensus.Protocol.PBFT.ChainState.HeaderHashBytes
Ouroboros.Consensus.Protocol.PBFT.Crypto
Ouroboros.Consensus.Protocol.Praos
Ouroboros.Consensus.Protocol.Signed
Expand Down
16 changes: 8 additions & 8 deletions ouroboros-consensus/src/Ouroboros/Consensus/ChainSyncClient.hs
Original file line number Diff line number Diff line change
Expand Up @@ -329,10 +329,10 @@ chainSyncClient mkPipelineDecision0 tracer cfg btime
-- it is followed by rolling forward again), but we need some
-- guarantees that the ChainSync protocol /does/ in fact give us a
-- switch-to-fork instead of a true rollback.
(theirFrag, theirChainState) <-
case (,) <$> AF.rollback (castPoint intersection) ourFrag
<*> rewindChainState cfg ourChainState (pointSlot intersection)
of
(theirFrag, theirChainState) <- do
let i = castPoint intersection
case (,) <$> AF.rollback i ourFrag
<*> rewindChainState cfg ourChainState i of
Just (c, d) -> return (c, d)
-- The @intersection@ is not on the candidate chain, even though
-- we sent only points from the candidate chain to find an
Expand Down Expand Up @@ -634,10 +634,10 @@ chainSyncClient mkPipelineDecision0 tracer cfg btime
, theirChainState
, ourTip
} -> traceException $ do
(theirFrag', theirChainState') <-
case (,) <$> AF.rollback (castPoint intersection) theirFrag
<*> rewindChainState cfg theirChainState (pointSlot intersection)
of
(theirFrag', theirChainState') <- do
let i = castPoint intersection
case (,) <$> AF.rollback i theirFrag
<*> rewindChainState cfg theirChainState i of
Just (c, d) -> return (c,d)
-- Remember that we use our current chain fragment as the starting
-- point for the candidate's chain. Our fragment contained @k@
Expand Down
19 changes: 7 additions & 12 deletions ouroboros-consensus/src/Ouroboros/Consensus/Protocol/Abstract.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ import GHC.Stack

import Cardano.Prelude (NoUnexpectedThunks)

import Ouroboros.Network.Block (HasHeader (..), SlotNo (..))
import Ouroboros.Network.Point (WithOrigin)
import Ouroboros.Network.Block (HasHeader (..), Point, SlotNo (..))

import Ouroboros.Consensus.BlockchainTime.SlotLengths
import Ouroboros.Consensus.Util.Random
Expand Down Expand Up @@ -188,10 +187,10 @@ class ( Show (ChainState p)
-- blocks.
--
-- This function should attempt to rewind the chain state to the state at some
-- given slot, or Origin to rewind to the state with no blocks.
-- given point.
--
-- PRECONDITION: the slot to rewind to must correspond to the slot of a
-- header (or 'Origin') that was previously applied to the chain state using
-- PRECONDITION: the point to rewind to must correspond to a header (or
-- 'GenesisPoint') that was previously applied to the chain state using
-- 'applyChainState'.
--
-- Rewinding the chain state is intended to be used when switching to a
Expand All @@ -206,14 +205,10 @@ class ( Show (ChainState p)
-- state). For example, rewinding a chain state by @i@ blocks and then
-- rewinding that chain state again by @j@ where @i + j > k@ is not possible
-- and will yield 'Nothing'.
rewindChainState :: NodeConfig p
rewindChainState :: CanValidate p hdr
=> NodeConfig p
-> ChainState p
-> WithOrigin SlotNo
-- ^ Slot to rewind to
--
-- This should be the state at the /end/ of the specified
-- slot (i.e., after the block in that slot, if any, has
-- been applied).
-> Point hdr -- ^ Point to rewind to
-> Maybe (ChainState p)

--
Expand Down
33 changes: 23 additions & 10 deletions ouroboros-consensus/src/Ouroboros/Consensus/Protocol/PBFT.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
Expand Down Expand Up @@ -39,6 +40,7 @@ import Control.Monad.Except
import Crypto.Random (MonadRandom)
import Data.Bimap (Bimap)
import qualified Data.Bimap as Bimap
import Data.Proxy (Proxy (..))
import qualified Data.Set as Set
import Data.Typeable (Typeable)
import Data.Word (Word64)
Expand All @@ -49,8 +51,10 @@ import qualified Cardano.Chain.Genesis as CC.Genesis
import Cardano.Crypto.DSIGN.Class
import Cardano.Prelude (NoUnexpectedThunks)

import Ouroboros.Network.Block (HasHeader (..), SlotNo (..))
import Ouroboros.Network.Point (WithOrigin (At))
import Ouroboros.Network.Block (pattern BlockPoint,
pattern GenesisPoint, HasHeader (..), HeaderHash, Point,
SlotNo (..))
import Ouroboros.Network.Point (WithOrigin (..))

import Ouroboros.Consensus.Block
import Ouroboros.Consensus.BlockchainTime
Expand All @@ -60,6 +64,8 @@ import Ouroboros.Consensus.NodeId (CoreNodeId (..))
import Ouroboros.Consensus.Protocol.Abstract
import Ouroboros.Consensus.Protocol.PBFT.ChainState (PBftChainState)
import qualified Ouroboros.Consensus.Protocol.PBFT.ChainState as CS
import Ouroboros.Consensus.Protocol.PBFT.ChainState.HeaderHashBytes
(headerHashBytes)
import Ouroboros.Consensus.Protocol.PBFT.Crypto
import Ouroboros.Consensus.Util.Condense
import Ouroboros.Consensus.Util.Orphans ()
Expand Down Expand Up @@ -91,6 +97,7 @@ instance (PBftCrypto c, Typeable toSign) => NoUnexpectedThunks (PBftFields c toS
-- epoch boundary blocks (EBBs), which are unsigned. Of course the intention
-- here is that 'headerPBftFields' will return 'Just' for regular blocks.
class ( HasHeader hdr
, Serialise (HeaderHash hdr)
, Signable (PBftDSIGN c) (OptSigned hdr)
, BlockProtocol hdr ~ PBft cfg c
) => HeaderSupportsPBft cfg c hdr where
Expand Down Expand Up @@ -244,7 +251,7 @@ instance ( PBftCrypto c
applyChainState cfg@PBftNodeConfig{..} lv@(PBftLedgerView dms) (b :: hdr) chainState =
case headerPBftFields pbftExtConfig b of
Nothing -> do
return $! appendEBB cfg params (blockSlot b) chainState
return $! appendEBB cfg params b chainState
Just (PBftFields{..}, signed) -> do
-- Check that the issuer signature verifies, and that it's a delegate of a
-- genesis key, and that genesis key hasn't voted too many times.
Expand Down Expand Up @@ -354,26 +361,32 @@ append PBftNodeConfig{..} PBftWindowParams{..} =
where
PBftParams{..} = pbftParams

appendEBB :: PBftCrypto c
appendEBB :: forall cfg c hdr.
(PBftCrypto c, HeaderSupportsPBft cfg c hdr)
=> NodeConfig (PBft cfg c)
-> PBftWindowParams
-> SlotNo
-> hdr
-> PBftChainState c -> PBftChainState c
appendEBB PBftNodeConfig{..} PBftWindowParams{..} =
appendEBB PBftNodeConfig{..} PBftWindowParams{..} b =
CS.appendEBB pbftSecurityParam windowSize
(blockSlot b) (headerHashBytes (Proxy :: Proxy hdr) (blockHash b))
where
PBftParams{..} = pbftParams

rewind :: PBftCrypto c
rewind :: forall cfg c hdr.
(PBftCrypto c, HeaderSupportsPBft cfg c hdr)
=> NodeConfig (PBft cfg c)
-> PBftWindowParams
-> WithOrigin SlotNo
-> Point hdr
-> PBftChainState c
-> Maybe (PBftChainState c)
rewind PBftNodeConfig{..} PBftWindowParams{..} =
CS.rewind pbftSecurityParam windowSize
rewind PBftNodeConfig{..} PBftWindowParams{..} p =
CS.rewind pbftSecurityParam windowSize p'
where
PBftParams{..} = pbftParams
p' = case p of
GenesisPoint -> Origin
BlockPoint s hh -> At (s, headerHashBytes (Proxy :: Proxy hdr) hh)

{-------------------------------------------------------------------------------
Extract necessary context
Expand Down
Loading

0 comments on commit 36c8ab2

Please sign in to comment.