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:Unification: Integrate vote message signatures into new fork database #2067

Closed
wants to merge 12 commits into from

Conversation

linh2931
Copy link
Member

Process vote messages received from net plugin:

  • added a new finality_controller.cpp within hotstuff directory (which will be renamed to finality directory) to contain control related code
  • aggregated the vote signature into the pending QC for the block the vote corresponds to
  • added tests

Resolved #2046

@linh2931 linh2931 requested review from heifner and greg7mdp January 10, 2024 15:30
@linh2931 linh2931 marked this pull request as draft January 10, 2024 15:36
@linh2931
Copy link
Member Author

Please hold on reviewing this. Need to resolve merge conflicts.

@linh2931 linh2931 marked this pull request as ready for review January 10, 2024 16:16
Copy link
Contributor

@greg7mdp greg7mdp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not understanding why we need finality_controller? It holds no data.
Couldn't we just have a function in block_state, for example block_state::aggregate_vote(const hs_vote_message& vote)?

if (!fc::crypto::blslib::verify(pubkey, proposal_digest, new_sig))
}
if (!fc::crypto::blslib::verify(pubkey, proposal_digest, new_sig)) {
wlog( "sinature from finalizer ${i} cannot be verified", ("i", index) );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
wlog( "sinature from finalizer ${i} cannot be verified", ("i", index) );
wlog( "signature from finalizer ${i} cannot be verified", ("i", index) );

Comment on lines 4024 to 4027
auto bsp = fetch_block_state_by_id(vote.proposal_id);
if( bsp ) {
my->finality_control.aggregate_vote(bsp, vote);
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding fetch_block_state_by_id and apply_block_data_new, I suggest you add a new method in block_data_t named:

void aggregate_vote(const hs_vote_message& vote) which would do nothing for the dpos case, and would fetch the block_state and apply the vote in the if case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is block_data_t a general class and its main purpose to service fork_db APIs? aggregate_vote seems too specific for block_data_t.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Block data and the other structs with variants should contain, as much as possible, any code that does something different for dpos and if, or accesses the block_state_* structs, so that the rest of controller doesn't see these differences.

It is perfectly fine to add new members like aggregate_vote which behave differently for dpos and if.

The apply functions were mostly present to make controller work in the dpos mode while changes were not completed, ideally they should go away.

@linh2931
Copy link
Member Author

I'm not understanding why we need finality_controller? It holds no data. Couldn't we just have a function in block_state, for example block_state::aggregate_vote(const hs_vote_message& vote)?

We were talking about consolidate hoststuff directory into a new finality directory. I created finality_controller as a placeholder for that purpose. But we could do that in the future if needed. Will move to block_state for simplicity.

@linh2931 linh2931 requested a review from greg7mdp January 10, 2024 21:00
@@ -3889,7 +3902,7 @@ std::optional<signed_block_header> controller::fetch_block_header_by_number( uin


block_state_legacy_ptr controller::fetch_block_state_by_id( block_id_type id )const {
// returns nullptr when in IF mode
// returns nullptr when in in mode
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

??

Comment on lines +252 to +263
bool aggregate_vote(const hs_vote_message& vote) {
EOS_ASSERT(std::holds_alternative<block_data_new_t>(v), misc_exception, "attempting to call aggregate_vote in legacy mode");

block_data_new_t& bd = std::get<block_data_new_t>(v);
auto bsp = bd.fork_db.get_block(vote.proposal_id);
if( bsp ) {
return bsp->aggregate_vote(vote);
} else {
wlog( "no block exists for the vote (proposal_id: ${id}", ("id", vote.proposal_id) );
return false;
}
}
Copy link
Contributor

@greg7mdp greg7mdp Jan 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to avoid holds_alternative and std::get, please use std::visit instead.

Suggested change
bool aggregate_vote(const hs_vote_message& vote) {
EOS_ASSERT(std::holds_alternative<block_data_new_t>(v), misc_exception, "attempting to call aggregate_vote in legacy mode");
block_data_new_t& bd = std::get<block_data_new_t>(v);
auto bsp = bd.fork_db.get_block(vote.proposal_id);
if( bsp ) {
return bsp->aggregate_vote(vote);
} else {
wlog( "no block exists for the vote (proposal_id: ${id}", ("id", vote.proposal_id) );
return false;
}
}
bool aggregate_vote(const hs_vote_message& vote) {
return std::visit(
overloaded{[](const block_data_legacy_t&) {
FC_THROW_EXCEPTION(misc_exception, "attempting to call aggregate_vote in legacy mode");
return false;
},
[&](const block_data_new_t& bd) {
auto bsp = bd.fork_db.get_block(vote.proposal_id);
if (bsp) {
return bsp->aggregate_vote(vote);
} else {
wlog("no block exists for the vote (proposal_id: ${id}", ("id", vote.proposal_id));
return false;
}
}},
v);
}

@@ -4007,8 +4020,8 @@ void controller::get_finalizer_state( finalizer_state& fs ) const {
}

// called from net threads
void controller::notify_hs_message( const uint32_t connection_id, const hs_message& msg ) {
my->pacemaker->on_hs_msg(connection_id, msg);
void controller::notify_vote_message( const hs_vote_message& vote ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change the function name to process_vote_message or aggregate_vote_message or something like that.

Comment on lines +141 to +144
bool pending_quorum_certificate::add_vote(bool strong, size_t index,
const bls_public_key& pubkey, const bls_signature& sig) {
return strong ? add_strong_vote(proposal_digest, index, pubkey, sig)
: add_weak_vote(proposal_digest, index, pubkey, sig);
return strong ? add_strong_vote(index, pubkey, sig)
: add_weak_vote(index, pubkey, sig);
Copy link
Contributor

@greg7mdp greg7mdp Jan 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as discussed in the meeting, you'll have to pass the finalizer_digest from the block_state, and we can remove the _proposal_digest member.

@linh2931
Copy link
Member Author

Replaced by simpler #2073

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants