Skip to content

Commit

Permalink
Merge branch 'tests/btc-relay' into 'dev'
Browse files Browse the repository at this point in the history
[BTC-Relay] Integration tests

See merge request interlay/btc-parachain!115
  • Loading branch information
nud3l committed May 21, 2020
2 parents 7a60dc8 + 6cb1a9a commit 1448891
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 44 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/btc-relay/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "btc-relay"
version = "0.0.1"
version = "0.1.0"
authors = ["Interlay Ltd"]
edition = "2018"

Expand Down
49 changes: 26 additions & 23 deletions crates/btc-relay/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ decl_storage! {
BlockHeaders: map hasher(blake2_128_concat) H256Le => RichBlockHeader;

/// Sorted mapping of BlockChain elements with reference to ChainsIndex
Chains: map hasher(blake2_128_concat) u32 => u32;
Chains: map hasher(blake2_128_concat) u32 => Option<u32>;

/// Store the index for each tracked blockchain
ChainsIndex: map hasher(blake2_128_concat) u32 => Option<BlockChain>;
Expand Down Expand Up @@ -399,18 +399,9 @@ impl<T: Trait> Module<T> {
) -> Result<(), Error> {
Self::transaction_verification_allowed(block_height)?;

//let main_chain = Self::get_block_chain_from_id(MAIN_CHAIN_ID);
let best_block_height = Self::get_best_block_height();

let next_best_fork_id = Self::get_chain_id_from_position(1);
let next_best_fork_chain = Self::get_block_chain_from_id(next_best_fork_id)?;
let next_best_fork_height = next_best_fork_chain.max_height;

// fail if there is an ongoing fork
ensure!(
best_block_height >= next_best_fork_height + Self::confirmations(),
Error::OngoingFork
);
Self::ensure_no_ongoing_fork(best_block_height)?;

// This call fails if not enough confirmations
Self::check_confirmations(best_block_height, confirmations, block_height, insecure)?;
Expand Down Expand Up @@ -471,8 +462,8 @@ impl<T: Trait> Module<T> {
// ********************************

/// Get chain id from position (sorted by max block height)
fn get_chain_id_from_position(position: u32) -> u32 {
<Chains>::get(position)
fn get_chain_id_from_position(position: u32) -> Result<u32, Error> {
<Chains>::get(position).ok_or(Error::InvalidChainID)
}
/// Get the position of the fork in Chains
fn get_chain_position_from_chain_id(chain_id: u32) -> Result<u32, Error> {
Expand All @@ -483,16 +474,7 @@ impl<T: Trait> Module<T> {
}
Err(Error::ForkIdNotFound)
}
// match <Chains>::enumerate()
// .position(|(_k, v)| v == chain_id)
// {
// Some(pos) => return Ok(pos as u32),
// None => return Err(Error::ForkIdNotFound),
// };
//}
/// Get a blockchain from the id
// TODO: the return of this element can an empty element when it was deleted
// Function should be changed to return a Result or Option
fn get_block_chain_from_id(chain_id: u32) -> Result<BlockChain, Error> {
<ChainsIndex>::get(chain_id).ok_or(Error::InvalidChainID)
}
Expand Down Expand Up @@ -904,7 +886,7 @@ impl<T: Trait> Module<T> {
// get the previous position
let prev_position = current_position - 1;
// get the blockchain id
let prev_blockchain_id = Self::get_chain_id_from_position(prev_position);
let prev_blockchain_id = Self::get_chain_id_from_position(prev_position)?;
// get the previous blockchain height
let prev_height = Self::get_block_chain_from_id(prev_blockchain_id)?.max_height;
// swap elements if block height is greater
Expand Down Expand Up @@ -1139,6 +1121,27 @@ impl<T: Trait> Module<T> {
}
Ok(())
}

fn ensure_no_ongoing_fork(best_block_height: u32) -> UnitResult {
// check if there is a next best fork
match Self::get_chain_id_from_position(1) {
// if yes, check that the main chain is at least Self::confirmations() ahead
Ok(id) => {
let next_best_fork_height = Self::get_block_chain_from_id(id)?.max_height;

debug::print!("Best block height: {}", best_block_height);
debug::print!("Next best fork height: {}", next_best_fork_height);
// fail if there is an ongoing fork
ensure!(
best_block_height >= next_best_fork_height + Self::confirmations(),
Error::OngoingFork
);
}
// else, do nothing if there is no fork
Err(_) => {}
}
Ok(())
}
}

decl_event! {
Expand Down
60 changes: 57 additions & 3 deletions crates/btc-relay/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ fn next_best_fork_chain_succeeds() {
})
}

#[test]
fn test_get_block_chain_from_id_empty_chain_fails() {
run_test(|| {
assert_err!(BTCRelay::get_block_chain_from_id(1), Error::InvalidChainID);
})
}

/// # Main functions
///
/// initialize
Expand Down Expand Up @@ -1225,7 +1232,7 @@ fn test_verify_transaction_inclusion_succeeds() {
get_empty_block_chain_from_chain_id_and_height(fork_ref, start, fork_chain_height);

BTCRelay::get_chain_id_from_position
.mock_safe(move |_| MockResult::Return(fork_ref.clone()));
.mock_safe(move |_| MockResult::Return(Ok(fork_ref.clone())));
BTCRelay::get_block_chain_from_id.mock_safe(move |id| {
if id == chain_ref.clone() {
return MockResult::Return(Ok(main.clone()));
Expand Down Expand Up @@ -1254,6 +1261,52 @@ fn test_verify_transaction_inclusion_succeeds() {
});
}

#[test]
fn test_verify_transaction_inclusion_empty_fork_succeeds() {
run_test(|| {
let chain_ref = 0;
let block_height = 203;
let start = 10;
let main_chain_height = 300;
// Random init since we mock this
let raw_merkle_proof = vec![0u8; 100];
let confirmations = 0;
let insecure = false;
let rich_block_header = sample_rich_tx_block_header(chain_ref, main_chain_height);

let proof_result = sample_valid_proof_result();

let main =
get_empty_block_chain_from_chain_id_and_height(chain_ref, start, main_chain_height);

BTCRelay::get_block_chain_from_id.mock_safe(move |id| {
if id == chain_ref.clone() {
return MockResult::Return(Ok(main.clone()));
} else {
return MockResult::Return(Err(Error::InvalidChainID));
}
});

BTCRelay::get_best_block_height.mock_safe(move || MockResult::Return(main_chain_height));

BTCRelay::verify_merkle_proof.mock_safe(move |_| MockResult::Return(Ok(proof_result)));

BTCRelay::get_block_header_from_height
.mock_safe(move |_, _| MockResult::Return(Ok(rich_block_header)));

BTCRelay::check_confirmations.mock_safe(|_, _, _, _| MockResult::Return(Ok(())));

assert_ok!(BTCRelay::verify_transaction_inclusion(
Origin::signed(3),
proof_result.transaction_hash,
block_height,
raw_merkle_proof,
confirmations,
insecure
));
});
}

#[test]
fn test_verify_transaction_inclusion_invalid_tx_id_fails() {
run_test(|| {
Expand Down Expand Up @@ -1286,7 +1339,7 @@ fn test_verify_transaction_inclusion_invalid_tx_id_fails() {
get_empty_block_chain_from_chain_id_and_height(fork_ref, start, fork_chain_height);

BTCRelay::get_chain_id_from_position
.mock_safe(move |_| MockResult::Return(fork_ref.clone()));
.mock_safe(move |_| MockResult::Return(Ok(fork_ref.clone())));
BTCRelay::get_block_chain_from_id.mock_safe(move |id| {
if id == chain_ref.clone() {
return MockResult::Return(Ok(main.clone()));
Expand Down Expand Up @@ -1351,7 +1404,7 @@ fn test_verify_transaction_inclusion_invalid_merkle_root_fails() {
get_empty_block_chain_from_chain_id_and_height(fork_ref, start, fork_chain_height);

BTCRelay::get_chain_id_from_position
.mock_safe(move |_| MockResult::Return(fork_ref.clone()));
.mock_safe(move |_| MockResult::Return(Ok(fork_ref.clone())));
BTCRelay::get_block_chain_from_id.mock_safe(move |id| {
if id == chain_ref.clone() {
return MockResult::Return(Ok(main.clone()));
Expand Down Expand Up @@ -1386,6 +1439,7 @@ fn test_verify_transaction_inclusion_invalid_merkle_root_fails() {
#[test]
fn test_verify_transaction_inclusion_fails_with_ongoing_fork() {
run_test(|| {
BTCRelay::get_chain_id_from_position.mock_safe(|_| MockResult::Return(Ok(1)));
BTCRelay::get_block_chain_from_id
.mock_safe(|_| MockResult::Return(Ok(BlockChain::default())));

Expand Down
2 changes: 1 addition & 1 deletion crates/exchange-rate-oracle/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "exchange-rate-oracle"
version = "0.0.1"
version = "0.1.0"
authors = ["Interlay Ltd"]
edition = "2018"

Expand Down
7 changes: 0 additions & 7 deletions crates/issue/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,6 @@ impl<T: Trait> Module<T> {
let btc_address =
ext::vault_registry::increase_to_be_issued_tokens::<T>(&vault_id, amount)?;

//let mut hasher = Sha256::default();
// TODO: nonce from security module
//hasher.input(requester.encode());
//let mut result = [0; 32];
//result.copy_from_slice(&hasher.result()[..]);
//let key = H256(result);

let key = ext::security::get_secure_id::<T>(&requester);

Self::insert_issue_request(
Expand Down
2 changes: 1 addition & 1 deletion crates/vault-registry/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "vault-registry"
version = "0.0.1"
version = "0.1.0"
authors = ["Interlay Ltd"]
edition = "2018"

Expand Down
11 changes: 6 additions & 5 deletions parachain/runtime/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,12 @@ pub fn force_issue_tokens(
}

fn assert_store_main_chain_header_event(height: u32, hash: H256Le) {
let _store_event = Event::btc_relay(BTCRelayEvent::StoreMainChainHeader(height, hash));
let _events = SystemModule::events();
let store_event = Event::btc_relay(BTCRelayEvent::StoreMainChainHeader(height, hash));
let events = SystemModule::events();

// FIXME: store only main chain header
// assert!(events.iter().any(|a| a.event == store_event));
// store only main chain header
// events.iter().for_each(|a| println!("{:?}",a.event));
assert!(events.iter().any(|a| a.event == store_event));
}

#[allow(dead_code)]
Expand Down Expand Up @@ -208,7 +209,7 @@ impl ExtBuilder {
.assimilate_storage(&mut storage)
.unwrap();

btc_relay::GenesisConfig { confirmations: 0 }
btc_relay::GenesisConfig { confirmations: 6 }
.assimilate_storage(&mut storage)
.unwrap();

Expand Down
1 change: 1 addition & 0 deletions parachain/runtime/tests/test_issue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ fn integration_test_issue_polka_btc() {

SystemModule::set_block_number(5);

// alice executes the issue by confirming the btc transaction
assert_ok!(IssueCall::execute_issue(id, tx_id, height, proof, raw_tx)
.dispatch(origin_of(account_of(ALICE))));
});
Expand Down

0 comments on commit 1448891

Please sign in to comment.