Copyright | © 2021 IOHK |
---|---|
License | Apache-2.0 |
Safe Haskell | None |
Language | Haskell2010 |
Data type that represents a collection of checkpoints.
Each checkpoints is associated with a
Slot
.
Synopsis
- data Checkpoints a
- checkpoints :: Checkpoints a -> Map Slot a
- loadCheckpoints :: [( Slot , a)] -> Checkpoints a
- fromGenesis :: a -> Checkpoints a
- getLatest :: Checkpoints a -> ( Slot , a)
- findNearestPoint :: Checkpoints a -> Slot -> Maybe Slot
-
data
DeltaCheckpoints
a
- = PutCheckpoint Slot a
- | RollbackTo Slot
- | RestrictTo [ Slot ]
- type DeltasCheckpoints a = [ DeltaCheckpoints a]
-
data
SparseCheckpointsConfig
=
SparseCheckpointsConfig
{
- edgeSize :: Word8
- epochStability :: Word32
- defaultSparseCheckpointsConfig :: Quantity "block" Word32 -> SparseCheckpointsConfig
- sparseCheckpoints :: SparseCheckpointsConfig -> Quantity "block" Word32 -> [ Word32 ]
- gapSize :: SparseCheckpointsConfig -> Word32
Checkpoints
data Checkpoints a Source #
Collection of checkpoints indexed by
Slot
.
Instances
Eq a => Eq ( Checkpoints a) Source # | |
Defined in Cardano.Wallet.Checkpoints (==) :: Checkpoints a -> Checkpoints a -> Bool Source # (/=) :: Checkpoints a -> Checkpoints a -> Bool Source # |
|
Show a => Show ( Checkpoints a) Source # | |
Defined in Cardano.Wallet.Checkpoints |
|
Generic ( Checkpoints a) Source # | |
Defined in Cardano.Wallet.Checkpoints from :: Checkpoints a -> Rep ( Checkpoints a) x Source # to :: Rep ( Checkpoints a) x -> Checkpoints a Source # |
|
type Rep ( Checkpoints a) Source # | |
Defined in Cardano.Wallet.Checkpoints
type
Rep
(
Checkpoints
a) =
D1
('
MetaData
"Checkpoints" "Cardano.Wallet.Checkpoints" "cardano-wallet-core-2022.7.1-AGKhlyz9liLKN3QqZD1gj" '
True
) (
C1
('
MetaCons
"Checkpoints" '
PrefixI
'
True
) (
S1
('
MetaSel
('
Just
"checkpoints") '
NoSourceUnpackedness
'
NoSourceStrictness
'
DecidedLazy
) (
Rec0
(
Map
Slot
a))))
|
checkpoints :: Checkpoints a -> Map Slot a Source #
Map of checkpoints. Always contains the genesis checkpoint.
loadCheckpoints :: [( Slot , a)] -> Checkpoints a Source #
Turn the list of checkpoints into a map of checkpoints.
FIXME LATER during ADP-1043: The database actually does not store the checkpoint at genesis, but the checkpoint after that. Hence, this function does not check whether the genesis checkpoint is in the list of checkpoints.
fromGenesis :: a -> Checkpoints a Source #
Begin with the genesis checkpoint.
getLatest :: Checkpoints a -> ( Slot , a) Source #
Get the checkpoint with the largest
SlotNo
.
findNearestPoint :: Checkpoints a -> Slot -> Maybe Slot Source #
Find the nearest
Checkpoint
that is either at the given point or before.
Delta types
data DeltaCheckpoints a Source #
PutCheckpoint Slot a | |
RollbackTo Slot | |
RestrictTo [ Slot ] |
Restrict to the intersection of this list with the checkpoints that are already present. The genesis checkpoint will always be present. |
Instances
Buildable ( DeltaCheckpoints a) Source # | |
Defined in Cardano.Wallet.Checkpoints build :: DeltaCheckpoints a -> Builder Source # |
|
Delta ( DeltaCheckpoints a) Source # | |
Defined in Cardano.Wallet.Checkpoints type Base ( DeltaCheckpoints a) Source # apply :: DeltaCheckpoints a -> Base ( DeltaCheckpoints a) -> Base ( DeltaCheckpoints a) Source # |
|
type Base ( DeltaCheckpoints a) Source # | |
Defined in Cardano.Wallet.Checkpoints |
type DeltasCheckpoints a = [ DeltaCheckpoints a] Source #
Checkpoint hygiene
data SparseCheckpointsConfig Source #
Captures the configuration for the
sparseCheckpoints
function.
NOTE: large values of
edgeSize
aren't recommended as they would mean
storing many unnecessary checkpoints. In Ouroboros Praos, there's a
reasonable probability for small forks each a few blocks deep so it makes sense to
maintain a small part that is denser near the edge.
Instances
Show SparseCheckpointsConfig Source # | |
Defined in Cardano.Wallet.Checkpoints |
defaultSparseCheckpointsConfig :: Quantity "block" Word32 -> SparseCheckpointsConfig Source #
A sensible default to use in production. See also
SparseCheckpointsConfig
:: SparseCheckpointsConfig |
Parameters for the function. |
-> Quantity "block" Word32 |
A given block height |
-> [ Word32 ] |
The list of checkpoint heights that should be kept in DB. |
Storing EVERY checkpoints in the database is quite expensive and useless. We make the following assumptions:
- We can't rollback for more than `k=epochStability` blocks in the past
- It is pretty fast to re-sync a few hundred blocks
- Small rollbacks may occur more often than deep ones
So, as we insert checkpoints, we make sure to:
-
Prune any checkpoint that more than
k
blocks in the past - Keep only one checkpoint every 100 blocks
- But still keep ~10 most recent checkpoints to cope with small rollbacks
Example 1
: Inserting
cp153
ℹ:
cp142
is discarded and
cp153
inserted.
Currently in DB: ┌───┬───┬───┬─ ──┬───┐ │cp000 │cp100 │cp142 │.. ..│cp152 │ └───┴───┴───┴─ ──┴───┘ Want in DB: ┌───┬───┬───┬─ ──┬───┐ │cp000 │cp100 │cp143 │.. ..│cp153 │ └───┴───┴───┴─ ──┴───┘
Example 2
: Inserting
cp111
ℹ:
cp100
is kept and
cp111
inserted.
Currently in DB: ┌───┬───┬───┬─ ──┬───┐ │cp000 │cp100 │cp101 │.. ..│cp110 │ └───┴───┴───┴─ ──┴───┘ Want in DB: ┌───┬───┬───┬─ ──┬───┐ │cp000 │cp100 │cp101 │.. ..│cp111 │ └───┴───┴───┴─ ──┴───┘
NOTE: There might be cases where the chain following "fails" (because, for example, the node has switched to a different chain, different by more than k), and in such cases, we have no choice but rolling back from genesis. Therefore, we need to keep the very first checkpoint in the database, no matter what.
gapSize :: SparseCheckpointsConfig -> Word32 Source #
A reasonable gap size used internally in
sparseCheckpoints
.
Reasonable
means that it's not _too frequent_ and it's not too large. A
value that is too small in front of k would require generating much more
checkpoints than necessary.
A value that is larger than
k
may have dramatic consequences in case of
deep rollbacks.
As a middle ground, we current choose `k / 3`, which is justified by:
- The current speed of the network layer (several thousands blocks per seconds)
- The current value of k = 2160
So, `k / 3` = 720, which should remain around a second of time needed to catch up in case of large rollbacks.