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

Remove permissioned access type #666

Merged
merged 50 commits into from
Mar 22, 2024
Merged

Remove permissioned access type #666

merged 50 commits into from
Mar 22, 2024

Conversation

JesseAbram
Copy link
Member

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

Copy link

vercel bot commented Mar 8, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
entropy-core ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 22, 2024 6:06pm

@@ -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>,
Copy link
Contributor

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]

Copy link
Member Author

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

Copy link
Collaborator

@HCastano HCastano left a 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

}

#[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);
Copy link
Collaborator

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

Copy link
Collaborator

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

Copy link
Member Author

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<
Copy link
Collaborator

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?

Copy link
Contributor

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.

Copy link
Member Author

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

Copy link
Member Author

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

Copy link
Collaborator

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

Copy link
Member Author

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

/// An account has been registered. \[who\]
AccountRegistered(T::AccountId),
/// An account has been registered. [who, signing_group, verifying_key]
AccountRegistering(T::AccountId, u8, VerifyingKey),
Copy link
Collaborator

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?

Copy link
Member Author

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 Show resolved Hide resolved
@@ -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(
Copy link
Collaborator

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

Copy link
Member Author

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

Copy link
Collaborator

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

Comment on lines +63 to +67
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,
Copy link
Collaborator

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?

Copy link
Member Author

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")
Copy link
Collaborator

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?

Copy link
Member Author

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];
Copy link
Collaborator

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?

Copy link
Contributor

@ameba23 ameba23 Mar 21, 2024

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.

Copy link
Member Author

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

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.

🥇

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.

crates/test-cli/src/main.rs Outdated Show resolved Hide resolved
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];
Copy link
Contributor

@ameba23 ameba23 Mar 21, 2024

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 {
Copy link
Contributor

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 {
Copy link
Contributor

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

Copy link
Member Author

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(
Copy link
Contributor

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.

Copy link
Member Author

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

Copy link
Collaborator

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 {
Copy link
Contributor

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?

Copy link
Member Author

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()),
Copy link
Contributor

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;
}
Copy link
Contributor

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<
Copy link
Contributor

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..];
Copy link
Contributor

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

JesseAbram and others added 6 commits March 21, 2024 09:24
Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
Co-authored-by: peg <peg@magmacollective.org>
Copy link
Collaborator

@HCastano HCastano 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 still confused at the ModifiableKeys thing - but overall this does what I expect.

Good work on this 💪

CHANGELOG.md Outdated Show resolved Hide resolved
pallets/registry/src/lib.rs Show resolved Hide resolved

#[pallet::storage]
#[pallet::getter(fn modifiable_keys)]
pub type ModifiableKeys<T: Config> = StorageMap<
Copy link
Collaborator

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

pallets/registry/src/lib.rs Outdated Show resolved Hide resolved
@@ -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);
Copy link
Collaborator

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?

Copy link
Member Author

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

crates/test-cli/src/main.rs Outdated Show resolved Hide resolved
crates/test-cli/src/main.rs Outdated Show resolved Hide resolved
@@ -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
Copy link
Collaborator

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");
Copy link
Collaborator

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?

@@ -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(
Copy link
Collaborator

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

JesseAbram and others added 11 commits March 22, 2024 11:07
Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
@JesseAbram JesseAbram merged commit da40bd7 into master Mar 22, 2024
10 checks passed
@JesseAbram JesseAbram deleted the remove-permissioned branch March 22, 2024 18:25
@HCastano HCastano changed the title Remove permissioned Remove permissioned access type Mar 22, 2024
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.

Remove Permissioned accounts
3 participants