-
Notifications
You must be signed in to change notification settings - Fork 23
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
docs: draft HardForkCombinatorRollbackMonotonicityProposal.md #346
base: main
Are you sure you want to change the base?
Conversation
This is a Draft PR. But I'd appreciate your thoughts already. |
1fe5f75
to
c89615d
Compare
docs/website/contents/for-developers/HardForkCombinatorRollbackMonotonicityProposal.md
Outdated
Show resolved
Hide resolved
- Let R count the number of blocks after L on D. | ||
Observe that there must be more than R blocks after L on C, since C is better than D. | ||
(This isn't necessarily true, due to tiebreakers. | ||
However, even with tiebreakers, this remains true in the worst case, which is what ultimately matters.) |
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's not clear to me what the worst case is here, and why this is true in that case.
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.
Yes, this parenthetical is admittedly handwaivy.
C can be better than D in two ways: it can be the same length and have a better tiebreaker or it can be longer. When it's longer requires a deeper rollback from us. That extra depth is the "worst case" aspect here.
However, even with tiebreakers, this remains true in the worst case, which is what ultimately matters.) | ||
- Common Prefix ensures R <= k. | ||
- L must contain enough information for the node to correctly judge the validity of the k+1th block after L on C. | ||
- Otherwise the Header-Body Split would prevent the node from adopting C, even though doing so requires at most rolling back k blocks. |
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.
Perhaps the "Otherwise" bullet can be merged with the previous one, or indented one level.
docs/website/contents/for-developers/HardForkCombinatorRollbackMonotonicityProposal.md
Outdated
Show resolved
Hide resolved
docs/website/contents/for-developers/HardForkCombinatorRollbackMonotonicityProposal.md
Outdated
Show resolved
Hide resolved
|
||
Note that, if necessary, L can be ticked in order to validate the first header after L on C, without requiring any predictions. | ||
In the absence of the corresponding block body---ie because of the Header-Body Split---the assessment of subsequent headers on C will require predictions. | ||
Thus a prediction range of at least 3k/f ensures at least k blocks after the first header, and hence k+1 blocks in total, as necessary. |
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 k+1
in total? Are we counting the header of the block that led to L
?
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.
Suppose Y is the first block after L on C. The forecasting allows for k blocks after Y on C. So that's k+1 total.
- L must contain enough information for the node to correctly judge the validity of the k+1th block after L on C. | ||
- Otherwise the Header-Body Split would prevent the node from adopting C, even though doing so requires at most rolling back k blocks. | ||
|
||
That is a complete answer. |
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.
What constitutes a complete answer in this context? (and how do we convince ourselves this is one of them?)
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.
What constitutes a complete answer in this context?
The next sentence was intended to clarify that.
how do we convince ourselves this is one of them?
Conversation, property testing, etc :D
docs/website/contents/for-developers/HardForkCombinatorRollbackMonotonicityProposal.md
Outdated
Show resolved
Hide resolved
docs/website/contents/for-developers/HardForkCombinatorRollbackMonotonicityProposal.md
Outdated
Show resolved
Hide resolved
If the safe zone were instead less than one stability window, then L does not necessarily contain enough information to validate the R+1th header after L on C, _even without_ a Chain Growth violation. | ||
Specifically, the node will need to know if the chain will actually be in whichever era that header claims to be in, and it wouldn't necessarily be able to answer that question more than a safe zone after the first header after L on C. | ||
|
||
The answer to Question 2 does change: there is one additional change in behavior possibly enabled by a Chain Growth violation. |
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 think a concrete example would be great here.
GetDRepStakeDistr :: Set (LC.DRep (EraCrypto era)) -> BlockQuery (ShelleyBlock proto era) (Map (LC.DRep (EraCrypto era)) Coin) | ||
GetCommitteeState :: BlockQuery (ShelleyBlock proto era) (SL.CommitteeState era) | ||
|
||
The queries marked with `*` and/or `+` are the only queries whose responses exhibit weak monotinicity as the node improves its selection by switching/extending chains. |
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.
Could we define, explain and exemplify "weak monotonicity" in this context?
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's a slightly more complicated general version of "non-descending". I think it'd actually be a non-trivial aside. But I have no doubt a reference exists.
Just a point of reference: the node CLI query for the leader schedule is perhaps also in the same gray area as time translations. Should that query refuse to answer until a rollback by <= k blocks could not change it? Edit: it was discussed, and yes it should refuse. See Issue #390. |
Nick would like me to fully understand the document before approving
c89615d
to
3b20329
Compare
I pushed up an Introduction; hopefully that makes the document easier to approach. |
3b20329
to
6d0dec8
Compare
I also pushed up some adjustments for the smaller comments you made. |
|
||
| DST | CCT | PIL | DSR | ZEE | ZBE | QSR | | ||
| --- | --- | --- | --- | --- | --- | --- | | ||
| I | A | P 1 | I | 2 | 3 | I | |
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.
About DST: I
: I would have expected that it is sensitive to ticks since ticking might cause votes to be counted and a hardfork could be decided as a consequence of this. Would it be possible to explain why this is not the case?
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.
Yeah. Extremely high-level summary: it's because of PIL=Possible. The ticking itself does make the vote-counting actually happen, but if there hasn't been enough blocks, the Cardano HFC logic will "veto" the decision to end the era and simply not transition to the next era.
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.
The ticking itself does make the vote-counting actually happen
Oh, I thought this was the case. Do you know how we currently determine if we should transition to the next era based on the ledger info? I guess that we do not rely on this rule on epoch change. Do we roll out our own logic (that totally ignores the 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.
The ticking itself does make the vote-counting actually happen
Oh, I thought this was the case.
I sounds like maybe you read "doesn't" because I wrote "does", which is a bit unusual.
Do we roll out our own logic (that totally ignores the ledger?)
Here's the entrypoint to the Consensus-side logic https://github.com/input-output-hk/ouroboros-consensus/blob/51da3876c01edc2eec250fdc998f6cb33cdc4367/ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/ShelleyHFC.hs#L130-L164
There's probably plenty of redundancy that could be removed from this Consensus-side logic (in the "Inspect
" module), but it's only exactly this one line that "ignores the ledger" https://github.com/input-output-hk/ouroboros-consensus/blob/51da3876c01edc2eec250fdc998f6cb33cdc4367/ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/ShelleyHFC.hs#L160 shelleyAfterVoting
is from the ledger state; it's incremented (here) whenever we apply a block.
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 sounds like maybe you read "doesn't" because I wrote "does", which is a bit unusual.
I can't read 🤦 Sorry about that.
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.
Thanks for the links to the relevant snippets 🙏
but it's only exactly this one line that "ignores the ledger"
"Ignores the ledger when there aren't k
blocks after a transition to an era was voted on the ledger, right?
- (2) The current HFC's behavior is inconsistent without making further assumptions. | ||
Overall, ZEE is allowed, but it might cause some unexpected behavior. | ||
In particular, forecasts always anticipate that there is at least one safe zone of slots in an era (which is not true for eras with zero epochs). | ||
That mismatch could manifest as incorrect time-slot translations eg (within ledger rules execution, but not within Node-To-Client query reponses). |
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.
Could we elaborate an example of 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.
We could. It should be pretty simple, but it will require a lot of words, just because of the context. If it doesn't require a lot of works, then it would remain pretty abstract, which kind of defeats the purpose of the example.
I left it out for now because it seems like a lot of words. Maybe we could consolidate all of the examples into an "example" section that shares the necessary context amongst a few pointed examples.
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.
Yeah, I think that would help the readers greatly. But I acknowledge this is not intended to be a document used for mass consumption, right? So perhaps this is also out of scope.
docs/website/contents/for-developers/HardForkCombinatorRollbackMonotonicityProposal.md
Show resolved
Hide resolved
docs/website/contents/for-developers/HardForkCombinatorRollbackMonotonicityProposal.md
Show resolved
Hide resolved
|
||
- (1) ZBE would be achievable for a prefix of eras when constructing the initial HFC ledger state (in the `ProtocolInfo` passed to the Consensus layer), but otherwise the HFC as a block type does not need to support ZBE at all. | ||
|
||
- (2) Esgen points out that perhaps DSR could/should still be Insensitive, and that wouldn't obviously lose too much simplicity. |
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 wonder how that could even be possible. 🤔 Do you have an example?
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 think @amesgen would more easily be able to explain it than I can.
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.
Right now, the criterion for singleEraTransition
to report the era transition for Shelley-based eras is:
Were there at least
$k$ blocks after the voting deadline ($6k/f$ before an epoch boundary)?
We could change that to
Were there at least
$k$ blocks after the voting deadline or was the last applied block within the last$3k/f$ slots of the epoch?
This choice would have DST=Sensitive, PIL=Impossible and DSR=Insensitive (apart from chain growth violations in the
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.
Were there at least
$k$ blocks after the voting deadline ($6k/f$ before an epoch boundary)?
But don't we require 2k blocks after the voting deadline to actually transition to the next era?
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 choice would have DST=Sensitive
Why? Because we would be counting slots?
PIL=Impossible
Because we would be counting slots, like the ledger does?
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.
was the last applied block within the last
$3k/f$ slots of the epoch?
and I don't get why this will ensure that a rollback won't cause a different era-transition decision (even if there are no CG violations).
(sorry for the many questions 🙏 )
docs/website/contents/for-developers/HardForkCombinatorRollbackMonotonicityProposal.md
Show resolved
Hide resolved
There may be other points in the design space worth considering. | ||
(Or even other dimensions, of course.) | ||
In particular, DST=Insensitive and PIL=Impossible could be achieved by changing the Cardano ledger's governance to match the existing Cardano HFC logic. | ||
Specifically, if the ledger did not enact governance actions unless there have actually been k+1 blocks since they were ratified even despite possible Chain Growth violations, then the Cardano HFC would never override the 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.
I fail to see the relation between chain growth violations and k + 1 blocks.
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.
Right now governance actions are enacted if they both 1) get enough votes and 2) get those votes before a slot-based deadline. The specified choice of slot for the deadline has so far ensured that the final Yes-vs-No status of the governance action would be determined (ie predictable) more than k blocks before the change was actually made (aka "enacted")---unless there was a Chain Growth violation (since Chain Growth ensures at least k blocks of growth per a fixed number of slots).
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.
Let me see if I get this: if
The vote counting is not stable until we reach/add? block
And does the insensitivity to ticks stem from the fact that we're counting blocks instead of slots?
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.
The deadline is actually a boundary between slots. There's a slot that's the last slot you could sneak in a vote, and the next slot you can't. The boundary between them is the deadline.
If
The vote counting is not stable until we reach/add? block
$b^d_{k+1}$ , right?
Hmm. The word "stable" is tricky, since it is often used to refer to something that's one stability window old. But in the presence of CG violations, that could still be subject to rollback.
So it's "actually stable" only once block k+1
arrives, yes.
And does the insensitivity to ticks stem from the fact that we're counting blocks instead of slots?
Yep.
docs/website/contents/for-developers/HardForkCombinatorRollbackMonotonicityProposal.md
Show resolved
Hide resolved
- Assume k > 0. | ||
- Let C be the current best valid chain in the net. | ||
- Let D be the node's currently selected chain, and assume it's worse than C. | ||
- Let L be the ledger state resulting from the youngest block that is on both C and D, aka their intersection. |
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.
Now I realize that I'm confused about the mention of "youngest block", doesn't "block at the intersection" suffice?
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.
Yeah; see our previous convo #346 (comment)
(This isn't necessarily true, due to tiebreakers. | ||
However, even with tiebreakers, this remains true in the worst case, which is what ultimately matters.) | ||
- Common Prefix ensures R <= k. | ||
- L must contain enough information for the node to correctly judge the validity of the k+1th block after L on C. |
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.
Not related to this PR, but why do we require k+1
instead of k? Because we won't be able to switch to C
otherwise?
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.
Yep, that's why. Praos promises we'll never need to rollback more than k
. And it's possible that (the tiebreakers align such that) we'd need to rollback exactly k
in order to a longer chain, ie a chain with at least k+1 blocks after the intersection.
If we assume Chain Growth in addition to Common Prefix, then we can further refine the answer. | ||
|
||
- Chain Growth ensures that every window of scg (ie "the s parameter of the papers' CG property", aka "one stability window") slots will contain at least k blocks on C. | ||
- Because of the Header-Body Split, L must contain enough information for the node to correctly judge the validity of any header that is no more than 3k/f after the first block after L on C. |
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 do we require that L
can judge the validity of at least k + 1
blocks on any chain that forks from it, but judge the validity of 3k / f
slots only? CG ensures we have at least k
blocks, but we could have exactly k
. Does that mean that we can only switch to chains that have > k
blocks in 3k/f
slots?
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.
Hmmm, I think this is described below:
and hence k+1 blocks in total, as necessary.
Are we counting the intersection block as well? If so I'm still confused about the requirement that L
can validate k + 1
blocks after the intersection 😬
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.
We can tick L up to the next block on their chain. And then we can forecast 3k/f from there.
I think that's actually exactly one slot short 🤔 of ensuring L can validate k+1 headers on a chain that does not violate without having to apply any more blocks to L, unless the sparsity of the k headers after the first violate Chain Growth.
What behaviors could arise only if Chain Growth were violated? | ||
|
||
- For example, suppose R=k and the k+1th block after L on C was more than 3k/f slots after the first block after L on C. | ||
- In this case, the node might not be able to switch from D to C despite R <= k. |
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.
- In this case, the node might not be able to switch from D to C despite R <= k. | ||
It can't switch to C without downloading the R+1 blocks, which it can't do without validating the R+1 headers, which it can't do without predicting more than 3k/f slots after the first header, which it might not be able to do. | ||
|
||
For example, suppose that L is the result of a block in relative slot number 7k/f - 2 within some epoch (ie "slightly more than scg before the end of the epoch"). |
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.
Here is a bit of context I'm missing: do we assume a certain duration of the epochs in terms of 3k/f
(or k/f
)?
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.
Yes: Byron was 10k and every era after has been 10k/f slots per epoch. It could vary to other values in later eras, but no one within IOG has yet suggested it should.
|
||
For example, suppose that L is the result of a block in relative slot number 7k/f - 2 within some epoch (ie "slightly more than scg before the end of the epoch"). | ||
Because there might be a block in relative slot 7k/f - 1---which would change the nonce used for the next epoch---L is unable to validate headers in the next epoch. | ||
If the first header after L on C is indeed in slot 7k/f - 1, then Chain Growth ensures the k+1th header after L on C will still be in this same epoch, and so L can validate it. |
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.
Without a drawing, it's quite hard for me to follow what L
and C
are. (I had to make one myself and I go to it back and forth, maybe we can spare the reader having to make her own drawing).
For example, suppose that L is the result of a block in relative slot number 7k/f - 2 within some epoch (ie "slightly more than scg before the end of the epoch"). | ||
Because there might be a block in relative slot 7k/f - 1---which would change the nonce used for the next epoch---L is unable to validate headers in the next epoch. | ||
If the first header after L on C is indeed in slot 7k/f - 1, then Chain Growth ensures the k+1th header after L on C will still be in this same epoch, and so L can validate it. | ||
If the first header after L on C is instead after slot 7k/f - 1, then ticking L to that first header will tick it past slot 7k/f - 1, and so determines the next epoch's nonce. |
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.
We would also need some more context/background info on when nonces are determined in relation to the slot numbers or division of epoch into chunks of k/f
.
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's currently acquired 3k/f before the end of the epoch. IOG Researchers want us to move it slightly earlier, ie 4k/f before the end.
|
||
- No other behavior of the simplified node will change due to a Chain Growth violation. | ||
(This is actually false, but only because we use predictions in the leadership check. | ||
One option to make this true is to instead use ticking in the leadership check. |
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 ticking would make this true?
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.
Because you can only forecast so far, but you can tick indefinitely (in theory, at least). EG if there's a block in the slot 0 of an epoch, but there no block in the next 3k/f slots, then today's node wouldn't be able to lead even if it were elected in the next slot (ie slot 3k/f+1 of the epoch), since it couldn't forecast far enough to see that. On the other hand, it can tick to that slot.
(In theory ticking has no limit, but I think the Cardano ledger currently assumes you can't tick across more than one epoch boundary.)
- No other behavior of the simplified node will change due to a Chain Growth violation. | ||
(This is actually false, but only because we use predictions in the leadership check. | ||
One option to make this true is to instead use ticking in the leadership check. | ||
Another option is to also characterize here how Chain Growth violations affect the predication-based leadership check, which is even milder than the above: it only manifests when there are zero blocks in some 3k/f slot window, not merely any number of blocks less than k.) |
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 get wahy this is the case. Would it be possible to illustrate 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.
Claim: "No other behavior of the simplified node will change due to a Chain Growth violation."
It's claiming that the intersection of A and B is empty, where A is "behaviors that only arise in the presence of CG violations" and B is "behaviors that haven't already been discussed".
-
If we change the leadership check to use ticking, then CG violations wouldn't affect it, and so the above claim would actually be true, since the leadership check is no longer member of A.
-
If we instead also explained that (very extreme) CG violations can affect the leadership check, then the above claim would actually be true, since the leadership check is no longer a member of B.
Unlike the ledger, the hard fork combinator actually counts blocks instead of only slots. | ||
If a hypothetical roll back of k-many blocks could possibly change the ledger-based governance decision that was intended to trigger the era transition---which is true if Chain Growth was (severely) violated in the last two stability windows before the intended era transition---then the hard fork combinator will not transition to the next era. | ||
(For this reason, the voting deadline was moved from 7k/f to 4k/f (ie two stablity windows before the end) in the ledger governance rules, so that the hard fork combinator's final decision would be known at least a stability window (and so the safe zone) before the epoch transition.) | ||
Awkwardly, the ledger will still update the major version of the protocol version protocol parameter, but the chain will remain in the previous era, which many users and developers would find counter-intuitive. |
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 section makes more sense after I read your answers to my questions. Also the second draft helped me a lot.
|
||
Consider the following alteration of the hard fork combinator. | ||
|
||
- Remove the hard fork combinator's second trigger constraint, such that it transitions to the next era exactly when the ledger governance updates the major version of the protocol version protocol parameter (mutatis mutandi as of Conway). |
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.
What is the first trigger constraint? 😬
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 the ledger governance decided the protocol major version would change.
|
||
There are three main benefits for the Consensus Team. | ||
|
||
- The hard fork combinator would no longer need the block-counting logic. |
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.
Does this mean that, when checking era transitions we'd be counting slots instead?
There are three main benefits for the Consensus Team. | ||
|
||
- The hard fork combinator would no longer need the block-counting logic. | ||
- The Consensus Team would no longer have to justify the "double-stability" for the ledger governance rules. |
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 follow this. Even if we rely on the ledger's decision, we'd still need a double stability to ensure time-translations are sound. If not, a rollback could give a different answer to a time-translation.
@@ -0,0 +1,285 @@ | |||
# DRAFT NUMBER 2 |
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.
We suspect we should rename the .md
file, as of this second draft
This an attempt at the first step of Issue #389.