-
Notifications
You must be signed in to change notification settings - Fork 786
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
Batch state blocks signatures verification #956
Changes from 58 commits
f2a09de
43a1eb3
3cf25a0
1e3ee88
8816f91
798a9cc
d551bc5
ee9e144
fbf8194
9448c3d
d50d535
db7b505
2da990c
b37da3c
9764412
952e6f5
187a61f
7278510
fa56cae
002665a
cb345e1
9116d53
ce95b50
227b544
2a83923
4dbf4ac
998371d
f2058fb
29a3c65
8bc7d30
5430fb7
38174cc
60482af
0fd2285
78d094d
a9d403a
387593a
5aa2428
56174ab
0d961cc
b18596d
0acc71b
6ef07bd
6663bdc
82b52d0
b5fad43
b1b6ade
13a73c9
6118b53
62a7fde
1fd2e35
4785938
7a7b194
2e83193
4bad6d3
0550cc5
c025a5e
797d560
7468154
d86047c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -936,7 +936,7 @@ void rai::block_processor::stop () | |
void rai::block_processor::flush () | ||
{ | ||
std::unique_lock<std::mutex> lock (mutex); | ||
while (!stopped && (!blocks.empty () || active)) | ||
while (!stopped && (have_blocks () || active)) | ||
{ | ||
condition.wait (lock); | ||
} | ||
|
@@ -955,8 +955,14 @@ void rai::block_processor::add (std::shared_ptr<rai::block> block_a, std::chrono | |
std::lock_guard<std::mutex> lock (mutex); | ||
if (blocks_hashes.find (block_a->hash ()) == blocks_hashes.end ()) | ||
{ | ||
blocks.push_back (std::make_pair (block_a, origination)); | ||
blocks_hashes.insert (block_a->hash ()); | ||
if (block_a->type () == rai::block_type::state && block_a->link () != node.ledger.epoch_link) | ||
{ | ||
state_blocks.push_back (std::make_pair (block_a, origination)); | ||
} | ||
else | ||
{ | ||
blocks.push_back (std::make_pair (block_a, origination)); | ||
} | ||
condition.notify_all (); | ||
} | ||
} | ||
|
@@ -1010,16 +1016,61 @@ bool rai::block_processor::should_log () | |
bool rai::block_processor::have_blocks () | ||
{ | ||
assert (!mutex.try_lock ()); | ||
return !blocks.empty () || !forced.empty (); | ||
return !blocks.empty () || !forced.empty () || !state_blocks.empty (); | ||
} | ||
|
||
void rai::block_processor::verify_state_blocks (std::unique_lock<std::mutex> & lock_a) | ||
{ | ||
lock_a.lock (); | ||
std::deque<std::pair<std::shared_ptr<rai::block>, std::chrono::steady_clock::time_point>> items; | ||
items.swap (state_blocks); | ||
lock_a.unlock (); | ||
auto size (items.size ()); | ||
cryptocode marked this conversation as resolved.
Show resolved
Hide resolved
|
||
std::vector<rai::uint256_union> hashes; | ||
hashes.reserve (size); | ||
std::vector<unsigned char const *> messages; | ||
messages.reserve (size); | ||
std::vector<size_t> lengths; | ||
lengths.reserve (size); | ||
std::vector<unsigned char const *> pub_keys; | ||
pub_keys.reserve (size); | ||
std::vector<unsigned char const *> signatures; | ||
signatures.reserve (size); | ||
std::vector<int> verifications; | ||
verifications.resize (size); | ||
for (auto i (0); i < size; ++i) | ||
{ | ||
auto & block (static_cast<rai::state_block &> (*items[i].first)); | ||
hashes.push_back (block.hash ()); | ||
messages.push_back (hashes.back ().bytes.data ()); | ||
lengths.push_back (sizeof (decltype (hashes)::value_type)); | ||
pub_keys.push_back (block.hashables.account.bytes.data ()); | ||
signatures.push_back (block.signature.bytes.data ()); | ||
} | ||
auto code (rai::validate_message_batch (messages.data (), lengths.data (), pub_keys.data (), signatures.data (), size, verifications.data ())); | ||
(void)code; | ||
rkeene marked this conversation as resolved.
Show resolved
Hide resolved
|
||
lock_a.lock (); | ||
for (auto i (0); i < size; ++i) | ||
{ | ||
assert (verifications[i] == 1 || verifications[i] == 0); | ||
if (verifications[i] == 1) | ||
{ | ||
blocks.push_back (items.front ()); | ||
} | ||
items.pop_front (); | ||
} | ||
lock_a.unlock (); | ||
} | ||
|
||
void rai::block_processor::process_receive_many (std::unique_lock<std::mutex> & lock_a) | ||
{ | ||
verify_state_blocks (lock_a); | ||
{ | ||
auto transaction (node.store.tx_begin_write ()); | ||
auto start_time (std::chrono::steady_clock::now ()); | ||
lock_a.lock (); | ||
while (have_blocks () && std::chrono::steady_clock::now () - start_time < node.config.block_processor_batch_max_time) | ||
// Processing blocks | ||
while ((!blocks.empty () || !forced.empty ()) && std::chrono::steady_clock::now () - start_time < node.config.block_processor_batch_max_time) | ||
{ | ||
if (blocks.size () > 64 && should_log ()) | ||
{ | ||
|
@@ -1051,7 +1102,7 @@ void rai::block_processor::process_receive_many (std::unique_lock<std::mutex> & | |
node.ledger.rollback (transaction, successor->hash ()); | ||
} | ||
} | ||
auto process_result (process_receive_one (transaction, block.first, block.second)); | ||
auto process_result (process_receive_one (transaction, block.first, block.second, !force)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forced state blocks are not validated in verify_state_blocks () function There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but only state blocks vefirication can be skipped by flag in ledger.processor |
||
(void)process_result; | ||
lock_a.lock (); | ||
} | ||
|
@@ -1073,11 +1124,11 @@ void rai::block_processor::process_receive_many (std::unique_lock<std::mutex> & | |
} | ||
} | ||
|
||
rai::process_return rai::block_processor::process_receive_one (rai::transaction const & transaction_a, std::shared_ptr<rai::block> block_a, std::chrono::steady_clock::time_point origination) | ||
rai::process_return rai::block_processor::process_receive_one (rai::transaction const & transaction_a, std::shared_ptr<rai::block> block_a, std::chrono::steady_clock::time_point origination, bool validated_state_block) | ||
{ | ||
rai::process_return result; | ||
auto hash (block_a->hash ()); | ||
result = node.ledger.process (transaction_a, *block_a); | ||
result = node.ledger.process (transaction_a, *block_a, validated_state_block); | ||
switch (result.code) | ||
{ | ||
case rai::process_result::progress: | ||
|
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.
Should we
assert(false)
here (or just not implement this virtual function for non-state blocks) ? The receive block probably has the equivalent of a linkThere 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.
That's similar to source (), previous () & some other functions returning 0 for some block types. We can just not implement such functions when they return 0 I guess to save some lines in code
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.
Is this a case of using release_assert since we shouldn’t be looking for the link of non-state blocks?
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.
Either release_assert() or not declaring the virtual methods for these block types which should generate a fatal exception