// This file is part of Substrate. // Copyright (C) 2021 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 . //! RPC API for BEEFY. #![warn(missing_docs)] use std::sync::Arc; use sp_runtime::traits::Block as BlockT; use futures::{FutureExt, SinkExt, StreamExt}; use jsonrpc_derive::rpc; use jsonrpc_pubsub::{manager::SubscriptionManager, typed::Subscriber, SubscriptionId}; use log::warn; use beefy_gadget::notification::BeefySignedCommitmentStream; mod notification; /// Provides RPC methods for interacting with BEEFY. #[rpc] pub trait BeefyApi { /// RPC Metadata type Metadata; /// Returns the block most recently finalized by BEEFY, alongside side its justification. #[pubsub( subscription = "beefy_justifications", subscribe, name = "beefy_subscribeJustifications" )] fn subscribe_justifications( &self, metadata: Self::Metadata, subscriber: Subscriber, ); /// Unsubscribe from receiving notifications about recently finalized blocks. #[pubsub( subscription = "beefy_justifications", unsubscribe, name = "beefy_unsubscribeJustifications" )] fn unsubscribe_justifications( &self, metadata: Option, id: SubscriptionId, ) -> jsonrpc_core::Result; } /// Implements the BeefyApi RPC trait for interacting with BEEFY. pub struct BeefyRpcHandler { signed_commitment_stream: BeefySignedCommitmentStream, manager: SubscriptionManager, } impl BeefyRpcHandler { /// Creates a new BeefyRpcHandler instance. pub fn new(signed_commitment_stream: BeefySignedCommitmentStream, executor: E) -> Self where E: futures::task::Spawn + Send + Sync + 'static, { let manager = SubscriptionManager::new(Arc::new(executor)); Self { signed_commitment_stream, manager } } } impl BeefyApi for BeefyRpcHandler where Block: BlockT, { type Metadata = sc_rpc::Metadata; fn subscribe_justifications( &self, _metadata: Self::Metadata, subscriber: Subscriber, ) { let stream = self .signed_commitment_stream .subscribe() .map(|x| Ok::<_, ()>(Ok(notification::SignedCommitment::new::(x)))); self.manager.add(subscriber, |sink| { stream .forward(sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e))) .map(|_| ()) }); } fn unsubscribe_justifications( &self, _metadata: Option, id: SubscriptionId, ) -> jsonrpc_core::Result { Ok(self.manager.cancel(id)) } }