Merge pull request #95 from paritytech/snd-integration-tests

fix for #87 & integration tests to prevent regression
This commit is contained in:
Marek Kotewicz 2018-01-24 10:26:08 +01:00 committed by GitHub
commit 7d9a875cab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 809 additions and 319 deletions

2
.gitignore vendored
View File

@ -22,3 +22,5 @@ truffle/build
node_modules
compiled_contracts
integration-tests/tmp

View File

@ -13,8 +13,13 @@ matrix:
- sudo add-apt-repository ppa:ethereum/ethereum -y
- sudo apt-get update -y
- sudo apt-get install solc -y
- wget https://parity-downloads-mirror.parity.io/v1.8.6/x86_64-unknown-linux-gnu/parity
- chmod +x parity
- cp parity ${HOME}/bin
- export PATH=${HOME}/bin:${PATH}
- cd integration-tests
script:
- cargo test --all
- env BACKTRACE=1 cargo test --all -- --nocapture
- language: rust
rust: beta
cache: cargo
@ -23,8 +28,13 @@ matrix:
- sudo add-apt-repository ppa:ethereum/ethereum -y
- sudo apt-get update -y
- sudo apt-get install solc -y
- wget https://parity-downloads-mirror.parity.io/v1.8.6/x86_64-unknown-linux-gnu/parity
- chmod +x parity
- cp parity ${HOME}/bin
- export PATH=${HOME}/bin:${PATH}
- cd integration-tests
script:
- cargo test --all
- env BACKTRACE=1 cargo test --all -- --nocapture
- language: rust
rust: nightly
cache: cargo
@ -33,8 +43,13 @@ matrix:
- sudo add-apt-repository ppa:ethereum/ethereum -y
- sudo apt-get update -y
- sudo apt-get install solc -y
- wget https://parity-downloads-mirror.parity.io/v1.8.6/x86_64-unknown-linux-gnu/parity
- chmod +x parity
- cp parity ${HOME}/bin
- export PATH=${HOME}/bin:${PATH}
- cd integration-tests
script:
- cargo test --all
- env BACKTRACE=1 cargo test --all -- --nocapture
- language: node_js
node_js: node
cache: yarn

704
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1,2 @@
[workspace]
members = ["tests", "cli", "bridge"]
members = ["tests", "cli", "bridge", "integration-tests"]

View File

@ -13,9 +13,9 @@ tokio-timer = "0.1.2"
toml = "0.4.2"
web3 = { git = "https://github.com/tomusdrw/rust-web3", branch = "bridge" }
error-chain = "0.11.0-rc.2"
ethabi = "4.0"
ethabi-derive = "4.0"
ethabi-contract = "4.0"
ethabi = "5.0"
ethabi-derive = "5.0"
ethabi-contract = "5.0"
rustc-hex = "1.0"
log = "0.3"

View File

@ -32,8 +32,10 @@ fn withdraw_confirm_sign_payload(foreign: &foreign::ForeignBridge, log: Log) ->
Ok(result.into())
}
fn withdraw_submit_signature_payload(foreign: &foreign::ForeignBridge, withdraw_payload: Bytes, signature: H520) -> Bytes {
foreign.functions().submit_signature().input(signature.to_vec(), withdraw_payload.0).into()
fn withdraw_submit_signature_payload(foreign: &foreign::ForeignBridge, withdraw_message: Bytes, signature: H520) -> Bytes {
assert_eq!(signature.0.len(), 65);
assert_eq!(withdraw_message.0.len(), 84, "ForeignBridge never accepts messages with len != 84 bytes; qed");
foreign.functions().submit_signature().input(signature.0.to_vec(), withdraw_message.0).into()
}
/// State of withdraw confirmation.
@ -88,9 +90,13 @@ impl<T: Transport> Stream for WithdrawConfirm<T> {
let next_state = match self.state {
WithdrawConfirmState::Wait => {
let item = try_stream!(self.logs.poll());
info!("got {} new withdraws to sign", item.logs.len());
let withdraws = item.logs
.into_iter()
.map(|log| withdraw_confirm_sign_payload(&self.app.foreign_bridge, log))
.map(|log| {
info!("withdraw is ready for signature submission. tx hash {}", log.transaction_hash.unwrap());
withdraw_confirm_sign_payload(&self.app.foreign_bridge, log)
})
.collect::<Result<Vec<_>, _>>()?;
let requests = withdraws.clone()
@ -102,6 +108,7 @@ impl<T: Transport> Stream for WithdrawConfirm<T> {
})
.collect::<Vec<_>>();
info!("signing");
WithdrawConfirmState::SignWithdraws {
future: join_all(requests),
withdraws: withdraws,
@ -110,13 +117,14 @@ impl<T: Transport> Stream for WithdrawConfirm<T> {
},
WithdrawConfirmState::SignWithdraws { ref mut future, ref mut withdraws, block } => {
let signatures = try_ready!(future.poll());
info!("signing complete");
// borrow checker...
let app = &self.app;
let foreign_contract = &self.foreign_contract;
let confirmations = withdraws
.drain(ops::RangeFull)
.zip(signatures.into_iter())
.map(|(withdraw, signature)| withdraw_submit_signature_payload(&app.foreign_bridge, withdraw, signature))
.map(|(withdraw_message, signature)| withdraw_submit_signature_payload(&app.foreign_bridge, withdraw_message, signature))
.map(|payload| TransactionRequest {
from: app.config.foreign.account.clone(),
to: Some(foreign_contract.clone()),
@ -128,12 +136,14 @@ impl<T: Transport> Stream for WithdrawConfirm<T> {
condition: None,
})
.map(|request| {
info!("submitting signature");
app.timer.timeout(
api::send_transaction(&app.connections.foreign, request),
app.config.foreign.request_timeout)
})
.collect::<Vec<_>>();
info!("submitting {} signatures", confirmations.len());
WithdrawConfirmState::ConfirmWithdraws {
future: join_all(confirmations),
block,
@ -141,10 +151,14 @@ impl<T: Transport> Stream for WithdrawConfirm<T> {
},
WithdrawConfirmState::ConfirmWithdraws { ref mut future, block } => {
let _ = try_ready!(future.poll());
info!("submitting signatures complete");
WithdrawConfirmState::Yield(Some(block))
},
WithdrawConfirmState::Yield(ref mut block) => match block.take() {
None => WithdrawConfirmState::Wait,
None => {
info!("waiting for new withdraws that should get signed");
WithdrawConfirmState::Wait
},
some => return Ok(some.into()),
}
};

View File

@ -11,6 +11,7 @@ use contracts::{home, foreign};
use util::web3_filter;
use database::Database;
use error::{self, Error};
use rustc_hex::ToHex;
/// returns a filter for `ForeignBridge.CollectedSignatures` events
fn collected_signatures_filter(foreign: &foreign::ForeignBridge, address: Address) -> FilterBuilder {
@ -37,6 +38,7 @@ fn signatures_payload(foreign: &foreign::ForeignBridge, required_signatures: u32
};
let collected_signatures = foreign.events().collected_signatures().parse_log(raw_log)?;
if collected_signatures.authority != my_address.0 {
info!("bridge not responsible for relaying transaction to home. tx hash: {}", log.transaction_hash.unwrap());
// this authority is not responsible for relaying this transaction.
// someone else will relay this transaction to home.
return Ok(None);
@ -90,7 +92,10 @@ fn withdraw_relay_payload(home: &home::HomeBridge, signatures: &[Bytes], message
pub enum WithdrawRelayState<T: Transport> {
Wait,
FetchMessagesSignatures {
future: Join<JoinAll<Vec<Timeout<ApiCall<Bytes, T::Out>>>>, JoinAll<Vec<JoinAll<Vec<Timeout<ApiCall<Bytes, T::Out>>>>>>>,
future: Join<
JoinAll<Vec<Timeout<ApiCall<Bytes, T::Out>>>>,
JoinAll<Vec<JoinAll<Vec<Timeout<ApiCall<Bytes, T::Out>>>>>>
>,
block: u64,
},
FetchMessageValueSufficient {
@ -141,13 +146,17 @@ impl<T: Transport> Stream for WithdrawRelay<T> {
let next_state = match self.state {
WithdrawRelayState::Wait => {
let item = try_stream!(self.logs.poll());
info!("got {} new signed withdraws to relay", item.logs.len());
let assignments = item.logs
.into_iter()
.map(|log| signatures_payload(
.map(|log| {
info!("collected signature is ready for relay: tx hash: {}", log.transaction_hash.unwrap());
signatures_payload(
&self.app.foreign_bridge,
self.app.config.authorities.required_signatures,
self.app.config.foreign.account.clone(),
log))
log)
})
.collect::<error::Result<Vec<_>>>()?;
let (signatures, messages): (Vec<_>, Vec<_>) = assignments.into_iter()
@ -176,19 +185,41 @@ impl<T: Transport> Stream for WithdrawRelay<T> {
.map(|calls| join_all(calls))
.collect::<Vec<_>>();
// wait for fetching of messages and signatures to complete
info!("fetching messages and signatures");
WithdrawRelayState::FetchMessagesSignatures {
future: join_all(message_calls).join(join_all(signature_calls)),
block: item.to,
}
},
WithdrawRelayState::FetchMessagesSignatures { ref mut future, block } => {
let (messages, signatures) = try_ready!(future.poll());
assert_eq!(messages.len(), signatures.len());
let (messages_raw, signatures_raw) = try_ready!(future.poll());
info!("fetching messages and signatures complete");
assert_eq!(messages_raw.len(), signatures_raw.len());
let app = &self.app;
let home_contract = &self.home_contract;
let messages = messages_raw
.iter()
.map(|message| {
app.foreign_bridge.functions().message().output(message.0.as_slice()).map(Bytes)
})
.collect::<ethabi::Result<Vec<_>>>()
.map_err(error::Error::from)?;
let signatures = signatures_raw
.iter()
.map(|signatures|
signatures.iter().map(
|signature| {
app.foreign_bridge.functions().signature().output(signature.0.as_slice()).map(Bytes)
}
)
.collect::<ethabi::Result<Vec<_>>>()
.map_err(error::Error::from)
)
.collect::<error::Result<Vec<_>>>()?;
let message_value_sufficient_payloads = messages
.iter()
.map(|message| {
@ -204,6 +235,7 @@ impl<T: Transport> Stream for WithdrawRelay<T> {
})
.collect::<Vec<_>>();
info!("fetching whether message values are sufficent");
WithdrawRelayState::FetchMessageValueSufficient {
future: join_all(message_value_sufficient_payloads),
messages,
@ -218,6 +250,7 @@ impl<T: Transport> Stream for WithdrawRelay<T> {
block
} => {
let message_value_sufficient = try_ready!(future.poll());
info!("fetching whether message values are sufficent complete");
let app = &self.app;
let home_contract = &self.home_contract;
@ -227,12 +260,16 @@ impl<T: Transport> Stream for WithdrawRelay<T> {
.zip(message_value_sufficient.into_iter())
// ignore those messages that don't have sufficient
// value to pay for the relay gas cost
.filter(|&(_, ref is_message_value_sufficient)| {
.filter(|&((ref message, _), ref is_message_value_sufficient)| {
// TODO [snd] this is ugly.
// in the future ethabi should return a bool
// for `is_message_value_sufficient`
// since the contract function returns a bool
U256::from(is_message_value_sufficient.0.as_slice()) == U256::from(1)
let is_sufficient = U256::from(is_message_value_sufficient.0.as_slice()) == U256::from(1);
if !is_sufficient {
info!("value in message is not sufficient to cover relay costs. ignoring. message: {}", message.0.to_hex());
}
is_sufficient
})
.map(|((message, signatures), _)| withdraw_relay_payload(&app.home_bridge, &signatures, message))
.map(|payload| TransactionRequest {
@ -251,7 +288,7 @@ impl<T: Transport> Stream for WithdrawRelay<T> {
app.config.home.request_timeout)
})
.collect::<Vec<_>>();
// wait for relays to complete
info!("relaying {} withdraws", relays.len());
WithdrawRelayState::RelayWithdraws {
future: join_all(relays),
block,
@ -259,10 +296,14 @@ impl<T: Transport> Stream for WithdrawRelay<T> {
},
WithdrawRelayState::RelayWithdraws { ref mut future, block } => {
let _ = try_ready!(future.poll());
info!("relaying withdraws complete");
WithdrawRelayState::Yield(Some(block))
},
WithdrawRelayState::Yield(ref mut block) => match block.take() {
None => WithdrawRelayState::Wait,
None => {
info!("waiting for signed withdraws to relay");
WithdrawRelayState::Wait
},
some => return Ok(some.into()),
}
};

View File

@ -0,0 +1,15 @@
[package]
name = "integration-tests"
version = "0.1.0"
authors = ["snd <kruemaxi@gmail.com>"]
[dependencies]
bridge = { path = "../bridge" }
futures = "0.1"
jsonrpc-core = "7.0"
web3 = { git = "https://github.com/tomusdrw/rust-web3", branch = "bridge" }
serde_json = "1.0"
pretty_assertions = "0.2.1"
tempdir = "0.3.5"
ethereum-types = { git = "https://github.com/paritytech/primitives.git" }
tokio-core = "0.1.8"

View File

@ -0,0 +1,30 @@
estimated_gas_cost_of_withdraw = 0
[home]
account = "0x00bd138abd70e2f00903268f3db08f2d25677c9e"
ipc = "./home.ipc"
required_confirmations = 0
[home.contract]
bin = "../compiled_contracts/HomeBridge.bin"
[foreign]
account = "0x00bd138abd70e2f00903268f3db08f2d25677c9e"
ipc = "./foreign.ipc"
required_confirmations = 0
[foreign.contract]
bin = "../compiled_contracts/ForeignBridge.bin"
[authorities]
accounts = [
"0x00bd138abd70e2f00903268f3db08f2d25677c9e",
]
required_signatures = 1
[transactions]
home_deploy = { gas = 1000000 }
foreign_deploy = { gas = 3000000 }
deposit_relay = { gas = 100000 }
withdraw_relay = { gas = 3000000 }
withdraw_confirm = { gas = 3000000 }

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,238 @@
/// spins up two parity nodes with the dev chain.
/// starts one bridge authority that connects the two.
/// does a deposit by sending ether to the HomeBridge.
/// asserts that the deposit got relayed to foreign chain.
/// does a withdraw by executing ForeignBridge.transferToHomeBridge.
/// asserts that the withdraw got relayed to home chain.
extern crate tempdir;
extern crate ethereum_types;
extern crate web3;
extern crate tokio_core;
extern crate bridge;
use std::process::Command;
use std::time::Duration;
use std::thread;
use std::path::Path;
use tokio_core::reactor::Core;
use web3::transports::ipc::Ipc;
use web3::api::Namespace;
use ethereum_types::{Address, U256};
const TMP_PATH: &str = "tmp";
fn parity_home_command() -> Command {
let mut command = Command::new("parity");
command
.arg("--base-path").arg(format!("{}/home", TMP_PATH))
.arg("--chain").arg("dev")
.arg("--ipc-path").arg("home.ipc")
.arg("--logging").arg("rpc=trace")
.arg("--jsonrpc-port").arg("8550")
.arg("--jsonrpc-apis").arg("all")
.arg("--port").arg("30310")
.arg("--gasprice").arg("0")
.arg("--reseal-min-period").arg("0")
.arg("--no-ws")
.arg("--no-dapps")
.arg("--no-ui");
command
}
fn parity_foreign_command() -> Command {
let mut command = Command::new("parity");
command
.arg("--base-path").arg(format!("{}/foreign", TMP_PATH))
.arg("--chain").arg("dev")
.arg("--ipc-path").arg("foreign.ipc")
.arg("--logging").arg("rpc=trace")
.arg("--jsonrpc-port").arg("8551")
.arg("--jsonrpc-apis").arg("all")
.arg("--port").arg("30311")
.arg("--gasprice").arg("0")
.arg("--reseal-min-period").arg("0")
.arg("--no-ws")
.arg("--no-dapps")
.arg("--no-ui");
command
}
#[test]
fn test_basic_deposit_then_withdraw() {
if Path::new(TMP_PATH).exists() {
std::fs::remove_dir_all(TMP_PATH).expect("failed to remove tmp dir");
}
let _tmp_dir = tempdir::TempDir::new(TMP_PATH).expect("failed to create tmp dir");
println!("\nbuild the bridge cli executable so we can run it later\n");
assert!(Command::new("cargo")
.env("RUST_BACKTRACE", "1")
.current_dir("../cli")
.arg("build")
.status()
.expect("failed to build bridge cli")
.success());
// start a parity node that represents the home chain
let mut parity_home = parity_home_command()
.spawn()
.expect("failed to spawn parity home node");
// start a parity node that represents the foreign chain
let mut parity_foreign = parity_foreign_command()
.spawn()
.expect("failed to spawn parity foreign node");
// give the clients time to start up
thread::sleep(Duration::from_millis(3000));
// create authority account on home
let exit_status = Command::new("curl")
.arg("--data").arg(r#"{"jsonrpc":"2.0","method":"parity_newAccountFromPhrase","params":["node0", ""],"id":0}"#)
.arg("-H").arg("Content-Type: application/json")
.arg("-X").arg("POST")
.arg("localhost:8550")
.status()
.expect("failed to create authority account on home");
assert!(exit_status.success());
// create authority account on foreign
let exit_status = Command::new("curl")
.arg("--data").arg(r#"{"jsonrpc":"2.0","method":"parity_newAccountFromPhrase","params":["node0", ""],"id":0}"#)
.arg("-H").arg("Content-Type: application/json")
.arg("-X").arg("POST")
.arg("localhost:8551")
.status()
.expect("failed to create/unlock authority account on foreign");
assert!(exit_status.success());
// give the operations time to complete
thread::sleep(Duration::from_millis(5000));
// kill the clients so we can restart them with the accounts unlocked
parity_home.kill().unwrap();
parity_foreign.kill().unwrap();
// wait for clients to shut down
thread::sleep(Duration::from_millis(5000));
// start a parity node that represents the home chain with accounts unlocked
let mut parity_home = parity_home_command()
.arg("--unlock").arg("0x00a329c0648769a73afac7f9381e08fb43dbea72,0x00bd138abd70e2f00903268f3db08f2d25677c9e")
.arg("--password").arg("password.txt")
.spawn()
.expect("failed to spawn parity home node");
// start a parity node that represents the foreign chain with accounts unlocked
let mut parity_foreign = parity_foreign_command()
.arg("--unlock").arg("0x00a329c0648769a73afac7f9381e08fb43dbea72,0x00bd138abd70e2f00903268f3db08f2d25677c9e")
.arg("--password").arg("password.txt")
.spawn()
.expect("failed to spawn parity foreign node");
// give nodes time to start up
thread::sleep(Duration::from_millis(10000));
// start bridge authority 1
let mut bridge1 = Command::new("env")
.arg("RUST_BACKTRACE=1")
.arg("../target/debug/bridge")
.env("RUST_LOG", "info")
.arg("--config").arg("bridge_config.toml")
.arg("--database").arg("tmp/bridge1_db.txt")
.spawn()
.expect("failed to spawn bridge process");
// give the bridge time to start up and deploy the contracts
thread::sleep(Duration::from_millis(10000));
println!("\ndeposit ether into HomeBridge\n");
// user deposits into HomeBridge
let exit_status = Command::new("curl")
.arg("--data").arg(r#"{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{
"from": "0x00a329c0648769a73afac7f9381e08fb43dbea72",
"to": "0xebd3944af37ccc6b67ff61239ac4fef229c8f69f",
"value": "0x186a0"
}],"id":0}"#)
.arg("-H").arg("Content-Type: application/json")
.arg("-X").arg("POST")
.arg("localhost:8550")
.status()
.expect("failed to deposit into HomeBridge");
assert!(exit_status.success());
println!("\ndeposit into home sent. give it plenty of time to get mined and relayed\n");
thread::sleep(Duration::from_millis(10000));
// connect for 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);
// balance on ForeignBridge should have increased
let balance_payload = foreign.functions().balances().input(Address::from("0x00a329c0648769a73afac7f9381e08fb43dbea72"));
let future = foreign_eth.call(web3::types::CallRequest{
from: None,
to: web3::types::Address::from(&Address::from("0xebd3944af37ccc6b67ff61239ac4fef229c8f69f").0[..]),
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());
assert_eq!(
balance,
U256::from(100000),
"balance on ForeignBridge should have increased");
println!("\nconfirmed that deposit reached foreign\n");
// withdraw
let transfer_payload = foreign.functions()
.transfer_home_via_relay()
.input(
Address::from("0x00aa39d30f0d20ff03a22ccfc30b7efbfca597c2"),
U256::from(100000));
let future = foreign_eth.send_transaction(web3::types::TransactionRequest{
from: web3::types::Address::from(&Address::from("0x00a329c0648769a73afac7f9381e08fb43dbea72").0[..]),
to: Some(web3::types::Address::from(&Address::from("0xebd3944af37ccc6b67ff61239ac4fef229c8f69f").0[..])),
gas: None,
gas_price: None,
value: None,
data: Some(web3::types::Bytes(transfer_payload)),
condition: None,
nonce: None,
});
event_loop.run(future).unwrap();
println!("\nForeignBridge.transferHomeViaRelay transaction sent. give it plenty of time to get mined and relayed\n");
thread::sleep(Duration::from_millis(10000));
// test that withdraw completed
let future = home_eth.balance(web3::types::Address::from(&Address::from("0x00aa39d30f0d20ff03a22ccfc30b7efbfca597c2").0[..]), None);
println!("waiting for future");
let balance = event_loop.run(future).unwrap();
assert!(balance > web3::types::U256::from(0));
println!("\nconfirmed that withdraw reached home\n");
bridge1.kill().unwrap();
// wait for bridge to shut down
thread::sleep(Duration::from_millis(1000));
parity_home.kill().unwrap();
parity_foreign.kill().unwrap();
}

View File

@ -118,14 +118,14 @@ test_app_stream! {
// call to `message`
"eth_call" =>
req => r#"[{"data":"0x490a32c600000000000000000000000000000000000000000000000000000000000000f0","to":"0x0000000000000000000000000000000000000000"},"latest"]"#,
res => r#""0x333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333""#;
res => r#""0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000054333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333000000000000000000000000""#;
// calls to `signature`
"eth_call" =>
req => r#"[{"data":"0x1812d99600000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000000","to":"0x0000000000000000000000000000000000000000"},"latest"]"#,
res => r#""0x1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111""#;
res => r#""0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000041111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000""#;
"eth_call" =>
req => r#"[{"data":"0x1812d99600000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000001","to":"0x0000000000000000000000000000000000000000"},"latest"]"#,
res => r#""0x2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222""#;
res => r#""0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000041222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222200000000000000000000000000000000000000000000000000000000000000""#;
]
}
@ -168,14 +168,14 @@ test_app_stream! {
// call to `message`
"eth_call" =>
req => r#"[{"data":"0x490a32c600000000000000000000000000000000000000000000000000000000000000f0","to":"0x0000000000000000000000000000000000000000"},"latest"]"#,
res => r#""0x333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333""#;
res => r#""0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000054333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333000000000000000000000000""#;
// calls to `signature`
"eth_call" =>
req => r#"[{"data":"0x1812d99600000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000000","to":"0x0000000000000000000000000000000000000000"},"latest"]"#,
res => r#""0x1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111""#;
res => r#""0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000041111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000""#;
"eth_call" =>
req => r#"[{"data":"0x1812d99600000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000001","to":"0x0000000000000000000000000000000000000000"},"latest"]"#,
res => r#""0x2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222""#;
res => r#""0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000041222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222200000000000000000000000000000000000000000000000000000000000000""#;
]
}
@ -226,14 +226,14 @@ test_app_stream! {
// call to `message`
"eth_call" =>
req => r#"[{"data":"0x490a32c600000000000000000000000000000000000000000000000000000000000000f0","to":"0x0000000000000000000000000000000000000000"},"latest"]"#,
res => r#""0x333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333""#;
res => r#""0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000054333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333000000000000000000000000""#;
// calls to `signature`
"eth_call" =>
req => r#"[{"data":"0x1812d99600000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000000","to":"0x0000000000000000000000000000000000000000"},"latest"]"#,
res => r#""0x1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111""#;
res => r#""0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000041111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000""#;
"eth_call" =>
req => r#"[{"data":"0x1812d99600000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000001","to":"0x0000000000000000000000000000000000000000"},"latest"]"#,
res => r#""0x2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222""#;
res => r#""0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000041222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222200000000000000000000000000000000000000000000000000000000000000""#;
]
}
@ -282,13 +282,13 @@ test_app_stream! {
// call to `message`
"eth_call" =>
req => r#"[{"data":"0x490a32c600000000000000000000000000000000000000000000000000000000000000f0","to":"0x00000000000000000000000000000000000000ee"},"latest"]"#,
res => r#""0x333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333""#;
res => r#""0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000054333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333000000000000000000000000""#;
// calls to `signature`
"eth_call" =>
req => r#"[{"data":"0x1812d99600000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000000","to":"0x00000000000000000000000000000000000000ee"},"latest"]"#,
res => r#""0x1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111""#;
res => r#""0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000041111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000""#;
"eth_call" =>
req => r#"[{"data":"0x1812d99600000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000001","to":"0x00000000000000000000000000000000000000ee"},"latest"]"#,
res => r#""0x2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222""#;
res => r#""0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000041222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222200000000000000000000000000000000000000000000000000000000000000""#;
]
}