Problem: integration tests won't compile or pass

Solution: map it to the API used in bridge.sol
This commit is contained in:
Yurii Rashkovskii 2018-03-02 09:02:33 +07:00
parent ee633d18a2
commit d9bc432ab8
No known key found for this signature in database
GPG Key ID: 1D60D7CFD80845FF
6 changed files with 176 additions and 44 deletions

4
Cargo.lock generated
View File

@ -308,10 +308,14 @@ name = "integration-tests"
version = "0.1.0"
dependencies = [
"bridge 0.1.0",
"ethabi 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi-contract 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ethabi-derive 5.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ethereum-types 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -1,2 +1,3 @@
use_contract!(home, "HomeBridge", "../compiled_contracts/HomeBridge.abi");
use_contract!(foreign, "ForeignBridge", "../compiled_contracts/ForeignBridge.abi");
use_contract!(erc20, "ERC20", "../compiled_contracts/ERC20.abi");

View File

@ -263,3 +263,10 @@ contract BridgeableToken is MintableToken {
return true;
}
}
// For test purposes
contract Token is BridgeableToken {
function Token() {
}
}

View File

@ -292,6 +292,7 @@ contract ERC20 {
function transfer(address to, uint256 value) public returns (bool);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function allowance(address owner, address spender) public constant returns (uint256);
function balanceOf(address tokenOwner) public constant returns (uint balance);
}
contract ForeignBridge {

View File

@ -13,3 +13,7 @@ pretty_assertions = "0.2.1"
tempdir = "0.3.5"
ethereum-types = "0.2"
tokio-core = "0.1.8"
ethabi = "5.1"
ethabi-contract = "5.0"
ethabi-derive = "5.0"
rustc-hex = "1.0"

View File

@ -10,6 +10,11 @@ extern crate ethereum_types;
extern crate web3;
extern crate tokio_core;
extern crate bridge;
extern crate ethabi;
#[macro_use] extern crate ethabi_contract;
#[macro_use] extern crate ethabi_derive;
use_contract!(token, "Token", "../compiled_contracts/Token.abi");
use std::process::Command;
use std::time::Duration;
@ -22,6 +27,9 @@ use web3::transports::ipc::Ipc;
use web3::api::Namespace;
use ethereum_types::{Address, U256};
extern crate rustc_hex;
use rustc_hex::FromHex;
const TMP_PATH: &str = "tmp";
fn parity_home_command() -> Command {
@ -165,6 +173,132 @@ fn test_basic_deposit_then_withdraw() {
let home_contract_address = "0xebd3944af37ccc6b67ff61239ac4fef229c8f69f";
let foreign_contract_address = "0xebd3944af37ccc6b67ff61239ac4fef229c8f69f";
// connect to foreign and home via IPC
let mut event_loop = Core::new().unwrap();
let foreign_transport = Ipc::with_event_loop("foreign.ipc", &event_loop.handle())
.expect("failed to connect to foreign.ipc");
let foreign = bridge::contracts::foreign::ForeignBridge::default();
let foreign_eth = web3::api::Eth::new(foreign_transport);
let home_transport = Ipc::with_event_loop("home.ipc", &event_loop.handle())
.expect("failed to connect to home.ipc");
let home_eth = web3::api::Eth::new(home_transport);
// deploy the token
println!("== deploy the token");
let token_constructor = token::Token::default().constructor(include_str!("../../compiled_contracts/Token.bin").from_hex().unwrap());
let future = foreign_eth.send_transaction(web3::types::TransactionRequest {
from: address_from_str(authority_address),
to: None,
gas: None,
gas_price: None,
value: None,
data: Some(token_constructor.into()),
condition: None,
nonce: None,
});
let tx = event_loop.run(future).unwrap();
let future = foreign_eth.transaction_receipt(tx);
let token_receipt = event_loop.run(future).unwrap();
let token_addr = token_receipt.unwrap().contract_address.unwrap();
// check token validity
let is_token = token::Token::default().functions().is_token().input();
let future = foreign_eth.call(web3::types::CallRequest {
from: None,
to: token_addr,
gas: None,
gas_price: None,
value: None,
data: Some(web3::types::Bytes(is_token)),
}, None);
event_loop.run(future).unwrap();
// set the token
println!("== set the token");
let set_token = foreign.functions().set_token_address().input(token_addr);
let future = foreign_eth.send_transaction(web3::types::TransactionRequest {
from: address_from_str(authority_address),
to: Some(address_from_str(foreign_contract_address)),
gas: None,
gas_price: None,
value: None,
data: Some(web3::types::Bytes(set_token)),
condition: None,
nonce: None,
});
event_loop.run(future).unwrap();
// check that the token has been set correctly
println!("== check token setup");
let token = foreign.functions().erc20token().input();
let future = foreign_eth.call(web3::types::CallRequest {
from: None,
to: address_from_str(foreign_contract_address),
gas: None,
gas_price: None,
value: None,
data: Some(web3::types::Bytes(token)),
}, None);
let response = event_loop.run(future).unwrap();
assert_eq!(Address::from(&response.0.as_slice()[(response.0.len()-20)..]), token_addr);
let erc20 = bridge::contracts::erc20::ERC20::default();
// fund the contract
println!("== set mint agent");
let set_mint_agent = token::Token::default().functions().set_mint_agent().input(address_from_str(authority_address), true);
let future = foreign_eth.send_transaction(web3::types::TransactionRequest {
from: address_from_str(authority_address),
to: Some(token_addr),
gas: None,
gas_price: None,
value: None,
data: Some(web3::types::Bytes(set_mint_agent)),
condition: None,
nonce: None,
});
event_loop.run(future).unwrap();
println!("== fund contract through minting");
let fund = token::Token::default().functions().mint().input(address_from_str(foreign_contract_address), ::std::u32::MAX);
let future = foreign_eth.send_transaction(web3::types::TransactionRequest {
from: address_from_str(authority_address),
to: Some(token_addr),
gas: None,
gas_price: None,
value: None,
data: Some(web3::types::Bytes(fund)),
condition: None,
nonce: None,
});
event_loop.run(future).unwrap();
println!("== check token supply");
let supply_payload = token::Token::default().functions().total_supply().input();
let supply_call = web3::types::CallRequest {
from: None,
to: token_addr,
gas: None,
gas_price: None,
value: None,
data: Some(web3::types::Bytes(supply_payload)),
};
assert!(!U256::from(event_loop.run(foreign_eth.call(supply_call, None)).unwrap().0.as_slice()).is_zero());
println!("== check contract balance");
let balance_payload = erc20.functions().balance_of().input(address_from_str(foreign_contract_address));
let balance_call = web3::types::CallRequest {
from: None,
to: token_addr,
gas: None,
gas_price: None,
value: None,
data: Some(web3::types::Bytes(balance_payload)),
};
assert!(!U256::from(event_loop.run(foreign_eth.call(balance_call, None)).unwrap().0.as_slice()).is_zero());
println!("\nuser deposits ether into HomeBridge\n");
// TODO [snd] use rpc client here instead of curl
@ -184,48 +318,27 @@ fn test_basic_deposit_then_withdraw() {
println!("\ndeposit into home sent. give it plenty of time to get mined and relayed\n");
thread::sleep(Duration::from_millis(10000));
// connect to foreign and home via IPC
let mut event_loop = Core::new().unwrap();
let foreign_transport = Ipc::with_event_loop("foreign.ipc", &event_loop.handle())
.expect("failed to connect to foreign.ipc");
let foreign = bridge::contracts::foreign::ForeignBridge::default();
let foreign_eth = web3::api::Eth::new(foreign_transport);
let home_transport = Ipc::with_event_loop("home.ipc", &event_loop.handle())
.expect("failed to connect to home.ipc");
let home_eth = web3::api::Eth::new(home_transport);
// totalSupply on ForeignBridge should have increased
let total_supply_payload = foreign.functions().total_supply().input();
let future = foreign_eth.call(web3::types::CallRequest{
from: None,
to: address_from_str(foreign_contract_address),
gas: None,
gas_price: None,
value: None,
data: Some(web3::types::Bytes(total_supply_payload)),
}, None);
let response = event_loop.run(future).unwrap();
assert_eq!(
U256::from(response.0.as_slice()),
U256::from(100000),
"totalSupply on ForeignBridge should have increased");
// balance on ForeignBridge should have increased
let balance_payload = foreign.functions().balance_of().input(Address::from(user_address));
let balance_payload = erc20.functions().balance_of().input(Address::from(user_address));
let balance_call = web3::types::CallRequest {
from: None,
to: token_addr,
gas: None,
gas_price: None,
value: None,
data: Some(web3::types::Bytes(balance_payload)),
};
let balance = loop {
thread::sleep(Duration::from_secs(1));
let future = foreign_eth.call(balance_call.clone(), None);
let response = event_loop.run(future).unwrap();
let balance = U256::from(response.0.as_slice());
let future = foreign_eth.call(web3::types::CallRequest{
from: None,
to: address_from_str(foreign_contract_address),
gas: None,
gas_price: None,
value: None,
data: Some(web3::types::Bytes(balance_payload)),
}, None);
let response = event_loop.run(future).unwrap();
let balance = U256::from(response.0.as_slice());
// wait until balance is above zero
if balance > U256::from(0) {
break balance;
}
};
assert_eq!(
balance,
U256::from(100000),
@ -233,13 +346,15 @@ fn test_basic_deposit_then_withdraw() {
println!("\nconfirmed that deposit reached foreign\n");
println!("\nuser executes ForeignBridge.transferHomeViaRelay\n");
println!("\nuser executes ForeignBridge.receiveApproval(\n");
let transfer_payload = foreign.functions()
.transfer_home_via_relay()
.receive_approval()
.input(
Address::from(user_address),
U256::from(100000),
U256::from(0));
token_addr, // FIXME: doesn't seem to be used
vec![], // FIXME: doesn't seem to be used either
);
let future = foreign_eth.send_transaction(web3::types::TransactionRequest{
from: address_from_str(user_address),
to: Some(address_from_str(foreign_contract_address)),
@ -252,7 +367,7 @@ fn test_basic_deposit_then_withdraw() {
});
event_loop.run(future).unwrap();
println!("\nForeignBridge.transferHomeViaRelay transaction sent. give it plenty of time to get mined and relayed\n");
println!("\nForeignBridge.receiveApproval sent. give it plenty of time to get mined and relayed\n");
thread::sleep(Duration::from_millis(10000));
// test that withdraw completed