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

Check current signers still validators #1097

Merged
merged 35 commits into from
Oct 24, 2024

Conversation

JesseAbram
Copy link
Member

@JesseAbram JesseAbram commented Oct 3, 2024

Related #1114

@JesseAbram JesseAbram marked this pull request as ready for review October 17, 2024 19:59
Copy link
Contributor

@ameba23 ameba23 left a comment

Choose a reason for hiding this comment

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

⭐ this is great.

Is it possible to further improve this by having the parties who are leaving the signing set also participate in the reshare, but not receive new shares? So that we don't have to keep t parties the same. I can't remember whether synderion lets you do this.

crates/shared/src/types.rs Outdated Show resolved Hide resolved
@@ -169,7 +170,8 @@ pub async fn new_reshare(
.await?;

let (new_key_share, aux_info) =
execute_reshare(session_id.clone(), channels, signer.signer(), inputs, None).await?;
execute_reshare(session_id.clone(), channels, signer.signer(), inputs, &new_holders, None)
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe ive misunderstood something, but it looks like new_holders is the same as inputs.new_holders - so why add the extra argument to the execute_reshare function?

Copy link
Member Author

Choose a reason for hiding this comment

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

explained lower down

@@ -273,8 +275,15 @@ pub async fn validate_new_reshare(
.await?
.ok_or_else(|| ValidatorErr::ChainFetch("Not Currently in a reshare"))?;

if reshare_data.new_signer != chain_data.new_signer
|| chain_data.block_number != reshare_data.block_number
let mut hasher_chain_data = Blake2s256::new();
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to hash this? Can we not compare two Vec<Vec<u8>>s for equality?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes you are right a holdover of a change I revereted from #1114 but will change back

.collect()
Ok(if !new_signers.is_empty() {
let mut filtered_validators_info = vec![];
for new_signer in new_signers {
Copy link
Contributor

Choose a reason for hiding this comment

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

This works fine - but since we are anyway about to convert this to a BTreeSet, we can use .difference()

remove_index_len = remove_indexs.len();
let remove_indexs_reversed: Vec<_> = remove_indexs.iter().rev().collect();
// TODO: Only remove up to threhsold https://github.com/entropyxyz/entropy-core/issues/1114
let truncated = if remove_index_len > signers_info.threshold as usize {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe im getting confused, but should this not be signers_info.total_signers - signers_info.threshold? As in the number of redundant signers (n - t) rather than t.
So with 2 of 3, we can afford to loose at most 1 signer, not 2.

Copy link
Member Author

Choose a reason for hiding this comment

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

yes, writing a better test for regression now

let mut randomness = Self::get_randomness();
// grab a current signer to initiate value
let mut next_signer_up = &current_signers[0].clone();
let mut next_signer_up = &validators[0].clone();
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this not be a random validator rather than the first in the list?

Copy link
Member Author

Choose a reason for hiding this comment

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

just a place holder for rust not complaining, gets changed lower down (not initialized compile error)

Copy link
Contributor

Choose a reason for hiding this comment

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

it looks to me like it only gets changed lower down if validators[0] is currently a member of the signer set

Copy link
Member Author

Choose a reason for hiding this comment

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

right this should be grabbed from current_signers to initiate it

@@ -334,6 +334,7 @@ pub async fn execute_reshare(
chans: Channels,
threshold_pair: &sr25519::Pair,
inputs: KeyResharingInputs<KeyParams, PartyId>,
verifiers: &BTreeSet<PartyId>,
Copy link
Contributor

@ameba23 ameba23 Oct 18, 2024

Choose a reason for hiding this comment

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

im not sure we need this argument as it looks like whenever we call this function verifiers is the same as inputs.new_holders

Copy link
Member Author

Choose a reason for hiding this comment

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

yes originally I changed it to allow for old holders to be more and not in new holders however ran into the #1114 issue, didn't change it back because this is still more right imo and adds no overhead, and hopefully will be needed when the issue is resolved

@JesseAbram
Copy link
Member Author

⭐ this is great.

Is it possible to further improve this by having the parties who are leaving the signing set also participate in the reshare, but not receive new shares? So that we don't have to keep t parties the same. I can't remember whether synderion lets you do this.

not currently opened an issue, a limitation with synedrion see #1114

pallets/staking/src/benchmarking.rs Outdated Show resolved Hide resolved
pallets/staking/src/benchmarking.rs Outdated Show resolved Hide resolved
@@ -427,13 +429,22 @@ benchmarks! {
new_session {
let c in 1 .. MAX_SIGNERS as u32 - 1;
let l in 0 .. MAX_SIGNERS as u32;
let v in 0 .. MAX_SIGNERS as u32;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Shouldn't this value be higher than MAX_SIGNERS?

Comment on lines 705 to 723
if current_signers_length >= signers_info.total_signers as usize {
let mut remove_indexs = vec![];
for (i, current_signer) in current_signers.clone().into_iter().enumerate() {
if !validators.contains(&current_signer) {
remove_indexs.push(i);
}
}
if remove_indexs.is_empty() {
current_signers.remove(0);
} else {
remove_index_len = remove_indexs.len();
let remove_indexs_reversed: Vec<_> = remove_indexs.iter().rev().collect();
let truncated = remove_indexs_reversed
[..(signers_info.total_signers as usize - signers_info.threshold as usize)]
.to_vec();
for remove_index in truncated {
current_signers.remove(*remove_index);
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Trying to follow the transformations here is pretty confusing. Maybe you could make use of Vec's .retain and .truncate methods here to clean stuff up instead of things like .rev and slices.

Copy link
Member Author

Choose a reason for hiding this comment

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

commented it up more, for what it is worth the truncated should eventually be removed

pallets/staking/src/lib.rs Outdated Show resolved Hide resolved
pallets/staking/src/tests.rs Outdated Show resolved Hide resolved
crates/threshold-signature-server/src/validator/tests.rs Outdated Show resolved Hide resolved
OcwMessageReshare { new_signer: new_signer.0.to_vec(), block_number };
let onchain_reshare_request = OcwMessageReshare {
new_signers: vec![new_signer.0.to_vec()],
block_number: block_number - 1,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why change this instead of keeping the +1 in run_to_block?

Copy link
Member Author

Choose a reason for hiding this comment

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

because this needs to match the onchain info or it will not pass the validate check

@JesseAbram JesseAbram requested a review from HCastano October 23, 2024 15:24
// Stash address of new signer
pub new_signer: Vec<u8>,
// Stash addresses of new signers
pub new_signers: Vec<Vec<u8>>,
Copy link
Contributor

Choose a reason for hiding this comment

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

A few lines above, in ValidatorInfo, Vecs are provided with the full path, codec::alloc::vec::Vec<u8>. Should we be consistent? The short form here seems better.

Comment on lines +123 to +125
// old holders -> next_signers - new_signers (will be at least t)
let old_holders =
&prune_old_holders(&api, &rpc, data.new_signers, validators_info.clone()).await?;
Copy link
Contributor

Choose a reason for hiding this comment

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

I can't find where the (will be at least t) invariant is checked; doesn't seem to happen in prune_old_holders (also, but unrelated to this PR, that method seems to be cloning wildly but not sure that's needed).

Copy link
Member Author

Choose a reason for hiding this comment

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

crates/threshold-signature-server/src/validator/api.rs Outdated Show resolved Hide resolved
OcwMessageReshare { new_signer: new_signer.0.to_vec(), block_number };
let onchain_reshare_request = OcwMessageReshare {
new_signers: reshare_data.new_signers.into_iter().map(|s| s.to_vec()).collect(),
block_number: block_number - 1,
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this blow up on block 0? Maybe checked_sub?

Copy link
Member Author

Choose a reason for hiding this comment

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

the block number is hard coded one line above to a number way over 0

@JesseAbram JesseAbram merged commit 9eab023 into master Oct 24, 2024
8 checks passed
@JesseAbram JesseAbram deleted the check-if-current-signers-are-still-validators branch October 24, 2024 18:20
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.

4 participants