Skip to content

Commit 4bcb91d

Browse files
committed
fix: ethereum_adapter validate_channel
1 parent 760e70c commit 4bcb91d

File tree

5 files changed

+239
-88
lines changed

5 files changed

+239
-88
lines changed

adapter/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ serde = {version = "^1.0", features = ['derive']}
1414
serde_json = "1.0"
1515
serde-hex = "0.1.0"
1616
# Ethereum
17-
web3 = { git = "https://github.com/tomusdrw/rust-web3" }
17+
web3 = { git = "https://github.com/samparsky/rust-web3" }
1818
eth_checksum = "0.1.1"
19-
ethabi = "8.0.1"
19+
ethabi = { git = "https://github.com/samparsky/ethabi", branch = "graph-patches" }
2020
tiny-keccak = "1.5"
2121
parity-crypto = { version = "0.4.2", features = ["publickey"], git = "https://github.com/paritytech/parity-common" }
2222
ethstore = { version = "0.2.1", git = "https://github.com/paritytech/parity-ethereum"}

adapter/src/ethereum.rs

Lines changed: 157 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use web3::{
2424
futures::Future,
2525
types::U256,
2626
};
27+
use ethabi::token::Token;
2728

2829
lazy_static! {
2930
static ref ADEXCORE_ABI: &'static [u8] =
@@ -133,24 +134,34 @@ impl Adapter for EthereumAdapter {
133134
let channel_id = eth_channel
134135
.hash_hex(&self.config.ethereum_core_address)
135136
.map_err(|_| map_error("Failed to hash the channel id"))?;
136-
137+
138+
println!("checking1");
139+
println!("checking2");
137140
let our_channel_id = format!("0x{}", hex::encode(channel.id));
141+
println!(" our_channel_id {}", our_channel_id);
142+
println!(" channel_id {}", channel_id);
138143
if channel_id != our_channel_id {
139144
return Err(AdapterError::Configuration(
140145
"channel.id is not valid".to_string(),
141146
));
142147
}
143148

144-
// query the blockchain for the channel status
145-
let contract_address = Address::from_slice(self.config.ethereum_core_address.as_bytes());
146-
let contract = get_contract(&self.config, contract_address, &ADEXCORE_ABI)
149+
let (_eloop, transport) = web3::transports::Http::new(&self.config.ethereum_network)
150+
.map_err(|_| map_error("failed to init core contract"))?;
151+
let web3 = web3::Web3::new(transport);
152+
153+
let contract = Contract::from_json(web3.eth(), contract_address, &ADEXCORE_ABI)
147154
.map_err(|_| map_error("failed to init core contract"))?;
148155

149156
let channel_status: U256 = contract
150-
.query("states", channel_id, None, Options::default(), None)
157+
.query("states", (Token::FixedBytes(channel.id.as_ref().to_vec()),), None, Options::default(), None)
151158
.wait()
152-
.map_err(|_| map_error("contract channel status query failed"))?;
153-
159+
.map_err(|e| {
160+
println!("{:?}", e);
161+
map_error("contract channel status query failed")
162+
})?;
163+
164+
println!(" channel_status {}", channel_status);
154165
if channel_status != *CHANNEL_STATE_ACTIVE {
155166
return Err(AdapterError::Configuration(
156167
"channel is not Active on the ethereum network".to_string(),
@@ -366,27 +377,39 @@ mod test {
366377
use super::*;
367378
use primitives::adapter::KeystoreOptions;
368379
use primitives::config::configuration;
380+
use primitives::ChannelId;
381+
use primitives::{SpecValidators, ValidatorDesc, ChannelSpec, EventSubmission};
382+
use chrono::{Duration, TimeZone, Utc};
383+
use std::convert::TryFrom;
384+
use hex::FromHex;
385+
use ethabi::token::{Token};
386+
use crate::EthereumChannel;
369387

370-
fn setup_eth_adapter() -> EthereumAdapter {
371-
let config = configuration("development", None).expect("failed parse config");
388+
389+
fn setup_eth_adapter(contract_address: Option<[u8; 20]>) -> EthereumAdapter {
390+
let mut config = configuration("development", None).expect("failed parse config");
372391
let keystore_options = KeystoreOptions {
373392
keystore_file: "./test/resources/keystore.json".to_string(),
374393
keystore_pwd: "adexvalidator".to_string(),
375394
};
376395

396+
if let Some(ct_address) = contract_address {
397+
config.ethereum_core_address = ct_address;
398+
}
399+
377400
EthereumAdapter::init(keystore_options, &config).expect("should init ethereum adapter")
378401
}
379402

380403
#[test]
381404
fn should_init_and_unlock_ethereum_adapter() {
382-
let mut eth_adapter = setup_eth_adapter();
405+
let mut eth_adapter = setup_eth_adapter(None);
383406
eth_adapter.unlock().expect("should unlock eth adapter");
384407
}
385408

386409
#[test]
387410
fn should_get_whoami_sign_and_verify_messages() {
388411
// whoami
389-
let mut eth_adapter = setup_eth_adapter();
412+
let mut eth_adapter = setup_eth_adapter(None);
390413
let whoami = eth_adapter.whoami();
391414
assert_eq!(
392415
whoami.to_string(),
@@ -419,7 +442,7 @@ mod test {
419442

420443
#[test]
421444
fn should_generate_correct_ewt_sign_and_verify() {
422-
let mut eth_adapter = setup_eth_adapter();
445+
let mut eth_adapter = setup_eth_adapter(None);
423446
eth_adapter.unlock().expect("should unlock eth adapter");
424447

425448
let payload = Payload {
@@ -446,4 +469,125 @@ mod test {
446469
"generated wrong verification payload"
447470
);
448471
}
449-
}
472+
473+
#[test]
474+
fn should_validate_channel_properly() {
475+
let (eloop, http) = web3::transports::Http::new("http://localhost:8545").expect("failed to init transport");
476+
eloop.into_remote();
477+
478+
let web3 = web3::Web3::new(http);
479+
let leader_account: Address = "Df08F82De32B8d460adbE8D72043E3a7e25A3B39".parse().expect("failed to parse leader account");
480+
let follower_account: Address = "6704Fbfcd5Ef766B287262fA2281C105d57246a6".parse().expect("failed to parse leader account");
481+
482+
// tokenbytecode.json
483+
let token_bytecode = include_str!("../test/resources/tokenbytecode.json");
484+
// token_abi.json
485+
let token_abi = include_bytes!("../test/resources/tokenabi.json");
486+
// adexbytecode.json
487+
let adex_bytecode = include_str!("../../lib/protocol-eth/resources/bytecode/AdExCore.json");
488+
// adexabi.json
489+
let adex_abi = include_bytes!("../../lib/protocol-eth/abi/AdExCore.json");
490+
491+
// deploy contracts
492+
let token_contract = Contract::deploy(web3.eth(), token_abi)
493+
.expect("invalid token token contract")
494+
.confirmations(0)
495+
.options(
496+
Options::with(|opt| {
497+
opt.gas_price = Some(1.into());
498+
opt.gas = Some(6_721_975.into());
499+
})
500+
)
501+
.execute(
502+
token_bytecode,
503+
(),
504+
leader_account,
505+
)
506+
.expect("Correct parameters are passed to the constructor.")
507+
.wait()
508+
.expect("failed to wait");
509+
510+
let adex_contract = Contract::deploy(web3.eth(), adex_abi)
511+
.expect("invalid adex contract")
512+
.confirmations(0)
513+
.options(
514+
Options::with(|opt| {
515+
opt.gas_price = Some(1.into());
516+
opt.gas = Some(6_721_975.into());
517+
})
518+
)
519+
.execute(
520+
adex_bytecode,
521+
(),
522+
leader_account,
523+
)
524+
.expect("Correct parameters are passed to the constructor.")
525+
.wait()
526+
.expect("failed to init adex contract");
527+
528+
println!("adex_contract address {:?}", adex_contract.address());
529+
// contract call set balance
530+
token_contract.call("setBalanceTo", (Token::Address(leader_account), Token::Uint(2000.into())), leader_account, Options::default()).wait()
531+
.expect("Failed to set balance");
532+
println!("token address {}", token_contract.address());
533+
534+
let leader_validator_desc = ValidatorDesc {
535+
// keystore.json addresss (same with js)
536+
id: ValidatorId::try_from("2bdeafae53940669daa6f519373f686c1f3d3393").expect("failed to create id"),
537+
url: "http://localhost:8005".to_string(),
538+
fee: 100.into(),
539+
};
540+
541+
let follower_validator_desc = ValidatorDesc {
542+
// keystore2.json addresss (same with js)
543+
id: ValidatorId::try_from("6704Fbfcd5Ef766B287262fA2281C105d57246a6").expect("failed to create id"),
544+
url: "http://localhost:8006".to_string(),
545+
fee: 100.into(),
546+
};
547+
548+
let mut valid_channel = Channel {
549+
// to be replace with the proper id
550+
id: ChannelId::from_hex("061d5e2a67d0a9a10f1c732bca12a676d83f79663a396f7d87b3e30b9b411088").expect("prep_db: failed to deserialize channel id"),
551+
// leader_account
552+
creator: "0xDf08F82De32B8d460adbE8D72043E3a7e25A3B39".to_string(),
553+
deposit_asset: eth_checksum::checksum(&format!("{:?}", token_contract.address())),
554+
deposit_amount: 2_000.into(),
555+
valid_until: Utc::now() + Duration::days(2),
556+
spec: ChannelSpec {
557+
title: None,
558+
validators: SpecValidators::new(leader_validator_desc, follower_validator_desc),
559+
max_per_impression: 10.into(),
560+
min_per_impression: 10.into(),
561+
targeting: vec![],
562+
min_targeting_score: None,
563+
event_submission: Some(EventSubmission { allow: vec![] }),
564+
created: Some(Utc::now()),
565+
active_from: None,
566+
nonce: None,
567+
withdraw_period_start: Utc::now() + Duration::days(1),
568+
ad_units: vec![],
569+
},
570+
};
571+
572+
// convert to eth channel
573+
let eth_channel = EthereumChannel::try_from(&valid_channel).expect("failed to create eth channel");
574+
let sol_tuple = eth_channel.to_solidity_tuple();
575+
576+
// contract call open channel
577+
adex_contract.call("channelOpen", (sol_tuple,), leader_account, Options::default()).wait()
578+
.expect("open channel");
579+
580+
let contract_addr = <[u8; 20]>::from_hex(&format!("{:?}", adex_contract.address())[2..]).expect("failed to deserialise contract addr");
581+
582+
let channel_id = eth_channel.hash(&contract_addr).expect("hash hex");
583+
println!("channel_id {}", hex::encode(channel_id));
584+
// set id to proper id
585+
valid_channel.id = ChannelId::from_hex(hex::encode(channel_id)).expect("prep_db: failed to deserialize channel id");
586+
587+
// eth adapter
588+
let mut eth_adapter = setup_eth_adapter(Some(contract_addr));
589+
eth_adapter.unlock().expect("should unlock eth adapter");
590+
// validate channel
591+
eth_adapter.validate_channel(&valid_channel).expect("failed to validate channel");
592+
}
593+
}

0 commit comments

Comments
 (0)