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

Rework slotting functions #2352

Merged
merged 1 commit into from
Dec 1, 2020
Merged

Rework slotting functions #2352

merged 1 commit into from
Dec 1, 2020

Conversation

rvl
Copy link
Contributor

@rvl rvl commented Nov 26, 2020

Overview

I am looking at the changes in #2245 related to slotting.

The way the error handling is, it seems like we are walking around with our shoelaces tied together.

Times relative to system start

Part of the problem is that converting a UTC time into a time relative to the system start can fail. (UTCTimeToRel :: UTCTime -> Qry (Maybe Cardano.RelativeTime)). But, really in most cases it won't. The best way to deal with that is to push relative time conversions outside of the queries. Then the caller of the slotting can make decisions about how to get a RelativeTime.

Things like converting a slot range to a time range become much simpler.

Shorten Slotting module.

We already chopped out a lot of old code in #2351.

But if we use unembellished types from ouroboros-consensus, this module can be even shorter. Qry is now just a ReaderT wrapper around HF.Qry.

Running a query is to just apply the start time parameter to runReaderT and then call Ouroboros.Consensus.HardFork.History.Qry.interpretQuery.

Mixing with IO

Sometimes we want to know the chain-relative time for "now". A simplification is to assume that "now" is always after the start time. In the corner case, it suffices to use the relative time of 0. Now callers of this function don't need to worry about whether it can fail somehow.

Relative times are usually better - e.g. Sync progress

The calculation of sync progress with UTC is something like (b - a - s) / (b - s). But with relative times it's just a / b.

Todo

Separate running a query from obtaining the time interpreter

Currently the TimeInterpreter is fetched from the network layer through an IORef (or similar). Then the query is run in IO, when most of the time it's a pure computation (due to the changes above). This just muddles things up.

Stake pool retirement time

Because stake pool retirement epochs are almost certainly past time safe zone, we need to use the unsafeExtend function to assume that the current epoch is the final epoch.

Transaction expiry (TTL)

Expiry times need to be converted fo/from slots. But these are rarely going to be outside of the safe zone. If they are, it is fine to refuse to convert, and show "Nothing" (for incoming tx) or reject the payment request (for outgoing tx).

@rvl rvl added the IMPROVEMENT Mark a PR as an improvement, for auto-generated CHANGELOG label Nov 26, 2020
@rvl rvl requested a review from Anviking November 26, 2020 17:35
@rvl rvl self-assigned this Nov 26, 2020
@rvl rvl force-pushed the rvl/clean-up-slotting branch 2 times, most recently from beffe61 to 965e543 Compare November 27, 2020 09:11
Base automatically changed from rvl/clean-up-slotting to master November 27, 2020 11:50
@rvl rvl force-pushed the rvl/rework-slotting branch 2 times, most recently from e76a218 to efde25f Compare November 30, 2020 07:01
@rvl rvl changed the title WIP: Rework slotting functions Rework slotting functions Nov 30, 2020
@rvl rvl marked this pull request as ready for review November 30, 2020 12:33
Copy link
Member

@Anviking Anviking left a comment

Choose a reason for hiding this comment

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

Ok, separating the RelativeTime Maybe problem seems fair.

Currently the TimeInterpreter is fetched from the network layer through an IORef (or similar). Then the query is run in IO, when most of the time it's a pure computation (due to the changes above). This just muddles things up.

Maybe. I think there's value in allowing the TimeInterpreter including the IORef to escape from the NetworkLayer and to be modified by combinators.

currentEpoch ti = ti . epochAt =<< liftIO getCurrentTime
-- | This is 'Ouroboros.Consensus.HardFork.History.Qry.Qry' wrapped in a reader
-- to provide the blockchain system start time as context.
type Qry = ReaderT StartTime HF.Qry
Copy link
Member

Choose a reason for hiding this comment

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

Ok, neat!

-- If the current time is before the system start (this would only happen when
-- launching testnets), the relative time is reported as 0.
currentRelativeTime :: MonadIO m => TimeInterpreter m -> m RelativeTime
currentRelativeTime ti = ti getStartTime >>= getCurrentTimeRelativeFromStart
Copy link
Member

Choose a reason for hiding this comment

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

Rebasing #2245 I found that if m ~ ExceptT PastHorizonException IO then suddenly the currentRelativeTime can fail… with PastHorizonException, which doesn't make sense.

I changed it to

currentRelativeTime :: MonadIO m => TimeInterpreter n -> m RelativeTime

but we can deal with that in #2245.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK thanks.
Maybe we should change MonadIO to just IO, or MonadTime (from io-sim-classes package).

@Anviking Anviking force-pushed the rvl/rework-slotting branch from 7e52749 to 85ebd67 Compare November 30, 2020 17:51
@Anviking
Copy link
Member

@rvl I rebased off master and added a hint fix commit. I'll leave it to you to squash and merge.

Although the tests are suddenly failing 🤔 That seems weird.

test/unit/Cardano/DB/Sqlite/DeleteSpec.hs:45:9:
--
  | 1) Cardano.DB.Sqlite.Delete.RefCount waitForFree waits for withRef to finish
  | expected: ((),False)
  | but got: ((),True)
  |  
  | To rerun use: --match "/Cardano.DB.Sqlite.Delete/RefCount/waitForFree waits for withRef to finish/"
  |  
  | Randomized with seed 2076715646

@rvl rvl force-pushed the rvl/rework-slotting branch from 85ebd67 to 24c2c7b Compare December 1, 2020 07:52
@rvl
Copy link
Contributor Author

rvl commented Dec 1, 2020

Thanks.
I reverted the change I made to a slotRangeFromTimeRange test case, and fixed the code accordingly. And squashed everything.

I have never seen that test failure locally. It looks like a new one.

bors r+

@iohk-bors
Copy link
Contributor

iohk-bors bot commented Dec 1, 2020

Build succeeded:

@iohk-bors iohk-bors bot merged commit 59bd458 into master Dec 1, 2020
@iohk-bors iohk-bors bot deleted the rvl/rework-slotting branch December 1, 2020 08:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
IMPROVEMENT Mark a PR as an improvement, for auto-generated CHANGELOG
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants