Skip to content

Commit

Permalink
CYB460 added working with few singnature providers (#41)
Browse files Browse the repository at this point in the history
* CYB460 added working with few singnature providers

* little refactoring

Co-authored-by: Emil Guseynov <theluckyemil@gmail.com>
  • Loading branch information
sadaocasino and justefg committed Jan 13, 2020
1 parent 40dd444 commit 5c13ee0
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 136 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ template<class T>
class network_msg {
public:
T data;
signature_type signature;
std::vector<signature_type> signatures;
network_msg() = default;
network_msg(const T& data_, const signature_type& signature_): data(data_), signature(signature_) {}
network_msg(const T& data_, signature_type&& signature_): data(data_), signature(signature_) {}
network_msg(const T& data_, const signature_provider_type& signature_provider) {
network_msg(const T& data_, const std::vector<signature_type>& signatures_): data(data_), signatures(signatures_) {}
network_msg(const T& data_, std::vector<signature_type>&& signatures_): data(data_), signatures(signatures_) {}
network_msg(const T& data_, const std::vector<signature_provider_type>& signature_providers) {
data = data_;
signature = signature_provider(hash());
for(const auto &sig_prov : signature_providers) {
signatures.push_back(sig_prov(hash()));
}
}

digest_type hash() const {
Expand All @@ -28,12 +30,16 @@ class network_msg {
return e.result();
}

public_key_type public_key() const {
return public_key_type(signature, hash());
std::vector<public_key_type> public_keys() const {
std::vector<public_key_type> public_keys;
for (const auto& sign : signatures) {
public_keys.push_back(public_key_type(sign, hash()));
}
return public_keys;
}

bool validate(const public_key_type& pub_key) const {
return public_key() == pub_key;
bool validate(const std::vector<public_key_type>& pub_keys) const {
return pub_keys == public_keys();
}
};

Expand Down Expand Up @@ -103,4 +109,4 @@ FC_REFLECT(randpa_finality::proof_type, (round_num)(best_block)(prevotes)(precom
FC_REFLECT(randpa_finality::finality_notice_type, (round_num)(best_block))
FC_REFLECT(randpa_finality::finality_req_proof_type, (round_num))

FC_REFLECT_TEMPLATE((typename T), randpa_finality::network_msg<T>, (data)(signature))
FC_REFLECT_TEMPLATE((typename T), randpa_finality::network_msg<T>, (data)(signatures))
113 changes: 65 additions & 48 deletions plugins/randpa_plugin/include/eosio/randpa_plugin/randpa.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,6 @@ class randpa {
: _peer_messages{_messages_cache_size},
_self_messages{_messages_cache_size},
_last_proofs{_proofs_cache_size} {
auto private_key = private_key_type::generate();
_signature_provider = [private_key](const digest_type& digest) {
return private_key.sign(digest);
};
}

randpa& set_in_net_channel(const net_channel_ptr& ptr) {
Expand All @@ -224,15 +220,23 @@ class randpa {
return *this;
}

randpa& set_signature_provider(const signature_provider_type& signature_provider,
const public_key_type& public_key) {
_signature_provider = signature_provider;
_public_key = public_key;
randpa& set_signature_providers(const vector<signature_provider_type>& signature_providers,
const vector<public_key_type>& public_keys) {
_signature_providers = signature_providers;
_public_keys = public_keys;
_provided_bp_key = true;
randpa_dlog("set signature provider: ${p}", ("p", public_key));
randpa_dlog("set signature providers for ${p}", ("p", public_keys));
return *this;
}

void add_signature_provider(const signature_provider_type& signature_provider,
const public_key_type& public_key) {
_signature_providers.push_back(signature_provider);
_public_keys.push_back(public_key);
_provided_bp_key = true;
randpa_dlog("added signature provider for ${p}", ("p", public_key));
}

void start(prefix_tree_ptr tree) {
FC_ASSERT(_in_net_channel && _in_event_channel, "in channels should be inited");
FC_ASSERT(_out_net_channel, "out channels should be inited");
Expand Down Expand Up @@ -287,8 +291,8 @@ class randpa {

std::unique_ptr<std::thread> _thread_ptr;
std::atomic<bool> _done { false };
signature_provider_type _signature_provider;
public_key_type _public_key;
std::vector<signature_provider_type> _signature_providers;
std::vector<public_key_type> _public_keys;
prefix_tree_ptr _prefix_tree;
randpa_round_ptr _round;
block_id_type _lib; // last irreversible block
Expand Down Expand Up @@ -371,7 +375,7 @@ class randpa {
template <typename T>
bool check_is_valid_msg(const T& msg) const {
try {
msg.public_key();
msg.public_keys();
} catch (const fc::exception&) {
return false;
}
Expand Down Expand Up @@ -487,28 +491,30 @@ class randpa {
const auto& bp_keys = node->active_bp_keys;

for (const auto& prevote : proof.prevotes) {
const auto& prevoter_pub_key = prevote.public_key();
if (!validate_prevote(prevote.data, prevoter_pub_key, best_block, bp_keys)) {
randpa_dlog("Prevote validation failed, base_block: ${id}, blocks: ${blocks}",
("id", prevote.data.base_block)
("blocks", prevote.data.blocks));
return false;
for (const auto& prevoter_pub_key : prevote.public_keys()) {
if (!validate_prevote(prevote.data, prevoter_pub_key, best_block, bp_keys)) {
randpa_dlog("Prevote validation failed, base_block: ${id}, blocks: ${blocks}",
("id", prevote.data.base_block)
("blocks", prevote.data.blocks));
return false;
}
prevoted_keys.insert(prevoter_pub_key);
}
prevoted_keys.insert(prevoter_pub_key);
}

for (const auto& precommit : proof.precommits) {
const auto& precommiter_pub_key = precommit.public_key();
if (!prevoted_keys.count(precommiter_pub_key)) {
randpa_dlog("Precommiter has not prevoted, pub_key: ${pub_key}", ("pub_key", precommiter_pub_key));
return false;
for (const auto& precommiter_pub_key : precommit.public_keys()) {
if (!prevoted_keys.count(precommiter_pub_key)) {
randpa_dlog("Precommiter has not prevoted, pub_key: ${pub_key}", ("pub_key", precommiter_pub_key));
return false;
}

if (!validate_precommit(precommit.data, precommiter_pub_key, best_block, bp_keys)) {
randpa_dlog("Precommit validation failed for ${id}", ("id", precommit.data.block_id));
return false;
}
precommited_keys.insert(precommiter_pub_key);
}

if (!validate_precommit(precommit.data, precommiter_pub_key, best_block, bp_keys)) {
randpa_dlog("Precommit validation failed for ${id}", ("id", precommit.data.block_id));
return false;
}
precommited_keys.insert(precommiter_pub_key);
}
return precommited_keys.size() > node->active_bp_keys.size() * 2 / 3;
}
Expand All @@ -528,7 +534,7 @@ class randpa {
randpa_dlog("no need to get finality proof for block producer node");
return;
}
send(ses_id, finality_req_proof_msg{{data.round_num}, _signature_provider});
send(ses_id, finality_req_proof_msg{{data.round_num}, _signature_providers});
}

void on(uint32_t ses_id, const finality_req_proof_msg& msg) {
Expand All @@ -537,7 +543,7 @@ class randpa {
for (const auto& proof : _last_proofs) {
if (proof.round_num == data.round_num) {
randpa_dlog("proof found; sending it");
send(ses_id, proof_msg{proof, _signature_provider});
send(ses_id, proof_msg{proof, _signature_providers});
break;
}
}
Expand Down Expand Up @@ -569,7 +575,9 @@ class randpa {
}

if (!validate_proof(proof)) {
randpa_ilog("Invalid proof from ${peer}", ("peer", msg.public_key()));
for (const auto& public_key : msg.public_keys()) {
randpa_ilog("Invalid proof among ${peer}", ("peer", public_key));
}
randpa_dlog("Proof msg: ${msg}", ("msg", msg));
return;
}
Expand All @@ -584,22 +592,26 @@ class randpa {
}

void on(uint32_t ses_id, const handshake_msg& msg) {
randpa_ilog("Randpa handshake_msg received, ses_id: ${ses_id}, from: ${pk}", ("ses_id", ses_id)("pk", msg.public_key()));
try {
_peers[msg.public_key()] = ses_id;

send(ses_id, handshake_ans_msg(handshake_ans_type { _lib }, _signature_provider));
} catch (const fc::exception& e) {
randpa_elog("Randpa handshake_msg handler error, reason: ${e}", ("e", e.what()));
for (const auto& public_key : msg.public_keys()) {
randpa_ilog("Randpa handshake_msg received, ses_id: ${ses_id}, from: ${pk}", ("ses_id", ses_id)("pk", public_key));
try {
_peers[public_key] = ses_id;

send(ses_id, handshake_ans_msg(handshake_ans_type { _lib }, _signature_providers));
} catch (const fc::exception& e) {
randpa_elog("Randpa handshake_msg handler error, reason: ${e}", ("e", e.what()));
}
}
}

void on(uint32_t ses_id, const handshake_ans_msg& msg) {
randpa_ilog("Randpa handshake_ans_msg received, ses_id: ${ses_id}, from: ${pk}", ("ses_id", ses_id)("pk", msg.public_key()));
try {
_peers[msg.public_key()] = ses_id;
} catch (const fc::exception& e) {
randpa_elog("Randpa handshake_ans_msg handler error, reason: ${e}", ("e", e.what()));
for (const auto& public_key : msg.public_keys()) {
randpa_ilog("Randpa handshake_ans_msg received, ses_id: ${ses_id}, from: ${pk}", ("ses_id", ses_id)("pk", public_key));
try {
_peers[public_key] = ses_id;
} catch (const fc::exception& e) {
randpa_elog("Randpa handshake_ans_msg handler error, reason: ${e}", ("e", e.what()));
}
}
}

Expand Down Expand Up @@ -663,7 +675,7 @@ class randpa {

void on(const on_new_peer_event& event) {
randpa_dlog("Randpa on_new_peer_event event handled, ses_id: ${ses_id}", ("ses_id", event.ses_id));
auto msg = handshake_msg(handshake_type{_lib}, _signature_provider);
auto msg = handshake_msg(handshake_type{_lib}, _signature_providers);
send(event.ses_id, msg);
}

Expand All @@ -673,7 +685,7 @@ class randpa {

_last_prooved_block_num = get_block_num(proof.best_block);
_finality_channel->send(proof.best_block);
bcast(finality_notice_msg{{proof.round_num, proof.best_block}, _signature_provider});
bcast(finality_notice_msg{{proof.round_num, proof.best_block}, _signature_providers});
}

template <typename T>
Expand Down Expand Up @@ -744,7 +756,12 @@ class randpa {
return false;
}

return node_ptr->active_bp_keys.count(_public_key);
for (const auto& public_key : _public_keys) {
if (node_ptr->active_bp_keys.count(public_key)) {
return true;
}
}
return false;
}

void finish_round() {
Expand All @@ -771,7 +788,7 @@ class randpa {
}

void new_round(uint32_t round_num, const public_key_type& primary) {
_round.reset(new randpa_round(round_num, primary, _prefix_tree, _signature_provider,
_round.reset(new randpa_round(round_num, primary, _prefix_tree, _signature_providers,
[this](const prevote_msg& msg) {
bcast(msg);
},
Expand Down
Loading

0 comments on commit 5c13ee0

Please sign in to comment.