diff --git a/mu_coin/mu_coin.cpp b/mu_coin/mu_coin.cpp index c581151e..2a2ea8c8 100644 --- a/mu_coin/mu_coin.cpp +++ b/mu_coin/mu_coin.cpp @@ -1069,11 +1069,36 @@ void mu_coin::network::receive_action (boost::system::error_code const & error, case mu_coin::message_type::publish_con: { ++publish_con_count; + auto incoming (new mu_coin::publish_con); + mu_coin::byte_read_stream stream (buffer.data (), size_a); + auto error (incoming->deserialize (stream)); + receive (); + if (!error) + { + std::unique_lock lock (mutex); + auto session (publish_listeners.find (incoming->block)); + if (session != publish_listeners.end ()) + { + lock.release (); + session->second (std::unique_ptr {incoming}, sender); + } + } break; } case mu_coin::message_type::publish_dup: { ++publish_dup_count; + auto incoming (new mu_coin::publish_dup); + mu_coin::byte_read_stream stream (buffer.data (), size_a); + auto error (incoming->deserialize (stream)); + receive (); + if (!error) + { + std::unique_lock lock (mutex); + auto session (publish_listeners.find (incoming->block)); + lock.release (); + session->second (std::unique_ptr {incoming}, sender); + } break; } case mu_coin::message_type::publish_unk: @@ -1697,6 +1722,14 @@ void mu_coin::publish_nak::visit (mu_coin::message_visitor & visitor_a) void mu_coin::publish_con::serialize (mu_coin::byte_write_stream & stream) { stream.write (mu_coin::message_type::publish_con); + stream.write (block); + assert (authorizations.size () < 256); + auto authorization_count (static_cast (authorizations.size ())); + stream.write (authorization_count); + for (auto i (authorizations.begin ()), j (authorizations.end ()); i != j; ++i) + { + stream.write (*i); + } } bool mu_coin::publish_con::deserialize (mu_coin::byte_read_stream & stream) @@ -1704,6 +1737,20 @@ bool mu_coin::publish_con::deserialize (mu_coin::byte_read_stream & stream) mu_coin::message_type type; auto result (stream.read (type)); assert (type == mu_coin::message_type::publish_con); + result = stream.read (block); + if (!result) + { + uint8_t authorizations_count; + result = stream.read (authorizations_count); + if (!result) + { + for (auto i (0); i < authorizations_count; ++i) + { + authorizations.push_back (mu_coin::authorization {}); + stream.read (authorizations.back ()); + } + } + } return result; } @@ -1771,4 +1818,22 @@ size_t mu_coin::network::publish_listener_size () mu_coin::publish_con::publish_con (mu_coin::block_hash const & block_a) : block (block_a) { +} + +bool mu_coin::publish_dup::deserialize (mu_coin::byte_read_stream & stream) +{ + mu_coin::message_type type; + auto result (stream.read (type)); + assert (type == mu_coin::message_type::publish_dup); + return result; +} + +bool mu_coin::publish_con::operator == (mu_coin::publish_con const & other_a) const +{ + return block == other_a.block && authorizations == other_a.authorizations; +} + +bool mu_coin::authorization::operator == (mu_coin::authorization const & other_a) const +{ + return address == other_a.address && signature == other_a.signature; } \ No newline at end of file diff --git a/mu_coin/mu_coin.hpp b/mu_coin/mu_coin.hpp index 73081629..c1829962 100644 --- a/mu_coin/mu_coin.hpp +++ b/mu_coin/mu_coin.hpp @@ -345,6 +345,7 @@ namespace mu_coin { public: mu_coin::address address; mu_coin::signature signature; + bool operator == (mu_coin::authorization const &) const; }; class message_visitor; class message @@ -380,10 +381,12 @@ namespace mu_coin { class publish_con : public message { public: + publish_con () = default; publish_con (mu_coin::block_hash const &); bool deserialize (mu_coin::byte_read_stream &); void serialize (mu_coin::byte_write_stream &); void visit (mu_coin::message_visitor &) override; + bool operator == (mu_coin::publish_con const &) const; mu_coin::block_hash block; std::vector authorizations; }; diff --git a/mu_coin_test/block.cpp b/mu_coin_test/block.cpp index 8952b5a3..82bcde19 100644 --- a/mu_coin_test/block.cpp +++ b/mu_coin_test/block.cpp @@ -254,4 +254,21 @@ TEST (send_block, copy) block1.signatures.push_back (mu_coin::uint512_union ()); mu_coin::send_block block2 (block1); ASSERT_EQ (block1, block2); +} + +TEST (publish_con, serialization) +{ + mu_coin::block_hash hash; + mu_coin::publish_con con1 {hash}; + mu_coin::keypair key1; + mu_coin::signature signature; + mu_coin::sign_message (key1.prv, key1.pub, hash, signature); + mu_coin::authorization authorization {key1.pub, signature}; + con1.authorizations.push_back (authorization); + mu_coin::byte_write_stream stream1; + con1.serialize (stream1); + mu_coin::byte_read_stream stream2 (stream1.data, stream1.size); + mu_coin::publish_con con2; + con2.deserialize (stream2); + ASSERT_EQ (con1, con2); } \ No newline at end of file