-
Notifications
You must be signed in to change notification settings - Fork 86
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
Conversation
There was a problem hiding this 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 |
There was a problem hiding this comment.
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/src/Ouroboros/Consensus/Demo/Ledger/Byron/Config.hs
Outdated
Show resolved
Hide resolved
ouroboros-consensus/src/Ouroboros/Consensus/Protocol/WithEBBs.hs
Outdated
Show resolved
Hide resolved
ouroboros-consensus/src/Ouroboros/Consensus/Protocol/WithEBBs.hs
Outdated
Show resolved
Hide resolved
ouroboros-consensus/src/Ouroboros/Consensus/Protocol/WithEBBs.hs
Outdated
Show resolved
Hide resolved
ouroboros-consensus/src/Ouroboros/Consensus/Demo/Ledger/Byron/Forge.hs
Outdated
Show resolved
Hide resolved
This depends on cardano-ledger#566, which still needs to be merged. |
Rebased atop master, addressed a bunch of the comments. |
type ByronGiven = ( | ||
Given Crypto.ProtocolMagicId | ||
, Given CC.Slot.EpochSlots | ||
) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed?
There was a problem hiding this comment.
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...
There was a problem hiding this comment.
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 🙂 )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use nix :)
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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.
ouroboros-consensus/src/Ouroboros/Consensus/Demo/Ledger/Byron/Forge.hs
Outdated
Show resolved
Hide resolved
annotateBoundary :: Crypto.ProtocolMagicId | ||
-> CC.Block.BoundaryValidationData () | ||
-> CC.Block.BoundaryValidationData ByteString | ||
annotateBoundary pm = |
There was a problem hiding this comment.
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' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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.
343a733
to
ad4f2b0
Compare
- 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.
This PR introduces the following:
WithEBBs
. The reason for this abstraction is that it still makes more sense to associate the "raw"ByronBlock
with PBFT. If instead we usedByronBlockOrEBB
, everything would have to have associatedNothing
cases where the block turned out to be an EBB. Instead, we keep the association of PBFT with the rawByronBlock
and associateByronBlockOrEBB
with the extensionWithEBBs PBFT
.In spite of retaining
ByronBlock
for this reason, in most cases everything defined overByronBlock
is now defined overByronBlockOrEBB
.This is still in draft, since there's an assertion failure in
AnchoredFragment
which I don't yet understand.