Skip to content

Commit

Permalink
Add bridge signer pallet
Browse files Browse the repository at this point in the history
  • Loading branch information
vovac12 committed Sep 17, 2024
1 parent 2269286 commit 4855524
Show file tree
Hide file tree
Showing 10 changed files with 1,857 additions and 0 deletions.
61 changes: 61 additions & 0 deletions Cargo.lock

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

43 changes: 43 additions & 0 deletions pallets/bridge-signer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
[package]
name = "bridge-signer"
description = "Bridge signer"
version = "0.1.1"
edition = "2021"
authors = ['Polka Biome Ltd. <[email protected]>']
license = "BSD-4-Clause"
homepage = 'https://sora.org'
repository = 'https://github.com/sora-xor/sora2-common'

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
serde = { version = "1.0.101", optional = true }
codec = { version = "3", package = "parity-scale-codec", default-features = false, features = [
"derive",
] }
scale-info = { version = "2", default-features = false, features = ["derive"] }
bridge-common = { path = "../bridge-common", default-features = false }

frame-benchmarking = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.38", default-features = false, optional = true }
frame-support = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.38", default-features = false }
frame-system = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.38", default-features = false }
sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.38", default-features = false }
sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.38", default-features = false }
sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.38", default-features = false }
sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.38", default-features = false }

bridge-types = { path = "../types", default-features = false }
derive-where = "1.2.7"

[dev-dependencies]
sp-keyring = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.38" }
sp-keystore = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.38" }
hex-literal = { version = "0.4.1" }

[features]
default = ["std"]
std = ["bridge-common/std", "serde", "codec/std", "scale-info/std", "frame-support/std", "frame-system/std", "sp-core/std", "sp-io/std", "sp-runtime/std", "sp-std/std", "bridge-types/std"]
runtime-benchmarks = ["bridge-types/runtime-benchmarks", "frame-benchmarking", "sp-runtime/runtime-benchmarks", "frame-system/runtime-benchmarks"]

try-runtime = ["frame-support/try-runtime"]
150 changes: 150 additions & 0 deletions pallets/bridge-signer/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
// This file is part of the SORA network and Polkaswap app.

// Copyright (c) 2020, 2021, Polka Biome Ltd. All rights reserved.
// SPDX-License-Identifier: BSD-4-Clause

// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:

// Redistributions of source code must retain the above copyright notice, this list
// of conditions and the following disclaimer.
// Redistributions in binary form must reproduce the above copyright notice, this
// list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// All advertising materials mentioning features or use of this software must display
// the following acknowledgement: This product includes software developed by Polka Biome
// Ltd., SORA, and Polkaswap.
//
// Neither the name of the Polka Biome Ltd. nor the names of its contributors may be used
// to endorse or promote products derived from this software without specific prior written permission.

// THIS SOFTWARE IS PROVIDED BY Polka Biome Ltd. AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Polka Biome Ltd. BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#![cfg(feature = "runtime-benchmarks")]

use super::*;
use crate::Pallet as BridgeDataSigner;
use bridge_types::GenericNetworkId;
use core::fmt::Write;
use frame_benchmarking::benchmarks;
use frame_support::assert_ok;
use frame_support::traits::EnsureOrigin;
use frame_system::{self, RawOrigin};
use sp_core::bounded::BoundedBTreeMap;
use sp_core::{bounded::BoundedVec, ecdsa, Get, H256};
use sp_std::prelude::*;

fn initial_peers<T: Config>(n: usize) -> BoundedVec<ecdsa::Public, <T as Config>::MaxPeers> {
let mut keys = Vec::new();
for i in 0..n {
let key = generate_key(i);
keys.push(key);
}

keys.try_into().unwrap()
}

fn generate_key(i: usize) -> ecdsa::Public {
let mut seed = sp_std::Writer::default();
core::write!(seed, "//TestPeer//p-{}", i).unwrap();
sp_io::crypto::ecdsa_generate(sp_core::crypto::key_types::DUMMY, Some(seed.into_inner()))
}

fn initialize_network<T: Config>(
network_id: GenericNetworkId,
n: usize,
) -> BoundedVec<ecdsa::Public, <T as Config>::MaxPeers> {
let keys = initial_peers::<T>(n);
assert_ok!(BridgeDataSigner::<T>::register_network(
RawOrigin::Root.into(),
network_id,
keys.clone()
));
keys
}

fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
frame_system::Pallet::<T>::assert_last_event(generic_event.into());
}

benchmarks! {
register_network {
let n = <T as Config>::MaxPeers::get();
let network_id = bridge_types::GenericNetworkId::Sub(bridge_types::SubNetworkId::Mainnet);
let peers = initial_peers::<T>(n as usize);
}: _(RawOrigin::Root, network_id, peers.clone())
verify {
assert_last_event::<T>(Event::Initialized{network_id, peers}.into());
}

add_peer {
let network_id = bridge_types::GenericNetworkId::Sub(bridge_types::SubNetworkId::Mainnet);

initialize_network::<T>(network_id, 3);
let key = generate_key(3);
}: _(RawOrigin::Root, network_id, key)
verify {
assert!(PendingPeerUpdate::<T>::get(network_id));
}

remove_peer {
let network_id = bridge_types::GenericNetworkId::Sub(bridge_types::SubNetworkId::Mainnet);

let peers = initialize_network::<T>(network_id, 3);
let key = peers[0];
}: _(RawOrigin::Root, network_id, key)
verify {
assert!(PendingPeerUpdate::<T>::get(network_id));
}

finish_add_peer {
let network_id = bridge_types::GenericNetworkId::Sub(bridge_types::SubNetworkId::Mainnet);

let peers = initialize_network::<T>(network_id, 3);
let key = generate_key(3);
BridgeDataSigner::<T>::add_peer(RawOrigin::Root.into(), network_id, key).expect("remove_peer: Error adding peer");
}: {
BridgeDataSigner::<T>::finish_add_peer(T::CallOrigin::try_successful_origin().unwrap(), key)?;
}
verify {
assert!(!PendingPeerUpdate::<T>::get(network_id));
assert!(BridgeDataSigner::<T>::peers(network_id).expect("add_peer: key found").contains(&key));
}

finish_remove_peer {
let network_id = bridge_types::GenericNetworkId::Sub(bridge_types::SubNetworkId::Mainnet);

let peers = initialize_network::<T>(network_id, 3);
let key = peers[0];
BridgeDataSigner::<T>::remove_peer(RawOrigin::Root.into(), network_id, key).expect("remove_peer: Error removing peer");
}: {
BridgeDataSigner::<T>::finish_remove_peer(T::CallOrigin::try_successful_origin().unwrap(), key)?;
}
verify {
assert!(!PendingPeerUpdate::<T>::get(network_id));
assert!(!BridgeDataSigner::<T>::peers(network_id).expect("remove_peer: No key found").contains(&key));
}

approve {
let network_id = bridge_types::GenericNetworkId::Sub(bridge_types::SubNetworkId::Mainnet);
let peers = initialize_network::<T>(network_id, 3);
let key = peers[0];
let data = [3u8; 32];
let signature = sp_io::crypto::ecdsa_sign_prehashed(sp_core::crypto::key_types::DUMMY, &key, &data).unwrap();
let mut expected = BoundedBTreeMap::<ecdsa::Public, ecdsa::Signature, T::MaxPeers>::new();
expected.try_insert(key, signature.clone()).unwrap();
}: _(RawOrigin::None, network_id, data.into(), signature)
verify {
assert_eq!(Approvals::<T>::get(network_id, H256::from(data)), expected);
}

impl_benchmark_test_suite!(BridgeDataSigner, crate::mock::new_test_ext(), mock::Test)
}
Loading

0 comments on commit 4855524

Please sign in to comment.