Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce HasBinaryBlockInfo and make it overridable in SerialiseHFC #2435

Merged
merged 2 commits into from
Jul 18, 2020

Conversation

mrBliss
Copy link
Contributor

@mrBliss mrBliss commented Jul 17, 2020

Fixes #2239.

Instead of having a RunNode method to get the BinaryBlockInfo of a
block (offset and size of the header within the block), create a separate type
class HasBinaryBlockInfo for it. This is another step in the clean-up process
of RunNode that started in the weeks before the HFC was merged.

This means we can provide a generic implementation of HasBinaryBlockInfo for
HardForkBlock that takes the HFC wrapper into account. This wrapper adds a
listlen 2 and a tag indicating the era to the start of each block, so we need to
shift the offset of the header by 2 bytes.

More importantly, we now allow overriding the getBinaryBlockInfo method in
SerialiseHFC, just like we allow overriding the disk en/decoder for blocks.
This allows us to do the right thing for the Byron era: no era wrapper for
Byron, but start using era wrappers for the eras after it.

This also fixes a bug: cardano-node running in pure Shelley mode uses
ShelleyHFC, i.e., a ShelleyBlock wrapped in the HFC. Since the generic
RunNode instance for HardForkBlock '[blk] forwards everything to the
instance for blk, we were using the BinaryBlockInfo implementation for
Shelley, which didn't account for the era wrapper in the header offset. Since
we were using the era wrapper to serialise ShelleyHFC blocks on disk, this
meant we were extracting the header from the on-disk blocks incorrectly,
resulting in deserialisation failures when reading headers from disk.

This refactoring allows us to fix it properly: now the defaults for
SerialiseHFC do the right thing for ShelleyHFC, and for ByronHFC we
forward to ByronBlock, just like for all the other methods. This means
ShelleyHFC starts out with an era wrapper around blocks from the first era (to
allow for easier transitions to later eras, which is the right thing to do from
the start), but ByronHFC's block format is binary compatible with
ByronBlock.

So that we later can refer from
`Ouroboros.Consensus.Storage.ChainDB.Serialisation`. The dependency was
previously in the wrong direction, `Common` should not rely on `ChainDB`.
Fixes #2239.

Instead of having a `RunNode` method to get the `BinaryBlockInfo` of a
block (offset and size of the header within the block), create a separate type
class `HasBinaryBlockInfo` for it. This is another step in the clean-up process
of `RunNode` that started in the weeks before the HFC was merged.

This means we can provide a generic implementation of `HasBinaryBlockInfo` for
`HardForkBlock` that takes the HFC wrapper into account. This wrapper adds a
listlen 2 and a tag indicating the era to the start of each block, so we need to
shift the offset of the header by 2 bytes.

More importantly, we now allow overriding the `getBinaryBlockInfo` method in
`SerialiseHFC`, just like we allow overriding the disk en/decoder for blocks.
This allows us to do the right thing for the Byron era: no era wrapper for
Byron, but start using era wrappers for the eras after it.

This also fixes a bug: `cardano-node` running in pure Shelley mode uses
`ShelleyHFC`, i.e., a `ShelleyBlock` wrapped in the HFC. Since the generic
`RunNode` instance for `HardForkBlock '[blk]` forwards everything to the
instance for `blk`, we were using the `BinaryBlockInfo` implementation for
Shelley, which didn't account for the era wrapper in the header offset. Since
we *were* using the era wrapper to serialise `ShelleyHFC` blocks on disk, this
meant we were extracting the header from the on-disk blocks incorrectly,
resulting in deserialisation failures when reading headers from disk.

This refactoring allows us to fix it properly: now the defaults for
`SerialiseHFC` do the right thing for `ShelleyHFC`, and for `ByronHFC` we
forward to `ByronBlock`, just like for all the other methods. This means
`ShelleyHFC` starts out with an era wrapper around blocks from the first era (to
allow for easier transitions to later eras, which is the right thing to do from
the start), but `ByronHFC`'s block format is binary compatible with
`ByronBlock`.
@mrBliss mrBliss added the consensus issues related to ouroboros-consensus label Jul 17, 2020
@mrBliss mrBliss requested review from edsko and dcoutts July 17, 2020 19:22
Copy link
Contributor

@dcoutts dcoutts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dcoutts
Copy link
Contributor

dcoutts commented Jul 18, 2020

bors merge

@iohk-bors
Copy link
Contributor

iohk-bors bot commented Jul 18, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
consensus issues related to ouroboros-consensus
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Introduce class for GetBinaryInfo
2 participants