-
Notifications
You must be signed in to change notification settings - Fork 648
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
Improve adjust_balance performance #1083 #1099
Conversation
Note: asset_api::get_asset_holders(...) and asset_api::get_all_asset_holders() will return unordered results after this change.
I'm thinking about adding a compile-time option, e.g. name it Looks like this approach can please both parties. Also not too hard to code (although the code would be uglier). Thoughts? |
That will work for me. Thanks for considering it.
El mar., jun. 26, 2018 9:22 PM, Abit <notifications@github.com> escribió:
… I'm thinking about adding a compile-time option, e.g. name it
ENABLE_ASSET_BALANCE_SORTING, disabled by default for better performance.
API nodes that want to enable asset::api can be compiled with that option
enabled. Or enable it by default?
Looks like this approach can please both parties. Also not too hard to
code.
Thoughts?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#1099 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AUrjaSnPKEm3dIPB3OaP4mg2buNkuQ4Jks5uAtAxgaJpZM4U4mTD>
.
|
Added new compile-option OP updated accordingly. |
Changed the new option to |
// From next maintenance interval, need to stop updating this account's active/owner. | ||
// Here we check if each asset is added earlier in this maintenance interval, | ||
// if yes, remove it from "added"; otherwise, add it to "removed". | ||
d.modify( special_meta, [&assets_before](special_assets_meta_object& p) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we are modifying a persisted data object. Could this cause problems if you run witness_node with ASSET_BALANCE_SORTED and later without (or vice-versa, or yes-no-yes, or no-yes-no)? I have not tested these situations, just typing out loud.
If it does cause problems, it seems the use of this feature will be rare. So are the symptoms easily detectable? If so, we could [log a message | force a replay]. We should also document the consequences.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good questions.
- when to replay
Currently only DB_VERSION
is used to detect whether need a replay.
Ideally the node should automatically detect a) whether db schema changed E.G. caused by code changes or compile-time option changes and b) whether certain options in config.ini
changed. But probably need too much work to make it perfect.
For this issue, a quick solution is to define DB_VERSION
to different values when using different compile-time options.
- automatically replay or not
The main concern is that replay takes long time. In case when a node operator accidentally ran a node with an incompatible data directory, being forced to replay is painful. So it makes some sense if the node refuses to start and shows an error message when incompatible db schema is detected.
IMHO these questions worth a new issue, or perhaps two issues.
@pmconrad @oxarbitrage your opinion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this issue, a quick solution is to define
DB_VERSION
to different values when using different compile-time options.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO the quick solution is good enough.
d6712c2
to
0ba0e30
Compare
0ba0e30
to
42de5b9
Compare
please note that each time the flag is changed you need to run mentioning this as i think it is not a solution to abuse. |
Usually I use two build directories or more to test different values. Don't know if there is a better way. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small fix to CMakeLists.txt
@@ -69,6 +69,13 @@ IF(NOT "${Boost_VERSION}" MATCHES "1.53(.*)") | |||
SET(Boost_LIBRARIES ${BOOST_LIBRARIES_TEMP} ${Boost_LIBRARIES}) | |||
ENDIF() | |||
|
|||
OPTION( ASSET_BALANCE_SORTING "Keep account_balance objects sorted by asset and amount, to be used in asset_api (ON OR OFF)" ON ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All code other than CMAKE uses ASSET_BALANCE_SORTED, but CMAKE is looking for ASSET_BALANCE_SORTING. The easier fix is to change it in CMakeLists.txt.
My opinion: ASSET_BALANCE_SORTING is not as descriptive as ASSET_BALANCE_SORTED. ASSET_BALANCE_SORTING makes me think it is not an ON/OFF option, but perhaps an algorithm choice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahhh, Now I see why that was done. CMake doesn't like it when their variables are the same name as compile variables. I think there is a workaround for more recent versions of cmake, but I haven't explored it. I'm cancelling my request for changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or change the CMAKE option to something else, e.g. SORT_ASSET_BALANCE
(verb+object)? To be honest I'm not good at naming things. Actually, when the option is ON
, we sort balances by asset + quantity
; when it's OFF
, we sort balances by asset
only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And I do not like haggling about variable names. Had we needed to chose one or the other, I was stating my opinion. But now we don't need to choose. I think your name is clear enough, especially with the option comment next to it.
add asset api test case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All looks good. I tested this along with the test created by @oxarbitrage in PR #1169 on Ubuntu 18.04, with ASSET_BALANCE_SORTING ON and OFF.
I am marking this approved, but perhaps merging PR 1169 into this branch before merging this into develop would be a good thing.
What should be the procedure in this case? Should I (a) "Request Changes" until 1169 is merged in here? Or (b) mark this "Approved" and keep 1169 independent?
Update: Merge happened while I was writing review. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be a good idea (and simplify the code) if you switch the special authority logic to the separate account_special_balance index unconditionally, and have the ASSET_BALANCE_SORTED flag only affect the sorting of asset balances.
The great advantage I see there is that the chain logic does not depend on a compile-time flag.
b.balance = delta.amount.value; | ||
if( b.asset_type == asset_id_type() ) // CORE asset | ||
b.balance = delta.amount; | ||
if( maint_flag ) | ||
b.maintenance_flag = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use unconditional set: b.maintenance_flag = maint_flag;
flat_set<asset_id_type> account_object::get_top_n_control_assets() const | ||
{ | ||
flat_set<asset_id_type> result; | ||
if( owner_special_authority.which() == special_authority::tag< top_holders_special_authority >::value ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
visitor pattern might look better here
p.special_assets_added_this_interval.insert( a ); | ||
} | ||
}); | ||
#endif | ||
} | ||
|
||
return void_result(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO the handling of special_assets_meta_object is broken in several respects:
- account_create_evaluator::do_apply can create special authorities, similar code needs to be added there as well
- you don't handle the case if an account switches from one asset to another (i. e. both sa_before and sa_after are true)
- you cannot remove an asset just because an account doesn't use it anymore - it could still be used by a different account
Please add unit tests for all of these.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. My bad. Apparently the code is incomplete. I don't know why I didn't realize it. Perhaps I was thinking that it's updating an asset but not an account.
Still need much work to get this PR done, and it's possible that we won't merge it at all. I've removed it from this release, and will rebase other PR's which were based on it to be based on develop branch, hope that they can get merged for the coming release.
If we switch the special authority logic to the separate Actually, as mentioned in the in-code comments, if there are too many accounts with special authorities, or the configured assets have too many holders (E.G. BTS), the approach done in this PR (massive data copy on maintenance interval) can greatly impact performance, which can be considered as an attack factor. I guess I'll abandon the whole idea and close this PR. Some code may still be usable, so I will cherry-pick them to a new branch and submit a new PR. Hope that we can find a better solution. |
PR for #1083.
In this PR we added a new compile-time option:
ASSET_BALANCE_SORTING
, enabled by default.27,000,000
blocks reduced by1 - 5063/5633 ~= 10%.
More profiling data is here: Improve adjust_balance performance #1083 (comment)asset_api::get_asset_holders(...)
andasset_api::get_all_asset_holders()
will return unordered results.To disable the new compile-time option (before compiling):