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

[Validation] Introduce rolling cache for block hashes in masternode manager #1904

Merged

Conversation

random-zebra
Copy link

Problem:
Validation of many objects on the second layer (masternode pings, winners/scores, etc...) requires access to chainActive to get the hashes of blocks at a certain height. This is done very often (especially for masternode pings) and means holding cs_main lock every time, making the process slow and possibly leading to locking order inconsistencies.

Solution:
Cache the last N block hashes in the masternode manager.
In order to implement this efficiently, we introduce a new data structure called CyclingVector, which is a fixed-size vector, exposing only a setter Set(i, value) which modifies the index i % N.
The cache is initialized at startup and updated when blocks get connected to / disconnected from the tip.

The size (CACHED_BLOCK_HASHES) is currently set a default value of 200 making it possible to validate all masternode pings (but not all masternode winners) without accessing chainActive. In the future we could add a startup flag to let the user customize this (higher cache size would, as usual, mean faster execution but higher memory usage).

An RPC getcachedblockhashes is introduced, in order to print the content of the cache. This can be used later in the functional test suite for better testing.

This PR also removes the accesses to chainActive to get the current chain-height (using a value cached in the manager).

@random-zebra random-zebra added RPC Validation Needs Release Notes Placeholder tag for anything needing mention in the "Notable Changes" section of release notes Masternode labels Oct 8, 2020
@random-zebra random-zebra added this to the 5.0.0 milestone Oct 8, 2020
@random-zebra random-zebra self-assigned this Oct 8, 2020
@random-zebra random-zebra force-pushed the 202010_mnping_faster-validation branch from af6f11b to bb53c17 Compare October 15, 2020 17:09
@random-zebra
Copy link
Author

Rebased on master and added functional test.

@furszy
Copy link

furszy commented Oct 18, 2020

Rebase needed. Small conflicts with master

@random-zebra random-zebra force-pushed the 202010_mnping_faster-validation branch from bb53c17 to 3e3059a Compare October 18, 2020 19:44
@random-zebra
Copy link
Author

Done.

Copy link

@furszy furszy left a comment

Choose a reason for hiding this comment

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

Code review ACK 3e3059a.
Really really nice 🍺 .

src/masternodeman.cpp Outdated Show resolved Hide resolved
} else {
// Use chainActive
LOCK(cs_main);
return chainActive[nHeight]->GetBlockHash();
Copy link

Choose a reason for hiding this comment

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

Note for the future: this cs_main could be a potential deadlock in GetNextMasternodeInQueueForPayment, where we are locking the internal CMasternodeMan::cs first.

Copy link
Author

Choose a reason for hiding this comment

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

Yeah. It should be addressed in the future (even before deterministic masternodes, GetNextMasternodeInQueueForPayment can be refactored, rearranging its locks properly and removing the redundancies).
But, at least with this patch, it's only on blocks deeper than 200.
Currently on master we lock it for every block (even twice inside CalculateScore).

@random-zebra random-zebra force-pushed the 202010_mnping_faster-validation branch from 3e3059a to dd67066 Compare October 19, 2020 09:39
@random-zebra
Copy link
Author

Nit addressed and PR rebased on master.

Copy link

@furszy furszy left a comment

Choose a reason for hiding this comment

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

tested with #1916 and have run it for a while in mainnet, all looking good. Really nice, ACK dd67066 .

Copy link
Collaborator

@Fuzzbawls Fuzzbawls left a comment

Choose a reason for hiding this comment

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

ACK dd67066

@furszy furszy merged commit 92035f8 into PIVX-Project:master Oct 20, 2020
furszy added a commit that referenced this pull request Oct 25, 2020
872da91 Speedup listmasternodes removing a redundant for loop over every MN on the mnnodeman. (furszy)
ea434a1 CMasternodeMan::GetMasternodeRanks removed unneeded MN extra validations and totally unnecessary extra vector load. (furszy)

Pull request description:

  Built on top of #1904 . PR starting on 9123d22.

  `listmasternodes` RPC command was taking a considerable amount of time, checked the flow and discovered a lot of redundancies in the process. This PR aims to correct them.

   1) `CMasternodeMan::GetMasternodeRanks` is only used for an RPC call and it was checking and validating each Masternode instead of just retrieve them as it suppose to be doing (the tier two thread is the only one responsible of check and update the masternodes list).

  2) `CMasternodeMan::GetMasternodeRanks` had a totally unneeded second vector load. Looping over the entire masternodes list one more time after getting it.

  3) `listmasternodes` after calling `GetMasternodeRanks` was looking for each of the retrieved masternodes one more time using the retrieved masternode vin (yes..).

ACKs for top commit:
  random-zebra:
    ACK 872da91
  Fuzzbawls:
    ACK 872da91

Tree-SHA512: 52db4488ec429594a8fa6cacceaaf494ec0da179929b7de30f8698cbbb2d940c0d859f8a0082dce33ead5227066079011f30480434ab935906e12aa80b4199a3
@random-zebra random-zebra removed the Needs Release Notes Placeholder tag for anything needing mention in the "Notable Changes" section of release notes label Jan 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants