You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bug Description public_key_type has no operator< implementation, but it can be implicitly converted to address (at the cost of a SHA512 calculation) which does. Thus any set or map keyed on public_key_type does two SHA512 calculations per operator< call. This is ridiculously slow.
Impacts
Describe which portion(s) of Peerplays may be impacted by this bug. Please tick at least one box.
API (the application programming interface)
Build (the build process or something prior to compiled code)
CLI (the command line wallet)
Deployment (the deployment process after building such as Docker, Gitlab, etc.)
P2P (the peer-to-peer network for transaction/block propagation)
Performance (system or user efficiency, etc.)
Protocol (the blockchain logic, consensus, validation, etc.)
Security (the security of system or user data, etc.)
UX (the User Experience)
Other (please add below)
Additional Context (optional)
Benching code:
BOOST_AUTO_TEST_CASE(public_key_type_comparison) {
flat_set<public_key_type> s1;
for (int i = 0; i < 5; ++i)
s1.insert(fc::ecc::private_key::generate().get_public_key());
flat_set<public_key_type, pubkey_comparator> s2(s1.begin(), s1.end());
constint rounds = 1'000'000;
auto start = fc::time_point::now();
for (int i = 0; i < rounds; ++i)
BOOST_CHECK(s1.contains(*s1.begin()));
auto end = fc::time_point::now();
wlog("public_key_type default comparion: ${rounds} rounds in ${ms} ms",
("rounds", rounds)("ms", (end-start).count()/1000));
start = fc::time_point::now();
for (int i = 0; i < rounds; ++i)
BOOST_CHECK(s2.contains(*s2.begin()));
end = fc::time_point::now();
wlog("public_key_type proper comparion: ${rounds} rounds in ${ms} ms",
("rounds", rounds)("ms", (end-start).count()/1000));
}
Output:
83440ms th_a performance_tests.cpp:67 test_method ] public_key_type default comparion: 1000000 rounds in 5637 ms
83772ms th_a performance_tests.cpp:75 test_method ] public_key_type proper comparion: 1000000 rounds in 332 ms
PBSA / Developer tasks
Evaluate / Prioritize Bug Report
Refine User Stories / Requirements
Define Test Cases
Design / Develop Solution
Perform QA/Testing
Update Documentation
The text was updated successfully, but these errors were encountered:
As it turns out, this issue has been known to BitShares for at least a couple of years and they haven't fixed it because it may affect consensus. See BitShares #2248 for more information. For this reason, it is not safe to implement the most obvious solution, as in #377. Unfortunately, it does not appear as though BitShares has identified exactly which locations of the code may be susceptible to forking if the sorting order of public_key_types is changed.
If Peerplays wishes to fix this issue, probably the safest and simplest way is to add a constructor to pubkey_comparator which takes a callback to get the current blockchain time, i.e. a std::function<fc::time_point_sec()> and call that to compare the current time against the hardfork time each time the comparator is invoked, to determine which less-than operation to use. Then all comparisons of public_key_type should be converted to use pubkey_comparator.
To find all comparisons of public_key_type, add the following to its definition, like in #377:
The compiler will throw an error giving the location of each use of the operator. Convert each location to use pubkey_comparator until no errors persist.
Bug Description
public_key_type
has nooperator<
implementation, but it can be implicitly converted toaddress
(at the cost of a SHA512 calculation) which does. Thus anyset
ormap
keyed onpublic_key_type
does two SHA512 calculations peroperator<
call. This is ridiculously slow.Impacts
Describe which portion(s) of Peerplays may be impacted by this bug. Please tick at least one box.
Additional Context (optional)
Benching code:
Output:
PBSA / Developer tasks
The text was updated successfully, but these errors were encountered: