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

Optimistic elections #4111

Merged

Conversation

pwojcikdev
Copy link
Contributor

When bootstrapping, a node needs to cement a large number of blocks (~175 million so far), so it is critical to ensure this process is as efficient and quick as possible. Currently, it is done in a very naive way of confirming blocks in account chains one by one, ie. election scheduler always activates election for account's confirmation frontier + 1. This means that the time to confirm all blocks is more or less proportional to number of all blocks in the ledger.

This PR introduces a helper mechanism to speed up this cementing process. An optimistic scheduler randomly samples accounts with unconfirmed blocks and activates an election for the account head block (the latest unconfirmed block in an account chain). This means that the time to confirm all blocks will be proportional to number of all accounts in the ledger. The number of optimistic elections is limited to 500, so it doesn't replace or impact the default election scheduling behavior.

This is a very simple algorithm that can definitely be improved further. However, even is such a basic form it provides a significant speedup to the cementing process.

The following test results are thanks to @gr0vity-dev:

Live network:

The testcase uses a fully cemented live ledger and then resets the confirmation height.

Screenshot 2023-02-08 at 19 33 10

Beta network:

Screenshot 2023-02-08 at 19 31 50

I suspect the main reason for such a big difference between live and beta performance is the greater variety of PRs, thus it's harder to gather enough votes for block confirmation.

@qwahzi
Copy link
Collaborator

qwahzi commented Feb 8, 2023

@pwojcikdev Does the optimistic confirmation process apply per account-chain, or does it apply cross-chain too (and/or could that be an avenue for future optimization)?

For example, if account_c has receives from account_a and account_b, if account_c's latest frontier is confirmed, are transactions from account_a and account_b (up to the send associated with account_c) confirmed too?


Semi-related, does this change replace/modify previous automatic dependent block confirmations via confirmation_height? Or is it completely separate?

When confirmation height is set, any blocks below that height in the account are also considered confirmed by extension, as well as any dependent blocks from other account chains. This means the node can stop any elections for these lower blocks and remove them from any processing queues. This will save processing and bandwidth resources.

@clemahieu clemahieu force-pushed the optimistic-elections-2-rebased branch from df59041 to 2176199 Compare February 9, 2023 10:28
nano/node/active_transactions.cpp Outdated Show resolved Hide resolved
nano/node/node.cpp Outdated Show resolved Hide resolved
nano/test_common/chains.hpp Show resolved Hide resolved
nano/node/election.cpp Outdated Show resolved Hide resolved
@qwahzi
Copy link
Collaborator

qwahzi commented Feb 12, 2023

@pwojcikdev - I've been testing this for the last few days with good results, but it looks like my node just switched out of bootstrapping mode, even though it wasn't finished. Unchecked is suddenly capped to 256,000 (unchecked memory table?) and count/cemented drastically slowed down to ~20/hour (from 200k-300k/hr). It's probably not directly related to this branch/change, but I figured I'd report it just in case:

Sun Feb 12 08:00:01 AM CST 2023
{
    "count": "168740012",
    "unchecked": "11596953",
    "cemented": "168513871"
}

Sun Feb 12 12:56:01 PM CST 2023
{
    "count": "169643611",
    "unchecked": "256000",
    "cemented": "169559033"
}

Sun Feb 12 01:09:43 PM CST 2023
{
    "count": "169643635",
    "unchecked": "256000",
    "cemented": "169568762"
}

EDIT:

Per some Discord discussion, this is probably just the legacy bootstrap implementation - I'll wait for the updated ascending bootstrap client

@dsiganos
Copy link
Contributor

The latest bootstrap cutoff point is: 169643594.

@pwojcikdev
Copy link
Contributor Author

pwojcikdev commented Feb 13, 2023

@qwahzi This PR actually builds upon the improvements introduced in dependent block confirmation. It applies cross chain, so if we happen to confirm account A that has receives from B & C, then exactly as you said, both B & C chains will be confirmed (up to the associated sends). The problem before introduction of this PR was that there was no reliable mechanism to fully utilise those dependent elections.

It's worth noting that the current mechanism is still not working to the fullest potential. The biggest bottleneck I see is the vote requesting, which will be improved by vote generator refactor & vote storage.

# Conflicts:
#	nano/node/active_transactions.cpp
#	nano/node/election.cpp
#	nano/node/election.hpp
#	nano/node/election_scheduler.cpp
@clemahieu clemahieu force-pushed the optimistic-elections-2-rebased branch from 595857f to 0d74cab Compare February 14, 2023 20:16
…-2-rebased

# Conflicts:
#	nano/lib/stats_enums.hpp
pwojcikdev and others added 2 commits February 22, 2023 19:12
# Conflicts:
#	nano/core_test/active_transactions.cpp
#	nano/lib/stats_enums.hpp
#	nano/node/active_transactions.cpp
#	nano/node/active_transactions.hpp
#	nano/node/election.cpp
#	nano/node/election_scheduler.cpp
#	nano/node/node.cpp
@clemahieu clemahieu added documentation This item indicates the need for or supplies updated or expanded documentation major This item indicates the need for or supplies a major or notable change labels Feb 23, 2023
@clemahieu clemahieu added this to the V25.0 milestone Feb 23, 2023
@@ -210,8 +215,8 @@ int64_t nano::active_transactions::vacancy (nano::election_behavior behavior) co
case nano::election_behavior::normal:
return limit () - static_cast<int64_t> (roots.size ());
case nano::election_behavior::hinted:
case nano::election_behavior::optimistic:
return limit (nano::election_behavior::hinted) - count_by_behavior[nano::election_behavior::hinted];
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@clemahieu Merge introduced a small bug here, it should pass in 'behavior' parameter instead of fixed enum value.

@pwojcikdev pwojcikdev merged commit e1c893b into nanocurrency:develop Feb 23, 2023
qwahzi added a commit to qwahzi/nano-docs-1 that referenced this pull request May 24, 2023
Adding info for optimistic elections, based on Piotr's PR here: nanocurrency/nano-node#4111
thsfs pushed a commit to nanocurrency/nano-docs that referenced this pull request May 24, 2023
Adding info for optimistic elections, based on Piotr's PR here: nanocurrency/nano-node#4111
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation This item indicates the need for or supplies updated or expanded documentation major This item indicates the need for or supplies a major or notable change
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants