cardano-sl-0.4.3: Cardano SL main implementation

Safe HaskellNone




Logic of blocks processing.



lcaWithMainChain :: WorkMode ssc m => OldestFirst NE (BlockHeader ssc) -> m (Maybe HeaderHash) Source #

Find LCA of headers list and main chain, including oldest header's parent hash. Iterates from newest to oldest until meets first header that's in main chain. O(n).

tipMismatchMsg :: Text -> HeaderHash -> HeaderHash -> Text Source #

Common error message

withBlkSemaphore :: WorkMode ssc m => (HeaderHash -> m (a, HeaderHash)) -> m a Source #

Run action acquiring lock on block application. Argument of action is an old tip, result is put as a new tip.

withBlkSemaphore_ :: WorkMode ssc m => (HeaderHash -> m HeaderHash) -> m () Source #

Version of withBlkSemaphore which doesn't have any result.


data ClassifyHeaderRes Source #

Result of single (new) header classification.



Header is direct continuation of main chain (i.e. its parent is our tip).


Header continues main or alternative chain, it's more difficult than tip.

CHUseless !Text

Header is useless.

CHInvalid !Text

Header is invalid.

classifyNewHeader :: WorkMode ssc m => BlockHeader ssc -> m ClassifyHeaderRes Source #

Classify new header announced by some node. Result is represented as ClassifyHeaderRes type.

data ClassifyHeadersRes ssc Source #

Result of multiple headers classification.


CHsValid (BlockHeader ssc)

Header list can be applied, LCA child attached.

CHsUseless !Text

Header is useless.

CHsInvalid !Text

Header is invalid.

classifyHeaders :: forall ssc m. WorkMode ssc m => NewestFirst NE (BlockHeader ssc) -> m (ClassifyHeadersRes ssc) Source #

Classify headers received in response to GetHeaders message.

  • If there are any errors in chain of headers, CHsInvalid is returned.
  • If chain of headers is a valid continuation or alternative branch, lca child is returned.
  • If chain of headers forks from our main chain too much, CHsUseless is returned, because paper suggests doing so.

getHeadersFromManyTo Source #


:: (MonadDB m, SscHelpersClass ssc, CanLog m, HasLoggerName m) 
=> NonEmpty HeaderHash

Checkpoints; not guaranteed to be in any particular order

-> Maybe HeaderHash 
-> m (Either Text (NewestFirst NE (BlockHeader ssc))) 

Given a set of checkpoints c to stop at and a terminating header hash h, we take h block (or tip if latter is Nothing) and fetch the blocks until one of checkpoints is encountered. In case we got deeper than recoveryHeadersMessage, we return recoveryHeadersMessage headers starting from the the newest checkpoint that's in our main chain to the newest ones.

getHeadersOlderExp :: forall ssc m. (MonadDB m, SscHelpersClass ssc) => Maybe HeaderHash -> m (OldestFirst [] HeaderHash) Source #

Given a starting point hash (we take tip if it's not in storage) it returns not more than blkSecurityParam blocks distributed exponentially base 2 relatively to the depth in the blockchain.

getHeadersFromToIncl :: forall ssc m. (MonadDB m, SscHelpersClass ssc) => HeaderHash -> HeaderHash -> m (Maybe (OldestFirst NE HeaderHash)) Source #

Given from and to headers where from is older (not strict) than to, and valid chain in between can be found, headers in range [] will be found.


verifyAndApplyBlocks :: (MonadDBCore m, WorkMode ssc m, SscWorkersClass ssc) => m (Set NodeId) -> Bool -> OldestFirst NE (Block ssc) -> m (Either Text HeaderHash) Source #

Applies blocks if they're valid. Takes one boolean flag "rollback". Returns header hash of last applied block (new tip) on success. Failure behaviour depends on "rollback" flag. If it's on, all blocks applied inside this function will be rollbacked, so it will do effectively nothing and return 'Left error'. If it's off, it will try to apply as much blocks as it's possible and return header hash of new tip. It's up to caller to log warning that partial application happened.

rollbackBlocks :: WorkMode ssc m => m (Set NodeId) -> NewestFirst NE (Blund ssc) -> m (Maybe Text) Source #

Rollbacks blocks. Head must be the current tip.

applyWithRollback Source #


:: (MonadDBCore m, WorkMode ssc m, SscWorkersClass ssc) 
=> m (Set NodeId) 
-> NewestFirst NE (Blund ssc)

Blocks to rollbck

-> OldestFirst NE (Block ssc)

Blocks to apply

-> m (Either Text HeaderHash) 

Rollbacks some blocks and then applies some blocks.

createGenesisBlock :: forall ssc m. WorkMode ssc m => m (Set NodeId) -> EpochIndex -> m (Maybe (GenesisBlock ssc)) Source #

Create genesis block if necessary.

We create genesis block for current epoch when head of currently known best chain is MainBlock corresponding to one of last slotSecurityParam slots of (i - 1)-th epoch. Main check is that epoch is `(last stored epoch + 1)`, but we also don't want to create genesis block on top of blocks from previous epoch which are not from last slotSecurityParam slots, because it's practically impossible for them to be valid. [CSL-481] We can do consider doing it though.

createMainBlock :: forall ssc m. WorkMode ssc m => m (Set NodeId) -> SlotId -> Maybe ProxySKEither -> m (Either Text (MainBlock ssc)) Source #

Create a new main block on top of best chain if possible. Block can be created if: • we know genesis block for epoch from given SlotId • last known block is not more than slotSecurityParam blocks away from given SlotId