mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-12 02:55:41 +00:00
e16ef0861f
This is a rather big change in jsonrpsee, the major things in this bump are: - Server backpressure (the subscription impls are modified to deal with that) - Allow custom error types / return types (remove jsonrpsee::core::Error and jsonrpee::core::CallError) - Bug fixes (graceful shutdown in particular not used by substrate anyway) - Less dependencies for the clients in particular - Return type requires Clone in method call responses - Moved to tokio channels - Async subscription API (not used in this PR) Major changes in this PR: - The subscriptions are now bounded and if subscription can't keep up with the server it is dropped - CLI: add parameter to configure the jsonrpc server bounded message buffer (default is 64) - Add our own subscription helper to deal with the unbounded streams in substrate The most important things in this PR to review is the added helpers functions in `substrate/client/rpc/src/utils.rs` and the rest is pretty much chore. Regarding the "bounded buffer limit" it may cause the server to handle the JSON-RPC calls slower than before. The message size limit is bounded by "--rpc-response-size" thus "by default 10MB * 64 = 640MB" but the subscription message size is not covered by this limit and could be capped as well. Hopefully the last release prior to 1.0, sorry in advance for a big PR Previous attempt: https://github.com/paritytech/substrate/pull/13992 Resolves https://github.com/paritytech/polkadot-sdk/issues/748, resolves https://github.com/paritytech/polkadot-sdk/issues/627
151 lines
4.2 KiB
Rust
151 lines
4.2 KiB
Rust
// This file is part of Substrate.
|
|
|
|
// Copyright (C) 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 std::{
|
|
collections::{BTreeSet, HashSet},
|
|
fmt::Debug,
|
|
ops::Add,
|
|
};
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use sc_consensus_grandpa::{report, AuthorityId, SharedAuthoritySet, SharedVoterState};
|
|
|
|
use crate::error::Error;
|
|
|
|
/// Utility trait to get reporting data for the current GRANDPA authority set.
|
|
pub trait ReportAuthoritySet {
|
|
fn get(&self) -> (u64, HashSet<AuthorityId>);
|
|
}
|
|
|
|
/// Utility trait to get reporting data for the current GRANDPA voter state.
|
|
pub trait ReportVoterState {
|
|
fn get(&self) -> Option<report::VoterState<AuthorityId>>;
|
|
}
|
|
|
|
impl<H, N> ReportAuthoritySet for SharedAuthoritySet<H, N>
|
|
where
|
|
N: Add<Output = N> + Ord + Clone + Debug,
|
|
H: Clone + Debug + Eq,
|
|
{
|
|
fn get(&self) -> (u64, HashSet<AuthorityId>) {
|
|
let current_voters: HashSet<AuthorityId> =
|
|
self.current_authorities().iter().map(|p| p.0.clone()).collect();
|
|
|
|
(self.set_id(), current_voters)
|
|
}
|
|
}
|
|
|
|
impl ReportVoterState for SharedVoterState {
|
|
fn get(&self) -> Option<report::VoterState<AuthorityId>> {
|
|
self.voter_state()
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Serialize, Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
struct Prevotes {
|
|
current_weight: u32,
|
|
missing: BTreeSet<AuthorityId>,
|
|
}
|
|
|
|
#[derive(Clone, Serialize, Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
struct Precommits {
|
|
current_weight: u32,
|
|
missing: BTreeSet<AuthorityId>,
|
|
}
|
|
|
|
#[derive(Clone, Serialize, Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
struct RoundState {
|
|
round: u32,
|
|
total_weight: u32,
|
|
threshold_weight: u32,
|
|
prevotes: Prevotes,
|
|
precommits: Precommits,
|
|
}
|
|
|
|
impl RoundState {
|
|
fn from(
|
|
round: u64,
|
|
round_state: &report::RoundState<AuthorityId>,
|
|
voters: &HashSet<AuthorityId>,
|
|
) -> Result<Self, Error> {
|
|
let prevotes = &round_state.prevote_ids;
|
|
let missing_prevotes = voters.difference(prevotes).cloned().collect();
|
|
|
|
let precommits = &round_state.precommit_ids;
|
|
let missing_precommits = voters.difference(precommits).cloned().collect();
|
|
|
|
Ok(Self {
|
|
round: round.try_into()?,
|
|
total_weight: round_state.total_weight.get().try_into()?,
|
|
threshold_weight: round_state.threshold_weight.get().try_into()?,
|
|
prevotes: Prevotes {
|
|
current_weight: round_state.prevote_current_weight.0.try_into()?,
|
|
missing: missing_prevotes,
|
|
},
|
|
precommits: Precommits {
|
|
current_weight: round_state.precommit_current_weight.0.try_into()?,
|
|
missing: missing_precommits,
|
|
},
|
|
})
|
|
}
|
|
}
|
|
|
|
/// The state of the current best round, as well as the background rounds in a
|
|
/// form suitable for serialization.
|
|
#[derive(Clone, Serialize, Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct ReportedRoundStates {
|
|
set_id: u32,
|
|
best: RoundState,
|
|
background: Vec<RoundState>,
|
|
}
|
|
|
|
impl ReportedRoundStates {
|
|
pub fn from<AuthoritySet, VoterState>(
|
|
authority_set: &AuthoritySet,
|
|
voter_state: &VoterState,
|
|
) -> Result<Self, Error>
|
|
where
|
|
AuthoritySet: ReportAuthoritySet,
|
|
VoterState: ReportVoterState,
|
|
{
|
|
let voter_state = voter_state.get().ok_or(Error::EndpointNotReady)?;
|
|
|
|
let (set_id, current_voters) = authority_set.get();
|
|
let set_id =
|
|
u32::try_from(set_id).map_err(|_| Error::AuthoritySetIdReportedAsUnreasonablyLarge)?;
|
|
|
|
let best = {
|
|
let (round, round_state) = voter_state.best_round;
|
|
RoundState::from(round, &round_state, ¤t_voters)?
|
|
};
|
|
|
|
let background = voter_state
|
|
.background_rounds
|
|
.iter()
|
|
.map(|(round, round_state)| RoundState::from(*round, round_state, ¤t_voters))
|
|
.collect::<Result<Vec<_>, Error>>()?;
|
|
|
|
Ok(Self { set_id, best, background })
|
|
}
|
|
}
|