diff --git a/libraries/core_libs/consensus/include/pillar_chain/bls_signature.hpp b/libraries/core_libs/consensus/include/pillar_chain/bls_signature.hpp index fbe83613b4..68909fc191 100644 --- a/libraries/core_libs/consensus/include/pillar_chain/bls_signature.hpp +++ b/libraries/core_libs/consensus/include/pillar_chain/bls_signature.hpp @@ -1,14 +1,15 @@ #pragma once -#include "common/types.hpp" #include #include + #include + +#include "common/types.hpp" #include "pillar_chain/pillar_block.hpp" namespace taraxa { - /** @addtogroup PILLAR_CHAIN * @{ */ @@ -23,7 +24,8 @@ class BlsSignature { public: BlsSignature(const dev::RLP& rlp); - BlsSignature(PillarBlock::Hash pillar_block_hash, const libff::alt_bn128_G2& public_key, const libff::alt_bn128_Fr& secret); + BlsSignature(PillarBlock::Hash pillar_block_hash, const libff::alt_bn128_G2& public_key, + const libff::alt_bn128_Fr& secret); /** * @brief Validates BLS signature diff --git a/libraries/core_libs/consensus/include/pillar_chain/pillar_chain_manager.hpp b/libraries/core_libs/consensus/include/pillar_chain/pillar_chain_manager.hpp index e01fdf14d5..fd03ebf42a 100644 --- a/libraries/core_libs/consensus/include/pillar_chain/pillar_chain_manager.hpp +++ b/libraries/core_libs/consensus/include/pillar_chain/pillar_chain_manager.hpp @@ -54,10 +54,10 @@ class PillarChainManager { bool addVerifiedBlsSig(const std::shared_ptr& signature); /** - * @brief Get all bls signatures + * @brief Get all bls signatures for specified pillar block * @return all bls signatures */ - // std::vector> getVerifiedBlsSigs() const; + std::vector> getVerifiedBlsSigs(const PillarBlock::Hash pillar_block_hash) const; private: std::shared_ptr db_; diff --git a/libraries/core_libs/consensus/src/pillar_chain/bls_signature.cpp b/libraries/core_libs/consensus/src/pillar_chain/bls_signature.cpp index c7ae525fee..d1064cbfb7 100644 --- a/libraries/core_libs/consensus/src/pillar_chain/bls_signature.cpp +++ b/libraries/core_libs/consensus/src/pillar_chain/bls_signature.cpp @@ -1,33 +1,40 @@ #include "pillar_chain/bls_signature.hpp" -#include "common/encoding_rlp.hpp" + #include +#include "common/encoding_rlp.hpp" + namespace taraxa { BlsSignature::BlsSignature(const dev::RLP& rlp) { - // TODO: parse rlp -} + std::string sig_str, pk_str; + util::rlp_tuple(util::RLPDecoderRef(rlp, true), pillar_block_hash_, sig_str, pk_str); -BlsSignature::BlsSignature(PillarBlock::Hash pillar_block_hash, const libff::alt_bn128_G2& public_key, const libff::alt_bn128_Fr& secret) { - pillar_block_hash_ = pillar_block_hash; - public_key_ = public_key; - signature_ = libBLS::Bls::CoreSignAggregated( pillar_block_hash_.toString(), secret ); + std::stringstream(sig_str) >> signature_; + std::stringstream(pk_str) >> public_key_; } -bool BlsSignature::isValid() const { - return libBLS::Bls::CoreVerify( public_key_, pillar_block_hash_.toString(), signature_); -} +BlsSignature::BlsSignature(PillarBlock::Hash pillar_block_hash, const libff::alt_bn128_G2& public_key, + const libff::alt_bn128_Fr& secret) + : pillar_block_hash_(pillar_block_hash), + signature_(libBLS::Bls::CoreSignAggregated(getHash().toString(), secret)), + public_key_(public_key) {} -blk_hash_t BlsSignature::getPillarBlockHash() const { - return pillar_block_hash_; -} +bool BlsSignature::isValid() const { return libBLS::Bls::CoreVerify(public_key_, getHash().toString(), signature_); } + +blk_hash_t BlsSignature::getPillarBlockHash() const { return pillar_block_hash_; } dev::bytes BlsSignature::getRlp() const { - dev::RLPStream s(1); + dev::RLPStream s(3); s << pillar_block_hash_; - // TODO: add signature into rlp - //s << signature_; - //s << public_key_; + + std::stringstream sig_ss; + sig_ss << signature_; + s << sig_ss.str(); + + std::stringstream pk_ss; + pk_ss << public_key_; + s << pk_ss.str(); return s.invalidate(); } diff --git a/libraries/core_libs/consensus/src/pillar_chain/pillar_chain_manager.cpp b/libraries/core_libs/consensus/src/pillar_chain/pillar_chain_manager.cpp index 2c3325f304..748d06b026 100644 --- a/libraries/core_libs/consensus/src/pillar_chain/pillar_chain_manager.cpp +++ b/libraries/core_libs/consensus/src/pillar_chain/pillar_chain_manager.cpp @@ -70,8 +70,28 @@ bool PillarChainManager::isRelevantBlsSig(const std::shared_ptr si bool PillarChainManager::addVerifiedBlsSig(const std::shared_ptr& signature) { std::scoped_lock lock(mutex_); - // TODO: adjust also last_pillar_block_signatures_weight_ - return last_pillar_block_signatures_.emplace(std::make_pair(signature->getHash(), signature)).second; + if (last_pillar_block_signatures_.emplace(std::make_pair(signature->getHash(), signature)).second) { + // TODO: adjust also last_pillar_block_signatures_weight_ + + return true; + } + + return false; +} + +std::vector> PillarChainManager::getVerifiedBlsSigs(const PillarBlock::Hash pillar_block_hash) const { + std::shared_lock lock(mutex_); + if (pillar_block_hash != last_pillar_block_->getHash()) { + return {}; + } + + std::vector> signatures; + signatures.reserve(last_pillar_block_signatures_.size()); + for (const auto& sig: last_pillar_block_signatures_) { + signatures.push_back(sig.second); + } + + return signatures; } void PillarChainManager::setNetwork(std::weak_ptr network) { network_ = std::move(network); } diff --git a/libraries/core_libs/network/include/network/tarcap/packet_types.hpp b/libraries/core_libs/network/include/network/tarcap/packet_types.hpp index 7defb0338c..a2bc3694bb 100644 --- a/libraries/core_libs/network/include/network/tarcap/packet_types.hpp +++ b/libraries/core_libs/network/include/network/tarcap/packet_types.hpp @@ -30,6 +30,8 @@ enum SubprotocolPacketType : uint32_t { PbftSyncPacket, GetDagSyncPacket, BlsSigPacket, + GetBlsSigsBundlePacket, + BlsSigsBundlePacket, PacketCount }; @@ -60,6 +62,12 @@ inline std::string convertPacketTypeToString(SubprotocolPacketType packet_type) return "GetPbftSyncPacket"; case PbftSyncPacket: return "PbftSyncPacket"; + case BlsSigPacket: + return "BlsSigPacket"; + case GetBlsSigsBundlePacket: + return "GetBlsSigsBundlePacket"; + case BlsSigsBundlePacket: + return "BlsSigsBundlePacket"; default: break; } diff --git a/libraries/core_libs/network/include/network/tarcap/packets_handlers/latest/bls_sig_packet_handler.hpp b/libraries/core_libs/network/include/network/tarcap/packets_handlers/latest/bls_sig_packet_handler.hpp index 1e45ea653a..9f891221c1 100644 --- a/libraries/core_libs/network/include/network/tarcap/packets_handlers/latest/bls_sig_packet_handler.hpp +++ b/libraries/core_libs/network/include/network/tarcap/packets_handlers/latest/bls_sig_packet_handler.hpp @@ -1,11 +1,10 @@ #pragma once -#include "common/packet_handler.hpp" -#include "pillar_chain/pillar_chain_manager.hpp" +#include "common/ext_bls_sig_packet_handler.hpp" namespace taraxa::network::tarcap { -class BlsSigPacketHandler : public PacketHandler { +class BlsSigPacketHandler : public ExtBlsSigPacketHandler { public: BlsSigPacketHandler(const FullNodeConfig& conf, std::shared_ptr peers_state, std::shared_ptr packets_stats, @@ -24,8 +23,6 @@ class BlsSigPacketHandler : public PacketHandler { protected: constexpr static size_t kBlsSigPacketSize{1}; - - std::shared_ptr pillar_chain_manager_; }; } // namespace taraxa::network::tarcap diff --git a/libraries/core_libs/network/include/network/tarcap/packets_handlers/latest/bls_sigs_bundle_packet_handler.hpp b/libraries/core_libs/network/include/network/tarcap/packets_handlers/latest/bls_sigs_bundle_packet_handler.hpp new file mode 100644 index 0000000000..16748dcca4 --- /dev/null +++ b/libraries/core_libs/network/include/network/tarcap/packets_handlers/latest/bls_sigs_bundle_packet_handler.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include "common/ext_bls_sig_packet_handler.hpp" + +namespace taraxa::network::tarcap { + +class BlsSigsBundlePacketHandler : public ExtBlsSigPacketHandler { + public: + BlsSigsBundlePacketHandler(const FullNodeConfig& conf, std::shared_ptr peers_state, + std::shared_ptr packets_stats, + std::shared_ptr pillar_chain_manager, const addr_t& node_addr, + const std::string& logs_prefix); + + // Packet type that is processed by this handler + static constexpr SubprotocolPacketType kPacketType_ = SubprotocolPacketType::BlsSigsBundlePacket; + + private: + virtual void validatePacketRlpFormat(const threadpool::PacketData& packet_data) const override; + virtual void process(const threadpool::PacketData& packet_data, const std::shared_ptr& peer) override; + + protected: + constexpr static size_t kMaxSignaturesInBundleRlp{250}; +}; + +} // namespace taraxa::network::tarcap diff --git a/libraries/core_libs/network/include/network/tarcap/packets_handlers/latest/common/ext_bls_sig_packet_handler.hpp b/libraries/core_libs/network/include/network/tarcap/packets_handlers/latest/common/ext_bls_sig_packet_handler.hpp new file mode 100644 index 0000000000..0e7fe1c10e --- /dev/null +++ b/libraries/core_libs/network/include/network/tarcap/packets_handlers/latest/common/ext_bls_sig_packet_handler.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "packet_handler.hpp" +#include "pillar_chain/pillar_chain_manager.hpp" + +namespace taraxa::network::tarcap { + +class ExtBlsSigPacketHandler : public PacketHandler { + public: + ExtBlsSigPacketHandler(const FullNodeConfig& conf, std::shared_ptr peers_state, + std::shared_ptr packets_stats, + std::shared_ptr pillar_chain_manager, const addr_t& node_addr, + const std::string& logs_prefix); + + protected: + void processBlsSignature(const std::shared_ptr& signature, const std::shared_ptr& peer); + + protected: + std::shared_ptr pillar_chain_manager_; +}; + +} // namespace taraxa::network::tarcap diff --git a/libraries/core_libs/network/include/network/tarcap/packets_handlers/latest/get_bls_sigs_bundle_packet_handler.hpp b/libraries/core_libs/network/include/network/tarcap/packets_handlers/latest/get_bls_sigs_bundle_packet_handler.hpp new file mode 100644 index 0000000000..93deb71589 --- /dev/null +++ b/libraries/core_libs/network/include/network/tarcap/packets_handlers/latest/get_bls_sigs_bundle_packet_handler.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "common/packet_handler.hpp" +#include "pillar_chain/pillar_block.hpp" +#include "pillar_chain/pillar_chain_manager.hpp" + +namespace taraxa::network::tarcap { + +class GetBlsSigsBundlePacketHandler : public PacketHandler { + public: + GetBlsSigsBundlePacketHandler(const FullNodeConfig& conf, std::shared_ptr peers_state, + std::shared_ptr packets_stats, + std::shared_ptr pillar_chain_manager, const addr_t& node_addr, + const std::string& logs_prefix); + + void requestBlsSigsBundle(PillarBlock::Hash pillar_block_hash, const std::shared_ptr& peer); + + // Packet type that is processed by this handler + static constexpr SubprotocolPacketType kPacketType_ = SubprotocolPacketType::GetBlsSigsBundlePacket; + + private: + virtual void validatePacketRlpFormat(const threadpool::PacketData& packet_data) const override; + virtual void process(const threadpool::PacketData& packet_data, const std::shared_ptr& peer) override; + + protected: + constexpr static size_t kGetBlsSigsPacketSize{1}; + + std::shared_ptr pillar_chain_manager_; +}; + +} // namespace taraxa::network::tarcap diff --git a/libraries/core_libs/network/src/tarcap/packets_handlers/latest/bls_sig_packet_handler.cpp b/libraries/core_libs/network/src/tarcap/packets_handlers/latest/bls_sig_packet_handler.cpp index 2431ae3fa9..6c382e3eac 100644 --- a/libraries/core_libs/network/src/tarcap/packets_handlers/latest/bls_sig_packet_handler.cpp +++ b/libraries/core_libs/network/src/tarcap/packets_handlers/latest/bls_sig_packet_handler.cpp @@ -1,15 +1,13 @@ #include "network/tarcap/packets_handlers/latest/bls_sig_packet_handler.hpp" -#include "pillar_chain/pillar_chain_manager.hpp" - namespace taraxa::network::tarcap { BlsSigPacketHandler::BlsSigPacketHandler(const FullNodeConfig &conf, std::shared_ptr peers_state, std::shared_ptr packets_stats, std::shared_ptr pillar_chain_manager, const addr_t &node_addr, const std::string &logs_prefix) - : PacketHandler(conf, std::move(peers_state), std::move(packets_stats), node_addr, logs_prefix + "BLS_SIG_PH"), - pillar_chain_manager_{std::move(pillar_chain_manager)} {} + : ExtBlsSigPacketHandler(conf, std::move(peers_state), std::move(packets_stats), std::move(pillar_chain_manager), + node_addr, logs_prefix + "BLS_SIG_PH") {} void BlsSigPacketHandler::validatePacketRlpFormat([[maybe_unused]] const threadpool::PacketData &packet_data) const { auto items = packet_data.rlp_.itemCount(); @@ -19,29 +17,15 @@ void BlsSigPacketHandler::validatePacketRlpFormat([[maybe_unused]] const threadp } void BlsSigPacketHandler::process(const threadpool::PacketData &packet_data, const std::shared_ptr &peer) { - const auto bls_signature = std::make_shared(packet_data.rlp_[0]); - - if (!pillar_chain_manager_->isRelevantBlsSig(bls_signature)) { - LOG(log_dg_) << "Drop irrelevant signature " << bls_signature->getHash() << " from peer " << peer->getId(); - } - - if (!bls_signature->isValid()) { - std::ostringstream err_msg; - err_msg << "Invalid signature " << bls_signature->getHash() << " from peer " << peer->getId(); - throw MaliciousPeerException(err_msg.str()); - } - - pillar_chain_manager_->addVerifiedBlsSig(bls_signature); - - // Mark bls signature as known for peer - peer->markBlsSigAsKnown(bls_signature->getHash()); + const auto bls_signature = std::make_shared(packet_data.rlp_); + processBlsSignature(bls_signature, peer); onNewBlsSig(bls_signature); } void BlsSigPacketHandler::onNewBlsSig(const std::shared_ptr &signature, bool rebroadcast) { for (const auto &peer : peers_state_->getAllPeers()) { if (peer.second->syncing_) { - LOG(log_dg_) << " PBFT vote " << signature << " not sent to " << peer.first << " peer syncing"; + LOG(log_dg_) << "BLS signature " << signature->getHash() << " not sent to " << peer.first << " peer syncing"; continue; } diff --git a/libraries/core_libs/network/src/tarcap/packets_handlers/latest/bls_sigs_bundle_packet_handler.cpp b/libraries/core_libs/network/src/tarcap/packets_handlers/latest/bls_sigs_bundle_packet_handler.cpp new file mode 100644 index 0000000000..9e33c53bb4 --- /dev/null +++ b/libraries/core_libs/network/src/tarcap/packets_handlers/latest/bls_sigs_bundle_packet_handler.cpp @@ -0,0 +1,29 @@ +#include "network/tarcap/packets_handlers/latest/bls_sigs_bundle_packet_handler.hpp" + +namespace taraxa::network::tarcap { + +BlsSigsBundlePacketHandler::BlsSigsBundlePacketHandler(const FullNodeConfig &conf, + std::shared_ptr peers_state, + std::shared_ptr packets_stats, + std::shared_ptr pillar_chain_manager, + const addr_t &node_addr, const std::string &logs_prefix) + : ExtBlsSigPacketHandler(conf, std::move(peers_state), std::move(packets_stats), std::move(pillar_chain_manager), + node_addr, logs_prefix + "BLS_SIGS_BUNDLE_PH") {} + +void BlsSigsBundlePacketHandler::validatePacketRlpFormat( + [[maybe_unused]] const threadpool::PacketData &packet_data) const { + auto items = packet_data.rlp_.itemCount(); + if (items == 0 || items > kMaxSignaturesInBundleRlp) { + throw InvalidRlpItemsCountException(packet_data.type_str_, items, kMaxSignaturesInBundleRlp); + } +} + +void BlsSigsBundlePacketHandler::process(const threadpool::PacketData &packet_data, + const std::shared_ptr &peer) { + for (const auto signature_rlp : packet_data.rlp_) { + const auto bls_signature = std::make_shared(signature_rlp); + processBlsSignature(bls_signature, peer); + } +} + +} // namespace taraxa::network::tarcap diff --git a/libraries/core_libs/network/src/tarcap/packets_handlers/latest/common/ext_bls_sig_packet_handler.cpp b/libraries/core_libs/network/src/tarcap/packets_handlers/latest/common/ext_bls_sig_packet_handler.cpp new file mode 100644 index 0000000000..4433395ca3 --- /dev/null +++ b/libraries/core_libs/network/src/tarcap/packets_handlers/latest/common/ext_bls_sig_packet_handler.cpp @@ -0,0 +1,32 @@ +#include "network/tarcap/packets_handlers/latest/common/ext_bls_sig_packet_handler.hpp" + +#include "pillar_chain/pillar_chain_manager.hpp" + +namespace taraxa::network::tarcap { + +ExtBlsSigPacketHandler::ExtBlsSigPacketHandler(const FullNodeConfig &conf, std::shared_ptr peers_state, + std::shared_ptr packets_stats, + std::shared_ptr pillar_chain_manager, + const addr_t &node_addr, const std::string &logs_prefix) + : PacketHandler(conf, std::move(peers_state), std::move(packets_stats), node_addr, logs_prefix + "BLS_SIG_PH"), + pillar_chain_manager_{std::move(pillar_chain_manager)} {} + +void ExtBlsSigPacketHandler::processBlsSignature(const std::shared_ptr &signature, + const std::shared_ptr &peer) { + if (!pillar_chain_manager_->isRelevantBlsSig(signature)) { + LOG(log_dg_) << "Drop irrelevant signature " << signature->getHash() << " from peer " << peer->getId(); + } + + if (!signature->isValid()) { + std::ostringstream err_msg; + err_msg << "Invalid signature " << signature->getHash() << " from peer " << peer->getId(); + throw MaliciousPeerException(err_msg.str()); + } + + pillar_chain_manager_->addVerifiedBlsSig(signature); + + // Mark bls signature as known for peer + peer->markBlsSigAsKnown(signature->getHash()); +} + +} // namespace taraxa::network::tarcap diff --git a/libraries/core_libs/network/src/tarcap/packets_handlers/latest/get_bls_sigs_bundle_packet_handler.cpp b/libraries/core_libs/network/src/tarcap/packets_handlers/latest/get_bls_sigs_bundle_packet_handler.cpp new file mode 100644 index 0000000000..5f3f43ea5a --- /dev/null +++ b/libraries/core_libs/network/src/tarcap/packets_handlers/latest/get_bls_sigs_bundle_packet_handler.cpp @@ -0,0 +1,50 @@ +#include "network/tarcap/packets_handlers/latest/get_bls_sigs_bundle_packet_handler.hpp" + +namespace taraxa::network::tarcap { + +GetBlsSigsBundlePacketHandler::GetBlsSigsBundlePacketHandler(const FullNodeConfig &conf, + std::shared_ptr peers_state, + std::shared_ptr packets_stats, + std::shared_ptr pillar_chain_manager, + const addr_t &node_addr, const std::string &logs_prefix) + : PacketHandler(conf, std::move(peers_state), std::move(packets_stats), node_addr, logs_prefix + "GET_BLS_SIGS_BUNDLE_PH"), + pillar_chain_manager_(std::move(std::move(pillar_chain_manager))) {} + +void GetBlsSigsBundlePacketHandler::validatePacketRlpFormat( + [[maybe_unused]] const threadpool::PacketData &packet_data) const { + auto items = packet_data.rlp_.itemCount(); + if (items != kGetBlsSigsPacketSize) { + throw InvalidRlpItemsCountException(packet_data.type_str_, items, kGetBlsSigsPacketSize); + } +} + +void GetBlsSigsBundlePacketHandler::process(const threadpool::PacketData &packet_data, + const std::shared_ptr &peer) { + const PillarBlock::Hash pillar_block_hash = packet_data.rlp_.toHash(); + + const auto signatures = pillar_chain_manager_->getVerifiedBlsSigs(pillar_block_hash); + + // TODO: split packet to multiple with kGetBlsSigsPacketSize sigs containing each + dev::RLPStream s(signatures.size()); + for (const auto& sig : signatures) { + s.appendRaw(sig->getRlp()); + } + + if (sealAndSend(peer->getId(), SubprotocolPacketType::BlsSigsBundlePacket, std::move(s))) {\ + for (const auto& sig : signatures) { + peer->markBlsSigAsKnown(sig->getHash()); + } + + LOG(log_dg_) << "BLS signatures bundle sent to " << peer->getId(); + } +} + +void GetBlsSigsBundlePacketHandler::requestBlsSigsBundle(PillarBlock::Hash pillar_block_hash, const std::shared_ptr& peer) { + dev::RLPStream s(1); + s << pillar_block_hash; + + sealAndSend(peer->getId(), SubprotocolPacketType::GetBlsSigsBundlePacket, std::move(s)); + LOG(log_dg_) << "Requested BLS signatures bundle for pillar block " << pillar_block_hash << " from peer " << peer->getId(); +} + +} // namespace taraxa::network::tarcap diff --git a/libraries/core_libs/network/src/threadpool/priority_queue.cpp b/libraries/core_libs/network/src/threadpool/priority_queue.cpp index 35a16922b5..3514fbf840 100644 --- a/libraries/core_libs/network/src/threadpool/priority_queue.cpp +++ b/libraries/core_libs/network/src/threadpool/priority_queue.cpp @@ -134,9 +134,12 @@ void PriorityQueue::updateDependenciesStart(const PacketData& packet) { // Packets that can be processed only 1 at the time // GetDagSyncPacket -> serve dag syncing data to only 1 node at the time // GetPbftSyncPacket -> serve pbft syncing data to only 1 node at the time + // GetBlsSigsBundlePacket -> serve bls signatures syncing data to only 1 node at the time // PbftSyncPacket -> process sync pbft blocks synchronously case SubprotocolPacketType::GetDagSyncPacket: case SubprotocolPacketType::GetPbftSyncPacket: + case SubprotocolPacketType::GetBlsSigsBundlePacket: + case SubprotocolPacketType::BlsSigsBundlePacket: case SubprotocolPacketType::PbftSyncPacket: blocked_packets_mask_.markPacketAsHardBlocked(packet, packet.type_); break;