Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

[DNM] approval-voting: approvals signature checks optimizations #7482

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
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
30 changes: 18 additions & 12 deletions node/core/approval-voting/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1269,14 +1269,15 @@ async fn handle_from_overseer<Context>(

actions
},
ApprovalVotingMessage::CheckAndImportApproval(a, res) =>
ApprovalVotingMessage::CheckAndImportApproval(a, res, sender_is_originator) =>
check_and_import_approval(
ctx.sender(),
state,
db,
session_info_provider,
metrics,
a,
sender_is_originator,
|r| {
let _ = res.send(r);
},
Expand Down Expand Up @@ -1930,6 +1931,7 @@ async fn check_and_import_approval<T, Sender>(
session_info_provider: &mut RuntimeInfo,
metrics: &Metrics,
approval: IndirectSignedApprovalVote,
sender_is_originator: bool,
with_response: impl FnOnce(ApprovalCheckResult) -> T,
) -> SubsystemResult<(Vec<Action>, T)>
where
Expand Down Expand Up @@ -1997,17 +1999,21 @@ where
};

// Signature check:
match DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking).check_signature(
&pubkey,
approved_candidate_hash,
block_entry.session(),
&approval.signature,
) {
Err(_) => respond_early!(ApprovalCheckResult::Bad(ApprovalCheckError::InvalidSignature(
approval.validator
),)),
Ok(()) => {},
};
// We perform signatures checks just for the cases where the approvals weren't received directly from
// peer and we received them via gossipping.
if !sender_is_originator {
match DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking).check_signature(
&pubkey,
approved_candidate_hash,
block_entry.session(),
&approval.signature,
) {
Err(_) => respond_early!(ApprovalCheckResult::Bad(
ApprovalCheckError::InvalidSignature(approval.validator),
)),
Ok(()) => {},
};
}

let candidate_entry = match db.load_candidate_entry(&approved_candidate_hash)? {
Some(c) => c,
Expand Down
1 change: 1 addition & 0 deletions node/core/approval-voting/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,7 @@ async fn check_and_import_approval(
msg: ApprovalVotingMessage::CheckAndImportApproval(
IndirectSignedApprovalVote { block_hash, candidate_index, validator, signature },
tx,
false,
),
},
)
Expand Down
31 changes: 20 additions & 11 deletions node/core/dispute-coordinator/src/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,17 +518,26 @@ impl ImportResult {
let (mut votes, _) = new_state.into_old_state();

for (index, sig) in approval_votes.into_iter() {
debug_assert!(
{
let pub_key = &env.session_info().validators.get(index).expect("indices are validated by approval-voting subsystem; qed");
let candidate_hash = votes.candidate_receipt.hash();
let session_index = env.session_index();
DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking)
.check_signature(pub_key, candidate_hash, session_index, &sig)
.is_ok()
},
"Signature check for imported approval votes failed! This is a serious bug. Session: {:?}, candidate hash: {:?}, validator index: {:?}", env.session_index(), votes.candidate_receipt.hash(), index
);
let pub_key = &env
.session_info()
.validators
.get(index)
.expect("indices are validated by approval-voting subsystem; qed");
let candidate_hash = votes.candidate_receipt.hash();
let session_index = env.session_index();
// The candidate sent us an invalid signature, so don't import it.
// This might happen because in approval-voting we do not checks signatures for votes received from the originator.
if !DisputeStatement::Valid(ValidDisputeStatementKind::ApprovalChecking)
.check_signature(pub_key, candidate_hash, session_index, &sig)
.is_ok()
{
gum::trace!(
target: LOG_TARGET,
"Approval checking signature was invalid, so just ignore it"
);
Comment on lines +534 to +537
Copy link
Member

Choose a reason for hiding this comment

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

this should never happen in practice though, unless the approval-voter was malicious, no?
if so, I would suggest to elevate this to a warn

continue
}

if votes.valid.insert_vote(index, ValidDisputeStatementKind::ApprovalChecking, sig) {
imported_valid_votes += 1;
imported_approval_votes += 1;
Expand Down
Loading