diff --git a/Cargo.lock b/Cargo.lock index 24c8d22751758..28dc2485d3d24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4481,7 +4481,7 @@ name = "srml-bridge" version = "0.1.0" dependencies = [ "parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "srml-session 2.0.0", diff --git a/srml/bridge/src/lib.rs b/srml/bridge/src/lib.rs index 4ac8541e1a95b..f24653a4f7987 100644 --- a/srml/bridge/src/lib.rs +++ b/srml/bridge/src/lib.rs @@ -33,23 +33,37 @@ #![cfg_attr(not(feature = "std"), no_std)] use codec::{Encode, Decode}; -use sr_primitives::traits::Member; -#[cfg(feature = "std")] -use sr_primitives::{Serialize, Deserialize}; +use sr_primitives::traits::{Header, Member}; use support::{ decl_error, decl_module, decl_storage, Parameter, }; use system::{ensure_signed}; +#[derive(Encode, Decode, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct BridgeInfo { + last_finalized_block_number: T::BlockNumber, + last_finalized_block_hash: T::Hash, + last_finalized_state_root: T::Hash, + current_validator_set: Vec, +} -#[derive(Encode, Decode, Default, Clone, PartialEq)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] -pub struct Bridge; - -impl Bridge { - pub fn new() -> Self { - Bridge +impl BridgeInfo { + pub fn new( + block_number: &T::BlockNumber, + block_hash: &T::Hash, + state_root: &T::Hash, + validator_set: Vec, + ) -> Self + { + // I don't like how this is done, should come back to... + BridgeInfo { + last_finalized_block_number: *block_number, + last_finalized_block_hash: *block_hash, + last_finalized_state_root: *state_root, + current_validator_set: validator_set, + } } } @@ -67,19 +81,7 @@ decl_storage! { /// Maps a bridge id to a bridge struct. Allows a single /// `bridge` module to manage multiple bridges. - pub BridgeFoo get(bridge_foo) config(): map BridgeId => Bridge; - - /// Get latest block number included in the chain - pub LastBlockNumber get(latest_block_num) config(): T::BlockNumber; - - /// Get the latest block header included in the chain - pub LastBlockHeader get(latest_block_header): Option; - - // Get the latest state root included in the chain - // pub LastStateRoot get(latest_state_root) config(): T::Hash; - - /// Latest set of validators - pub Validators get(validators) config(): Vec; + pub TrackedBridges get(tracked_bridges): map BridgeId => Option>; } } @@ -88,22 +90,27 @@ decl_module! { // TODO: Figure out the proper type for these proofs fn initialize_bridge( origin, - _block_header: T::Header, - _validator_set: Vec, - _validator_set_proof: Vec, - _storage_proof: Vec, + block_header: T::Header, + validator_set: Vec, + validator_set_proof: Vec, + storage_proof: Vec, ) { - // NOTE: Should this be a root call? - // Use srml/collective/src/lib.rs? + // NOTE: Will want to make this a governance issued call let _sender = ensure_signed(origin)?; - Self::check_storage_proof()?; - Self::check_validator_set_proof()?; + Self::check_storage_proof(storage_proof)?; + Self::check_validator_set_proof(validator_set_proof)?; + + let block_number = block_header.number(); + let block_hash = block_header.hash(); + let state_root = block_header.state_root(); + let bridge_info = BridgeInfo::new(block_number, &block_hash, state_root, validator_set); let new_bridge_id = NumBridges::get() + 1; - // Hmm, can this call fail? - BridgeFoo::insert(new_bridge_id, Bridge::new()); + // Hmm, can a call to `insert` fail? + // If this is an Option, why do we not need to wrap it in Some(T)? + >::insert(new_bridge_id, bridge_info); // Only increase the number of bridges if the insert call succeeds NumBridges::put(new_bridge_id); @@ -124,12 +131,12 @@ decl_error! { } impl Module { - fn check_storage_proof() -> std::result::Result<(), Error> { + fn check_storage_proof(_proof: Vec) -> std::result::Result<(), Error> { // ... Do some math ... Ok(()) // Otherwise, Error::InvalidStorageProof } - fn check_validator_set_proof() -> std::result::Result<(), Error> { + fn check_validator_set_proof(_proof: Vec) -> std::result::Result<(), Error> { // ... Do some math ... Ok(()) // Otherwise, Error::InvalidValidatorSetProof } @@ -155,7 +162,6 @@ mod tests { pub struct Test; type System = system::Module; - // type Bridge = Module; // With the Bridge struct this isn't great type MockBridge = Module; // TODO: Figure out what I actually need from here @@ -194,14 +200,8 @@ mod tests { fn new_test_ext() -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::default().build_storage::().unwrap(); - GenesisConfig:: { + GenesisConfig { num_bridges: 0, - latest_block_num: 0, - bridge_foo: vec![(0, Bridge::new()), (1, Bridge::new())], - - // How do I get a default Hash? - // latest_state_root: Hash::default(), - validators: vec![], }.assimilate_storage(&mut t).unwrap(); t.into() } @@ -210,25 +210,43 @@ mod tests { fn it_works_for_default_value() { with_externalities(&mut new_test_ext(), || { assert_eq!(MockBridge::num_bridges(), 0); - assert_eq!(MockBridge::latest_block_num(), 0); }); } #[test] fn it_creates_a_new_bridge() { + let dummy_state_root = H256::default(); let test_header = Header { parent_hash: H256::default(), - number: 0, - state_root: H256::default(), + number: 42, + state_root: dummy_state_root, extrinsics_root: H256::default(), digest: Digest::default(), }; with_externalities(&mut new_test_ext(), || { assert_eq!(MockBridge::num_bridges(), 0); - assert_eq!(MockBridge::bridge_foo(0), Bridge::new()); - assert_ok!(MockBridge::initialize_bridge(Origin::signed(1), test_header, vec![], vec![], vec![])); - assert_eq!(MockBridge::bridge_foo(1), Bridge::new()); + assert_eq!(MockBridge::tracked_bridges(0), None); + + dbg!(&test_header); + assert_ok!( + MockBridge::initialize_bridge( + Origin::signed(1), + test_header, + vec![1, 2, 3], + vec![], + vec![], + )); + + assert_eq!( + MockBridge::tracked_bridges(1), + Some(BridgeInfo { + last_finalized_block_number: 42, + last_finalized_block_hash: test_header.hash(), // FIXME: This is broken + last_finalized_state_root: dummy_state_root, + current_validator_set: vec![1, 2, 3], + })); + assert_eq!(MockBridge::num_bridges(), 1); }); }