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

Cleaner GRANDPA RPC API for proving finality #7339

Merged
38 commits merged into from
Jan 21, 2021
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
75d59d8
grandpa: persist block number for last block of authority set
octol Oct 8, 2020
c3dac36
grandpa: fix authority_set_changes field in tests
octol Oct 13, 2020
363ba7b
grandpa: fix date on copyright notice
octol Oct 16, 2020
1d54eb5
grandpa-rpc: implement cleaner api for prove finality rpc
octol Oct 16, 2020
58477bc
grandpa-rpc: replace the old prove_finality with the new one
octol Oct 16, 2020
10e507f
grandpa: undo accidental whitespace change
octol Oct 16, 2020
8e99c66
Merge remote-tracking branch 'upstream/master' into jon/cleaner-final…
octol Oct 30, 2020
83ff901
grandpa-rpc: start work on redo of the finality_proof RPC API
octol Oct 31, 2020
107a4fa
Merge remote-tracking branch 'upstream/master' into jon/cleaner-final…
octol Nov 11, 2020
df5cca1
grandpa: manual impl of Decode for AuthoritySet
octol Nov 11, 2020
6ed408a
grandpa: add comment about appending changes for forced changes
octol Nov 12, 2020
bde6188
grandpa: flip order in set changes, tidy up some comments
octol Nov 12, 2020
ec52b6f
grandpa: update some of the doc comments
octol Nov 12, 2020
0126c4c
Merge remote-tracking branch 'upstream/master' into jon/cleaner-final…
octol Nov 12, 2020
efcd04b
grandpa: store authority set changes when applying forced changes
octol Nov 19, 2020
88ea322
Merge remote-tracking branch 'upstream/master' into jon/cleaner-final…
octol Nov 25, 2020
62a7245
grandpa: simplify finality_proof.rs
octol Nov 20, 2020
65c4243
grandpa: move checks and extend tests in finality_proof
octol Nov 26, 2020
282d9f6
grandpa: address first set of review comments
octol Dec 7, 2020
a5644a9
grandpa: check that set changes have well-defined start
octol Dec 7, 2020
25a854a
grandpa: rework prove_finality and assocated tests
octol Dec 7, 2020
79d1840
grandpa: make AuthoritySetChanges tuple struct
octol Dec 8, 2020
ef993a4
grandpa: add assertions for tracking auth set changes
octol Dec 8, 2020
abeb9ec
grandpa: remove StorageAndProofProvider trait
octol Dec 8, 2020
fb12f98
Merge remote-tracking branch 'upstream/master' into jon/cleaner-final…
octol Dec 9, 2020
b14d97c
grandpa: return more informative results for unexpected input to RPC
octol Dec 9, 2020
4544bfd
Merge remote-tracking branch 'upstream/master' into jon/cleaner-final…
octol Dec 9, 2020
f2c3b23
grandpa: tiny tweak to error msg
octol Dec 9, 2020
3034193
grandpa: fix tests
octol Dec 9, 2020
2a9a86f
Merge remote-tracking branch 'upstream/master' into jon/cleaner-final…
octol Jan 7, 2021
c8efdbb
grandpa: add error specific to finality_proof
octol Jan 12, 2021
ceee16a
grandpa: fix review comments
octol Jan 15, 2021
adc39b8
Merge remote-tracking branch 'upstream/master' into jon/cleaner-final…
octol Jan 20, 2021
9feb90c
Merge remote-tracking branch 'upstream/master' into jon/cleaner-final…
octol Jan 20, 2021
aa6282e
grandpa: proper migration to new AuthoritySet
octol Jan 20, 2021
6d90ce3
grandpa: fix long lines
octol Jan 21, 2021
bb6cb32
Merge branch 'master' into jon/cleaner-finality-rpc-api
andresilva Jan 21, 2021
a8878a1
grandpa: fix unused warning after merge
octol Jan 21, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions bin/node/cli/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,11 @@ pub fn new_partial(config: &Configuration) -> Result<sc_service::PartialComponen
let shared_voter_state = grandpa::SharedVoterState::empty();
let rpc_setup = shared_voter_state.clone();

let finality_proof_provider =
grandpa::FinalityProofProvider::new_for_service(backend.clone(), client.clone());
let finality_proof_provider = grandpa::FinalityProofProvider::new_for_service(
backend.clone(),
client.clone(),
Some(shared_authority_set.clone()),
);

let babe_config = babe_link.config().clone();
let shared_epoch_changes = babe_link.epoch_changes().clone();
Expand Down
2 changes: 1 addition & 1 deletion client/finality-grandpa/rpc/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub enum Error {
VoterStateReportsUnreasonablyLargeNumbers,
/// GRANDPA prove finality failed.
#[display(fmt = "GRANDPA prove finality rpc failed: {}", _0)]
ProveFinalityFailed(sp_blockchain::Error),
ProveFinalityFailed(sc_finality_grandpa::FinalityProofError),
}

/// The error codes returned by jsonrpc.
Expand Down
22 changes: 9 additions & 13 deletions client/finality-grandpa/rpc/src/finality.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,16 @@ use sc_finality_grandpa::FinalityProofProvider;
use sp_runtime::traits::{Block as BlockT, NumberFor};

#[derive(Serialize, Deserialize)]
pub struct EncodedFinalityProofs(pub sp_core::Bytes);
pub struct EncodedFinalityProof(pub sp_core::Bytes);

andresilva marked this conversation as resolved.
Show resolved Hide resolved
/// Local trait mainly to allow mocking in tests.
pub trait RpcFinalityProofProvider<Block: BlockT> {
/// Return finality proofs for the given authorities set id, if it is provided, otherwise the
/// current one will be used.
/// Prove finality for the given block number by returning a Justification for the last block of
/// the authority set.
fn rpc_prove_finality(
andresilva marked this conversation as resolved.
Show resolved Hide resolved
&self,
begin: Block::Hash,
end: Block::Hash,
authorities_set_id: u64,
) -> Result<Option<EncodedFinalityProofs>, sp_blockchain::Error>;
block: NumberFor<Block>,
) -> Result<Option<EncodedFinalityProof>, sc_finality_grandpa::FinalityProofError>;
}

impl<B, Block> RpcFinalityProofProvider<Block> for FinalityProofProvider<B, Block>
Expand All @@ -44,11 +42,9 @@ where
{
fn rpc_prove_finality(
&self,
begin: Block::Hash,
end: Block::Hash,
authorities_set_id: u64,
) -> Result<Option<EncodedFinalityProofs>, sp_blockchain::Error> {
self.prove_finality(begin, end, authorities_set_id)
.map(|x| x.map(|y| EncodedFinalityProofs(y.into())))
block: NumberFor<Block>,
) -> Result<Option<EncodedFinalityProof>, sc_finality_grandpa::FinalityProofError> {
self.prove_finality(block)
.map(|x| x.map(|y| EncodedFinalityProof(y.into())))
}
}
75 changes: 33 additions & 42 deletions client/finality-grandpa/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ 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 finality::{EncodedFinalityProof, RpcFinalityProofProvider};
use report::{ReportAuthoritySet, ReportVoterState, ReportedRoundStates};
use notification::JustificationNotification;

Expand All @@ -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, Number> {
/// RPC Metadata
type Metadata;

Expand Down Expand Up @@ -82,15 +82,13 @@ 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 by returning the Justification for the last block
/// in the set and all the intermediary headers to link them together.
#[rpc(name = "grandpa_proveFinality")]
fn prove_finality(
&self,
begin: Hash,
end: Hash,
authorities_set_id: Option<u64>,
) -> FutureResult<Option<EncodedFinalityProofs>>;
block: Number,
) -> FutureResult<Option<EncodedFinalityProof>>;
}

/// Implements the GrandpaApi RPC trait for interacting with GRANDPA.
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -171,16 +170,9 @@ where

fn prove_finality(
&self,
begin: Block::Hash,
end: Block::Hash,
authorities_set_id: Option<u64>,
) -> 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);
block: NumberFor<Block>,
) -> FutureResult<Option<EncodedFinalityProof>> {
let result = self.finality_proof_provider.rpc_prove_finality(block);
let future = async move { result }.boxed();
Box::new(
future
Expand All @@ -204,7 +196,7 @@ mod tests {
use sc_block_builder::BlockBuilder;
use sc_finality_grandpa::{
report, AuthorityId, GrandpaJustificationSender, GrandpaJustification,
FinalityProofFragment,
FinalityProof,
};
use sp_blockchain::HeaderBackend;
use sp_consensus::RecordProof;
Expand All @@ -223,7 +215,7 @@ mod tests {
struct EmptyVoterState;

struct TestFinalityProofProvider {
finality_proofs: Vec<FinalityProofFragment<Header>>,
finality_proof: Option<FinalityProof<Header>>,
}

fn voters() -> HashSet<AuthorityId> {
Expand Down Expand Up @@ -262,11 +254,15 @@ mod tests {
impl<Block: BlockT> RpcFinalityProofProvider<Block> for TestFinalityProofProvider {
fn rpc_prove_finality(
&self,
_begin: Block::Hash,
_end: Block::Hash,
_authoritites_set_id: u64,
) -> Result<Option<EncodedFinalityProofs>, sp_blockchain::Error> {
Ok(Some(EncodedFinalityProofs(self.finality_proofs.encode().into())))
_block: NumberFor<Block>
) -> Result<Option<EncodedFinalityProof>, sc_finality_grandpa::FinalityProofError> {
Ok(Some(EncodedFinalityProof(
self.finality_proof
.as_ref()
.expect("Don't call rpc_prove_finality without setting the FinalityProof")
.encode()
.into()
)))
}
}

Expand Down Expand Up @@ -308,20 +304,20 @@ mod tests {
) where
VoterState: ReportVoterState + Send + Sync + 'static,
{
setup_io_handler_with_finality_proofs(voter_state, Default::default())
setup_io_handler_with_finality_proofs(voter_state, None)
}

fn setup_io_handler_with_finality_proofs<VoterState>(
voter_state: VoterState,
finality_proofs: Vec<FinalityProofFragment<Header>>,
finality_proof: Option<FinalityProof<Header>>,
) -> (
jsonrpc_core::MetaIoHandler<sc_rpc::Metadata>,
GrandpaJustificationSender<Block>,
) where
VoterState: ReportVoterState + Send + Sync + 'static,
{
let (justification_sender, justification_stream) = GrandpaJustificationStream::channel();
let finality_proof_provider = Arc::new(TestFinalityProofProvider { finality_proofs });
let finality_proof_provider = Arc::new(TestFinalityProofProvider { finality_proof });

let handler = GrandpaRpcHandler::new(
TestAuthoritySet,
Expand Down Expand Up @@ -520,29 +516,24 @@ mod tests {

#[test]
fn prove_finality_with_test_finality_proof_provider() {
let finality_proofs = vec![FinalityProofFragment {
let finality_proof = FinalityProof {
block: header(42).hash(),
justification: create_justification().encode(),
unknown_headers: vec![header(2)],
authorities_proof: None,
}];
};
let (io, _) = setup_io_handler_with_finality_proofs(
TestVoterState,
finality_proofs.clone(),
Some(finality_proof.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);
let mut resp: serde_json::Value = serde_json::from_str(&resp.unwrap()).unwrap();
let result: sp_core::Bytes = serde_json::from_value(resp["result"].take()).unwrap();
let fragments: Vec<FinalityProofFragment<Header>> =
Decode::decode(&mut &result[..]).unwrap();
assert_eq!(fragments, finality_proofs);
let finality_proof_rpc: FinalityProof<Header> = Decode::decode(&mut &result[..]).unwrap();
assert_eq!(finality_proof_rpc, finality_proof);
}
}
Loading