First push

This commit is contained in:
Drew Stone 2018-11-21 20:22:53 +02:00
commit 9451d44ad6
5 changed files with 343 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/target
**/*.rs.bk
Cargo.lock

41
Cargo.toml Normal file
View File

@ -0,0 +1,41 @@
[package]
name = "edge_bridge"
version = "0.1.0"
authors = ["Drew Stone <drew@commonwealth.im>"]
[dependencies]
hex-literal = "0.1.0"
serde = { version = "1.0", default-features = false }
serde_derive = { version = "1.0", optional = true }
safe-mix = { version = "1.0", default-features = false}
parity-codec = { version = "2.1", default-features = false }
parity-codec-derive = { version = "2.1", default-features = false }
substrate-keyring = { git = "https://github.com/paritytech/substrate/", optional = true }
substrate-primitives = { git = "https://github.com/paritytech/substrate/", default-features = false }
sr-std = { git = "https://github.com/paritytech/substrate/", default-features = false }
sr-io = { git = "https://github.com/paritytech/substrate/", default-features = false }
sr-primitives = { git = "https://github.com/paritytech/substrate/", default-features = false }
srml-support = { git = "https://github.com/paritytech/substrate/", default-features = false }
srml-system = { git = "https://github.com/paritytech/substrate/", default-features = false }
srml-balances = { git = "https://github.com/paritytech/substrate/", default-features = false }
srml-council = { git = "https://github.com/paritytech/substrate/", default-features = false }
srml-democracy = { git = "https://github.com/paritytech/substrate/", default-features = false }
[features]
default = ["std"]
std = [
"serde/std",
"serde_derive",
"safe-mix/std",
"parity-codec/std",
"parity-codec-derive/std",
"substrate-primitives/std",
"sr-std/std",
"sr-io/std",
"srml-support/std",
"sr-primitives/std",
"srml-system/std",
"srml-balances/std",
"srml-council/std",
"srml-democracy/std",
]

33
README.md Normal file
View File

@ -0,0 +1,33 @@
# edge_bridge
This module contains the federated bridge implementation from Edgeware to eligible blockchains. The federation is currently managed by at least the active set of validators in the underlying consensus protocol. There may be more stakeholders that can be involved in the federated process, all of which are denoted as bridge authorities. The bridge authorizes a two-way peg against eligible blockchains using at least 2/3 of the stake to process incoming and outgoing requests.
# Setup
Install rust or update to the latest versions.
```
curl https://sh.rustup.rs -sSf | sh
rustup update nightly
rustup target add wasm32-unknown-unknown --toolchain nightly
rustup update stable
cargo install --git https://github.com/alexcrichton/wasm-gc
```
You will also need to install the following packages:
Linux:
```
sudo apt install cmake pkg-config libssl-dev git
```
Mac:
```
brew install cmake pkg-config openssl git
```
# Overview
The bridge enables users on one blockchain to exchange Edgeware-compliant, non-native tokens (such as an Edgeware ERC20 token) for native Edgeware tokens and vice versa.
### Deposit
Interested individuals will deposit compliant tokens in a mechanism run by the active set of bridge authorities. Each bridge authority should be incentivized to sign new deposit messages in a timely manner, enabling the interested individual the ability to present an aggregate signature or list of signatures to this module to process the creation of native tokens.
### Withdraw
Interested individuals will request to withdraw native Edgeware tokens using this module. Bridge authorities should be incentivized to sign new withdraw messages in a timely manner, enabling the interested individual the ability to present an aggregate signature or list of signatures to a mechanism on the target blockchain for minting of Edgeware-compliant, non-native tokens.

107
src/bridge.rs Normal file
View File

@ -0,0 +1,107 @@
// Copyright 2018 Commonwealth Labs, Inc.
// This file is part of Edgeware.
// Edgeware 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.
// Edgeware 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 Edgeware. If not, see <http://www.gnu.org/licenses/>.
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "std")]
extern crate serde;
// Needed for deriving `Serialize` and `Deserialize` for various types.
// We only implement the serde traits for std builds - they're unneeded
// in the wasm runtime.
#[cfg(feature = "std")]
extern crate parity_codec as codec;
extern crate substrate_primitives as primitives;
#[cfg_attr(not(feature = "std"), macro_use)]
extern crate sr_std as rstd;
extern crate srml_support as runtime_support;
extern crate sr_primitives as runtime_primitives;
extern crate sr_io as runtime_io;
extern crate srml_balances as balances;
extern crate srml_system as system;
use primitives::ed25519::Signature;
use runtime_primitives::traits::{MaybeSerializeDebug};
use rstd::prelude::*;
use system::ensure_signed;
use runtime_support::{StorageValue, StorageMap, Parameter};
use runtime_support::dispatch::Result;
use primitives::ed25519;
/// Record indices.
pub type DepositIndex = u32;
pub type WithdrawIndex = u32;
pub trait Trait: balances::Trait {
/// The overarching event type.
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}
pub type LinkedProof = Vec<u8>;
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
fn deposit_event() = default;
/// The deposit function should always succeed (in order) a deposit transaction
/// on the eligible blockchain that has an established two-way peg with Edgeware.
/// This function can be triggered by the depositor or any bridge authority that
/// sees the transaction first.
pub fn deposit(origin, tx_hash: T::Hash, quantity: T::Balance) -> Result {
unimplemented!()
}
/// The withdraw function should precede (in order) a withdraw transaction on the
/// eligible blockchain that has an established two-way peg with Edgeware. This
/// function should only be called by a token holder interested in transferring
/// native Edgeware tokens with Edgeware-compliant, non-native tokens like ERC20.
pub fn withdraw(origin, quantity: T::Balance) -> Result {
unimplemented!()
}
}
}
/// An event in this module.
decl_event!(
pub enum Event<T> where <T as system::Trait>::Hash,
<T as system::Trait>::AccountId,
<T as balances::Trait>::Balance {
// Deposit event for an account, an eligible blockchain transaction hash, and quantity
Deposit(AccountId, Hash, Balance),
// Withdraw event for an account, and an amount
Withdraw(AccountId, Balance),
}
);
decl_storage! {
trait Store for Module<T: Trait> as IdentityStorage {
/// List of all deposit requests on Edgeware taken to be the transaction hash
/// from the eligible blockchain
pub Deposits get(deposits): Vec<T::Hash>;
/// Mapping of deposit transaction hashes from the eligible blockchain to the
/// deposit request record
pub DepositOf get(deposit_of): map T::Hash => (DepositIndex, T::AccountId, T::Balance, Vec<Signature>);
/// List of all withdraw requests on Edgeware taken to be the unique hash created
/// on Edgeware with the user's account, quantity, and nonce
pub Withdraws get(withdraws): Vec<T::Hash>;
pub WithdrawOf get(withdraw_of): map T::Hash => (WithdrawIndex, T::AccountId, T::Balance, Vec<Signature>);
/// Nonce for creating unique hashes per user per withdraw request
pub WithdrawNonceOf get(withdraw_nonce_of): map T::AccountId => u32;
}
}

159
src/lib.rs Normal file
View File

@ -0,0 +1,159 @@
// Copyright 2018 Commonwealth Labs, Inc.
// This file is part of Edgeware.
// Edgeware 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.
// Edgeware 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 Edgeware. If not, see <http://www.gnu.org/licenses/>.
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "std")]
extern crate serde;
// Needed for deriving `Serialize` and `Deserialize` for various types.
// We only implement the serde traits for std builds - they're unneeded
// in the wasm runtime.
#[cfg(feature = "std")]
#[macro_use]
extern crate serde_derive;
#[cfg(test)]
#[macro_use]
extern crate hex_literal;
#[macro_use] extern crate parity_codec_derive;
#[macro_use] extern crate srml_support;
extern crate parity_codec as codec;
extern crate substrate_primitives as primitives;
#[cfg_attr(not(feature = "std"), macro_use)]
extern crate sr_std as rstd;
extern crate srml_support as runtime_support;
extern crate sr_primitives as runtime_primitives;
extern crate sr_io as runtime_io;
extern crate srml_system as system;
extern crate srml_balances as balances;
extern crate srml_democracy as democracy;
extern crate srml_council as council;
use council::{voting, motions, seats};
use rstd::prelude::*;
use runtime_support::dispatch::Result;
use primitives::ed25519;
pub mod bridge;
use bridge::{Module, Trait, RawEvent};
// Tests for Bridge Module
#[cfg(test)]
mod tests {
use super::*;
use system::{EventRecord, Phase};
use runtime_io::with_externalities;
use runtime_io::ed25519::Pair;
use primitives::{H256, Blake2Hasher, Hasher};
// The testing primitives are very useful for avoiding having to work with signatures
// or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried.
use runtime_primitives::{
BuildStorage, traits::{BlakeTwo256}, testing::{Digest, DigestItem, Header}
};
impl_outer_origin! {
pub enum Origin for Test {
motions
}
}
impl_outer_event! {
pub enum Event for Test {
bridge<T>,
balances<T>,
democracy<T>,
council<T>,
voting<T>,
motions<T>,
}
}
impl_outer_dispatch! {
pub enum Call for Test where origin: Origin {
balances::Balances,
democracy::Democracy,
}
}
// For testing the module, we construct most of a mock runtime. This means
// first constructing a configuration type (`Test`) which `impl`s each of the
// configuration traits of modules we want to use.
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct Test;
impl system::Trait for Test {
type Origin = Origin;
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
type Hashing = BlakeTwo256;
type Digest = Digest;
type AccountId = u64;
type Header = Header;
type Event = Event;
type Log = DigestItem;
}
impl balances::Trait for Test {
type Balance = u64;
type AccountIndex = u64;
type OnFreeBalanceZero = ();
type EnsureAccountLiquid = ();
type Event = Event;
}
impl democracy::Trait for Test {
type Proposal = Call;
type Event = Event;
}
impl council::Trait for Test {
type Event = Event;
}
impl voting::Trait for Test {
type Event = Event;
}
impl motions::Trait for Test {
type Origin = Origin;
type Proposal = Call;
type Event = Event;
}
impl Trait for Test {
type Event = Event;
}
pub type System = system::Module<Test>;
pub type Balances = balances::Module<Test>;
pub type Democracy = democracy::Module<Test>;
pub type Council = seats::Module<Test>;
pub type CouncilVoting = voting::Module<Test>;
pub type CouncilMotions = motions::Module<Test>;
pub type Bridge = Module<Test>;
// This function basically just builds a genesis storage key/value store according to
// our desired mockup.
fn new_test_ext() -> sr_io::TestExternalities<Blake2Hasher> {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
// // We use default for brevity, but you can configure as desired if needed.
// t.extend(bridge::GenesisConfig::<Test>{
// _genesis_phantom_data: Default::default(),
// }.build_storage().unwrap().0);
t.into()
}
}