Skip to content

Commit 6ac8fb3

Browse files
authored
Stage/poc (paritytech#143)
* btcbridge CandidateTx and records withdraw cache * Fix precision and initialization error * Initialize balance of alice same with activation_per_share * Tweak initial intention profile * fix bug for withdraw in canonize, add no_withdrawal flag * Can not unstake when still in frozen * Fix some bug * Tweak session_length and sessions_per_era * Fix bug: Only candidate confirmed can create new proposal * Fix unexpect deposit * Tweak staking fees * Fix bug: Add unexpect in Candidate to handle unexpect deposit * Fix/match precision (paritytech#131) * fix pending order precision * add tests * Update genesis_config * Fix when candidate initialize * Recover AccountMap to support btc register * Update genesis BlockHeader * Fix select utxo must balance > 0 * move best index set before deposit/withdraw in canonize * Fix build error * Modify > irr_block as >= * Fix bug: Only candidate is not confirmed can modifi it status * Fix btc transaction correlation * Adjust PCX precision in session reward (paritytech#134) * Fix/match precision (paritytech#132) * fix pending order precision * add tests * add reserve last * 1. Fix UTXOList bug (paritytech#136) 2. Update genesis_config irr_block from 0 to 2 * Remove String (paritytech#137) * Reserve initial nomination (paritytech#138) * Fix wasm build error * Init nominees of initial intenions (paritytech#139) * UTXO only store value > 0 * Init channel (paritytech#140) * Init channel relationship * Init genesis intention * chance channel name (paritytech#141) * fix fill fee (paritytech#142) * Tweak parameters
1 parent eaff0be commit 6ac8fb3

File tree

16 files changed

+815
-433
lines changed

16 files changed

+815
-433
lines changed

Cargo.lock

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cxrml/bridge/btc/src/blockchain.rs

+93-78
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use script::Script;
1414
use staking;
1515

1616
use {
17-
AccountMap, BestIndex, BlockHeaderFor, CertCache, DepositCache, HashsForNumber, Module,
18-
NumberForHash, Params, ParamsInfo, Trait, TxProposal,
17+
BestIndex, BlockHeaderFor, CertCache, DepositCache, HashsForNumber, Module, NumberForHash,
18+
Params, ParamsInfo, Trait, TxProposal,
1919
};
2020

2121
use tx::{Proposal, RollBack, TxStorage};
@@ -165,6 +165,20 @@ impl<T: Trait> Chain<T> {
165165
best_number + 1
166166
},
167167
};
168+
169+
<NumberForHash<T>>::insert(new_best_header.hash.clone(), new_best_header.number);
170+
runtime_io::print("------------");
171+
runtime_io::print(new_best_header.hash.to_vec().as_slice());
172+
<HashsForNumber<T>>::mutate(new_best_header.number, |v| {
173+
let h = new_best_header.hash.clone();
174+
if v.contains(&h) == false {
175+
v.push(h);
176+
}
177+
});
178+
// best chain choose finish
179+
<BestIndex<T>>::put(new_best_header.clone());
180+
181+
// deposit/withdraw handle start
168182
let symbol: Symbol = Module::<T>::SYMBOL.to_vec();
169183
let irr_block = <IrrBlock<T>>::get();
170184
// Deposit
@@ -174,9 +188,10 @@ impl<T: Trait> Chain<T> {
174188
for (account_id, amount, tx_hash, block_hash) in vec {
175189
match <NumberForHash<T>>::get(block_hash.clone()) {
176190
Some(height) => {
177-
if new_best_header.number > height + irr_block {
191+
if new_best_header.number >= height + irr_block {
178192
runtime_io::print("-----------financial_records deposit");
179-
<financial_records::Module<T>>::deposit(
193+
// TODO handle err
194+
let _ = <financial_records::Module<T>>::deposit(
180195
&account_id,
181196
&symbol,
182197
As::sa(amount),
@@ -195,75 +210,86 @@ impl<T: Trait> Chain<T> {
195210
}
196211

197212
// Withdraw
198-
let candidate = <TxProposal<T>>::get();
199-
if candidate.is_some() {
200-
let tx = candidate.unwrap();
201-
match <NumberForHash<T>>::get(tx.block_hash) {
202-
Some(height) => {
203-
if new_best_header.number > height + irr_block {
204-
runtime_io::print("----new_best_header.number-----");
205-
let txid = tx.tx.hash();
206-
for output in tx.tx.outputs.iter() {
207-
let script: Script = output.clone().script_pubkey.into();
208-
let script_address =
209-
script.extract_destinations().unwrap_or(Vec::new());
210-
let network_id = <NetworkId<T>>::get();
211-
let network = if network_id == 1 {
212-
keys::Network::Testnet
213-
} else {
214-
keys::Network::Mainnet
215-
};
216-
let address = keys::Address {
217-
kind: script_address[0].kind,
218-
network,
219-
hash: script_address[0].hash.clone(),
220-
};
221-
let account_id = <AddressMap<T>>::get(address);
222-
if account_id.is_some() {
223-
<financial_records::Module<T>>::withdrawal_finish(
224-
&account_id.unwrap(),
225-
&symbol,
226-
Some(txid.as_ref().to_vec()),
227-
);
228-
}
229-
}
230-
let vec = <financial_records::Module<T>>::get_withdraw_cache(&symbol);
231-
if vec.is_some() {
232-
let mut address_vec = Vec::new();
233-
for (account_id, balance) in vec.unwrap() {
234-
let address = <AccountMap<T>>::get(account_id);
235-
if address.is_some() {
236-
address_vec.push((address.unwrap(), balance.as_() as u64));
237-
}
238-
}
239-
let btc_fee = <BtcFee<T>>::get();
240-
if let Err(e) = <Proposal<T>>::create_proposal(address_vec, btc_fee) {
241-
return Err(ChainErr::OtherErr(e));
213+
let len = Module::<T>::tx_proposal_len();
214+
// get last proposal
215+
if len > 0 {
216+
let mut candidate = Module::<T>::tx_proposal(len - 1).unwrap();
217+
// candidate: CandidateTx
218+
if candidate.confirmed == false {
219+
match <NumberForHash<T>>::get(&candidate.block_hash) {
220+
Some(height) => {
221+
if new_best_header.number >= height + irr_block {
222+
runtime_io::print("----new_best_header.number-----");
223+
let txid = candidate.tx.hash();
224+
/*for output in candidate.tx.outputs.iter() {
225+
let script: Script = output.clone().script_pubkey.into();
226+
let script_address =
227+
script.extract_destinations().unwrap_or(Vec::new());
228+
let network_id = <NetworkId<T>>::get();
229+
let network = if network_id == 1 {
230+
keys::Network::Testnet
231+
} else {
232+
keys::Network::Mainnet
233+
};
234+
let address = keys::Address {
235+
kind: script_address[0].kind,
236+
network,
237+
hash: script_address[0].hash.clone(),
238+
};*/
239+
//let account_id = <AddressMap<T>>::get(address);
240+
//if account_id.is_some() {
241+
for (account_id, _) in candidate.outs.clone() {
242+
// TODO handle err
243+
let _ = <financial_records::Module<T>>::withdrawal_finish(
244+
&account_id,
245+
&symbol,
246+
Some(txid.as_ref().to_vec()),
247+
);
248+
}
249+
//}
250+
candidate.confirmed = true;
251+
// mark this tx withdraw finish!
252+
TxProposal::<T>::insert(len - 1, candidate);
242253
}
243-
} else {
244-
<TxProposal<T>>::kill();
245254
}
255+
None => {}
246256
}
247257
}
248-
None => {}
258+
}
259+
260+
// case 0: 当刚启动时Candidate lenth = 0 时
261+
// case 1: 所有提现交易都是正常逻辑执行,会confirmed.
262+
// case 2: 非正常逻辑提现,candidate.unexpect 会在handle_input时设置,
263+
// 标记该链上这笔proposal由于BTC 托管人没有按着正常逻辑签名广播, 该proposal可能永远不会confirmed.
264+
// 所以开始重新创建proposal.
265+
if len == 0 {
266+
// no withdraw cache would return None
267+
if let Some(indexs) = financial_records::Module::<T>::withdrawal_cache_indexs(&symbol) {
268+
let btc_fee = <BtcFee<T>>::get();
269+
if let Err(e) = <Proposal<T>>::create_proposal(indexs, btc_fee) {
270+
return Err(ChainErr::OtherErr(e));
271+
}
272+
}
273+
249274
}
250-
} else {
251-
let vec = <financial_records::Module<T>>::get_withdraw_cache(&symbol);
252-
if vec.is_some() {
253-
runtime_io::print("-----------first withdraw");
254-
let mut address_vec = Vec::new();
255-
for (account_id, balance) in vec.unwrap() {
256-
let address = <AccountMap<T>>::get(account_id);
257-
if address.is_some() {
258-
address_vec.push((address.unwrap(), balance.as_() as u64));
259-
}
260-
}
261-
let btc_fee = <BtcFee<T>>::get();
262-
if let Err(e) = <Proposal<T>>::create_proposal(address_vec, btc_fee) {
263-
return Err(ChainErr::OtherErr(e));
264-
}
275+
if len > 0 {
276+
let candidate = Module::<T>::tx_proposal(len - 1).unwrap();
277+
if candidate.confirmed || candidate.unexpect {
278+
// no withdraw cache would return None
279+
if let Some(indexs) = financial_records::Module::<T>::withdrawal_cache_indexs(&symbol) {
280+
let btc_fee = <BtcFee<T>>::get();
281+
if let Err(e) = <Proposal<T>>::create_proposal(indexs, btc_fee) {
282+
return Err(ChainErr::OtherErr(e));
283+
}
284+
}
285+
}
265286
}
266-
}
287+
// let candidate = <TxProposal<T>>::get();
288+
// if candidate.is_some() {
289+
// let tx = candidate.unwrap();
290+
// } else {
291+
//
292+
// }
267293
// SendCert
268294
if let Some(cert_info) = <CertCache<T>>::take() {
269295
runtime_io::print("------CertCache take");
@@ -272,17 +298,6 @@ impl<T: Trait> Chain<T> {
272298
}
273299
}
274300

275-
<NumberForHash<T>>::insert(new_best_header.hash.clone(), new_best_header.number);
276-
runtime_io::print("------------");
277-
runtime_io::print(new_best_header.hash.to_vec().as_slice());
278-
<HashsForNumber<T>>::mutate(new_best_header.number, |v| {
279-
let h = new_best_header.hash.clone();
280-
if v.contains(&h) == false {
281-
v.push(h);
282-
}
283-
});
284-
285-
<BestIndex<T>>::put(new_best_header);
286301
Ok(())
287302
}
288303
/// Rollbacks single best block

cxrml/bridge/btc/src/lib.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ mod b58;
6363
mod blockchain;
6464
mod tx;
6565
mod verify_header;
66+
mod utils;
6667

6768
use chain::{BlockHeader, Transaction as BTCTransaction};
6869
use codec::Decode;
@@ -189,10 +190,25 @@ impl Default for TxType {
189190

190191
#[derive(PartialEq, Clone, Encode, Decode)]
191192
pub struct CandidateTx<AccountId: Parameter + Ord + Default> {
192-
pub proposer: Vec<AccountId>,
193193
pub tx: BTCTransaction,
194-
pub perfection: bool,
194+
pub unexpect: bool,
195+
pub confirmed: bool,
195196
pub block_hash: H256,
197+
pub outs: Vec<(AccountId, u32)>,
198+
pub proposers: Vec<AccountId>,
199+
}
200+
201+
impl<AccountId: Parameter + Ord + Default> CandidateTx<AccountId> {
202+
pub fn new(tx: BTCTransaction, outs: Vec<(AccountId, u32)>) -> Self {
203+
CandidateTx {
204+
tx,
205+
unexpect: false,
206+
confirmed: false,
207+
block_hash: Default::default(),
208+
outs,
209+
proposers: Vec::new(),
210+
}
211+
}
196212
}
197213

198214
#[derive(PartialEq, Clone, Encode, Decode)]
@@ -261,7 +277,12 @@ decl_storage! {
261277
pub BlockTxids get(block_txids): map H256 => Vec<H256>;
262278
pub AddressMap get(address_map): map Address => Option<T::AccountId>;
263279
pub AccountMap get(account_map): map T::AccountId => Option<keys::Address>;
264-
pub TxProposal get(tx_proposal): Option<CandidateTx<T::AccountId>>;
280+
/// withdrawal tx outs for account, tx_hash => outs ( out index => withdrawal account )
281+
// pub WithdrawalOutsAccount get(withdrawal_outs_account): map H256 => Vec<(u32, T::AccountId)>
282+
283+
pub TxProposalLen get(tx_proposal_len): u32;
284+
pub TxProposal get(tx_proposal): map u32 => Option<CandidateTx<T::AccountId>>;
285+
265286
/// account, btc value, txhash, blockhash
266287
pub DepositCache get(deposit_cache): Option<Vec<(T::AccountId, u64, H256, H256)>>;
267288
/// tx_hash, utxo index, btc value, blockhash

0 commit comments

Comments
 (0)