-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Expose GRANDPA round state through RPC #5375
Expose GRANDPA round state through RPC #5375
Conversation
It looks like @octol signed our Contributor License Agreement. 👍 Many thanks, Parity Technologies CLA Bot |
2426a3d
to
58f52da
Compare
pub(crate) voter_set_state: SharedVoterSetState<Block>, | ||
pub(crate) voting_rule: VR, | ||
pub struct Environment<B, E, Block: BlockT, N: NetworkT<Block>, RA, SC, VR> { | ||
pub client: Arc<Client<B, E, Block, RA>>, |
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.
Do we need to make the fields public? We only care about exporting the Environment
type. If the fields are not public I assume that a lot less types would have to be exported.
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 I have some hope to be able to roll back some of these pub
changes once it's all up and working
bin/node/cli/src/service.rs
Outdated
@@ -54,6 +55,8 @@ macro_rules! new_full_start { | |||
type RpcExtension = jsonrpc_core::IoHandler<sc_rpc::Metadata>; | |||
let mut import_setup = None; | |||
let inherent_data_providers = sp_inherents::InherentDataProviders::new(); | |||
// WIP: sort out construction | |||
let shared_voter_state = Arc::new(RwLock::new(None)); |
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 part here, how to construct when we don't yet have Environment
available. Any ideas on the best approach @seunlanlege ?
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 have no idea what VoterState
is.
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.
tried checking out this PR, but it looks like you're using a custom finality-grandpa crate. Try using a git dependency.
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 that's right, it depends on paritytech/finality-grandpa#114
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.
Updated to use git dependency pointing to my fork on github
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 object will always be constructed by the Voter in finality-grandpa. You just keep it uninitialized here.
572ce7c
to
cdd55fe
Compare
db2a02d
to
83c82c9
Compare
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 didn't expect the VoterSet
changes to cause so much disruption here and I think they should be handled properly before we migrate to grandpa 0.12
. So in order to not block this PR on that let's target grandpa 0.11
here. I can help with rebasing this if you need.
Most of your WIP comments that aren't related to 0.12
changes seem sensible to me and should be done 👍
bin/node/cli/src/service.rs
Outdated
let shared_voter_state: grandpa::SharedVoterState<grandpa::AuthorityId> | ||
= Arc::new(parking_lot::RwLock::new(None)); |
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.
let shared_voter_state: grandpa::SharedVoterState<grandpa::AuthorityId> | |
= Arc::new(parking_lot::RwLock::new(None)); | |
let shared_voter_state: grandpa::SharedVoterState<grandpa::AuthorityId> = | |
Arc::new(parking_lot::RwLock::new(None)); |
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.
Is the type still needed?
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.
Nope not anymore!
jsonrpc_core::Error { | ||
message: format!("{}", error).into(), | ||
// WIP: what error code should we use? | ||
code: jsonrpc_core::ErrorCode::ServerError(1234), |
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.
1
? Put it in a const named NOT_READY
?
self.inner.read().current_authorities.iter().cloned().collect() | ||
pub fn current_authorities(&self) -> VoterSet<AuthorityId> { | ||
// WIP: unwrap | ||
VoterSet::new(self.inner.read().current_authorities.iter().cloned()).unwrap() |
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.
For now let's add an expect here with a message saying that authorities should not be 0. Let's deal with this in a follow-up PR.
client/finality-grandpa/src/lib.rs
Outdated
@@ -620,6 +632,9 @@ pub struct GrandpaParams<Block: BlockT, C, N, SC, VR> { | |||
pub voting_rule: VR, | |||
/// The prometheus metrics registry. | |||
pub prometheus_registry: Option<prometheus_endpoint::Registry>, | |||
/// The voter state is exposed at an RPC endpoint. | |||
// WIP: should we use Environment::Id istead of AuthorityId? | |||
pub shared_voter_state: SharedVoterState<AuthorityId>, |
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 isn't typed by Environment
, it's okay to keep the id fixed.
client/finality-grandpa/src/lib.rs
Outdated
@@ -203,6 +206,9 @@ type CommunicationOutH<Block, H> = finality_grandpa::voter::CommunicationOut< | |||
AuthorityId, | |||
>; | |||
|
|||
// WIP: convert to struct | |||
pub type SharedVoterState<Id> = Arc<RwLock<Option<Box<dyn voter::VoterState<Id> + Sync + Send>>>>; |
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 shouldn't be typed by Id
and instead should fix the VoterState
to AuthorityId
.
6464139
to
c6486d6
Compare
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 some minor nits but overall lgtm! :)
bin/node/cli/src/service.rs
Outdated
@@ -100,12 +104,16 @@ macro_rules! new_full_start { | |||
keystore: builder.keystore(), | |||
babe_config: sc_consensus_babe::BabeLink::config(babe_link).clone(), | |||
shared_epoch_changes: sc_consensus_babe::BabeLink::epoch_changes(babe_link).clone() | |||
}, | |||
grandpa: node_rpc::GrandpaDeps { | |||
shared_voter_state: Arc::clone(&shared_voter_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.
shared_voter_state: Arc::clone(&shared_voter_state), | |
shared_voter_state: shared_voter_state.clone(), |
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.
Interesting, hadn't spotted that it wasn't the recommended style anymore
bin/node/cli/src/service.rs
Outdated
} | ||
}; | ||
Ok(node_rpc::create_full(deps)) | ||
})?; | ||
|
||
(builder, import_setup, inherent_data_providers) | ||
(builder, import_setup, inherent_data_providers, shared_voter_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.
Do you mind instead creating an let rpc_setup = Some((shared_voter_state));
and returning that instead? Similar to what we do for the import_setup
. It's futile right now as we only return one thing from the RPC setup but will make it easier if we need to add anything else in the future.
client/finality-grandpa/src/lib.rs
Outdated
@@ -203,6 +206,9 @@ type CommunicationOutH<Block, H> = finality_grandpa::voter::CommunicationOut< | |||
AuthorityId, | |||
>; | |||
|
|||
// WIP: convert to struct | |||
pub type SharedVoterState = Arc<RwLock<Option<Box<dyn voter::VoterState<AuthorityId> + Sync + Send>>>>; |
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 would be nice mainly to avoid exposing the lock, i.e. it would only expose a getter method to get the data we need. Not a blocker though.
let future = async move { round_states }.boxed(); | ||
Box::new(future.map_err(jsonrpc_core::Error::from).compat()) | ||
} | ||
} |
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.
Initially you had a test stub here and I think it was nice test to have.
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 second that.
client/finality-grandpa/src/lib.rs
Outdated
@@ -858,6 +877,10 @@ where | |||
last_finalized, | |||
); | |||
|
|||
// Repoint shared_voter_state so that the RPC endpoint can query the state | |||
let mut shared_voter_state = self.shared_voter_state.write(); |
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 safe, could you replace this .write()
with .try_write_for(Duration::from_secs(1))
? Just to be safe, in case there's a deadlock we won't block the voter.
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.
Yes that makes sense!
Fixed a bunch of nits, made the RPC handler testable and wrote tests. This currently depends on paritytech/finality-grandpa#118 being merged and |
|
||
let voter_state = voter_state.get().ok_or(Error::EndpointNotReady)?; | ||
|
||
let (set_id, current_voters) = authority_set.get(); |
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.
The first set_id
is shadowed and unused?
EDIT: my bad, it's not!
doesn't build? |
Waiting for a new release of finality-grandpa containing this: paritytech/finality-grandpa#118 |
Should build and pass tests now (if it doesn't then I did something wrong :) |
This one looks good, but polkadot companion PR seems to have build failures. |
@tomusdrw Not sure if there were any previous errors and/or you restarted the build, polkadot companion is green here atm. The PR on polkadot itself will be green once this is merged and substrate is updated. |
Updated the companion PR, @andresilva could you take another look here and there? (companion fails because I already updated the companion PR, but the reference is missing. However, it had passed prior.) |
* Companion PR for Substrate paritytech#5375 * fix compilation * Update rpc/Cargo.toml * update substrate Co-authored-by: André Silva <[email protected]> Co-authored-by: Benjamin Kampmann <[email protected]>
Implements #4921
Depends on paritytech/finality-grandpa#114
Left to do
SharedVoterState
to structAdd to light clientpolkadot companion: paritytech/polkadot#1040