forked from paritytech/substrate
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #25 from mangata-finance/fork_orml_tokens
fork orml_tokens 0.3.1 into repository
Showing
7 changed files
with
2,360 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
[package] | ||
name = "orml-tokens" | ||
description = "Fungible tokens module that implements `MultiCurrency` trait." | ||
repository = "https://github.com/open-web3-stack/open-runtime-module-library/tree/master/tokens" | ||
license = "Apache-2.0" | ||
version = "0.3.1" | ||
authors = ["Laminar Developers <hello@laminar.one>"] | ||
edition = "2018" | ||
|
||
[dependencies] | ||
serde = { version = "1.0.111", optional = true } | ||
codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } | ||
sp-runtime = { version = "2.0.0", default-features = false } | ||
sp-io = { version = "2.0.0", default-features = false } | ||
sp-std = { version = "2.0.0", default-features = false } | ||
|
||
frame-support = { version = "2.0.0", default-features = false } | ||
frame-system = { version = "2.0.0", default-features = false } | ||
|
||
orml-traits = { version = "0.3.1", default-features = false } | ||
|
||
|
||
[dev-dependencies] | ||
sp-core = { version = "2.0.0", default-features = false } | ||
pallet-treasury = { version = "2.0.0" } | ||
pallet-elections-phragmen = { version = "2.0.0" } | ||
|
||
clear_on_drop = { version = "0.2.4", features = ["no_cc"] } # https://github.com/paritytech/substrate/issues/4179 | ||
|
||
[features] | ||
default = ["std"] | ||
std = [ | ||
"serde", | ||
"codec/std", | ||
"sp-runtime/std", | ||
"sp-std/std", | ||
"sp-io/std", | ||
"frame-support/std", | ||
"frame-system/std", | ||
"orml-traits/std", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
This is Fork of the `orml_tokens` crate because Origin crate does not support minting | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
//! Weights for the Tokens Module | ||
use frame_support::weights::{ | ||
constants::{RocksDbWeight as DbWeight, WEIGHT_PER_MICROS}, | ||
Weight, | ||
}; | ||
|
||
impl crate::WeightInfo for () { | ||
fn transfer() -> Weight { | ||
WEIGHT_PER_MICROS | ||
.saturating_mul(84) | ||
.saturating_add(DbWeight::get().reads_writes(4, 2)) | ||
} | ||
|
||
fn transfer_all() -> Weight { | ||
WEIGHT_PER_MICROS | ||
.saturating_mul(88) | ||
.saturating_add(DbWeight::get().reads_writes(4, 2)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
// wrapping these imbalances in a private module is necessary to ensure absolute | ||
// privacy of the inner member. | ||
use crate::{TotalIssuance, Trait}; | ||
use frame_support::storage::StorageMap; | ||
use frame_support::traits::{Get, Imbalance, TryDrop}; | ||
use sp_runtime::traits::{Saturating, Zero}; | ||
use sp_std::{marker, mem, result}; | ||
|
||
/// Opaque, move-only struct with private fields that serves as a token | ||
/// denoting that funds have been created without any equal and opposite | ||
/// accounting. | ||
#[must_use] | ||
pub struct PositiveImbalance<T: Trait, GetCurrencyId: Get<T::CurrencyId>>( | ||
T::Balance, | ||
marker::PhantomData<GetCurrencyId>, | ||
); | ||
|
||
impl<T: Trait, GetCurrencyId: Get<T::CurrencyId>> PositiveImbalance<T, GetCurrencyId> { | ||
/// Create a new positive imbalance from a balance. | ||
pub fn new(amount: T::Balance) -> Self { | ||
PositiveImbalance(amount, marker::PhantomData::<GetCurrencyId>) | ||
} | ||
} | ||
|
||
/// Opaque, move-only struct with private fields that serves as a token | ||
/// denoting that funds have been destroyed without any equal and opposite | ||
/// accounting. | ||
#[must_use] | ||
pub struct NegativeImbalance<T: Trait, GetCurrencyId: Get<T::CurrencyId>>( | ||
T::Balance, | ||
marker::PhantomData<GetCurrencyId>, | ||
); | ||
|
||
impl<T: Trait, GetCurrencyId: Get<T::CurrencyId>> NegativeImbalance<T, GetCurrencyId> { | ||
/// Create a new negative imbalance from a balance. | ||
pub fn new(amount: T::Balance) -> Self { | ||
NegativeImbalance(amount, marker::PhantomData::<GetCurrencyId>) | ||
} | ||
} | ||
|
||
impl<T: Trait, GetCurrencyId: Get<T::CurrencyId>> TryDrop for PositiveImbalance<T, GetCurrencyId> { | ||
fn try_drop(self) -> result::Result<(), Self> { | ||
self.drop_zero() | ||
} | ||
} | ||
|
||
impl<T: Trait, GetCurrencyId: Get<T::CurrencyId>> Imbalance<T::Balance> for PositiveImbalance<T, GetCurrencyId> { | ||
type Opposite = NegativeImbalance<T, GetCurrencyId>; | ||
|
||
fn zero() -> Self { | ||
Self::new(Zero::zero()) | ||
} | ||
fn drop_zero(self) -> result::Result<(), Self> { | ||
if self.0.is_zero() { | ||
Ok(()) | ||
} else { | ||
Err(self) | ||
} | ||
} | ||
fn split(self, amount: T::Balance) -> (Self, Self) { | ||
let first = self.0.min(amount); | ||
let second = self.0 - first; | ||
|
||
mem::forget(self); | ||
(Self::new(first), Self::new(second)) | ||
} | ||
fn merge(mut self, other: Self) -> Self { | ||
self.0 = self.0.saturating_add(other.0); | ||
mem::forget(other); | ||
|
||
self | ||
} | ||
fn subsume(&mut self, other: Self) { | ||
self.0 = self.0.saturating_add(other.0); | ||
mem::forget(other); | ||
} | ||
fn offset(self, other: Self::Opposite) -> result::Result<Self, Self::Opposite> { | ||
let (a, b) = (self.0, other.0); | ||
mem::forget((self, other)); | ||
|
||
if a >= b { | ||
Ok(Self::new(a - b)) | ||
} else { | ||
Err(NegativeImbalance::new(b - a)) | ||
} | ||
} | ||
fn peek(&self) -> T::Balance { | ||
self.0 | ||
} | ||
} | ||
|
||
impl<T: Trait, GetCurrencyId: Get<T::CurrencyId>> TryDrop for NegativeImbalance<T, GetCurrencyId> { | ||
fn try_drop(self) -> result::Result<(), Self> { | ||
self.drop_zero() | ||
} | ||
} | ||
|
||
impl<T: Trait, GetCurrencyId: Get<T::CurrencyId>> Imbalance<T::Balance> for NegativeImbalance<T, GetCurrencyId> { | ||
type Opposite = PositiveImbalance<T, GetCurrencyId>; | ||
|
||
fn zero() -> Self { | ||
Self::new(Zero::zero()) | ||
} | ||
fn drop_zero(self) -> result::Result<(), Self> { | ||
if self.0.is_zero() { | ||
Ok(()) | ||
} else { | ||
Err(self) | ||
} | ||
} | ||
fn split(self, amount: T::Balance) -> (Self, Self) { | ||
let first = self.0.min(amount); | ||
let second = self.0 - first; | ||
|
||
mem::forget(self); | ||
(Self::new(first), Self::new(second)) | ||
} | ||
fn merge(mut self, other: Self) -> Self { | ||
self.0 = self.0.saturating_add(other.0); | ||
mem::forget(other); | ||
|
||
self | ||
} | ||
fn subsume(&mut self, other: Self) { | ||
self.0 = self.0.saturating_add(other.0); | ||
mem::forget(other); | ||
} | ||
fn offset(self, other: Self::Opposite) -> result::Result<Self, Self::Opposite> { | ||
let (a, b) = (self.0, other.0); | ||
mem::forget((self, other)); | ||
|
||
if a >= b { | ||
Ok(Self::new(a - b)) | ||
} else { | ||
Err(PositiveImbalance::new(b - a)) | ||
} | ||
} | ||
fn peek(&self) -> T::Balance { | ||
self.0 | ||
} | ||
} | ||
|
||
impl<T: Trait, GetCurrencyId: Get<T::CurrencyId>> Drop for PositiveImbalance<T, GetCurrencyId> { | ||
/// Basic drop handler will just square up the total issuance. | ||
fn drop(&mut self) { | ||
<TotalIssuance<T>>::mutate(GetCurrencyId::get(), |v| *v = v.saturating_add(self.0)); | ||
} | ||
} | ||
|
||
impl<T: Trait, GetCurrencyId: Get<T::CurrencyId>> Drop for NegativeImbalance<T, GetCurrencyId> { | ||
/// Basic drop handler will just square up the total issuance. | ||
fn drop(&mut self) { | ||
<TotalIssuance<T>>::mutate(GetCurrencyId::get(), |v| *v = v.saturating_sub(self.0)); | ||
} | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,362 @@ | ||
//! Mocks for the tokens module. | ||
#![cfg(test)] | ||
|
||
use frame_support::{ | ||
impl_outer_event, impl_outer_origin, parameter_types, | ||
traits::{ChangeMembers, Contains, ContainsLengthBound}, | ||
}; | ||
use frame_system as system; | ||
use sp_core::H256; | ||
use sp_runtime::{ | ||
testing::Header, | ||
traits::{Convert, IdentityLookup}, | ||
ModuleId, Perbill, Percent, Permill, | ||
}; | ||
use sp_std::cell::RefCell; | ||
use std::collections::HashMap; | ||
|
||
use super::*; | ||
|
||
impl_outer_origin! { | ||
pub enum Origin for Runtime {} | ||
} | ||
|
||
mod tokens { | ||
pub use crate::Event; | ||
} | ||
|
||
impl_outer_event! { | ||
pub enum TestEvent for Runtime { | ||
frame_system<T>, | ||
tokens<T>, | ||
pallet_treasury<T>, | ||
pallet_elections_phragmen<T>, | ||
} | ||
} | ||
|
||
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. | ||
#[derive(Clone, PartialEq, Eq, Debug)] | ||
pub struct Runtime; | ||
parameter_types! { | ||
pub const BlockHashCount: u64 = 250; | ||
pub const MaximumBlockWeight: u32 = 1024; | ||
pub const MaximumBlockLength: u32 = 2 * 1024; | ||
pub const AvailableBlockRatio: Perbill = Perbill::one(); | ||
} | ||
|
||
type AccountId = u64; | ||
impl frame_system::Trait for Runtime { | ||
type Origin = Origin; | ||
type Call = (); | ||
type Index = u64; | ||
type BlockNumber = u64; | ||
type Hash = H256; | ||
type Hashing = ::sp_runtime::traits::BlakeTwo256; | ||
type AccountId = AccountId; | ||
type Lookup = IdentityLookup<Self::AccountId>; | ||
type Header = Header; | ||
type Event = TestEvent; | ||
type BlockHashCount = BlockHashCount; | ||
type MaximumBlockWeight = MaximumBlockWeight; | ||
type MaximumBlockLength = MaximumBlockLength; | ||
type AvailableBlockRatio = AvailableBlockRatio; | ||
type Version = (); | ||
type PalletInfo = (); | ||
type AccountData = (); | ||
type OnNewAccount = (); | ||
type OnKilledAccount = (); | ||
type DbWeight = (); | ||
type BlockExecutionWeight = (); | ||
type ExtrinsicBaseWeight = (); | ||
type MaximumExtrinsicWeight = (); | ||
type BaseCallFilter = (); | ||
type SystemWeightInfo = (); | ||
} | ||
pub type System = system::Module<Runtime>; | ||
|
||
type CurrencyId = u32; | ||
pub type Balance = u64; | ||
|
||
thread_local! { | ||
pub static ACCUMULATED_RECEIVED: RefCell<HashMap<(AccountId, CurrencyId), Balance>> = RefCell::new(HashMap::new()); | ||
} | ||
|
||
pub struct MockOnReceived; | ||
impl OnReceived<AccountId, CurrencyId, Balance> for MockOnReceived { | ||
fn on_received(who: &AccountId, currency_id: CurrencyId, amount: Balance) { | ||
ACCUMULATED_RECEIVED.with(|v| { | ||
let mut old_map = v.borrow().clone(); | ||
if let Some(before) = old_map.get_mut(&(*who, currency_id)) { | ||
*before += amount; | ||
} else { | ||
old_map.insert((*who, currency_id), amount); | ||
}; | ||
|
||
*v.borrow_mut() = old_map; | ||
}); | ||
} | ||
} | ||
|
||
thread_local! { | ||
static TEN_TO_FOURTEEN: RefCell<Vec<u64>> = RefCell::new(vec![10,11,12,13,14]); | ||
} | ||
pub struct TenToFourteen; | ||
impl Contains<u64> for TenToFourteen { | ||
fn sorted_members() -> Vec<u64> { | ||
TEN_TO_FOURTEEN.with(|v| v.borrow().clone()) | ||
} | ||
#[cfg(feature = "runtime-benchmarks")] | ||
fn add(new: &u64) { | ||
TEN_TO_FOURTEEN.with(|v| { | ||
let mut members = v.borrow_mut(); | ||
members.push(*new); | ||
members.sort(); | ||
}) | ||
} | ||
} | ||
impl ContainsLengthBound for TenToFourteen { | ||
fn max_len() -> usize { | ||
TEN_TO_FOURTEEN.with(|v| v.borrow().len()) | ||
} | ||
fn min_len() -> usize { | ||
0 | ||
} | ||
} | ||
|
||
parameter_types! { | ||
pub const ProposalBond: Permill = Permill::from_percent(5); | ||
pub const ProposalBondMinimum: u64 = 1; | ||
pub const TipCountdown: u64 = 1; | ||
pub const TipFindersFee: Percent = Percent::from_percent(20); | ||
pub const TipReportDepositBase: u64 = 1; | ||
pub const DataDepositPerByte: u64 = 1; | ||
pub const SpendPeriod: u64 = 2; | ||
pub const Burn: Permill = Permill::from_percent(50); | ||
pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry"); | ||
pub const GetTokenId: CurrencyId = TEST_TOKEN_ID; | ||
} | ||
|
||
impl pallet_treasury::Trait for Runtime { | ||
type ModuleId = TreasuryModuleId; | ||
type Currency = CurrencyAdapter<Runtime, GetTokenId>; | ||
type ApproveOrigin = frame_system::EnsureRoot<u64>; | ||
type RejectOrigin = frame_system::EnsureRoot<u64>; | ||
type Tippers = TenToFourteen; | ||
type TipCountdown = TipCountdown; | ||
type TipFindersFee = TipFindersFee; | ||
type TipReportDepositBase = TipReportDepositBase; | ||
type DataDepositPerByte = DataDepositPerByte; | ||
type Event = TestEvent; | ||
type OnSlash = (); | ||
type ProposalBond = ProposalBond; | ||
type ProposalBondMinimum = ProposalBondMinimum; | ||
type SpendPeriod = SpendPeriod; | ||
type Burn = Burn; | ||
type BurnDestination = (); // Just gets burned. | ||
type BountyDepositBase = (); | ||
type BountyDepositPayoutDelay = (); | ||
type BountyUpdatePeriod = (); | ||
type BountyCuratorDeposit = (); | ||
type BountyValueMinimum = (); | ||
type MaximumReasonLength = (); | ||
type WeightInfo = (); | ||
} | ||
|
||
pub struct CurrencyToVoteHandler; | ||
impl Convert<u64, u64> for CurrencyToVoteHandler { | ||
fn convert(x: u64) -> u64 { | ||
x | ||
} | ||
} | ||
impl Convert<u128, u64> for CurrencyToVoteHandler { | ||
fn convert(x: u128) -> u64 { | ||
x as u64 | ||
} | ||
} | ||
|
||
parameter_types! { | ||
pub const CandidacyBond: u64 = 3; | ||
} | ||
|
||
thread_local! { | ||
static VOTING_BOND: RefCell<u64> = RefCell::new(2); | ||
static DESIRED_MEMBERS: RefCell<u32> = RefCell::new(2); | ||
static DESIRED_RUNNERS_UP: RefCell<u32> = RefCell::new(2); | ||
static TERM_DURATION: RefCell<u64> = RefCell::new(5); | ||
} | ||
|
||
pub struct VotingBond; | ||
impl Get<u64> for VotingBond { | ||
fn get() -> u64 { | ||
VOTING_BOND.with(|v| *v.borrow()) | ||
} | ||
} | ||
|
||
pub struct DesiredMembers; | ||
impl Get<u32> for DesiredMembers { | ||
fn get() -> u32 { | ||
DESIRED_MEMBERS.with(|v| *v.borrow()) | ||
} | ||
} | ||
|
||
pub struct DesiredRunnersUp; | ||
impl Get<u32> for DesiredRunnersUp { | ||
fn get() -> u32 { | ||
DESIRED_RUNNERS_UP.with(|v| *v.borrow()) | ||
} | ||
} | ||
|
||
pub struct TermDuration; | ||
impl Get<u64> for TermDuration { | ||
fn get() -> u64 { | ||
TERM_DURATION.with(|v| *v.borrow()) | ||
} | ||
} | ||
|
||
thread_local! { | ||
pub static MEMBERS: RefCell<Vec<u64>> = RefCell::new(vec![]); | ||
pub static PRIME: RefCell<Option<u64>> = RefCell::new(None); | ||
} | ||
|
||
pub struct TestChangeMembers; | ||
impl ChangeMembers<u64> for TestChangeMembers { | ||
fn change_members_sorted(incoming: &[u64], outgoing: &[u64], new: &[u64]) { | ||
// new, incoming, outgoing must be sorted. | ||
let mut new_sorted = new.to_vec(); | ||
new_sorted.sort(); | ||
assert_eq!(new, &new_sorted[..]); | ||
|
||
let mut incoming_sorted = incoming.to_vec(); | ||
incoming_sorted.sort(); | ||
assert_eq!(incoming, &incoming_sorted[..]); | ||
|
||
let mut outgoing_sorted = outgoing.to_vec(); | ||
outgoing_sorted.sort(); | ||
assert_eq!(outgoing, &outgoing_sorted[..]); | ||
|
||
// incoming and outgoing must be disjoint | ||
for x in incoming.iter() { | ||
assert!(outgoing.binary_search(x).is_err()); | ||
} | ||
|
||
let mut old_plus_incoming = MEMBERS.with(|m| m.borrow().to_vec()); | ||
old_plus_incoming.extend_from_slice(incoming); | ||
old_plus_incoming.sort(); | ||
|
||
let mut new_plus_outgoing = new.to_vec(); | ||
new_plus_outgoing.extend_from_slice(outgoing); | ||
new_plus_outgoing.sort(); | ||
|
||
assert_eq!( | ||
old_plus_incoming, new_plus_outgoing, | ||
"change members call is incorrect!" | ||
); | ||
|
||
MEMBERS.with(|m| *m.borrow_mut() = new.to_vec()); | ||
PRIME.with(|p| *p.borrow_mut() = None); | ||
} | ||
|
||
fn set_prime(who: Option<u64>) { | ||
PRIME.with(|p| *p.borrow_mut() = who); | ||
} | ||
} | ||
|
||
parameter_types! { | ||
pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect"; | ||
} | ||
|
||
impl pallet_elections_phragmen::Trait for Runtime { | ||
type ModuleId = ElectionsPhragmenModuleId; | ||
type Event = TestEvent; | ||
type Currency = CurrencyAdapter<Runtime, GetTokenId>; | ||
type CurrencyToVote = CurrencyToVoteHandler; | ||
type ChangeMembers = TestChangeMembers; | ||
type InitializeMembers = (); | ||
type CandidacyBond = CandidacyBond; | ||
type VotingBond = VotingBond; | ||
type TermDuration = TermDuration; | ||
type DesiredMembers = DesiredMembers; | ||
type DesiredRunnersUp = DesiredRunnersUp; | ||
type LoserCandidate = (); | ||
type KickedMember = (); | ||
type BadReport = (); | ||
type WeightInfo = (); | ||
} | ||
|
||
impl Trait for Runtime { | ||
type Event = TestEvent; | ||
type Balance = Balance; | ||
type Amount = i64; | ||
type CurrencyId = CurrencyId; | ||
type OnReceived = MockOnReceived; | ||
type WeightInfo = (); | ||
} | ||
|
||
pub type Tokens = Module<Runtime>; | ||
pub type TreasuryCurrencyAdapter = <Runtime as pallet_treasury::Trait>::Currency; | ||
|
||
pub const TEST_TOKEN_ID: CurrencyId = 1; | ||
pub const ALICE: AccountId = 1; | ||
pub const BOB: AccountId = 2; | ||
pub const TREASURY_ACCOUNT: AccountId = 3; | ||
pub const ID_1: LockIdentifier = *b"1 "; | ||
pub const ID_2: LockIdentifier = *b"2 "; | ||
|
||
pub struct ExtBuilder { | ||
endowed_accounts: Vec<(AccountId, CurrencyId, Balance)>, | ||
treasury_genesis: bool, | ||
} | ||
|
||
impl Default for ExtBuilder { | ||
fn default() -> Self { | ||
Self { | ||
endowed_accounts: vec![], | ||
treasury_genesis: false, | ||
} | ||
} | ||
} | ||
|
||
impl ExtBuilder { | ||
pub fn balances(mut self, endowed_accounts: Vec<(AccountId, CurrencyId, Balance)>) -> Self { | ||
self.endowed_accounts = endowed_accounts; | ||
self | ||
} | ||
|
||
pub fn one_hundred_for_alice_n_bob(self) -> Self { | ||
self.balances(vec![(ALICE, TEST_TOKEN_ID, 100), (BOB, TEST_TOKEN_ID, 100)]) | ||
} | ||
|
||
pub fn one_hundred_for_treasury_account(mut self) -> Self { | ||
self.treasury_genesis = true; | ||
self.balances(vec![(TREASURY_ACCOUNT, TEST_TOKEN_ID, 100)]) | ||
} | ||
|
||
pub fn build(self) -> sp_io::TestExternalities { | ||
let mut t = frame_system::GenesisConfig::default() | ||
.build_storage::<Runtime>() | ||
.unwrap(); | ||
|
||
GenesisConfig::<Runtime> { | ||
endowed_accounts: self.endowed_accounts, | ||
} | ||
.assimilate_storage(&mut t) | ||
.unwrap(); | ||
|
||
if self.treasury_genesis { | ||
pallet_treasury::GenesisConfig::default() | ||
.assimilate_storage::<Runtime, _>(&mut t) | ||
.unwrap(); | ||
|
||
pallet_elections_phragmen::GenesisConfig::<Runtime> { | ||
members: vec![(TREASURY_ACCOUNT, 10)], | ||
} | ||
.assimilate_storage(&mut t) | ||
.unwrap(); | ||
} | ||
|
||
let mut ext = sp_io::TestExternalities::new(t); | ||
ext.execute_with(|| System::set_block_number(1)); | ||
ext | ||
} | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.