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

Support Byron Epoch boundary blocks #704

Merged
merged 1 commit into from
Jul 17, 2019
Merged

Support Byron Epoch boundary blocks #704

merged 1 commit into from
Jul 17, 2019

Conversation

nc6
Copy link
Contributor

@nc6 nc6 commented Jul 3, 2019

This PR introduces the following:

  • Updates to cardano-ledger. This means changing a few things which have been updated in that repo, such as the naming for the proxy delegation certificates. The updates are needed to expose functions for dealing with serialisation of epoch boundary blocks.
  • Introduce a protocol extension WithEBBs. The reason for this abstraction is that it still makes more sense to associate the "raw" ByronBlock with PBFT. If instead we used ByronBlockOrEBB, everything would have to have associated Nothing cases where the block turned out to be an EBB. Instead, we keep the association of PBFT with the raw ByronBlock and associate ByronBlockOrEBB with the extension WithEBBs PBFT.

In spite of retaining ByronBlock for this reason, in most cases everything defined over ByronBlock is now defined over ByronBlockOrEBB.

This is still in draft, since there's an assertion failure in AnchoredFragment which I don't yet understand.

@nc6 nc6 requested a review from mrBliss July 3, 2019 14:02
@nc6 nc6 marked this pull request as ready for review July 3, 2019 14:36
Copy link
Contributor

@mrBliss mrBliss left a comment

Choose a reason for hiding this comment

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

Nice work!

I'll take a look at #705 too, because without fixing that, we can't test this.

cabal.project Outdated
@@ -44,25 +44,25 @@ source-repository-package
source-repository-package
type: git
location: https://github.com/input-output-hk/cardano-ledger
tag: 7f5263eac329d73a0626fc0d9603dec2cd51d352
tag: ebc1a24f5535d237616b92023eab80b998816807
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you manage to use @erikd's cardano-repo-tool for this?

ouroboros-consensus/ouroboros-consensus.cabal Show resolved Hide resolved
@mrBliss
Copy link
Contributor

mrBliss commented Jul 3, 2019

This depends on cardano-ledger#566, which still needs to be merged.

@nc6
Copy link
Contributor Author

nc6 commented Jul 3, 2019

Rebased atop master, addressed a bunch of the comments.

type ByronGiven = (
Given Crypto.ProtocolMagicId
, Given CC.Slot.EpochSlots
)
Copy link
Contributor

Choose a reason for hiding this comment

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

It was done this way in cardano-sl, as an improvement over the original design that used template haskell. Both are less than ideal: with TH, each build is fixed to one protocol magic; with reflections, it can be changed by runtime configuration, but it's not at all clear whether one process is capable of using two different protocol magics.

Copy link
Contributor

Choose a reason for hiding this comment

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

Would be considered to be old fashioned to suggest that we just use parameter passing for this?

Copy link
Contributor

Choose a reason for hiding this comment

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

That'd be my ideal solution. But since the design uses the typeclass HasHeader, something that makes these parameters seem static is needed (otherwise the instances couldn't be implemented).

Copy link
Contributor

Choose a reason for hiding this comment

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

Something more like an ML module would be nice here. Then the particular values of protocol magic and epoch slots could determine a new type for a byron block.

@@ -47,6 +52,7 @@ extra-deps:
commit: e8bfc1294e088f90e5ae0b4aedbc82ee46ac5ee4

- bimap-0.4.0
- binary-0.8.7.0
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Whenever I don't have it, I can't build. Not sure why nobody else seems to have this problem...

Copy link
Contributor

Choose a reason for hiding this comment

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

Aarrgh, this line has cost me soooo much time rebuilding when switching branches: stack always has to build +100 dependencies whenever the version of binary changes in stack.yaml. Why can't stack remember that it has built these dependencies before? (I'm not blaming you, just venting 🙂 )

Copy link
Contributor

Choose a reason for hiding this comment

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

Use nix :)

Copy link
Contributor

Choose a reason for hiding this comment

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

I would like to, but using cabal new-build in a nix-shell is still recompiling my dependencies, which is defeating the point 🤦‍♂️


newtype ByronBlockOrEBB cfg = ByronBlockOrEBB
{ unByronBlockOrEBB :: CC.Block.ABlockOrBoundary ByteString
} deriving (Eq, Show)
Copy link
Contributor

Choose a reason for hiding this comment

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

For byron-proxy, I'll need a type which includes Byron blocks and EBBs, but which also can be serialised. Since there's no way to serialise an ABlockOrBoundary ByteString, what I've done there is use

type Block = Annotated (ABlockOrBoundary ByteString) ByteString

as the block type, and encoded it using CBOR tag 24 so that when I decode it from the wire I can give the top-level annotation (I have the bytes).

Now I'm working on using ChainDB in byron-proxy, so I'll face the same problem with the block type chosen to go in the ChainDB. I'll need the top-level annotation there as well. Perhaps we could change ByronBlockOrEBB to include this?

Copy link
Contributor

Choose a reason for hiding this comment

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

This is also important for using the ChainDB to serve a Byron peer. That requires coming up with legacy cardano-sl Block and BlockHeader values, but if I'm using a ChainDB that uses new cardano-ledger variants, I can't do that without having the bytes from which they were decoded.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't understand this comment - why can't you serialise an ABlockOrBoundary ByteString? It's already annotated, and we have explicit serialisers for it (toCBORABOBBlock and toCBORABOBBoundary, but we could easily wrap these together).

Copy link
Contributor

Choose a reason for hiding this comment

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

ABlockOrBoundary ByteString couldn't be serialized, but now can since you recently merged a pull request into cardano-ledger.

Copy link
Contributor

Choose a reason for hiding this comment

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

For BoundaryValidationData a the annotation a is for the header bytes only, so ABOBBoundary (BoundaryValidationData ByteString) doesn't have the bytes for the whole block. That's why I put the annotation out front. Looks like the toCBORABOBBoundary just makes up a body... I'm not sure if that's actually ok. The Byron peers might not accept it.

annotateBoundary :: Crypto.ProtocolMagicId
-> CC.Block.BoundaryValidationData ()
-> CC.Block.BoundaryValidationData ByteString
annotateBoundary pm =
Copy link
Contributor

Choose a reason for hiding this comment

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

While debugging the demo with --real-pbft (#705): I discovered that there must be a bug somewhere in this function (or in cardano-ledger#566): if I give it an EBB with boundaryPrevHash = Left _, the block I get back after annotateBoundary suddenly has boundaryPrevHash = Right _. If I replace annotateBoundary with fmap (const mempty), then boundaryPrevHash remains Left _. This is the reason why the first produced block doesn't fit onto the chain.

Can you add a round-trip QC property for fromCBOR.. . toCBOR.. + find the actual bug? 🙂

@@ -123,7 +123,10 @@ validExtension
validExtension c b = blockInvariant b
&& headHash c == blockPrevHash b
&& headSlot c < blockSlot b
&& headBlockNo c == pred (blockNo b)
-- TODO This is a hack which should be addressed through 'WithOrigin'
Copy link
Contributor

Choose a reason for hiding this comment

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

@avieth when can we expect the sequel of #706? 🙂 We need WithOrigin for BlockNo (in addition to SlotNo) too, as the genesis EBB has BlockNo 0, the empty chain cannot have BlockNo 0 too.

If you're busy with the byron-proxy, I could take a stab at it instead.

Copy link
Contributor

Choose a reason for hiding this comment

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

I did this, for ouroboros-network only #774

It would probably be best if you did the follow up for ouroboros-consensus. I found there were some non-obvious choices to be made in there.

@mrBliss
Copy link
Contributor

mrBliss commented Jul 16, 2019

Sorry @nc6, but #727 caused some merge conflicts. It's mostly moving/splitting/renaming files, but some identifiers were renamed too.

@nc6 nc6 force-pushed the nc/ebb branch 2 times, most recently from 343a733 to ad4f2b0 Compare July 16, 2019 13:49
- Updates to cardano-ledger. This means changing a few things which have been
  updated in that repo, such as the naming for the proxy delegation
  certificates. The updates are needed to expose functions for dealing with
  serialisation of epoch boundary blocks.

- Introduce a protocol extension WithEBBs. The reason for this abstraction is
  that it still makes more sense to associate the "raw" ByronBlock with PBFT. If
  instead we used ByronBlockOrEBB, everything would have to have associated
  Nothing cases where the block turned out to be an EBB. Instead, we keep the
  association of PBFT with the raw ByronBlock and associate ByronBlockOrEBB with
  the extension WithEBBs PBFT. In spite of retaining ByronBlock for this reason,
  in most cases everything defined over ByronBlock is now defined over
  ByronBlockOrEBB.

- Change a few constraints which require block numbers to be sequential
(whereas EBBs share the same block - and slot - numbers as other
blocks). These constraints should ultimately become part of a new
'blockInvariant' method.
@nc6 nc6 merged commit 3d9fbb3 into master Jul 17, 2019
@iohk-bors iohk-bors bot deleted the nc/ebb branch July 17, 2019 13:27
@mrBliss mrBliss added the consensus issues related to ouroboros-consensus label Aug 2, 2019
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.

4 participants