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

Commit

Permalink
Signed commitments rpc pubsub (#26)
Browse files Browse the repository at this point in the history
* move beefy application crypto to primitives

* make primitives compile under no_std

* add beefy pallet that maintains authority set

* add beefy pallet to node example runtime

* tabify node-example cargo.toml files

* use double quotes in Cargo.toml files

* add missing hex-literal dependency

* add runtime api to fetch BEEFY authorities

* fix clippy warnings

* gadget: use commitment and signedcommitment

* gadget: send notifications for signed commitments

* gadget: add rpc pubsub for signed commitments

* node-example: enable beefy rpc

* gadget: fix clippy warnings

* rename beefy-pallet to pallet-beefy

* sort dependencies in node-example/runtime/Cargo.toml

* gadget: add documentation on SignedCommitment rpc wrapper type

* gadget: add todos about dummy beefy commitments

* gadget: remove redundant closure

Co-authored-by: Tomasz Drwięga <[email protected]>

Co-authored-by: Tomasz Drwięga <[email protected]>
  • Loading branch information
andresilva and tomusdrw authored Nov 23, 2020
1 parent cbda281 commit 89c151d
Show file tree
Hide file tree
Showing 6 changed files with 384 additions and 44 deletions.
1 change: 1 addition & 0 deletions client/beefy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "mast
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-utils = { git = "https://github.com/paritytech/substrate", branch = "master" }

sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
Expand Down
23 changes: 23 additions & 0 deletions client/beefy/rpc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "beefy-gadget-rpc"
version = "0.1.0"
authors = ["Parity Technologies <[email protected]>"]
edition = "2018"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"

[dependencies]
beefy-gadget = { path = "../." }
beefy-primitives = { path = "../../primitives" }

codec = { version = "1.3.5", package = "parity-scale-codec", features = ["derive"] }
sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
jsonrpc-core = "15.1.0"
jsonrpc-core-client = "15.1.0"
jsonrpc-derive = "15.1.0"
jsonrpc-pubsub = "15.1.0"
futures = { version = "0.3.4", features = ["compat"] }
serde = { version = "1.0.105", features = ["derive"] }
serde_json = "1.0.50"
log = "0.4.8"
119 changes: 119 additions & 0 deletions client/beefy/rpc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// 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/>.

//! RPC API for BEEFY.

#![warn(missing_docs)]

use codec::Encode;
use futures::{StreamExt, TryStreamExt};
use jsonrpc_core::futures::{
future::Executor as Executor01, future::Future as Future01, sink::Sink as Sink01, stream::Stream as Stream01,
};
use jsonrpc_derive::rpc;
use jsonrpc_pubsub::{manager::SubscriptionManager, typed::Subscriber, SubscriptionId};
use log::warn;
use std::sync::Arc;

mod notification;

use sp_runtime::traits::Block as BlockT;

use beefy_gadget::notification::BeefySignedCommitmentStream;

/// Provides RPC methods for interacting with BEEFY.
#[allow(clippy::needless_return)]
#[rpc]
pub trait BeefyApi<Notification, Hash> {
/// 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<Notification>);

/// Unsubscribe from receiving notifications about recently finalized blocks.
#[pubsub(
subscription = "beefy_justifications",
unsubscribe,
name = "beefy_unsubscribeJustifications"
)]
fn unsubscribe_justifications(
&self,
metadata: Option<Self::Metadata>,
id: SubscriptionId,
) -> jsonrpc_core::Result<bool>;
}

/// Implements the BeefyApi RPC trait for interacting with BEEFY.
pub struct BeefyRpcHandler<Block: BlockT, Signature> {
signed_commitment_stream: BeefySignedCommitmentStream<Block, Signature>,
manager: SubscriptionManager,
}

impl<Block: BlockT, Signature> BeefyRpcHandler<Block, Signature> {
/// Creates a new BeefyRpcHandler instance.
pub fn new<E>(signed_commitment_stream: BeefySignedCommitmentStream<Block, Signature>, executor: E) -> Self
where
E: Executor01<Box<dyn Future01<Item = (), Error = ()> + Send>> + Send + Sync + 'static,
{
let manager = SubscriptionManager::new(Arc::new(executor));
Self {
signed_commitment_stream,
manager,
}
}
}

impl<Block, Signature> BeefyApi<notification::SignedCommitment, Block> for BeefyRpcHandler<Block, Signature>
where
Block: BlockT,
Signature: Clone + Encode + Send + 'static,
{
type Metadata = sc_rpc::Metadata;

fn subscribe_justifications(
&self,
_metadata: Self::Metadata,
subscriber: Subscriber<notification::SignedCommitment>,
) {
let stream = self
.signed_commitment_stream
.subscribe()
.map(|x| Ok::<_, ()>(notification::SignedCommitment::new::<Block, Signature>(x)))
.map_err(|e| warn!("Notification stream error: {:?}", e))
.compat();

self.manager.add(subscriber, |sink| {
let stream = stream.map(Ok);
sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e))
.send_all(stream)
.map(|_| ())
});
}

fn unsubscribe_justifications(
&self,
_metadata: Option<Self::Metadata>,
id: SubscriptionId,
) -> jsonrpc_core::Result<bool> {
Ok(self.manager.cancel(id))
}
}
38 changes: 38 additions & 0 deletions client/beefy/rpc/src/notification.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// 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 codec::Encode;
use serde::{Deserialize, Serialize};

use sp_runtime::traits::Block as BlockT;

/// An encoded signed commitment proving that the given header has been finalized.
/// The given bytes should be the SCALE-encoded representation of a
/// `beefy_primitives::SignedCommitment`.
#[derive(Clone, Serialize, Deserialize)]
pub struct SignedCommitment(sp_core::Bytes);

impl SignedCommitment {
pub fn new<Block, Signature>(
signed_commitment: beefy_gadget::notification::SignedCommitment<Block, Signature>,
) -> Self
where
Block: BlockT,
Signature: Encode,
{
SignedCommitment(signed_commitment.encode().into())
}
}
Loading

0 comments on commit 89c151d

Please sign in to comment.