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

Commit

Permalink
grandpa-rpc: use FinalityProofProvider to check finality for rpc (#6215)
Browse files Browse the repository at this point in the history
* grandpa-rpc: use FinalityProofProvider to check finality for rpc

* grandpa-rpc: minor tidy

* grandpa-rpc: remove dyn FinalityProofProvider

* grandpa-rpc: remove unused dependencies

* node: move finality_proof_provider setup

* grandpa-rpc: print error reported by finality_proof_provider

* grandpa-rpc: add note about unnecessary encode/decode

* grandpa-rpc: dont encode/decode and use correct hash

* grandpa-rpc: set_id is optional

* grandpa-rpc: create test for prove_finality

* grandpa-rpc: set visibility back to how it was

* grandpa-rpc: remove unused dependency

* grandpa-rpc: minor tidy

* grandpa: doc strings

* grandpa-rpc: rename to prove_finality

* grandpa-rpc: use current set id if none is provided

* grandpa-rpc: remove unnecessary check in test

* node: group finality_proof_provider in rpc_setup

* grandpa: make prove_finality concrete in FinalityProofProvider

* grandpa-rpc: wrap finality output in struct and store as Bytes

* grandpa-rpc: exhaustive error codes and wrap

* grandpa-rpc: let prove_finality take a range instead of a starting point

* grandpa-rpc: fix test for changed API

* grandpa-rpc: fix line length

* grandpa: fix reviewer nits

* node/rpc: fix reviewer comments
  • Loading branch information
octol authored Sep 18, 2020
1 parent b28d202 commit 16474ee
Show file tree
Hide file tree
Showing 10 changed files with 263 additions and 31 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 9 additions & 5 deletions bin/node/cli/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ pub fn new_partial(config: &Configuration) -> Result<sc_service::PartialComponen
grandpa::LinkHalf<Block, FullClient, FullSelectChain>,
sc_consensus_babe::BabeLink<Block>,
),
grandpa::SharedVoterState,
(
grandpa::SharedVoterState,
Arc<GrandpaFinalityProofProvider<FullBackend, Block>>,
),
)
>, ServiceError> {
let (client, backend, keystore, task_manager) =
Expand Down Expand Up @@ -108,8 +111,10 @@ pub fn new_partial(config: &Configuration) -> Result<sc_service::PartialComponen
let justification_stream = grandpa_link.justification_stream();
let shared_authority_set = grandpa_link.shared_authority_set().clone();
let shared_voter_state = grandpa::SharedVoterState::empty();
let finality_proof_provider =
GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone());

let rpc_setup = shared_voter_state.clone();
let rpc_setup = (shared_voter_state.clone(), finality_proof_provider.clone());

let babe_config = babe_link.config().clone();
let shared_epoch_changes = babe_link.epoch_changes().clone();
Expand All @@ -135,6 +140,7 @@ pub fn new_partial(config: &Configuration) -> Result<sc_service::PartialComponen
shared_authority_set: shared_authority_set.clone(),
justification_stream: justification_stream.clone(),
subscription_executor,
finality_provider: finality_proof_provider.clone(),
},
};

Expand Down Expand Up @@ -174,8 +180,7 @@ pub fn new_full_base(
other: (rpc_extensions_builder, import_setup, rpc_setup),
} = new_partial(&config)?;

let finality_proof_provider =
GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone());
let (shared_voter_state, finality_proof_provider) = rpc_setup;

let (network, network_status_sinks, system_rpc_tx, network_starter) =
sc_service::build_network(sc_service::BuildNetworkParams {
Expand Down Expand Up @@ -220,7 +225,6 @@ pub fn new_full_base(
})?;

let (block_import, grandpa_link, babe_link) = import_setup;
let shared_voter_state = rpc_setup;

(with_startup_data)(&block_import, &babe_link);

Expand Down
1 change: 1 addition & 0 deletions bin/node/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ sp-block-builder = { version = "2.0.0-rc6", path = "../../../primitives/block-bu
sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" }
sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" }
sp-consensus-babe = { version = "0.8.0-rc6", path = "../../../primitives/consensus/babe" }
sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" }
sp-transaction-pool = { version = "2.0.0-rc6", path = "../../../primitives/transaction-pool" }
substrate-frame-rpc-system = { version = "2.0.0-rc6", path = "../../../utils/frame/rpc/system" }
20 changes: 14 additions & 6 deletions bin/node/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ use node_primitives::{Block, BlockNumber, AccountId, Index, Balance, Hash};
use sc_consensus_babe::{Config, Epoch};
use sc_consensus_babe_rpc::BabeRpcHandler;
use sc_consensus_epochs::SharedEpochChanges;
use sc_finality_grandpa::{SharedVoterState, SharedAuthoritySet, GrandpaJustificationStream};
use sc_finality_grandpa::{
SharedVoterState, SharedAuthoritySet, FinalityProofProvider, GrandpaJustificationStream
};
use sc_finality_grandpa_rpc::GrandpaRpcHandler;
use sc_keystore::KeyStorePtr;
pub use sc_rpc_api::DenyUnsafe;
Expand Down Expand Up @@ -71,7 +73,7 @@ pub struct BabeDeps {
}

/// Extra dependencies for GRANDPA
pub struct GrandpaDeps {
pub struct GrandpaDeps<B> {
/// Voting round info.
pub shared_voter_state: SharedVoterState,
/// Authority set info.
Expand All @@ -80,10 +82,12 @@ pub struct GrandpaDeps {
pub justification_stream: GrandpaJustificationStream<Block>,
/// Executor to drive the subscription manager in the Grandpa RPC handler.
pub subscription_executor: SubscriptionTaskExecutor,
/// Finality proof provider.
pub finality_provider: Arc<FinalityProofProvider<B, Block>>,
}

/// Full client dependencies.
pub struct FullDeps<C, P, SC> {
pub struct FullDeps<C, P, SC, B> {
/// The client instance to use.
pub client: Arc<C>,
/// Transaction pool instance.
Expand All @@ -95,15 +99,15 @@ pub struct FullDeps<C, P, SC> {
/// BABE specific dependencies.
pub babe: BabeDeps,
/// GRANDPA specific dependencies.
pub grandpa: GrandpaDeps,
pub grandpa: GrandpaDeps<B>,
}

/// A IO handler that uses all Full RPC extensions.
pub type IoHandler = jsonrpc_core::IoHandler<sc_rpc::Metadata>;

/// Instantiate all Full RPC extensions.
pub fn create_full<C, P, SC>(
deps: FullDeps<C, P, SC>,
pub fn create_full<C, P, SC, B>(
deps: FullDeps<C, P, SC, B>,
) -> jsonrpc_core::IoHandler<sc_rpc_api::Metadata> where
C: ProvideRuntimeApi<Block>,
C: HeaderBackend<Block> + HeaderMetadata<Block, Error=BlockChainError> + 'static,
Expand All @@ -115,6 +119,8 @@ pub fn create_full<C, P, SC>(
C::Api: BlockBuilder<Block>,
P: TransactionPool + 'static,
SC: SelectChain<Block> +'static,
B: sc_client_api::Backend<Block> + Send + Sync + 'static,
B::State: sc_client_api::backend::StateBackend<sp_runtime::traits::HashFor<Block>>,
{
use substrate_frame_rpc_system::{FullSystem, SystemApi};
use pallet_contracts_rpc::{Contracts, ContractsApi};
Expand All @@ -140,6 +146,7 @@ pub fn create_full<C, P, SC>(
shared_authority_set,
justification_stream,
subscription_executor,
finality_provider,
} = grandpa;

io.extend_with(
Expand Down Expand Up @@ -173,6 +180,7 @@ pub fn create_full<C, P, SC>(
shared_voter_state,
justification_stream,
subscription_executor,
finality_provider,
)
)
);
Expand Down
3 changes: 2 additions & 1 deletion client/finality-grandpa/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
[dependencies]
sc-finality-grandpa = { version = "0.8.0-rc6", path = "../" }
sc-rpc = { version = "2.0.0-rc6", path = "../../rpc" }
sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" }
sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" }
sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" }
finality-grandpa = { version = "0.12.3", features = ["derive-codec"] }
Expand All @@ -23,12 +24,12 @@ serde_json = "1.0.50"
log = "0.4.8"
derive_more = "0.99.2"
parity-scale-codec = { version = "1.3.0", features = ["derive"] }
sc-client-api = { version = "2.0.0-rc6", path = "../../api" }

[dev-dependencies]
sc-block-builder = { version = "0.8.0-rc6", path = "../../block-builder" }
sc-network-test = { version = "0.8.0-rc6", path = "../../network/test" }
sc-rpc = { version = "2.0.0-rc6", path = "../../rpc", features = ["test-helpers"] }
sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" }
sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" }
sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" }
sp-finality-grandpa = { version = "2.0.0-rc6", path = "../../../primitives/finality-grandpa" }
Expand Down
34 changes: 30 additions & 4 deletions client/finality-grandpa/rpc/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::NOT_READY_ERROR_CODE;

#[derive(derive_more::Display, derive_more::From)]
/// Top-level error type for the RPC handler
pub enum Error {
Expand All @@ -30,13 +28,41 @@ pub enum Error {
/// GRANDPA reports voter state with round id or weights larger than 32-bits.
#[display(fmt = "GRANDPA reports voter state as unreasonably large")]
VoterStateReportsUnreasonablyLargeNumbers,
/// GRANDPA prove finality failed.
#[display(fmt = "GRANDPA prove finality rpc failed: {}", _0)]
ProveFinalityFailed(sp_blockchain::Error),
}

/// The error codes returned by jsonrpc.
pub enum ErrorCode {
/// Returned when Grandpa RPC endpoint is not ready.
NotReady = 1,
/// Authority set ID is larger than 32-bits.
AuthoritySetTooLarge,
/// Voter state with round id or weights larger than 32-bits.
VoterStateTooLarge,
/// Failed to prove finality.
ProveFinality,
}

impl From<Error> for ErrorCode {
fn from(error: Error) -> Self {
match error {
Error::EndpointNotReady => ErrorCode::NotReady,
Error::AuthoritySetIdReportedAsUnreasonablyLarge => ErrorCode::AuthoritySetTooLarge,
Error::VoterStateReportsUnreasonablyLargeNumbers => ErrorCode::VoterStateTooLarge,
Error::ProveFinalityFailed(_) => ErrorCode::ProveFinality,
}
}
}

impl From<Error> for jsonrpc_core::Error {
fn from(error: Error) -> Self {
let message = format!("{}", error);
let code = ErrorCode::from(error);
jsonrpc_core::Error {
message: format!("{}", error),
code: jsonrpc_core::ErrorCode::ServerError(NOT_READY_ERROR_CODE),
message,
code: jsonrpc_core::ErrorCode::ServerError(code as i64),
data: None,
}
}
Expand Down
54 changes: 54 additions & 0 deletions client/finality-grandpa/rpc/src/finality.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// This file is part of Substrate.

// Copyright (C) 2020 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0

// This program 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.

// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.

use serde::{Serialize, Deserialize};

use sc_finality_grandpa::FinalityProofProvider;
use sp_runtime::traits::{Block as BlockT, NumberFor};

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

/// 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.
fn rpc_prove_finality(
&self,
begin: Block::Hash,
end: Block::Hash,
authorities_set_id: u64,
) -> Result<Option<EncodedFinalityProofs>, sp_blockchain::Error>;
}

impl<B, Block> RpcFinalityProofProvider<Block> for FinalityProofProvider<B, Block>
where
Block: BlockT,
NumberFor<Block>: finality_grandpa::BlockNumberOps,
B: sc_client_api::backend::Backend<Block> + Send + Sync + 'static,
{
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())))
}
}
Loading

0 comments on commit 16474ee

Please sign in to comment.