mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 19:11:02 +00:00
Add BEEFY latestFinalized RPC and deduplicate code between BEEFY and GRANDPA (#10568)
* beefy: add dummy latest_finalized() RPC * beefy: rpc latest_best_beefy() using shared mem * beefy: rpc populate latest_best_beefy() * beefy: rpc handle readiness * beefy: best block over channel - wip Not working because channel can't be simply opened and receiver passed to `rpc_extensions_builder` because `rpc_extensions_builder` has to be `Fn` and not `FnOnce`... and and Receiver side of mpsc can't be cloned yay!.. * beefy: make notification channels payload-agnostic * beefy: use notification mechanism instead of custom channel * beefy: add tracing key to notif channels * sc-utils: add notification channel - wip * beefy: use sc-utils generic notification channel * grandpa: use sc-utils generic notification channel * fix grumbles * beefy-rpc: get best block header instead of number * beefy-rpc: rename to `beefy_getFinalizedHead` * fix nitpicks * client-rpc-notifications: move generic Error from struct to fn * beefy: use header from notification instead of getting from database * beefy-rpc: get best block hash instead of header * beefy-rpc: fix and improve latestHead test * beefy-rpc: bubble up errors from rpc-handler instantiation * update lockfile * Apply suggestions from code review Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * fix errors and warnings * fix nit Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
This commit is contained in:
@@ -469,7 +469,7 @@ mod tests {
|
||||
|
||||
// Notify with a header and justification
|
||||
let justification = create_justification();
|
||||
justification_sender.notify(|| Ok(justification.clone())).unwrap();
|
||||
justification_sender.notify(|| Ok::<_, ()>(justification.clone())).unwrap();
|
||||
|
||||
// Inspect what we received
|
||||
let recv = futures::executor::block_on(receiver.take(1).collect::<Vec<_>>());
|
||||
|
||||
@@ -16,61 +16,15 @@
|
||||
// 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 parking_lot::Mutex;
|
||||
use std::sync::Arc;
|
||||
use sc_utils::notification::{NotificationSender, NotificationStream, TracingKeyStr};
|
||||
|
||||
use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender};
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
|
||||
use crate::{justification::GrandpaJustification, Error};
|
||||
|
||||
// Stream of justifications returned when subscribing.
|
||||
type JustificationStream<Block> = TracingUnboundedReceiver<GrandpaJustification<Block>>;
|
||||
|
||||
// Sending endpoint for notifying about justifications.
|
||||
type JustificationSender<Block> = TracingUnboundedSender<GrandpaJustification<Block>>;
|
||||
|
||||
// Collection of channel sending endpoints shared with the receiver side so they can register
|
||||
// themselves.
|
||||
type SharedJustificationSenders<Block> = Arc<Mutex<Vec<JustificationSender<Block>>>>;
|
||||
use crate::justification::GrandpaJustification;
|
||||
|
||||
/// The sending half of the Grandpa justification channel(s).
|
||||
///
|
||||
/// Used to send notifications about justifications generated
|
||||
/// at the end of a Grandpa round.
|
||||
#[derive(Clone)]
|
||||
pub struct GrandpaJustificationSender<Block: BlockT> {
|
||||
subscribers: SharedJustificationSenders<Block>,
|
||||
}
|
||||
|
||||
impl<Block: BlockT> GrandpaJustificationSender<Block> {
|
||||
/// The `subscribers` should be shared with a corresponding
|
||||
/// `GrandpaJustificationStream`.
|
||||
fn new(subscribers: SharedJustificationSenders<Block>) -> Self {
|
||||
Self { subscribers }
|
||||
}
|
||||
|
||||
/// Send out a notification to all subscribers that a new justification
|
||||
/// is available for a block.
|
||||
pub fn notify(
|
||||
&self,
|
||||
justification: impl FnOnce() -> Result<GrandpaJustification<Block>, Error>,
|
||||
) -> Result<(), Error> {
|
||||
let mut subscribers = self.subscribers.lock();
|
||||
|
||||
// do an initial prune on closed subscriptions
|
||||
subscribers.retain(|n| !n.is_closed());
|
||||
|
||||
// if there's no subscribers we avoid creating
|
||||
// the justification which is a costly operation
|
||||
if !subscribers.is_empty() {
|
||||
let justification = justification()?;
|
||||
subscribers.retain(|n| n.unbounded_send(justification.clone()).is_ok());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub type GrandpaJustificationSender<Block> = NotificationSender<GrandpaJustification<Block>>;
|
||||
|
||||
/// The receiving half of the Grandpa justification channel.
|
||||
///
|
||||
@@ -78,33 +32,12 @@ impl<Block: BlockT> GrandpaJustificationSender<Block> {
|
||||
/// at the end of a Grandpa round.
|
||||
/// The `GrandpaJustificationStream` entity stores the `SharedJustificationSenders`
|
||||
/// so it can be used to add more subscriptions.
|
||||
pub type GrandpaJustificationStream<Block> =
|
||||
NotificationStream<GrandpaJustification<Block>, GrandpaJustificationsTracingKey>;
|
||||
|
||||
/// Provides tracing key for GRANDPA justifications stream.
|
||||
#[derive(Clone)]
|
||||
pub struct GrandpaJustificationStream<Block: BlockT> {
|
||||
subscribers: SharedJustificationSenders<Block>,
|
||||
}
|
||||
|
||||
impl<Block: BlockT> GrandpaJustificationStream<Block> {
|
||||
/// Creates a new pair of receiver and sender of justification notifications.
|
||||
pub fn channel() -> (GrandpaJustificationSender<Block>, Self) {
|
||||
let subscribers = Arc::new(Mutex::new(vec![]));
|
||||
let receiver = GrandpaJustificationStream::new(subscribers.clone());
|
||||
let sender = GrandpaJustificationSender::new(subscribers.clone());
|
||||
(sender, receiver)
|
||||
}
|
||||
|
||||
/// Create a new receiver of justification notifications.
|
||||
///
|
||||
/// The `subscribers` should be shared with a corresponding
|
||||
/// `GrandpaJustificationSender`.
|
||||
fn new(subscribers: SharedJustificationSenders<Block>) -> Self {
|
||||
Self { subscribers }
|
||||
}
|
||||
|
||||
/// Subscribe to a channel through which justifications are sent
|
||||
/// at the end of each Grandpa voting round.
|
||||
pub fn subscribe(&self) -> JustificationStream<Block> {
|
||||
let (sender, receiver) = tracing_unbounded("mpsc_justification_notification_stream");
|
||||
self.subscribers.lock().push(sender);
|
||||
receiver
|
||||
}
|
||||
pub struct GrandpaJustificationsTracingKey;
|
||||
impl TracingKeyStr for GrandpaJustificationsTracingKey {
|
||||
const TRACING_KEY: &'static str = "mpsc_grandpa_justification_notification_stream";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user