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

New query GetPoolDistr #3932

Merged
merged 1 commit into from
Aug 17, 2022
Merged

New query GetPoolDistr #3932

merged 1 commit into from
Aug 17, 2022

Conversation

newhoggy
Copy link
Contributor

@newhoggy newhoggy commented Aug 1, 2022

Description

This introduce a new query GetPoolDistr which extracts the stake snapshot. This query is required to improve the CPU and memory efficiency of the query leadership-schedule command in the CLI.

Checklist

  • Branch
    • Commit sequence broadly makes sense
    • Commits have useful messages
    • New tests are added if needed and existing tests are updated
    • If this branch changes Consensus and has any consequences for downstream repositories or end users, said changes must be documented in interface-CHANGELOG.md
    • If this branch changes Network and has any consequences for downstream repositories or end users, said changes must be documented in interface-CHANGELOG.md
    • If serialization changes, user-facing consequences (e.g. replay from genesis) are confirmed to be intentional.
  • Pull Request
    • Self-reviewed the diff
    • Useful pull request description at least containing the following information:
      • What does this PR change?
      • Why these changes were needed?
      • How does this affect downstream repositories and/or end-users?
      • Which ticket does this PR close (if any)? If it does, is it linked?
    • Reviewer requested

cardano-api changes

There will be a new GetPoolDistr which uses a lot less CPU and memory:

GetPoolDistr
    :: SL.KeyHash 'SL.StakePool (EraCrypto era)
    -> BlockQuery (ShelleyBlock proto era)
                  (SL.PoolDistr (EraCrypto era))

This query takes a set of pool ids so it is possible to query multiple pools at once.

cardano-cli changes

A existing command query leadership-schedule will be be functionally unchanged, but use much less CPU and memory.

@newhoggy newhoggy marked this pull request as ready for review August 1, 2022 13:23
nfrisby
nfrisby previously requested changes Aug 1, 2022
Copy link
Contributor

@nfrisby nfrisby left a comment

Choose a reason for hiding this comment

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

I'm Requesting Changes, mostly to ensure that we have a good answer to whether calculatePoolDistr is prohibitively expensive.

@@ -273,6 +278,11 @@ instance ShelleyCompatible proto era => QueryLedger (ShelleyBlock proto era) whe
, SL._retiring = Map.restrictKeys (SL._retiring dpsPState) poolIds
}
Nothing -> dpsPState
GetPoolDistr mPoolIds ->
let poolDistr = SL.calculatePoolDistr . SL._pstakeSet . SL.esSnapshots $ getEpochState st in
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this calculatePoolDistr perhaps too expensive?

Copy link
Contributor

Choose a reason for hiding this comment

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

It might be, but I don't know that we have any clear requirements on what is too expensive. Note that SL._pstakeSet is one of the data structure that we anticipate being moved to disk.

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 for query leadership-schedule, so I think we have a good amount of headroom -- I wouldn't expect SPOs etc to be spamming this command (though it's easy enough to do that accidentally within a script).

Copy link
Contributor

Choose a reason for hiding this comment

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

We could micro-benchmark the function, and see where we are at, if we are worried.

For a general idea as to what calculatePoolDistr does:

https://github.com/input-output-hk/cardano-ledger/blob/dd4b6e31a05e3c02c6f00f0d53cf20e3b8b74468/eras/shelley/impl/src/Cardano/Ledger/Shelley/Rules/NewEpoch.hs#L204-L220

  • convert the very large stake distribution into an association list
    • un-compacting the coins in the process
    • lookup the stake creds in the delegation map in the process
  • Map.fromListWith (+) on the big association list
  • Map.intersectionWith on the condensed map to add in the VRF keys

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there a way to make this cheaper if we're only interested in a subset of pool ids?

Copy link
Contributor

Choose a reason for hiding this comment

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

great question! The following might be faster:

Make a new version of calculatePoolDistr with signature

calculatePoolDistr' :: SnapShot crypto -> Set (KeyHash 'Staking crypto) -> PoolDistr crypto

which is identical to calculatePoolDistr except that after looking up the credential in the delegation map (see here), it also looks up the pool ID in the set of pool IDs provided by the user (and discards the result if not found).

Choose a reason for hiding this comment

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

I'd look at use cases before optimising too much. I think the two likely cases are:

  • all pools
  • a specific pool (and then repeat for multi-pool operators)

The command is likely to be used occasionally rather than frequently, I expect

@newhoggy newhoggy force-pushed the newhoggy/new-query-GetPoolDistr branch from 9f54955 to c521d49 Compare August 4, 2022 13:38
@newhoggy newhoggy requested a review from bolt12 as a code owner August 4, 2022 13:38
@newhoggy newhoggy force-pushed the newhoggy/new-query-GetPoolDistr branch from c521d49 to f5d6a47 Compare August 5, 2022 08:14
@newhoggy newhoggy requested a review from nfrisby August 5, 2022 08:14
@newhoggy
Copy link
Contributor Author

newhoggy commented Aug 10, 2022

I reverted back to use calculatePoolDistr because some refactoring in cardono-ledger blocks merging the PR otherwise. I would like to merge this version and in a future PR switch to use calculatePoolDistr' #3949

@@ -35,7 +35,7 @@ data NodeToClientVersion
| NodeToClientV_13
-- ^ enabled @CardanoNodeToClientVersion9@, i.e., Babbage
| NodeToClientV_14
-- ^ added @GetPoolState, @GetSnapshots
-- ^ added @GetPoolDistr, @GetPoolState, @GetSnapshots
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 NodeToClientV_14 hasn't been yet released. node-1.35.x comes with NodeToClientV_13 as the latest version.

Copy link
Contributor

@nfrisby nfrisby left a comment

Choose a reason for hiding this comment

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

Marcin's commented that the NTC version was correct. So that's good.

The question of calculatePoolDistr's performance remains unresolved, but I don't think it's a blocker for this PR. We'll need to assess it, though. @newhoggy can you pursue that with some measurements etc after merging this (or before, if that's convenient)?

@newhoggy
Copy link
Contributor Author

Yep. I will evaluate after merging.

There is a follow up PR that improves the performance, but that's blocked on a refactoring PR.

@newhoggy
Copy link
Contributor Author

bors r+

@iohk-bors
Copy link
Contributor

iohk-bors bot commented Aug 17, 2022

@iohk-bors iohk-bors bot merged commit 15b56d1 into master Aug 17, 2022
@iohk-bors iohk-bors bot deleted the newhoggy/new-query-GetPoolDistr branch August 17, 2022 00:31
@newhoggy
Copy link
Contributor Author

I didn't notice much difference in CPU/memory usage of the new version of cardano-node. I think it's because query leadershipship-schedule was already very expensive to start with.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants