Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Expose GRANDPA round state through RPC #5375

Conversation

octol
Copy link
Contributor

@octol octol commented Mar 24, 2020

Implements #4921

Depends on paritytech/finality-grandpa#114

Left to do

  • JSON RPC error code?
  • Convert SharedVoterState to struct
  • Reintroduce the test stub
  • Add to light client
  • Move serialized structs to separate file
  • Can we use u32 for serialized fields?

polkadot companion: paritytech/polkadot#1040

@octol octol added the A3-in_progress Pull request is in progress. No review needed at this stage. label Mar 24, 2020
@parity-cla-bot
Copy link

It looks like @octol signed our Contributor License Agreement. 👍

Many thanks,

Parity Technologies CLA Bot

@octol octol force-pushed the jon/issue-4921-expose-grandpa-round-state-try-shared-arc branch from 2426a3d to 58f52da Compare March 25, 2020 11:08
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>>,
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 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.

Copy link
Contributor Author

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

@@ -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));
Copy link
Contributor Author

@octol octol Mar 25, 2020

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 ?

Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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

Copy link
Contributor Author

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

Copy link
Contributor

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.

@octol octol force-pushed the jon/issue-4921-expose-grandpa-round-state-try-shared-arc branch 2 times, most recently from 572ce7c to cdd55fe Compare April 7, 2020 11:03
@octol octol force-pushed the jon/issue-4921-expose-grandpa-round-state-try-shared-arc branch from db2a02d to 83c82c9 Compare April 15, 2020 20:06
Copy link
Contributor

@andresilva andresilva left a 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 👍

Comment on lines 52 to 53
let shared_voter_state: grandpa::SharedVoterState<grandpa::AuthorityId>
= Arc::new(parking_lot::RwLock::new(None));
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
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));

Copy link
Contributor

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?

Copy link
Contributor Author

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

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

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.

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

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.

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

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.

@octol octol force-pushed the jon/issue-4921-expose-grandpa-round-state-try-shared-arc branch from 6464139 to c6486d6 Compare April 23, 2020 21:07
Copy link
Contributor

@andresilva andresilva left a 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! :)

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

Choose a reason for hiding this comment

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

Suggested change
shared_voter_state: Arc::clone(&shared_voter_state),
shared_voter_state: shared_voter_state.clone(),

Copy link
Contributor Author

@octol octol Apr 24, 2020

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

}
};
Ok(node_rpc::create_full(deps))
})?;

(builder, import_setup, inherent_data_providers)
(builder, import_setup, inherent_data_providers, shared_voter_state)
Copy link
Contributor

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/rpc/src/lib.rs Show resolved Hide resolved
@@ -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>>>>;
Copy link
Contributor

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

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

I second that.

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

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes that makes sense!

@andresilva
Copy link
Contributor

Fixed a bunch of nits, made the RPC handler testable and wrote tests. This currently depends on paritytech/finality-grandpa#118 being merged and v0.12.1 published. @tomusdrw do you mind giving this another look?


let voter_state = voter_state.get().ok_or(Error::EndpointNotReady)?;

let (set_id, current_voters) = authority_set.get();
Copy link
Contributor Author

@octol octol May 1, 2020

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!

@gavofyork
Copy link
Member

doesn't build?

@octol
Copy link
Contributor Author

octol commented May 1, 2020

doesn't build?

Waiting for a new release of finality-grandpa containing this: paritytech/finality-grandpa#118

@andresilva
Copy link
Contributor

Should build and pass tests now (if it doesn't then I did something wrong :)

@tomusdrw
Copy link
Contributor

tomusdrw commented May 4, 2020

This one looks good, but polkadot companion PR seems to have build failures.

@andresilva
Copy link
Contributor

@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.

@gnunicorn gnunicorn requested a review from andresilva May 4, 2020 12:08
@gnunicorn gnunicorn added A0-please_review Pull request needs code review. and removed A8-mergeoncegreen labels May 4, 2020
@gnunicorn
Copy link
Contributor

gnunicorn commented May 4, 2020

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.)

@andresilva andresilva merged commit c0ccc24 into paritytech:master May 4, 2020
lamafab pushed a commit to lamafab/substrate that referenced this pull request Jun 16, 2020
* Companion PR for Substrate paritytech#5375

* fix compilation

* Update rpc/Cargo.toml

* update substrate

Co-authored-by: André Silva <andre.beat@gmail.com>
Co-authored-by: Benjamin Kampmann <ben@gnunicorn.org>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-please_review Pull request needs code review.
Projects
None yet
Development

Successfully merging this pull request may close these issues.