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

IF: Verify bls signature of vote while not holding a mutex #2359

Merged
merged 5 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 37 additions & 22 deletions libraries/chain/hotstuff/hotstuff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,19 @@ inline std::vector<uint32_t> bitset_to_vector(const hs_bitset& bs) {
return r;
}

vote_status pending_quorum_certificate::votes_t::add_vote(std::span<const uint8_t> proposal_digest, size_t index,
const bls_public_key& pubkey, const bls_signature& new_sig) {
if (_bitset[index]) {
return vote_status::duplicate; // shouldn't be already present
bool pending_quorum_certificate::is_duplicate_no_lock(bool strong, size_t index) const {
if (strong) {
return _strong_votes._bitset[index];
}
if (!fc::crypto::blslib::verify(pubkey, proposal_digest, new_sig)) {
wlog( "signature from finalizer ${i} cannot be verified", ("i", index) );
return vote_status::invalid_signature;
return _weak_votes._bitset[index];
}

vote_status pending_quorum_certificate::votes_t::add_vote(size_t index, const bls_signature& sig) {
if (_bitset[index]) { // check here as could have come in while unlocked
linh2931 marked this conversation as resolved.
Show resolved Hide resolved
return vote_status::duplicate; // shouldn't be already present
}
_bitset.set(index);
_sig.aggregate(new_sig); // works even if _sig is default initialized (fp2::zero())
_sig.aggregate(sig); // works even if _sig is default initialized (fp2::zero())
return vote_status::success;
}

Expand Down Expand Up @@ -59,10 +61,8 @@ bool pending_quorum_certificate::is_quorum_met() const {
}

// called by add_vote, already protected by mutex
vote_status pending_quorum_certificate::add_strong_vote(std::span<const uint8_t> proposal_digest, size_t index,
const bls_public_key& pubkey, const bls_signature& sig,
uint64_t weight) {
if (auto s = _strong_votes.add_vote(proposal_digest, index, pubkey, sig); s != vote_status::success) {
vote_status pending_quorum_certificate::add_strong_vote(size_t index, const bls_signature& sig, uint64_t weight) {
if (auto s = _strong_votes.add_vote(index, sig); s != vote_status::success) {
return s;
}
_strong_sum += weight;
Expand Down Expand Up @@ -91,10 +91,8 @@ vote_status pending_quorum_certificate::add_strong_vote(std::span<const uint8_t>
}

// called by add_vote, already protected by mutex
vote_status pending_quorum_certificate::add_weak_vote(std::span<const uint8_t> proposal_digest, size_t index,
const bls_public_key& pubkey, const bls_signature& sig,
uint64_t weight) {
if (auto s = _weak_votes.add_vote(proposal_digest, index, pubkey, sig); s != vote_status::success)
vote_status pending_quorum_certificate::add_weak_vote(size_t index, const bls_signature& sig, uint64_t weight) {
if (auto s = _weak_votes.add_vote(index, sig); s != vote_status::success)
return s;
_weak_sum += weight;

Expand Down Expand Up @@ -125,15 +123,32 @@ vote_status pending_quorum_certificate::add_weak_vote(std::span<const uint8_t> p
return vote_status::success;
}

// thread safe, status, pre state , post state
// thread safe
vote_status pending_quorum_certificate::add_vote(block_num_type block_num, bool strong, std::span<const uint8_t> proposal_digest, size_t index,
const bls_public_key& pubkey, const bls_signature& sig, uint64_t weight) {
std::lock_guard g(*_mtx);
auto pre_state = _state;
vote_status s = strong ? add_strong_vote(proposal_digest, index, pubkey, sig, weight)
: add_weak_vote(proposal_digest, index, pubkey, sig, weight);
vote_status s = vote_status::success;

std::unique_lock g(*_mtx);
state_t pre_state = _state;
state_t post_state = pre_state;
if (is_duplicate_no_lock(strong, index)) {
s = vote_status::duplicate;
} else {
g.unlock();
if (!fc::crypto::blslib::verify(pubkey, proposal_digest, sig)) {
wlog( "signature from finalizer ${i} cannot be verified", ("i", index) );
s = vote_status::invalid_signature;
} else {
g.lock();
s = strong ? add_strong_vote(index, sig, weight)
: add_weak_vote(index, sig, weight);
post_state = _state;
g.unlock();
}
}

dlog("block_num: ${bn}, vote strong: ${sv}, status: ${s}, pre-state: ${pre}, post-state: ${state}, quorum_met: ${q}",
("bn", block_num)("sv", strong)("s", s)("pre", pre_state)("state", _state)("q", is_quorum_met_no_lock()));
("bn", block_num)("sv", strong)("s", s)("pre", pre_state)("state", post_state)("q", is_quorum_met(post_state)));
greg7mdp marked this conversation as resolved.
Show resolved Hide resolved
return s;
}

Expand Down
12 changes: 4 additions & 8 deletions libraries/chain/include/eosio/chain/hotstuff/hotstuff.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,7 @@ namespace eosio::chain {
void resize(size_t num_finalizers) { _bitset.resize(num_finalizers); }
size_t count() const { return _bitset.count(); }

vote_status add_vote(std::span<const uint8_t> proposal_digest, size_t index, const bls_public_key& pubkey,
const bls_signature& new_sig);
vote_status add_vote(size_t index, const bls_signature& sig);

void reset(size_t num_finalizers);
};
Expand Down Expand Up @@ -126,20 +125,17 @@ namespace eosio::chain {
votes_t _strong_votes;

// called by add_vote, already protected by mutex
vote_status add_strong_vote(std::span<const uint8_t> proposal_digest,
size_t index,
const bls_public_key& pubkey,
vote_status add_strong_vote(size_t index,
const bls_signature& sig,
uint64_t weight);

// called by add_vote, already protected by mutex
vote_status add_weak_vote(std::span<const uint8_t> proposal_digest,
size_t index,
const bls_public_key& pubkey,
vote_status add_weak_vote(size_t index,
const bls_signature& sig,
uint64_t weight);

bool is_quorum_met_no_lock() const;
bool is_duplicate_no_lock(bool strong, size_t index) const;
};
} //eosio::chain

Expand Down
Loading