-
Couldn't load subscription status.
- Fork 33
[WIP] Add pure Peras voting rules #1723
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
base: peras-staging
Are you sure you want to change the base?
Conversation
ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Peras/Voting.hs
Outdated
Show resolved
Hide resolved
ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Peras/Voting.hs
Outdated
Show resolved
Hide resolved
ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Peras/Voting.hs
Outdated
Show resolved
Hide resolved
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.
Some implementation details are yet to be defined, especially around PerasVotingView
abde225 to
8f63b94
Compare
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.
Looks good, some first thoughts
ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Peras/Voting.hs
Show resolved
Hide resolved
ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Peras/Voting.hs
Outdated
Show resolved
Hide resolved
ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Peras/Voting.hs
Outdated
Show resolved
Hide resolved
966b262 to
2bf3cfb
Compare
55feefc to
713f30f
Compare
713f30f to
564060c
Compare
ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Peras/Voting.hs
Outdated
Show resolved
Hide resolved
564060c to
aa884d7
Compare
ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Block/SupportsPeras.hs
Outdated
Show resolved
Hide resolved
ouroboros-consensus/test/consensus-test/Test/Consensus/Peras/Voting.hs
Outdated
Show resolved
Hide resolved
ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Peras/Voting.hs
Outdated
Show resolved
Hide resolved
| -- NOTE: in the case of an extremely old certificate boosting a block | ||
| -- beyond the immutable prefix, this could incorrectly return false even | ||
| -- if the voting candidate technically extends the certificate point. | ||
| -- However, this a boring case that we can safely ignore. Conversely, | ||
| -- the case of a certificate that's too new to be voted for is covered | ||
| -- by using the approriate prefix of our current chain. | ||
| candidateExtendsCert cert = | ||
| AF.withinFragmentBounds certBoostedBlockHeader chainAtCandidate | ||
| where | ||
| certBoostedBlockHeader = castPoint (getPerasCertBoostedBlock cert) |
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 definitely fine for now, but we could also remove this caveat if we store one extra bit of information in the ChainDB/PerasCertDB, namely whether the most recent certificate boosts a block on our selected fragment or the immutable chain. Let's create an issue for this.
| , pvvLatestCertSeen :: !cert | ||
| -- ^ The most recent certificate seen by the voter. | ||
| , pvvLatestCertOnChain :: !cert | ||
| -- ^ The most recent certificate present in some chain. |
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.
Hmm, one real-world consideration here is what to do if there have been no certificates so far (eg because Peras just got enabled via a hard fork, or even after that if Peras immediately entered a cooldown). We of course need to make sure that we actually start voting once Peras is enabled 😅
The formal spec introduces a special cert₀ certificate for this purpose (for round 0 and boosting the genesis point). Maybe we could make this work, but it might be better to be a bit more explicit and use Maybe cert (or an isomorphic ADT) here. The round number of a Maybe cert could then be a WithOrigin PerasRoundNo.
ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Block/SupportsPeras.hs
Outdated
Show resolved
Hide resolved
With the currently selected generation sizes, we hit the different
voting rules in a somewhat decent proportion, even against randomly
generated functions as part of the PerasVotingView interface.
ouroboros-consensus
Peras
Peras voting rules
isPerasVotingAllowed: OK (1.55s)
+++ OK, passed 10000 tests.
Actual result (10000 in total):
60.29% NoVoteReason(VR-1A or VR-2A)
20.90% NoVoteReason(VR-1A or VR-2B)
9.60% VoteReason(VR-2A and VR-2B)
4.93% VoteReason(VR-1A and VR-1B)
2.67% NoVoteReason(VR-1B or VR-2A)
1.61% NoVoteReason(VR-1B or VR-2B)
Should vote according to model (10000 in total):
85.47% False
14.53% True
VR-(1A|1B|2A|2B) (10000 in total):
21.30% (False,True,False,False)
21.24% (False,False,False,False)
10.63% (False,False,True,False)
10.27% (False,True,True,False)
8.99% (False,False,False,True)
8.76% (False,True,False,True)
4.67% (False,True,True,True)
4.26% (False,False,True,True)
1.93% (True,False,False,False)
1.77% (True,True,False,False)
1.71% (True,True,True,False)
1.61% (True,False,True,False)
0.75% (True,True,True,True)
0.74% (True,False,False,True)
0.70% (True,True,False,True)
0.67% (True,False,True,True)
VR-1A (10000 in total):
90.12% False
9.88% True
VR-1B (10000 in total):
50.07% False
49.93% True
VR-2A (10000 in total):
65.43% False
34.57% True
VR-2B (10000 in total):
70.46% False
29.54% True
aa884d7 to
b46df86
Compare
b46df86 to
9869f7a
Compare
| HasPerasCertBoostedBlock cert => | ||
| HasPerasCertBoostedBlock (WithOriginCert cert) | ||
| where | ||
| type BoostedBlock (WithOriginCert cert) = WithOrigin (BoostedBlock cert) |
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.
Hmm, this feels a bit weird, as we have two levels of WithOrigin here, eg this will be WithOrigin (Point blk) in the end, which has three kinds of inhabitants, where the first two seem weird to both exist:
OriginNotOrigin GenesisPointNotOrigin (BlockPoint slot hash)
I think we can collapse this.
| getPerasCertRound = \case | ||
| Cert0 -> Origin | ||
| Cert cert -> At (getPerasCertRound cert) |
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 feels a bit surprising to have both getPerasCertRound and withOriginCertRoundNo for WithOriginCert. AFAICT, we don't actually use this instance at the moment at all, and instead only use withOriginCertRoundNo.
| , pvvLatestCertSeen :: !cert | ||
| -- ^ The most recent certificate seen by the voter. |
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 also needs to be WithOriginCert.
| -- | Eliminate the origin certificate case for a round number | ||
| -- | ||
| -- NOTE: this assumes that the origin certificate corresponds to round number 0 | ||
| withOriginCertRoundNo :: | ||
| (HasPerasCertRound cert, Num (RoundNo cert)) => | ||
| WithOriginCert cert -> RoundNo cert | ||
| withOriginCertRoundNo = withOriginCert 0 getPerasCertRound |
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.
Related to the previous comment: I think it would be a bit more in line to treat the round number of Cert0 specially, ie assume that it is Origin which is the slot before slot 0.
This is similar to how slot numbers work in the current code base: The pointSlot of a Point blk has type WithOrigin SlotNo, which is Origin when the point is the GenesisPoint. This makes arithmetic involving slots a bit annoying sometimes, but we have some utility functions like succWithOrigin :: WithOrigin SlotNo -> SlotNo that make it bearable.
For example, checking VR-1A would look very roughly like this:
VR1A
:= (pvvCurrRoundNo pvv :==: succWithOrigin latestCertSeenRoundNo)
:/\: case pvvLatestCertSeen pvv of
Cert0 -> Bool True
Cert c -> latestCertSeenArrivalSlot c :<=: latestCertSeenRoundStart c + _XDoes this make sense, given that you might have already tried sth like this?
Closes tweag/cardano-peras#116