-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Replay/Resync Optimizations: Low Hanging Fruit #5130
Replay/Resync Optimizations: Low Hanging Fruit #5130
Conversation
…ss necessary - dont add transactions to dedup if they will expire before replay ends - dont do various checks that cannot fail inside trx_context
…e-all-checks flag
maybe_session( maybe_session&& other) | ||
:_session(move(other._session)) | ||
{ | ||
} |
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 consistency with operator=()
add other._session.reset()
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.
the move constructor of _session handles that.
Unfortunately, the move assignment operator for fc::optional
is broken so, I had to replicate some of its features (just not the broken part).
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 wonder what if anything fixing the fc::optional
move assignment operator would break.
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.
Technically neither is broken as moved from state is unspecified, just must allow any methods with no prerequisites.
libraries/chain/controller.cpp
Outdated
auto guard_pending = fc::make_scoped_exit([this](){ | ||
pending.reset(); | ||
}); | ||
|
||
pending = db.start_undo_session(true); | ||
bool skip_db_sessions = !conf.disable_replay_opts && (s == controller::block_status::irreversible); | ||
if (!skip_db_sessions) { |
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.
If you move the pending->_block_status = s;
line up above here, you could use the new skip_db_sessions()
instead and consolidate that logic.
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 have to revert this change, the branch is what instantiates the inner pending block for that optional. so this change creates a bad access
libraries/chain/controller.cpp
Outdated
} | ||
|
||
bool controller::skip_trx_checks() const { | ||
return !my->conf.disable_replay_opts &&my->pending && !my->in_trx_requiring_checks && (my->pending->_block_status == block_status::irreversible || my->pending->_block_status == block_status::validated); |
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.
Since I recommended some other changes, I'll point out this space problem with &&
.
libraries/chain/controller.cpp
Outdated
@@ -815,14 +870,19 @@ struct controller_impl { | |||
void start_block( block_timestamp_type when, uint16_t confirm_block_count, controller::block_status s ) { | |||
EOS_ASSERT( !pending, block_validate_exception, "pending block is not available" ); |
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.
Since you are here, can you fix the assert message. It is backwards.
This mode enables skipping of auth checks, transaction signature recovery and other tests that can be inferred as passed if the node implicitly trusts the active set of producers to maintain correctness
Identified and implemented some low hanging fruit for Replays where we assume the block.log is trusted.
Replay
The optimizations
The caveats
A new config/cli option is provided
disable-replay-opts
which will disable all of the above optimizations and result in the current processing of replay. There are a few reasons why this option may be neccessary:The Results
A very basic test of v1.1.1, v1.1.3 and the new optimizations on my development machine yields:
(re)sync
Light validation mode
This mode enables skipping of auth checks, transaction signature recovery and other tests that can be inferred as passed if the node implicitly trusts the active set of producers to maintain correctness. This is essentially the same trust semantics that a header-validating light client would have.
The Caveats
This is not safe for use on any node that does not implicitly trust the elected set of producers. That should include the other elected producers (this mode is considered invalid if you are running a production node).
This mode is intended to help nodes (re)syncing from trusted peers and any other node that can outsource trust to a set of independent validators. For example, nodes that maintain MongoDB integration behind a layer of full validation-mode peers, or a new node that is syncing into an established blockchain and has well-known-checkpoints to enforce validity.