Skip to content

Commit 2c7fec4

Browse files
authored
integrate bitcoin to runtime and add genesis (paritytech#104)
1 parent 58281fd commit 2c7fec4

File tree

14 files changed

+221
-183
lines changed

14 files changed

+221
-183
lines changed

Cargo.lock

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

runtime/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ pub use pallet_timestamp::Call as TimestampCall;
4545
#[cfg(any(feature = "std", test))]
4646
pub use sp_runtime::BuildStorage;
4747
pub use sp_runtime::{Perbill, Permill};
48+
// xrml re-exports
49+
#[cfg(feature = "std")]
50+
pub use xrml_bridge_bitcoin::h256_conv_endian_from_str;
51+
pub use xrml_bridge_bitcoin::{BTCHeader, BTCNetwork, BTCParams, Compact, H256 as BTCHash};
4852

4953
impl_opaque_keys! {
5054
pub struct SessionKeys {
@@ -216,6 +220,10 @@ impl xrml_assets::Trait for Runtime {
216220
type DetermineTokenJackpotAccountId = Tmp;
217221
}
218222

223+
impl xrml_bridge_bitcoin::Trait for Runtime {
224+
type Event = Event;
225+
}
226+
219227
construct_runtime!(
220228
pub enum Runtime where
221229
Block = Block,
@@ -231,6 +239,7 @@ construct_runtime!(
231239

232240
TransactionPayment: pallet_transaction_payment::{Module, Storage},
233241
XAssets: xrml_assets::{Module, Call, Storage, Event<T>},
242+
XBridgeBitcoin: xrml_bridge_bitcoin::{Module, Call, Storage, Event<T>, Config},
234243
}
235244
);
236245

src/chain_spec.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use chainx_runtime::{
2-
AccountId, AuraConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig, SystemConfig,
2+
h256_conv_endian_from_str, AccountId, AuraConfig, BTCHeader, BTCNetwork, BTCParams, Compact,
3+
GenesisConfig, GrandpaConfig, Signature, SudoConfig, SystemConfig, XBridgeBitcoinConfig,
34
WASM_BINARY,
45
};
56
use sc_service::ChainType;
@@ -125,5 +126,37 @@ fn testnet_genesis(
125126
pallet_sudo: Some(SudoConfig {
126127
key: root_key.clone(),
127128
}),
129+
xrml_bridge_bitcoin: Some(XBridgeBitcoinConfig {
130+
genesis_header_and_height: (
131+
BTCHeader {
132+
version: 536870912,
133+
previous_header_hash: h256_conv_endian_from_str(
134+
"0000000000000000000a4adf6c5192128535d4dcb56cfb5753755f8d392b26bf",
135+
),
136+
merkle_root_hash: h256_conv_endian_from_str(
137+
"1d21e60acb0b12e5cfd3f775edb647f982a2d666f9886b2f61ea5e72577b0f5e",
138+
),
139+
time: 1558168296,
140+
bits: Compact::new(388627269),
141+
nonce: 1439505020,
142+
},
143+
576576,
144+
),
145+
genesis_hash: h256_conv_endian_from_str(
146+
"0000000000000000001721f58deb88b0710295a02551f0dde1e2e231a15f1882",
147+
),
148+
params_info: BTCParams::new(
149+
486604799, // max_bits
150+
2 * 60 * 60, // block_max_future
151+
2 * 7 * 24 * 60 * 60, // target_timespan_seconds
152+
10 * 60, // target_spacing_seconds
153+
4, // retargeting_factor
154+
), // retargeting_factor
155+
network_id: BTCNetwork::Mainnet,
156+
confirmation_number: 4,
157+
reserved_block: 2100,
158+
btc_withdrawal_fee: 500000,
159+
max_withdrawal_count: 100,
160+
}),
128161
}
129162
}

xrml/assets/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*, result};
1919

2020
use frame_support::{
2121
decl_error, decl_event, decl_module, decl_storage,
22-
dispatch::{DispatchResult, DispatchError},
23-
traits::{Imbalance, SignedImbalance, OnNewAccount},
22+
dispatch::{DispatchError, DispatchResult},
23+
traits::{Imbalance, OnNewAccount, SignedImbalance},
2424
Parameter,
2525
};
2626
use frame_system::{self as system, ensure_root, ensure_signed};

xrml/assets/src/pcx.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use sp_runtime::traits::{CheckedSub, Zero};
22
use sp_std::{cmp, result};
33

4-
use frame_support::dispatch::{DispatchResult, DispatchError};
4+
use frame_support::dispatch::{DispatchError, DispatchResult};
55
use frame_support::traits::{
66
BalanceStatus, Currency, ExistenceRequirement, Imbalance, ReservableCurrency, SignedImbalance,
77
WithdrawReason, WithdrawReasons,

xrml/bridge/bitcoin/src/assets_records.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ impl<T: Trait> Module<T> {
5050
// current 4
5151
// current 5
5252
for confirmed in 1_u32..confirmations {
53-
if let Some(info) = Module::<T>::block_header_for(current_hash) {
53+
if let Some(info) = Module::<T>::btc_header_for(current_hash) {
5454
// lookup withdrawal tx in current header
5555
for txid in info.txid_list {
5656
if let Some(tx_info) = Self::tx_for(&txid) {
@@ -116,7 +116,7 @@ impl<T: Trait> Module<T> {
116116
// current 4
117117
let mut current_hash = Self::best_index();
118118
for index in 0..(confirmations - 1) {
119-
if let Some(info) = Module::<T>::block_header_for(current_hash) {
119+
if let Some(info) = Module::<T>::btc_header_for(current_hash) {
120120
for txid in info.txid_list {
121121
if let Some(tx_info) = Self::tx_for(&txid) {
122122
if tx_info.tx_type == TxType::Deposit {

xrml/bridge/bitcoin/src/header/header_proof.rs

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ use sp_std::{cmp, result};
99
use xrml_support::{debug, ensure_with_errorlog, error, info};
1010

1111
// light-bitcoin
12-
use btc_chain::BlockHeader;
12+
use btc_chain::BlockHeader as BTCHeader;
13+
use btc_keys::Network;
1314
use btc_primitives::{Compact, H256, U256};
1415

1516
use super::ChainErr;
16-
use crate::types::Params;
17+
use crate::types::BTCParams;
1718
use crate::{Error, Module, Trait};
1819

1920
pub struct HeaderVerifier<'a> {
@@ -23,7 +24,7 @@ pub struct HeaderVerifier<'a> {
2324
}
2425

2526
impl<'a> HeaderVerifier<'a> {
26-
pub fn new<T: Trait>(header: &'a BlockHeader, height: u32) -> result::Result<Self, ChainErr> {
27+
pub fn new<T: Trait>(header: &'a BTCHeader, height: u32) -> result::Result<Self, ChainErr> {
2728
let now: T::Moment = pallet_timestamp::Module::<T>::now();
2829
// bitcoin use u32 to log time, we think the timestamp would not more then u32
2930
let current_time: u32 = now.saturated_into::<u32>();
@@ -36,9 +37,9 @@ impl<'a> HeaderVerifier<'a> {
3637
}
3738

3839
pub fn check<T: Trait>(&self) -> DispatchResult {
39-
let params: Params = Module::<T>::params_info();
40-
let network_id: u32 = Module::<T>::network_id();
41-
if network_id == 0 {
40+
let params: BTCParams = Module::<T>::params_info();
41+
let network_id: Network = Module::<T>::network_id();
42+
if let Network::Mainnet = network_id {
4243
self.work.check::<T>(&params)?;
4344
}
4445
self.proof_of_work.check::<T>(&params)?;
@@ -48,16 +49,16 @@ impl<'a> HeaderVerifier<'a> {
4849
}
4950

5051
pub struct HeaderWork<'a> {
51-
header: &'a BlockHeader,
52+
header: &'a BTCHeader,
5253
height: u32,
5354
}
5455

5556
impl<'a> HeaderWork<'a> {
56-
fn new(header: &'a BlockHeader, height: u32) -> Self {
57+
fn new(header: &'a BTCHeader, height: u32) -> Self {
5758
HeaderWork { header, height }
5859
}
5960

60-
fn check<T: Trait>(&self, p: &Params) -> DispatchResult {
61+
fn check<T: Trait>(&self, p: &BTCParams) -> DispatchResult {
6162
let previous_header_hash = self.header.previous_header_hash.clone();
6263
let work = work_required::<T>(previous_header_hash, self.height, p);
6364
ensure_with_errorlog!(
@@ -72,13 +73,13 @@ impl<'a> HeaderWork<'a> {
7273
}
7374
}
7475

75-
pub fn work_required<T: Trait>(parent_hash: H256, height: u32, params: &Params) -> Compact {
76+
pub fn work_required<T: Trait>(parent_hash: H256, height: u32, params: &BTCParams) -> Compact {
7677
let max_bits = params.max_bits().into();
7778
if height == 0 {
7879
return max_bits;
7980
}
8081

81-
let parent_header: BlockHeader = Module::<T>::block_header_for(&parent_hash).unwrap().header;
82+
let parent_header: BTCHeader = Module::<T>::btc_header_for(&parent_hash).unwrap().header;
8283

8384
if is_retarget_height(height, params) {
8485
let new_work = work_required_retarget::<T>(parent_header, height, params);
@@ -92,15 +93,15 @@ pub fn work_required<T: Trait>(parent_hash: H256, height: u32, params: &Params)
9293
parent_header.bits
9394
}
9495

95-
pub fn is_retarget_height(height: u32, p: &Params) -> bool {
96+
pub fn is_retarget_height(height: u32, p: &BTCParams) -> bool {
9697
height % p.retargeting_interval() == 0
9798
}
9899

99100
/// Algorithm used for retargeting work every 2 weeks
100101
pub fn work_required_retarget<T: Trait>(
101-
parent_header: BlockHeader,
102+
parent_header: BTCHeader,
102103
height: u32,
103-
params: &Params,
104+
params: &BTCParams,
104105
) -> Compact {
105106
let retarget_num = height - params.retargeting_interval();
106107

@@ -112,7 +113,7 @@ pub fn work_required_retarget<T: Trait>(
112113
let hash_list = Module::<T>::block_hash_for(&retarget_num);
113114
for h in hash_list {
114115
// look up in main chain
115-
if let Some(info) = Module::<T>::block_header_for(h) {
116+
if let Some(info) = Module::<T>::btc_header_for(h) {
116117
if info.confirmed == true {
117118
retarget_header = info.header;
118119
break;
@@ -152,7 +153,7 @@ pub fn work_required_retarget<T: Trait>(
152153
}
153154

154155
/// Returns constrained number of seconds since last retarget
155-
pub fn retarget_timespan(retarget_timestamp: u32, last_timestamp: u32, p: &Params) -> u32 {
156+
pub fn retarget_timespan(retarget_timestamp: u32, last_timestamp: u32, p: &BTCParams) -> u32 {
156157
// TODO i64??
157158
// subtract unsigned 32 bit numbers in signed 64 bit space in
158159
// order to prevent underflow before applying the range constraint.
@@ -169,15 +170,15 @@ fn range_constrain(value: i64, min: i64, max: i64) -> i64 {
169170
}
170171

171172
pub struct HeaderProofOfWork<'a> {
172-
header: &'a BlockHeader,
173+
header: &'a BTCHeader,
173174
}
174175

175176
impl<'a> HeaderProofOfWork<'a> {
176-
fn new(header: &'a BlockHeader) -> Self {
177+
fn new(header: &'a BTCHeader) -> Self {
177178
HeaderProofOfWork { header }
178179
}
179180

180-
fn check<T: Trait>(&self, p: &Params) -> DispatchResult {
181+
fn check<T: Trait>(&self, p: &BTCParams) -> DispatchResult {
181182
if is_valid_proof_of_work(p.max_bits(), self.header.bits, &self.header.hash()) {
182183
Ok(())
183184
} else {
@@ -209,19 +210,19 @@ pub fn is_valid_proof_of_work(max_work_bits: Compact, bits: Compact, hash: &H256
209210
}
210211

211212
pub struct HeaderTimestamp<'a> {
212-
header: &'a BlockHeader,
213+
header: &'a BTCHeader,
213214
current_time: u32,
214215
}
215216

216217
impl<'a> HeaderTimestamp<'a> {
217-
fn new(header: &'a BlockHeader, current_time: u32) -> Self {
218+
fn new(header: &'a BTCHeader, current_time: u32) -> Self {
218219
HeaderTimestamp {
219220
header,
220221
current_time,
221222
}
222223
}
223224

224-
fn check<T: Trait>(&self, p: &Params) -> DispatchResult {
225+
fn check<T: Trait>(&self, p: &BTCParams) -> DispatchResult {
225226
if self.header.time > self.current_time + p.block_max_future() {
226227
error!("[HeaderTimestamp check]|Futuristic timestamp|header time{:}|current time:{:}|max_future{:?}", self.header.time, self.current_time, p.block_max_future());
227228
Err(Error::<T>::HeaderFuturisticTimestamp)?

0 commit comments

Comments
 (0)