Skip to content

Commit

Permalink
Add bridges list in genesis config (fixes #515) (#520)
Browse files Browse the repository at this point in the history
* Add bridges list in genesis config (fixes #515)

* ci fixes
  • Loading branch information
Nutomic authored Mar 9, 2023
1 parent 265fc3e commit e37ef09
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 63 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

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

21 changes: 12 additions & 9 deletions dkg-test-suite/scripts/submitProposals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ async function run() {
sudoAccount.address
);
let nonce = accountNonce.toNumber();
setInterval(async () => {
while(true) {
// Create the header
const proposalHeader = createHeader(nonce);
assert(
Expand Down Expand Up @@ -84,17 +84,20 @@ async function run() {
prop.toU8a()
);
// Sign and send the transaction
const unsub = await api.tx.sudo
.sudo(call)
.signAndSend(sudoAccount, (result) => {
if (result.isFinalized || result.isError) {
console.log(result.txHash.toHex(), 'is', result.status.type);
unsub();
await new Promise(async (resolve, reject) => {
const unsub = await api.tx.sudo
.sudo(call)
.signAndSend(sudoAccount, (result) => {
if (result.isFinalized || result.isInBlock || result.isError) {
unsub();
console.log(result.txHash.toHex(), "is", result.status.type);
resolve(result.isFinalized);
}
});
});
});

nonce += 1;
}, 20_000);
};

// a perodic task to print How many proposals that have been submitted, unsigned and signed.
// This is just for debugging purpose.
Expand Down
2 changes: 2 additions & 0 deletions pallets/bridge-registry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ frame-support = { workspace = true }
frame-system = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }
serde = { workspace = true }
hex = { workspace = true }

frame-benchmarking = { workspace = true, optional = true }
pallet-identity = { workspace = true }
Expand Down
13 changes: 11 additions & 2 deletions pallets/bridge-registry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub mod mock;
mod tests;

mod benchmarking;
mod types;
pub mod types;

mod weights;
use weights::WeightInfo;
Expand Down Expand Up @@ -107,19 +107,28 @@ pub mod pallet {
#[pallet::genesis_config]
pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
pub phantom: (PhantomData<T>, PhantomData<I>),
pub bridges: Vec<BridgeMetadata<T::MaxResources, T::MaxAdditionalFields>>,
}

#[cfg(feature = "std")]
impl<T: Config<I>, I: 'static> Default for GenesisConfig<T, I> {
fn default() -> Self {
Self { phantom: Default::default() }
Self { phantom: Default::default(), bridges: Default::default() }
}
}

#[pallet::genesis_build]
impl<T: Config<I>, I: 'static> GenesisBuild<T, I> for GenesisConfig<T, I> {
fn build(&self) {
NextBridgeIndex::<T, I>::put(T::BridgeIndex::one());
for bridge in &self.bridges {
let idx: T::BridgeIndex = NextBridgeIndex::<T, I>::get();
Bridges::<T, I>::insert(idx, bridge);
NextBridgeIndex::<T, I>::put(idx + T::BridgeIndex::one());
for rid in &bridge.resource_ids {
ResourceToBridgeIndex::<T, I>::set(rid, Some(idx));
}
}
}
}

Expand Down
7 changes: 5 additions & 2 deletions pallets/bridge-registry/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,11 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
],
}
.assimilate_storage(&mut storage);
let _ = pallet_bridge_registry::GenesisConfig::<Test> { phantom: Default::default() }
.assimilate_storage(&mut storage);
let _ = pallet_bridge_registry::GenesisConfig::<Test> {
phantom: Default::default(),
bridges: vec![],
}
.assimilate_storage(&mut storage);

storage.into()
}
70 changes: 68 additions & 2 deletions pallets/bridge-registry/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,82 @@ use sp_std::prelude::*;
RuntimeDebugNoBound,
TypeInfo,
)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
#[codec(mel_bound())]
#[scale_info(skip_type_params(FieldLimit))]
pub struct BridgeInfo<FieldLimit: Get<u32>> {
/// Additional fields of the metadata that are not catered for with the struct's explicit
/// fields.
pub additional: BoundedVec<(Data, Data), FieldLimit>,
#[cfg_attr(feature = "std", serde(bound = ""))]
pub additional: BoundedVec<(SerdeData, SerdeData), FieldLimit>,

/// A reasonable display name for the bridge. This should be whatever it is
/// that it is typically known as and should not be confusable with other entities, given
/// reasonable context.
///
/// Stored as UTF-8.
pub display: Data,
pub display: SerdeData,
}

#[derive(
Clone,
Eq,
PartialEq,
frame_support::RuntimeDebug,
MaxEncodedLen,
Encode,
TypeInfo,
Decode,
Default,
)]
pub struct SerdeData(Data);

#[cfg(feature = "std")]
mod serde_ {
use super::*;
use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
struct DataVisitor;
use std::{fmt::Formatter, str::FromStr};

impl FromStr for SerdeData {
type Err = ();

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(SerdeData(Data::Raw(s.as_bytes().to_vec().try_into().unwrap())))
}
}

impl<'de> Visitor<'de> for DataVisitor {
type Value = SerdeData;

fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
formatter.write_str("a hex string with at most 32 bytes")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(SerdeData(Data::Raw(hex::decode(v).unwrap().try_into().unwrap())))
}
}
impl<'de> Deserialize<'de> for SerdeData {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(DataVisitor)
}
}

impl Serialize for SerdeData {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&hex::encode(self.0.encode()))
}
}
}

/// Information concerning the identity of the controller of an account.
Expand All @@ -62,13 +125,16 @@ pub struct BridgeInfo<FieldLimit: Get<u32>> {
#[derive(
CloneNoBound, Encode, Eq, MaxEncodedLen, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo,
)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
#[codec(mel_bound())]
#[scale_info(skip_type_params(MaxResources, MaxAdditionalFields))]
pub struct BridgeMetadata<MaxResources: Get<u32>, MaxAdditionalFields: Get<u32>> {
/// A list of resource IDs for the bridge
#[cfg_attr(feature = "std", serde(bound = ""))]
pub resource_ids: BoundedVec<ResourceId, MaxResources>,

/// Auxilliary information on the bridge.
#[cfg_attr(feature = "std", serde(bound = ""))]
pub info: BridgeInfo<MaxAdditionalFields>,
}

Expand Down
4 changes: 2 additions & 2 deletions pallets/dkg-proposals/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ pub mod pallet {
pub struct GenesisConfig<T: Config> {
/// Typed ChainId (chain type, chain id)
pub initial_chain_ids: Vec<[u8; 6]>,
pub initial_r_ids: Vec<([u8; 32], Vec<u8>)>,
pub initial_r_ids: Vec<(ResourceId, Vec<u8>)>,
pub initial_proposers: Vec<T::AccountId>,
}

Expand All @@ -345,7 +345,7 @@ pub mod pallet {
ChainNonces::<T>::insert(chain_id, ProposalNonce::from(0));
}
for (r_id, r_data) in self.initial_r_ids.iter() {
Resources::<T>::insert(ResourceId::from(*r_id), r_data.clone());
Resources::<T>::insert(r_id, r_data.clone());
}

for proposer in self.initial_proposers.iter() {
Expand Down
6 changes: 3 additions & 3 deletions scripts/run-standalone.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ cd "$PROJECT_ROOT"

echo "*** Start Webb DKG Node ***"
# Alice
./target/release/dkg-standalone-node --base-path=./tmp/alice --chain local -lerror --alice \
cargo run --bin dkg-standalone-node --release -- --base-path=./tmp/alice --chain local -lerror --alice \
--rpc-cors all --ws-external \
--port 30304 \
--ws-port 9944 &
# Bob
./target/release/dkg-standalone-node --base-path=./tmp/bob --chain local -lerror --bob \
cargo run --bin dkg-standalone-node --release -- --base-path=./tmp/bob --chain local -lerror --bob \
--rpc-cors all --ws-external \
--port 30305 \
--ws-port 9945 &
# Charlie
./target/release/dkg-standalone-node --base-path=./tmp/charlie --chain local -linfo --charlie \
cargo run --bin dkg-standalone-node --release -- --base-path=./tmp/charlie --chain local -linfo --charlie \
--rpc-cors all --ws-external \
--ws-port 9948 \
--port 30308 \
Expand Down
1 change: 1 addition & 0 deletions standalone/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ substrate-frame-rpc-system = { workspace = true }
frame-system = { workspace = true }
pallet-transaction-payment-rpc = { workspace = true }
pallet-transaction-payment = { workspace = true }
pallet-bridge-registry = { workspace = true }

# These dependencies are used for runtime benchmarking
frame-benchmarking = { workspace = true }
Expand Down
75 changes: 34 additions & 41 deletions standalone/node/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,38 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use dkg_primitives::ResourceId;
use dkg_standalone_runtime::{
constants::currency::{Balance, DOLLARS},
AccountId, BalancesConfig, DKGConfig, DKGId, DKGProposalsConfig, GenesisConfig, ImOnlineConfig,
MaxNominations, Perbill, ResourceId, SessionConfig, Signature, StakerStatus, StakingConfig,
SudoConfig, SystemConfig, WASM_BINARY,
MaxNominations, Perbill, SessionConfig, Signature, StakerStatus, StakingConfig, SudoConfig,
SystemConfig, WASM_BINARY,
};
use hex_literal::hex;
use pallet_bridge_registry::types::{BridgeInfo, BridgeMetadata, SerdeData};
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
use sc_service::ChainType;
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
use sp_core::{sr25519, Pair, Public};
use sp_core::{bounded_vec, sr25519, Pair, Public};
use sp_finality_grandpa::AuthorityId as GrandpaId;
use sp_runtime::traits::{IdentifyAccount, Verify};
use std::str::FromStr;

// The URL for the telemetry server.
// const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";

/// Hermes (Evm, 5001)
const CHAIN_ID_HERMES: [u8; 6] = hex_literal::hex!("010000001389");
/// Athena (Evm, 5002)
const CHAIN_ID_ATHENA: [u8; 6] = hex_literal::hex!("01000000138a");

const RESOURCE_ID_HERMES_ATHENA: ResourceId = ResourceId(hex_literal::hex!(
"0000000000000000e69a847cd5bc0c9480ada0b339d7f0a8cac2b6670000138a"
));
const RESOURCE_ID_ATHENA_HERMES: ResourceId = ResourceId(hex_literal::hex!(
"000000000000d30c8839c1145609e564b986f667b273ddcb8496010000001389"
));

/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
pub type ChainSpec = sc_service::GenericChainSpec<GenesisConfig>;

Expand Down Expand Up @@ -79,7 +94,6 @@ fn dkg_session_keys(

pub fn development_config() -> Result<ChainSpec, String> {
let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?;

Ok(ChainSpec::from_genesis(
// Name
"Development",
Expand Down Expand Up @@ -117,26 +131,11 @@ pub fn development_config() -> Result<ChainSpec, String> {
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
],
// Initial Chain Ids
vec![
hex_literal::hex!("010000001389"), // Hermis (Evm, 5001)
hex_literal::hex!("01000000138a"), // Athena (Evm, 5002)
],
vec![CHAIN_ID_HERMES, CHAIN_ID_ATHENA],
// Initial resource Ids
vec![
// Resource ID for Chain Hermis => Athena
(
hex_literal::hex!(
"000000000000e69a847cd5bc0c9480ada0b339d7f0a8cac2b66701000000138a"
),
Default::default(),
),
// Resource ID for Chain Athena => Hermis
(
hex_literal::hex!(
"000000000000d30c8839c1145609e564b986f667b273ddcb8496010000001389"
),
Default::default(),
),
(RESOURCE_ID_HERMES_ATHENA, Default::default()),
(RESOURCE_ID_ATHENA_HERMES, Default::default()),
],
// Initial proposers
vec![
Expand Down Expand Up @@ -204,26 +203,11 @@ pub fn local_testnet_config() -> Result<ChainSpec, String> {
}))
.collect(),
// Initial Chain Ids
vec![
hex_literal::hex!("010000001389"), // Hermis (Evm, 5001)
hex_literal::hex!("01000000138a"), // Athena (Evm, 5002)
],
vec![CHAIN_ID_HERMES, CHAIN_ID_ATHENA],
// Initial resource Ids
vec![
// Resource ID for Chain Hermis => Athena
(
hex_literal::hex!(
"0000000000000000e69a847cd5bc0c9480ada0b339d7f0a8cac2b6670000138a"
),
Default::default(),
),
// Resource ID for Chain Athena => Hermis
(
hex_literal::hex!(
"0000000000000000d30c8839c1145609e564b986f667b273ddcb849600001389"
),
Default::default(),
),
(RESOURCE_ID_HERMES_ATHENA, Default::default()),
(RESOURCE_ID_ATHENA_HERMES, Default::default()),
],
// Initial proposers
vec![
Expand Down Expand Up @@ -380,7 +364,16 @@ fn testnet_genesis(
authority_ids: initial_authorities.iter().map(|(x, ..)| x.clone()).collect::<_>(),
},
dkg_proposals: DKGProposalsConfig { initial_chain_ids, initial_r_ids, initial_proposers },
bridge_registry: Default::default(),
bridge_registry: pallet_bridge_registry::pallet::GenesisConfig {
bridges: bounded_vec![BridgeMetadata {
resource_ids: bounded_vec![RESOURCE_ID_HERMES_ATHENA, RESOURCE_ID_ATHENA_HERMES],
info: BridgeInfo {
additional: Default::default(),
display: SerdeData::from_str("hermes-athena").unwrap()
}
}],
..Default::default()
},
im_online: ImOnlineConfig { keys: vec![] },
}
}
Loading

0 comments on commit e37ef09

Please sign in to comment.