-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Cleaner GRANDPA RPC API for proving finality #7339
Changes from 6 commits
75d59d8
c3dac36
363ba7b
1d54eb5
58477bc
10e507f
8e99c66
83ff901
107a4fa
df5cca1
6ed408a
bde6188
ec52b6f
0126c4c
efcd04b
88ea322
62a7245
65c4243
282d9f6
a5644a9
25a854a
79d1840
ef993a4
abeb9ec
fb12f98
b14d97c
4544bfd
f2c3b23
3034193
2a9a86f
c8efdbb
ceee16a
adc39b8
9feb90c
aa6282e
6d90ce3
bb6cb32
a8878a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,7 +37,7 @@ mod notification; | |
| mod report; | ||
|
|
||
| use sc_finality_grandpa::GrandpaJustificationStream; | ||
| use sp_runtime::traits::Block as BlockT; | ||
| use sp_runtime::traits::{Block as BlockT, NumberFor}; | ||
|
|
||
| use finality::{EncodedFinalityProofs, RpcFinalityProofProvider}; | ||
| use report::{ReportAuthoritySet, ReportVoterState, ReportedRoundStates}; | ||
|
|
@@ -48,7 +48,7 @@ type FutureResult<T> = | |
|
|
||
| /// Provides RPC methods for interacting with GRANDPA. | ||
| #[rpc] | ||
| pub trait GrandpaApi<Notification, Hash> { | ||
| pub trait GrandpaApi<Notification, Hash, N> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's name it |
||
| /// RPC Metadata | ||
| type Metadata; | ||
|
|
||
|
|
@@ -82,14 +82,12 @@ pub trait GrandpaApi<Notification, Hash> { | |
| id: SubscriptionId | ||
| ) -> jsonrpc_core::Result<bool>; | ||
|
|
||
| /// Prove finality for the range (begin; end] hash. Returns None if there are no finalized blocks | ||
| /// unknown in the range. If no authorities set is provided, the current one will be attempted. | ||
| /// Prove finality for the given block number. | ||
| /// WIP: expand this | ||
| #[rpc(name = "grandpa_proveFinality")] | ||
| fn prove_finality( | ||
| &self, | ||
| begin: Hash, | ||
| end: Hash, | ||
| authorities_set_id: Option<u64>, | ||
| block: N, | ||
| ) -> FutureResult<Option<EncodedFinalityProofs>>; | ||
| } | ||
|
|
||
|
|
@@ -127,7 +125,8 @@ impl<AuthoritySet, VoterState, Block: BlockT, ProofProvider> | |
| } | ||
| } | ||
|
|
||
| impl<AuthoritySet, VoterState, Block, ProofProvider> GrandpaApi<JustificationNotification, Block::Hash> | ||
| impl<AuthoritySet, VoterState, Block, ProofProvider> | ||
| GrandpaApi<JustificationNotification, Block::Hash, NumberFor<Block>> | ||
| for GrandpaRpcHandler<AuthoritySet, VoterState, Block, ProofProvider> | ||
| where | ||
| VoterState: ReportVoterState + Send + Sync + 'static, | ||
|
|
@@ -171,16 +170,11 @@ where | |
|
|
||
| fn prove_finality( | ||
| &self, | ||
| begin: Block::Hash, | ||
| end: Block::Hash, | ||
| authorities_set_id: Option<u64>, | ||
| block: NumberFor<Block>, | ||
| ) -> FutureResult<Option<EncodedFinalityProofs>> { | ||
| // If we are not provided a set_id, try with the current one. | ||
| let authorities_set_id = authorities_set_id | ||
| .unwrap_or_else(|| self.authority_set.get().0); | ||
| let result = self | ||
| .finality_proof_provider | ||
| .rpc_prove_finality(begin, end, authorities_set_id); | ||
| .rpc_prove_finality(block); | ||
| let future = async move { result }.boxed(); | ||
| Box::new( | ||
| future | ||
|
|
@@ -262,9 +256,7 @@ mod tests { | |
| impl<Block: BlockT> RpcFinalityProofProvider<Block> for TestFinalityProofProvider { | ||
| fn rpc_prove_finality( | ||
| &self, | ||
| _begin: Block::Hash, | ||
| _end: Block::Hash, | ||
| _authoritites_set_id: u64, | ||
| _block: NumberFor<Block> | ||
| ) -> Result<Option<EncodedFinalityProofs>, sp_blockchain::Error> { | ||
| Ok(Some(EncodedFinalityProofs(self.finality_proofs.encode().into()))) | ||
| } | ||
|
|
@@ -531,11 +523,8 @@ mod tests { | |
| finality_proofs.clone(), | ||
| ); | ||
|
|
||
| let request = "{\"jsonrpc\":\"2.0\",\"method\":\"grandpa_proveFinality\",\"params\":[\ | ||
| \"0x0000000000000000000000000000000000000000000000000000000000000000\",\ | ||
| \"0x0000000000000000000000000000000000000000000000000000000000000001\",\ | ||
| 42\ | ||
| ],\"id\":1}"; | ||
| let request = | ||
| "{\"jsonrpc\":\"2.0\",\"method\":\"grandpa_proveFinality\",\"params\":[42],\"id\":1}"; | ||
|
|
||
| let meta = sc_rpc::Metadata::default(); | ||
| let resp = io.handle_request_sync(request, meta); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| // Copyright 2020 Parity Technologies (UK) Ltd. | ||
| // This file is part of Substrate. | ||
|
|
||
| // Substrate is free software: you can redistribute it and/or modify | ||
| // it under the terms of the GNU General Public License as published by | ||
| // the Free Software Foundation, either version 3 of the License, or | ||
| // (at your option) any later version. | ||
|
|
||
| // Substrate is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| // GNU General Public License for more details. | ||
|
|
||
| // You should have received a copy of the GNU General Public License | ||
| // along with Substrate. If not, see <http://www.gnu.org/licenses/>. | ||
|
|
||
| use parity_scale_codec::{Decode, Encode}; | ||
| use std::{cmp::Ord, sync::Arc}; | ||
|
|
||
| // Tracks authority set changes. We store the block numbers for the last block of each authority | ||
| // set. | ||
| #[derive(Debug, Encode, Decode)] | ||
| pub(crate) struct AuthoritySetChanges<N> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe this can go inside |
||
| authority_set_changes: Vec<N>, | ||
| } | ||
|
|
||
| impl<N: Ord + Copy> AuthoritySetChanges<N> { | ||
| pub(crate) fn empty() -> Self { | ||
| Self { | ||
| authority_set_changes: Vec::new(), | ||
| } | ||
| } | ||
|
|
||
| pub(crate) fn append(&mut self, number: N) { | ||
| self.authority_set_changes.push(number) | ||
| } | ||
|
|
||
| pub(crate) fn get_set_id(&self, number: N) -> (u64, N) { | ||
| let set_id = self | ||
| .authority_set_changes | ||
| .binary_search(&number) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know I suggested not storing the set_id and instead implicitly figuring out by the position in the array. The only disadvantage of this approach is that it breaks for nodes that didn't sync from scratch with this code. I guess it might be better to store the |
||
| .unwrap_or_else(|idx| idx); | ||
| let last_block_for_set_id = self.authority_set_changes[set_id]; | ||
| // WIP: avoid cast? | ||
| (set_id as u64, last_block_for_set_id) | ||
| } | ||
| } | ||
|
|
||
| pub(crate) type SharedAuthoritySetChanges<N> = Arc<parking_lot::Mutex<AuthoritySetChanges<N>>>; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,4 @@ | ||
| // This file is part of Substrate. | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's keep the newline since we have a template for the header. |
||
| // Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. | ||
| // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 | ||
|
|
||
|
|
@@ -49,6 +48,7 @@ use crate::{ | |
| use sp_consensus::SelectChain; | ||
|
|
||
| use crate::authorities::{AuthoritySet, SharedAuthoritySet}; | ||
| use crate::authority_set_changes::SharedAuthoritySetChanges; | ||
| use crate::communication::Network as NetworkT; | ||
| use crate::consensus_changes::SharedConsensusChanges; | ||
| use crate::notification::GrandpaJustificationSender; | ||
|
|
@@ -417,6 +417,7 @@ pub(crate) struct Environment<Backend, Block: BlockT, C, N: NetworkT<Block>, SC, | |
| pub(crate) config: Config, | ||
| pub(crate) authority_set: SharedAuthoritySet<Block::Hash, NumberFor<Block>>, | ||
| pub(crate) consensus_changes: SharedConsensusChanges<Block::Hash, NumberFor<Block>>, | ||
| pub(crate) authority_set_changes: SharedAuthoritySetChanges<NumberFor<Block>>, | ||
| pub(crate) network: crate::communication::NetworkBridge<Block, N>, | ||
| pub(crate) set_id: SetId, | ||
| pub(crate) voter_set_state: SharedVoterSetState<Block>, | ||
|
|
@@ -1071,6 +1072,7 @@ where | |
| finalize_block( | ||
| self.client.clone(), | ||
| &self.authority_set, | ||
| &self.authority_set_changes, | ||
| &self.consensus_changes, | ||
| Some(self.config.justification_period.into()), | ||
| hash, | ||
|
|
@@ -1136,6 +1138,7 @@ impl<Block: BlockT> From<GrandpaJustification<Block>> for JustificationOrCommit< | |
| pub(crate) fn finalize_block<BE, Block, Client>( | ||
| client: Arc<Client>, | ||
| authority_set: &SharedAuthoritySet<Block::Hash, NumberFor<Block>>, | ||
| authority_set_changes: &SharedAuthoritySetChanges<NumberFor<Block>>, | ||
| consensus_changes: &SharedConsensusChanges<Block::Hash, NumberFor<Block>>, | ||
| justification_period: Option<NumberFor<Block>>, | ||
| hash: Block::Hash, | ||
|
|
@@ -1175,6 +1178,8 @@ where | |
| // reverting in case of failure | ||
| let mut old_consensus_changes = None; | ||
|
|
||
| let mut authority_set_changes = authority_set_changes.lock(); | ||
|
|
||
| let mut consensus_changes = consensus_changes.lock(); | ||
| let canon_at_height = |canon_number| { | ||
| // "true" because the block is finalized | ||
|
|
@@ -1292,6 +1297,23 @@ where | |
| // the authority set has changed. | ||
| let (new_id, set_ref) = authority_set.current(); | ||
|
|
||
| // Persist the number of the last block of the session | ||
| if number > NumberFor::<Block>::zero() { | ||
| let parent_number = number - NumberFor::<Block>::one(); | ||
| authority_set_changes.append(parent_number); | ||
| let write_result = crate::aux_schema::update_authority_set_changes( | ||
| &*authority_set_changes, | ||
| |insert| apply_aux(import_op, insert, &[]), | ||
| ); | ||
| if let Err(e) = write_result { | ||
| warn!( | ||
| target: "afg", | ||
| "Failed to write updated authority set changes to disk: {}", | ||
| e | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| if set_ref.len() > 16 { | ||
| afg_log!(initial_sync, | ||
| "👴 Applying GRANDPA set change to new set with {} authorities", | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.