-
Notifications
You must be signed in to change notification settings - Fork 2
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
Remove permissioned access type #666
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
@@ -145,7 +147,7 @@ pub async fn sign( | |||
api: &OnlineClient<EntropyConfig>, | |||
rpc: &LegacyRpcMethods<EntropyConfig>, | |||
user_keypair: sr25519::Pair, | |||
signature_request_account: Option<SubxtAccountId32>, | |||
signature_verifying_key: Vec<u8>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to have a type for this or at least make it a [u8; 33]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tbh this PR has been a lot I wanna make a follow up with this and the program modification comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took a first glance today, still trying to wrap my head around the implications of using the verifying key here
pallets/registry/src/lib.rs
Outdated
} | ||
|
||
#[pallet::genesis_build] | ||
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> { | ||
fn build(&self) { | ||
for account_info in &self.registered_accounts { | ||
assert!(account_info.3.clone().len() as u32 == VERIFICATION_KEY_LENGTH); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
len()
shouldn't take an owned reference here, we probably don't need to clone()
this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm also curious though, since we use a BoundedVec
we're only guaranteed that we won't go past VERIFICATION_KEY_LENGTH
, but not that the value is of that length, right?
Might be worth looking into enforcing that the length is as expected in the types themselves
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh I added an ensure length to the confirm_done function
|
||
#[pallet::storage] | ||
#[pallet::getter(fn modifiable_keys)] | ||
pub type ModifiableKeys<T: Config> = StorageMap< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really understand what this is used for, can you clarify for me?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also like to know more about this.
It looks to me like this caps the number of entropy accounts which a single program modification account may control.
One thing to be aware of is that there is currently no check that the user owns the program modification account, so someone could activate this limit for someone else's program modification account. Although thats not really so bad since it doesn't effect their ability to use it with their existing accounts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ya so verifying_key => prog_mod_account (and other things) but a user can have multiple vk to pma so when they log in given one pma it should easily pull up all their vk
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this would be solved with #677 if we use a prog mod sig but ya def a potential
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JesseAbram I still don't understand the use case here.
Maybe as a follow up, is this something we need to introduce in this PR, or can we do it after? Because maybe having it added in isolation would help me understand the usecase a bit more
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ehhh maybe but @frankiebee asked for it and it is heavily related to this so idk if that would be the best call
pallets/registry/src/lib.rs
Outdated
/// An account has been registered. \[who\] | ||
AccountRegistered(T::AccountId), | ||
/// An account has been registered. [who, signing_group, verifying_key] | ||
AccountRegistering(T::AccountId, u8, VerifyingKey), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would we be able to know the VerifyingKey
before the registration process is done?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In registering this is the process where we need one representative from each subgroup to call back into the chain, this is like a checkpoint where validator x from subgroup n sends their verifying key saying im done here is what I got, the last validator triggered the registered event
pallets/registry/src/lib.rs
Outdated
@@ -453,7 +473,11 @@ pub mod pallet { | |||
} | |||
registering_info.confirmations.push(signing_subgroup); | |||
Registering::<T>::insert(&sig_req_account, registering_info); | |||
Self::deposit_event(Event::AccountRegistering(sig_req_account, signing_subgroup)); | |||
Self::deposit_event(Event::AccountRegistering( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, maybe we should change this to be something like a Confirmation
event or something like that. From reading the events it seemed like this would only be fired in the register
extrinsic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh that is SignalRegistery, but ya im easy when it comes to naming
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, let's change it since it's a bit confusing.
Something like RecievedConfirmation
would be better imo
passed_verifying_key: Option<Vec<u8>>, | ||
// If this is true a keyshare for the user will be generated and returned | ||
extra_private_keys: bool, | ||
// If true keyshare and verifying key is deterministic | ||
deterministic_key_share: bool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are the expected interactions between the passed_verifying_key
and deterministic_key_share
flags like?
E.g, should I be allowed to pass my own verifying key and also ask for a deterministic key share?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ya, wouldn't do much tho
let signing_key = if deterministic_key_share { | ||
Some( | ||
SigningKey::from_bytes( | ||
&hex!("4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How was this key derived? Can we derive it on the fly, or maybe put it in a const?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can put it in a const, I pulled it from the k256 docs
pub static ref DEFAULT_VERIFYING_KEY_NOT_REGISTERED: Vec<u8> = vec![10; VERIFICATION_KEY_LENGTH as usize]; | ||
pub static ref DAVE_VERIFYING_KEY: Vec<u8> = vec![1; VERIFICATION_KEY_LENGTH as usize]; | ||
// this key is associated with a constant key share generation in spawn_testing_validators | ||
pub static ref EVE_VERIFYING_KEY: Vec<u8> = vec![2, 78, 59, 129, 175, 156, 34, 52, 202, 208, 157, 103, 156, 230, 3, 94, 209, 57, 35, 71, 206, 100, 206, 64, 95, 93, 205, 54, 34, 138, 37, 222, 110]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar question here, how was this derived?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@HCastano This is the public key corresponding to the private key given here:
&hex!("4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318") |
The problem was that EVE is a pre-registered account used in the private mode test, but we could not know the verifying key beforehand when generating the keyshares randomly. So Jesse found how to give a static private key when generating shares with synedrion, and this is its public key.
Probably the private key should also be given as a constant here, or even generated here with lazy_static
or something. But i'd be happy to have that done it a follow up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it was the verifying key generated from the const generate from the deterministic key code above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🥇
Great. As already discussed theres maybe still some fixes needed for the test-cli, which can be done in a follow up. And i would like to see a type for a serialized verifying key - although i see we already have a type alias for it in the registry pallet. Something with methods or trait implementations for converting to / from synedrion::ecdsa::VerifyingKey
would be really cool.
If we can get this merged soon it will make me happy as this effects the stuff im doing with changing SignedMessage
- so followups are good for me.
pub static ref DEFAULT_VERIFYING_KEY_NOT_REGISTERED: Vec<u8> = vec![10; VERIFICATION_KEY_LENGTH as usize]; | ||
pub static ref DAVE_VERIFYING_KEY: Vec<u8> = vec![1; VERIFICATION_KEY_LENGTH as usize]; | ||
// this key is associated with a constant key share generation in spawn_testing_validators | ||
pub static ref EVE_VERIFYING_KEY: Vec<u8> = vec![2, 78, 59, 129, 175, 156, 34, 52, 202, 208, 157, 103, 156, 230, 3, 94, 209, 57, 35, 71, 206, 100, 206, 64, 95, 93, 205, 54, 34, 138, 37, 222, 110]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@HCastano This is the public key corresponding to the private key given here:
&hex!("4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318") |
The problem was that EVE is a pre-registered account used in the private mode test, but we could not know the verifying key beforehand when generating the keyshares randomly. So Jesse found how to give a static private key when generating shares with synedrion, and this is its public key.
Probably the private key should also be given as a constant here, or even generated here with lazy_static
or something. But i'd be happy to have that done it a follow up.
query_chain(api, rpc, registered_query, block_hash).await.unwrap(); | ||
if registered_status.is_some() { | ||
// check if the event belongs to this user | ||
if event.0 == account_id { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A nitpick, but can we not do this check before doing the registered status query, so that we only do that query if the account in the event is ours?
let validator_1_threshold_keyshare: Vec<u8> = | ||
entropy_kvdb::kv_manager::helpers::serialize(&shares[0]).unwrap(); | ||
let validator_2_threshold_keyshare: Vec<u8> = | ||
entropy_kvdb::kv_manager::helpers::serialize(&shares[1]).unwrap(); | ||
|
||
// uses the deterministic verifying key if requested | ||
let verifying_key = if deterministic_key_share { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not critical but do we need this if
? If deterministic_key_share
is true the public key from the keyshare should be identical to passed_verifying_key
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no and maybe I should refactor this function a little (im down but in a different PR tbh we should probably merge this soon) but you can still pass a passed_verifying_key
but if you set deterministic_key_share
to true it will override that and use the verifying_key from the keyshare created
@@ -120,9 +123,11 @@ pub async fn create_clients( | |||
} | |||
|
|||
pub async fn spawn_testing_validators( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not related to this PR but i just noticed we have this function twice - this one used in unit tests and then again in testing_utils::tss_server_process
used in integration tests. Im not sure what the difference is. I'll make an issue - might have been me that duplicated it, not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is, no difference to my mind I thought it might have been std and crate issues and didn't look into it tbh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty sure it had something to do with not importing certain crates into the integration tests. But yeah, I also think it was in one of your PRs Peg
for _ in 0..10 { | ||
let mut new_verifying_key = vec![]; | ||
// wait for registered event check that key exists in kvdb | ||
for _ in 0..45 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Im curious - does this actually fail if you only give it 10 tries as before, or did you bump that when the test wasn't working for some other reason?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lol no so the tests dev chain expects 2 validators and substate randomly choose which one should produce a block, in tests for ease we only spin up one, and they get chosen randomly (vrf really cool actually), so sometimes we get like 30 second delayed blocks and ya it could randomly fail at 10 sometimes lol
"5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw", | ||
hex::encode(DAVE_VERIFYING_KEY.to_vec()), | ||
hex::encode(EVE_VERIFYING_KEY.to_vec()), | ||
hex::encode(FERDIE_VERIFYING_KEY.to_vec()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much nicer
// check if the event belongs to this user | ||
if event.0 == account_id { | ||
return event.1 .0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This bit of code is used in a few places - we could maybe made a helper (in a follow up PR)
|
||
#[pallet::storage] | ||
#[pallet::getter(fn modifiable_keys)] | ||
pub type ModifiableKeys<T: Config> = StorageMap< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also like to know more about this.
It looks to me like this caps the number of entropy accounts which a single program modification account may control.
One thing to be aware of is that there is currently no check that the user owns the program modification account, so someone could activate this limit for someone else's program modification account. Although thats not really so bad since it doesn't effect their ability to use it with their existing accounts.
@@ -178,11 +178,9 @@ pub async fn get_all_keys( | |||
while let Some(Ok((key, _account))) = iter.next().await { | |||
let new_key = hex::encode(key); | |||
let len = new_key.len(); | |||
let final_key = &new_key[len - 64..]; | |||
let final_key = &new_key[len - 66..]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: could use entropy_shared::VERIFICATION_KEY_LENGTH * 2
Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
Co-authored-by: peg <peg@magmacollective.org>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still confused at the ModifiableKeys
thing - but overall this does what I expect.
Good work on this 💪
|
||
#[pallet::storage] | ||
#[pallet::getter(fn modifiable_keys)] | ||
pub type ModifiableKeys<T: Config> = StorageMap< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JesseAbram I still don't understand the use case here.
Maybe as a follow up, is this something we need to introduce in this PR, or can we do it after? Because maybe having it added in isolation would help me understand the usecase a bit more
@@ -58,6 +58,7 @@ pub fn add_non_syncing_validators<T: Config>( | |||
<SigningGroups<T>>::insert(sig_party_number, validators.clone()); | |||
for (c, validator) in validators.iter().enumerate() { | |||
<ThresholdServers<T>>::insert(validator, server_info.clone()); | |||
<ValidatorToSubgroup<T>>::insert(validator, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this generally missing before this PR, or did you have to add it because of the changes introduced here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh ya I did wanna ping you about it but got bogged down, this was weird it was def introduced in yours and the CI didn't pick it up, after we merge this imma check to see if benchmarks are being run, cuz this should have been caught
@@ -41,6 +42,14 @@ lazy_static! { | |||
.try_into() | |||
.unwrap(), | |||
]; | |||
pub static ref DEFAULT_VERIFYING_KEY_NOT_REGISTERED: Vec<u8> = vec![10; VERIFICATION_KEY_LENGTH as usize]; | |||
pub static ref DAVE_VERIFYING_KEY: Vec<u8> = vec![1; VERIFICATION_KEY_LENGTH as usize]; | |||
// this key is associated with a constant key share generation in spawn_testing_validators |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to update this comment now
pub static ref FERDIE_VERIFYING_KEY: Vec<u8> = vec![3; VERIFICATION_KEY_LENGTH as usize]; | ||
pub static ref DEFAULT_VERIFYING_KEY: Vec<u8> = vec![0; VERIFICATION_KEY_LENGTH as usize]; | ||
// key used to create a deterministic key share | ||
pub static ref DETERMINISTIC_KEY_SHARE: [u8; 32] = hex!("4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you got this from the k256
docs, do you mind linking those here?
pallets/registry/src/lib.rs
Outdated
@@ -453,7 +473,11 @@ pub mod pallet { | |||
} | |||
registering_info.confirmations.push(signing_subgroup); | |||
Registering::<T>::insert(&sig_req_account, registering_info); | |||
Self::deposit_event(Event::AccountRegistering(sig_req_account, signing_subgroup)); | |||
Self::deposit_event(Event::AccountRegistering( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, let's change it since it's a bit confusing.
Something like RecievedConfirmation
would be better imo
Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
Closes #650
As well without permissioned a sig request key is not needed and the verifying key is used to map the user to account