-
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
Trigger attestation check during validate
#1063
Conversation
With the tight coupling we're not able to build out a mock runtime for the staking extension pallet since the compiler isn't able to verify that we have an implementation of the staking extension pallet for our mock attestation pallet (yeah, bit of a roundabout thing...). The loose coupling gives us a bit of flexibility here, and also allows us to scope the iteraction between the pallets in a more fine grained way.
We can't rely on the `ThresholdToStash` or `ThresholdServer` storage entries being populated anymore.
We're going to try and use this to limit the number of entries for benchmarking purposes.
The compiler is complaining abou a missing `Div` implementation which I'm not really sure how to work around.
This isn't the best solution, but for now it needs to be done since the `attest()` extrinsic expects certain Staking pallet specific data structures to be populated before it has try and verify an attestation.
This reflects the more generic nature of the trait now.
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
/// | ||
/// Not every account ID will have an given key, in which case the implementer is expected to | ||
/// return `None`. | ||
pub trait KeyProvider<T> { |
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.
Just to be clear - these types are in entropy-shared
to avoid circular dependencies between pallets. They are not intendend to be used by entropy-tss
, right?
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.
Correct. These traits had to be defined somewhere that multiple unrelated pallets could access them
requests.push(account_id.encode()); | ||
} | ||
|
||
AttestationRequests::<T>::insert(now, requests); |
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 feels a little bit like this data structure is now redundant and the propagation pallet could read directly from the attestation queue that the staking pallet add requests to. But i guess we need to keep the nonce generation logic inside this pallet, and it might also be useful for when we add other methods of triggering attestation requests.
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.
well maybe Id like to explore this a little more because this does trigger an extra on init, the nonce creation doesn't look like it needs to be here, could potentially be done when the attest request is created, could be put into a generalize function like create request and be called instead of having to go through each pending request to add the nonce
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 agree, there probably is a way to consolidate these data structures but it's not something I wanted to prioritize for this PR. And yeah, this will probably need to change a bit once we start adding more attestation checks.
Can open a follow up issue for 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.
Opened #1089.
|
||
/// This is a randomly generated secret p256 ECDSA key - for mocking the provisioning certification | ||
/// key | ||
const PCK: [u8; 32] = [ |
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.
Nit: I think you also use this constant in the tests. I would put it in mock.rs
and make it public, and you can use it here and it the tests.
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 tried doing this but there are some issues around differing feature flags for tests and benchmarks, so we can't actually pull in constants from mock.rs
in easily.
Another solution would be to move the PCK
constant either to the top crate level and feature flag it there but for two uses it doesn't seem worth it to me. But ya can do it if you think it would be better
PendingAttestations::<T>::remove(&who); | ||
T::AttestationQueue::confirm_attestation(&who); |
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.
You are probably already aware of this - but if and when we add other ways of triggering attestation requests, confirm_attestation
is gonna get called regardless of whether this particular attestation request was related to something in the attestation queue. This is not a problem, since nothing bad happens if we call it several times when they are already in a Confirmed
state.
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 agreed. As I mentioned elsewhere, it would be nice to consolidate these if possible
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.
looks good a few comments, the only thing that I don't love here is the two on_inits just a little more elaboration on those comments then id be good to approve
@@ -742,4 +812,77 @@ pub mod pallet { | |||
I::start_session(start_index); | |||
} | |||
} | |||
|
|||
impl<T: Config> entropy_shared::KeyProvider<T::AccountId> for Pallet<T> { |
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 looks inefficient to me, in both cases you call get_server_info making a read, but you call both the functions twice in the same function in attest (and maybe elsewhere) probably a good idea to take server_info as in input so you can reduce reads, or a function that gets both
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 not the most efficient thing, but basically it boils down to me not knowing how much of the server logic to expose to the attestation pallet.
I don't really want to couple it that tightly if we don't have to, and having a key provider with just the right amount of fields we need seemed like a nice compromise. For example, we could have these be computed on the fly for example, as opposed to being stuck with the storage read for ServerInfo
.
requests.push(account_id.encode()); | ||
} | ||
|
||
AttestationRequests::<T>::insert(now, requests); |
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.
well maybe Id like to explore this a little more because this does trigger an extra on init, the nonce creation doesn't look like it needs to be here, could potentially be done when the attest request is created, could be put into a generalize function like create request and be called instead of having to go through each pending request to add the nonce
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.
happy with the issue looks good
When somebody states their intention to become a validator on the network they need to go
through the staking extension pallet's
validate()
extrinsic. As part of this process wewant to ensure that anybody submitting their candidacy is running on suitable hardware,
and as such we need issue an attestation challenge.
This PR adds a call into the attestation pallet from the
validate()
extrinsic and onlyaccepts a caller as a candidate if they successfully pass the attestation check.
There were some issues around using the Attestation pallet directly from the Staking
Extension pallet due to circular dependencies, so I worked around this in two ways:
which both pallets communicate
For (2) to work I had to add
on_initialize
hooks to both pallets in order to ensurethat any new attestations or confirmations got picked up and dealt with "automatically".