Add deposit functionality with super majority threshold
This commit is contained in:
parent
73bb53cbe0
commit
7a83016270
|
@ -14,6 +14,7 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with Edgeware. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#![feature(advanced_slice_patterns, slice_patterns)]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
|
@ -34,8 +35,12 @@ extern crate sr_io as runtime_io;
|
|||
|
||||
extern crate srml_balances as balances;
|
||||
extern crate srml_system as system;
|
||||
extern crate srml_democracy as democracy;
|
||||
|
||||
use democracy::{Approved, VoteThreshold};
|
||||
|
||||
use primitives::ed25519::Signature;
|
||||
use runtime_primitives::traits::{Zero, As};
|
||||
|
||||
use runtime_primitives::traits::{MaybeSerializeDebug};
|
||||
use rstd::prelude::*;
|
||||
|
@ -63,15 +68,55 @@ decl_module! {
|
|||
/// 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!()
|
||||
pub fn deposit(origin, target: T::AccountId, tx_hash: T::Hash, quantity: T::Balance) -> Result {
|
||||
let _sender = ensure_signed(origin)?;
|
||||
|
||||
// Match on deposit records by the respective transaction hash on the eligible blockchain
|
||||
match <DepositOf<T>>::get(tx_hash) {
|
||||
Some((inx, tgt, qty, signers)) => {
|
||||
// Ensure all parameters match for safety
|
||||
ensure!(tgt == target.clone(), "Accounts do not match");
|
||||
ensure!(qty == quantity, "Quantities don't match");
|
||||
// Ensure sender is a bridge authority if record exists
|
||||
ensure!(Self::authorities().iter().any(|id| id == &_sender), "Invalid non-authority sender");
|
||||
// Ensure senders can't sign twice
|
||||
ensure!(!signers.iter().any(|id| id == &_sender), "Invalid duplicate deposit signings");
|
||||
// Add record update with new signer
|
||||
let mut new_signers = signers;
|
||||
new_signers.push(_sender);
|
||||
<DepositOf<T>>::insert(tx_hash, (inx, tgt.clone(), qty, new_signers.clone()));
|
||||
|
||||
// Check if we have reached enough signers for the deposit
|
||||
let stake_sum = new_signers.iter()
|
||||
.map(|s| <AuthorityStake<T>>::get(s))
|
||||
.fold(Zero::zero(), |a,b| a + b);
|
||||
|
||||
// Check if we approve the proposal
|
||||
let total_issuance = <balances::Module<T>>::total_issuance();
|
||||
if VoteThreshold::SuperMajorityApprove.approved(stake_sum, Zero::zero(), total_issuance) {
|
||||
<balances::Module<T>>::increase_free_balance_creating(&tgt, qty);
|
||||
}
|
||||
},
|
||||
None => {
|
||||
let index = Self::deposit_count();
|
||||
<DepositCount<T>>::mutate(|i| *i += 1);
|
||||
let mut signers = vec![];
|
||||
if <Authorities<T>>::get().iter().any(|a| a == &_sender) {
|
||||
signers.push(_sender);
|
||||
}
|
||||
|
||||
<DepositOf<T>>::insert(tx_hash, (index, target, quantity, signers))
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
pub fn withdraw(origin, target: T::AccountId, quantity: T::Balance) -> Result {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
@ -91,17 +136,35 @@ decl_event!(
|
|||
|
||||
decl_storage! {
|
||||
trait Store for Module<T: Trait> as IdentityStorage {
|
||||
/// Mapping from an eligible blockchain by Hash(name) to the list of block headers
|
||||
/// TODO: V2 feature when we have stronger proofs of transfers
|
||||
pub BlockHeaders get(block_headers): map T::Hash => Vec<T::Hash>;
|
||||
|
||||
/// The active set of bridge authorities who can sign off on requests
|
||||
pub Authorities get(authorities): Vec<T::AccountId>;
|
||||
/// Mappings of stake per active authority
|
||||
pub AuthorityStake get(authority_stake): map T::AccountId => T::Balance;
|
||||
/// Total stake managed by the bridge authorities
|
||||
pub TotalAuthorityStake get(total_authority_stake): T::Balance;
|
||||
/// The required stake threshold for executing requests represented as an integer [0,100]
|
||||
pub StakeThreshold get(stake_threshold) config(): T::Balance;
|
||||
|
||||
/// Number of deposits
|
||||
pub DepositCount get(deposit_count): u32;
|
||||
/// 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>);
|
||||
pub DepositOf get(deposit_of): map T::Hash => Option<(DepositIndex, T::AccountId, T::Balance, Vec<T::AccountId>)>;
|
||||
|
||||
/// Number of withdraws
|
||||
pub WithdrawCount get(withdraw_count): u32;
|
||||
/// 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>;
|
||||
/// Mapping of withdraw record hashes to the record
|
||||
pub WithdrawOf get(withdraw_of): map T::Hash => (WithdrawIndex, T::AccountId, T::Balance, Vec<Signature>);
|
||||
pub WithdrawOf get(withdraw_of): map T::Hash => Option<(WithdrawIndex, T::AccountId, T::Balance, Vec<T::AccountId>)>;
|
||||
/// Nonce for creating unique hashes per user per withdraw request
|
||||
pub WithdrawNonceOf get(withdraw_nonce_of): map T::AccountId => u32;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue