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

confirm_req_hash to reduce bandwidth usage #1046

Merged
merged 74 commits into from Jan 28, 2019
Merged
Show file tree
Hide file tree
Changes from 70 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
f7d6388
confirm_req_hash to reduce bandwidth usage
SergiySW Aug 10, 2018
eb2e587
Fixes
SergiySW Aug 10, 2018
7c9576f
Update tests
SergiySW Aug 10, 2018
165b61c
rai::network::send_confirm_req_hash
SergiySW Aug 10, 2018
bf515f6
Formatting
SergiySW Aug 10, 2018
94a6c26
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Aug 13, 2018
caa8328
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Aug 20, 2018
80cabfc
Confirm only hash for non-forked blocks
SergiySW Aug 20, 2018
4aef9f4
Merge confirm by hash to confirm_req
SergiySW Aug 29, 2018
35d745e
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Aug 29, 2018
e1948ef
Typo
SergiySW Aug 29, 2018
487098d
Typo
SergiySW Aug 29, 2018
49fb402
Fix issues
SergiySW Aug 29, 2018
72b65d1
Use send_confirm_req_hash in beta & test networks
SergiySW Aug 29, 2018
1fc9fed
Remove unsused variable
SergiySW Aug 29, 2018
0ea83e9
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Aug 30, 2018
07a2d86
Batch confirmation request
SergiySW Aug 30, 2018
4fbb215
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Sep 6, 2018
b5b7cc3
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Sep 6, 2018
df553be
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Sep 9, 2018
f6d8f97
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Sep 10, 2018
f6a6850
Logical errors
SergiySW Sep 10, 2018
20a09f7
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Sep 21, 2018
a2f8fc6
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Oct 6, 2018
18f5f3f
Returning correct files permissions
SergiySW Oct 6, 2018
13480a3
Merge branch 'master' into confirm_req_hash
rkeene Oct 23, 2018
324807e
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Oct 23, 2018
420a441
Simplify request by removing hash-only option
SergiySW Oct 23, 2018
5070ffb
Fix issues
SergiySW Oct 23, 2018
b79173f
confirm_req count for root-hash pairs
SergiySW Oct 23, 2018
efe33c0
Previous for send block cannot be 0
SergiySW Oct 23, 2018
be385cf
Send vote-by-hash if successor = requested block
SergiySW Oct 24, 2018
f836014
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Nov 7, 2018
9de62e4
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Nov 8, 2018
1c95053
merge upstream/master
SergiySW Nov 30, 2018
3083b75
merge upstream/master
SergiySW Dec 29, 2018
d3f386f
restore file permissions
SergiySW Dec 29, 2018
e948b84
Namespace renaming
SergiySW Dec 29, 2018
2da27fa
Networks remaning
SergiySW Dec 29, 2018
42d084b
Fix republish_block
SergiySW Dec 29, 2018
162ca2c
Update test message_parser.exact_confirm_req_hash_size
SergiySW Dec 29, 2018
f528546
Formatting
SergiySW Dec 29, 2018
a924154
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Jan 2, 2019
c1bf159
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Jan 5, 2019
5996b08
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Jan 8, 2019
2d82f5d
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Jan 18, 2019
894fe22
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Jan 18, 2019
f16fdc5
Add bitset for previous blocks in roots
SergiySW Jan 18, 2019
922cca3
Use bool[32] for previous blocks in roots
SergiySW Jan 18, 2019
629b3a2
Test block.confirm_req_hash_bacth_serialization
SergiySW Jan 18, 2019
3250c24
Typo
SergiySW Jan 18, 2019
86c8c26
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Jan 22, 2019
f2d4f45
Using auto & for vectors iteration
SergiySW Jan 22, 2019
4d392be
Fix
SergiySW Jan 23, 2019
c3f93a4
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Jan 23, 2019
d9e5b4d
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Jan 24, 2019
383ae31
Use range-based for loop
SergiySW Jan 25, 2019
c5e9bad
Use std::vector<uint8_t> bytes instead of shared pointer vector
SergiySW Jan 25, 2019
2f939e5
Fix message_parser.exact_confirm_req_hash_size test
SergiySW Jan 25, 2019
8cee904
Use nano::block in test instead of pointers
SergiySW Jan 25, 2019
9edb078
Use nano::block in test instead of pointers
SergiySW Jan 25, 2019
646f182
Use std::vector<uint8_t> bytes instead of shared pointer vector
SergiySW Jan 25, 2019
68b4577
Better vectors initialization
SergiySW Jan 25, 2019
55852b5
Correct assert for roots_hashes.size ()
SergiySW Jan 25, 2019
6272694
Make max hashes in confirm_req packet constant
SergiySW Jan 25, 2019
bbdc897
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Jan 26, 2019
6c88b3d
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Jan 27, 2019
f86356f
Increase protocol version to 16
SergiySW Jan 27, 2019
fb0bff0
Remove unused variable
SergiySW Jan 27, 2019
6c02611
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Jan 27, 2019
d41477b
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Jan 28, 2019
c7ebd90
Avoid using double root in confirm_req
SergiySW Jan 28, 2019
200ac37
Recent changes fix
SergiySW Jan 28, 2019
345606a
Merge remote-tracking branch 'upstream/master' into confirm_req_hash
SergiySW Jan 28, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
52 changes: 52 additions & 0 deletions nano/core_test/block.cpp
Expand Up @@ -332,6 +332,58 @@ TEST (block, confirm_req_serialization)
ASSERT_EQ (*req.block, *req2.block);
}

TEST (block, confirm_req_hash_serialization)
{
nano::keypair key1;
nano::keypair key2;
nano::send_block block (1, key2.pub, 200, nano::keypair ().prv, 2, 3);
nano::confirm_req req (block.hash (), nano::uint512_union (block.previous (), block.root ()));
std::vector<uint8_t> bytes;
{
nano::vectorstream stream (bytes);
req.serialize (stream);
}
auto error (false);
nano::bufferstream stream2 (bytes.data (), bytes.size ());
nano::message_header header (error, stream2);
nano::confirm_req req2 (error, stream2, header);
ASSERT_FALSE (error);
ASSERT_EQ (req, req2);
ASSERT_EQ (req.roots_hashes, req2.roots_hashes);
}

TEST (block, confirm_req_hash_batch_serialization)
{
nano::keypair key;
nano::keypair representative;
std::vector<std::pair<nano::block_hash, nano::uint512_union>> roots_hashes;
nano::state_block open (key.pub, 0, representative.pub, 2, 4, key.prv, key.pub, 5);
roots_hashes.push_back (std::make_pair (open.hash (), nano::uint512_union (open.previous (), open.root ())));
for (auto i (roots_hashes.size ()); i < 7; i++)
{
nano::keypair key1;
nano::keypair previous;
nano::state_block block (key1.pub, previous.pub, representative.pub, 2, 4, key1.prv, key1.pub, 5);
roots_hashes.push_back (std::make_pair (block.hash (), nano::uint512_union (block.previous (), block.root ())));
}
roots_hashes.push_back (std::make_pair (open.hash (), nano::uint512_union (0, open.root ())));
nano::confirm_req req (roots_hashes);
std::vector<uint8_t> bytes;
{
nano::vectorstream stream (bytes);
req.serialize (stream);
}
auto error (false);
nano::bufferstream stream2 (bytes.data (), bytes.size ());
nano::message_header header (error, stream2);
nano::confirm_req req2 (error, stream2, header);
ASSERT_FALSE (error);
ASSERT_EQ (req, req2);
ASSERT_EQ (req.roots_hashes, req2.roots_hashes);
ASSERT_EQ (req.roots_hashes, roots_hashes);
ASSERT_EQ (req2.roots_hashes, roots_hashes);
}

TEST (state_block, serialization)
{
nano::keypair key1;
Expand Down
32 changes: 32 additions & 0 deletions nano/core_test/message_parser.cpp
Expand Up @@ -130,6 +130,38 @@ TEST (message_parser, exact_confirm_req_size)
ASSERT_NE (parser.status, nano::message_parser::parse_status::success);
}

TEST (message_parser, exact_confirm_req_hash_size)
{
nano::system system (24000, 1);
test_visitor visitor;
nano::block_uniquer block_uniquer;
nano::vote_uniquer vote_uniquer (block_uniquer);
nano::message_parser parser (block_uniquer, vote_uniquer, visitor, system.work);
nano::send_block block (1, 1, 2, nano::keypair ().prv, 4, system.work.generate (1));
nano::confirm_req message (block.hash (), nano::uint512_union (block.previous (), block.root ()));
std::vector<uint8_t> bytes;
{
nano::vectorstream stream (bytes);
message.serialize (stream);
}
ASSERT_EQ (0, visitor.confirm_req_count);
ASSERT_EQ (parser.status, nano::message_parser::parse_status::success);
auto error (false);
nano::bufferstream stream1 (bytes.data (), bytes.size ());
nano::message_header header1 (error, stream1);
ASSERT_FALSE (error);
parser.deserialize_confirm_req (stream1, header1);
ASSERT_EQ (1, visitor.confirm_req_count);
ASSERT_EQ (parser.status, nano::message_parser::parse_status::success);
bytes.push_back (0);
nano::bufferstream stream2 (bytes.data (), bytes.size ());
nano::message_header header2 (error, stream2);
ASSERT_FALSE (error);
parser.deserialize_confirm_req (stream2, header2);
ASSERT_EQ (1, visitor.confirm_req_count);
ASSERT_NE (parser.status, nano::message_parser::parse_status::success);
}

TEST (message_parser, exact_publish_size)
{
nano::system system (24000, 1);
Expand Down
108 changes: 102 additions & 6 deletions nano/node/common.cpp
Expand Up @@ -302,7 +302,7 @@ void nano::message_parser::deserialize_confirm_req (nano::stream & stream_a, nan
nano::confirm_req incoming (error, stream_a, header_a, &block_uniquer);
if (!error && at_end (stream_a))
{
if (!nano::work_validate (*incoming.block))
if (incoming.block == nullptr || !nano::work_validate (*incoming.block))
{
visitor.confirm_req (incoming);
}
Expand Down Expand Up @@ -484,12 +484,59 @@ block (block_a)
{
header.block_type_set (block->type ());
}
nano::confirm_req::confirm_req (std::vector<std::pair<nano::block_hash, nano::uint512_union>> const & roots_hashes_a) :
message (nano::message_type::confirm_req),
roots_hashes (roots_hashes_a)
{
// not_a_block (1) block type for hashes + roots request
header.block_type_set (nano::block_type::not_a_block);
}

nano::confirm_req::confirm_req (nano::block_hash const & hash_a, nano::uint512_union const & root_a) :
message (nano::message_type::confirm_req),
roots_hashes (std::vector<std::pair<nano::block_hash, nano::uint512_union>> (1, std::make_pair (hash_a, root_a)))
{
assert (!roots_hashes.empty ());
// not_a_block (1) block type for hashes + roots request
header.block_type_set (nano::block_type::not_a_block);
}

bool nano::confirm_req::deserialize (nano::stream & stream_a, nano::block_uniquer * uniquer_a)
{
bool result (true);
assert (header.type == nano::message_type::confirm_req);
block = nano::deserialize_block (stream_a, header.block_type (), uniquer_a);
auto result (block == nullptr);
if (header.block_type () == nano::block_type::not_a_block)
{
uint8_t count (0);
result = read (stream_a, count);
assert (count <= 32);
bool roots_previous[32] = { false };
result = read (stream_a, roots_previous);
for (auto i (0); i != count && !result; ++i)
{
nano::block_hash block_hash (0);
nano::block_hash root (0);
result = read (stream_a, block_hash);
if (!result && !block_hash.is_zero ())
{
result = read (stream_a, root);
if (!result && !root.is_zero ())
{
nano::uint512_union root_uint512 (roots_previous[i] ? root : 0, root);
roots_hashes.push_back (std::make_pair (block_hash, root_uint512));
}
}
}
if (!result)
{
result = roots_hashes.empty () || (roots_hashes.size () != count);
}
}
else
{
block = nano::deserialize_block (stream_a, header.block_type (), uniquer_a);
result = block == nullptr;
}
return result;
}

Expand All @@ -500,14 +547,63 @@ void nano::confirm_req::visit (nano::message_visitor & visitor_a) const

void nano::confirm_req::serialize (nano::stream & stream_a) const
{
assert (block != nullptr);
header.serialize (stream_a);
block->serialize (stream_a);
if (header.block_type () == nano::block_type::not_a_block)
{
assert (!roots_hashes.empty ());
// Calculate size
assert (roots_hashes.size () <= 32);
uint8_t count (roots_hashes.size ());
write (stream_a, count);
/* Calculate uint512_union roots status
true = previous == root
false = previous == 0 */
bool roots_previous[32] = { false };
for (auto i (0); i != count; ++i)
{
roots_previous[i] = !roots_hashes[i].second.uint256s[0].is_zero ();
assert (roots_hashes[i].second.uint256s[0].is_zero () || roots_hashes[i].second.uint256s[0] == roots_hashes[i].second.uint256s[1]);
}
write (stream_a, roots_previous);
// Write hashes & roots
for (auto & root_hash : roots_hashes)
{
write (stream_a, root_hash.first);
write (stream_a, root_hash.second.uint256s[1]);
}
}
else
{
assert (block != nullptr);
block->serialize (stream_a);
}
}

bool nano::confirm_req::operator== (nano::confirm_req const & other_a) const
{
return *block == *other_a.block;
bool equal (false);
if (block != nullptr && other_a.block != nullptr)
{
equal = *block == *other_a.block;
}
else if (!roots_hashes.empty () && !other_a.roots_hashes.empty ())
{
equal = roots_hashes == other_a.roots_hashes;
}
return equal;
}

std::string nano::confirm_req::roots_string () const
{
std::string result;
for (auto & root_hash : roots_hashes)
{
result += root_hash.first.to_string ();
result += ":";
result += root_hash.second.to_string ();
result += ", ";
}
return result;
}

nano::confirm_ack::confirm_ack (bool & error_a, nano::stream & stream_a, nano::message_header const & header_a, nano::vote_uniquer * uniquer_a) :
Expand Down
4 changes: 4 additions & 0 deletions nano/node/common.hpp
Expand Up @@ -297,11 +297,15 @@ class confirm_req : public message
public:
confirm_req (bool &, nano::stream &, nano::message_header const &, nano::block_uniquer * = nullptr);
confirm_req (std::shared_ptr<nano::block>);
confirm_req (std::vector<std::pair<nano::block_hash, nano::uint512_union>> const &);
confirm_req (nano::block_hash const &, nano::uint512_union const &);
bool deserialize (nano::stream &, nano::block_uniquer * = nullptr);
void serialize (nano::stream &) const override;
void visit (nano::message_visitor &) const override;
bool operator== (nano::confirm_req const &) const;
std::shared_ptr<nano::block> block;
std::vector<std::pair<nano::block_hash, nano::uint512_union>> roots_hashes;
std::string roots_string () const;
};
class confirm_ack : public message
{
Expand Down