Skip to content

Commit 6748650

Browse files
authored
Issue #122 Heartbeat & testing get_signable_state_root (#137)
* issue - 123 - make main heartbeat() fn work * remove asset - we don't use it * change state_root to &str instead of String on Adapter::sign() * sentry_interface - change the `propagate` to accept `&[MessageTypes]` instead of Vec * heartbeat - wrap the current work for heartbeat and leave some todos for the rest of the tasks * heartbeat - dummy state_root * fix producer * sentry_interface - change propagate + alter heartbeat to return directly Accounting instead of MessageTypes * adapter - Add byteorder & test if `get_state_root_hash` is aligned with the JS impl * validator_worker - add hex & byteorder and implement the rest of the Heartbeat * adapter - remove allow(dead_code) * clean up
1 parent 2c86d50 commit 6748650

File tree

12 files changed

+117
-199
lines changed

12 files changed

+117
-199
lines changed

Cargo.lock

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

adapter/Cargo.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ version = "0.1.0"
44
authors = ["Lachezar Lechev <[email protected]>, Omidiora Samuel <[email protected]>"]
55
edition = "2018"
66

7-
[features]
8-
9-
107
[dependencies]
118
primitives = {path = "../primitives"}
129
# Futures
@@ -15,7 +12,7 @@ futures-preview = {version = "=0.3.0-alpha.16"}
1512
chrono = "0.4"
1613
time = "0.1.42"
1714
# To/From Hex
18-
hex = {version = "0.3.2"}
15+
hex = "0.3.2"
1916
serde = {version = "^1.0", features = ['derive']}
2017
# Ethereum
2118
web3 = { git = "https://github.com/tomusdrw/rust-web3" }
@@ -24,3 +21,4 @@ ethabi = "8.0.1"
2421
tiny-keccak = "1.5"
2522

2623
[dev-dependencies]
24+
byteorder = "1.3"

adapter/src/dummy.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#![deny(clippy::all)]
22
#![deny(rust_2018_idioms)]
33

4-
use futures::future::{ok, FutureExt};
54
use primitives::adapter::{Adapter, AdapterOptions, AdapterResult};
65
use primitives::channel_validator::ChannelValidator;
76
use primitives::config::Config;
@@ -44,7 +43,7 @@ impl Adapter for DummyAdapter {
4443
self.identity.to_string()
4544
}
4645

47-
fn sign(&self, state_root: String) -> AdapterResult<String> {
46+
fn sign(&self, state_root: &str) -> AdapterResult<String> {
4847
let signature = format!(
4948
"Dummy adapter signature for {} by {}",
5049
state_root,

adapter/src/ethereum.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl Adapter for EthereumAdapter {
5555
self.address.unwrap().to_string()
5656
}
5757

58-
fn sign(&self, state_root: String) -> AdapterResult<String> {
58+
fn sign(&self, state_root: &str) -> AdapterResult<String> {
5959
let signature = format!(
6060
"Dummy adapter signature for {} by {}",
6161
state_root,

adapter/src/lib.rs

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#![deny(clippy::all)]
44
#![deny(clippy::match_bool)]
55
#![doc(test(attr(feature(async_await, await_macro))))]
6-
#![doc(test(attr(cfg(feature = "dummy-adapter"))))]
76

87
use ethabi::encode;
98
use ethabi::param_type::{ParamType, Reader};
@@ -26,12 +25,12 @@ pub fn get_signable_state_root(
2625
channel_id: &str,
2726
balance_root: &str,
2827
) -> Result<[u8; 32], Box<dyn Error>> {
29-
let types: Vec<String> = vec!["bytes32".to_string(), "bytes32".to_string()];
28+
let types = ["bytes32".to_string(), "bytes32".to_string()];
3029
let values = [channel_id.to_string(), balance_root.to_string()];
3130
let encoded = encode_params(&types, &values, true)?;
3231

3332
let mut result = Keccak::new_keccak256();
34-
result.update(encoded.as_ref());
33+
result.update(&encoded);
3534

3635
let mut res: [u8; 32] = [0; 32];
3736
result.finalize(&mut res);
@@ -45,7 +44,7 @@ pub fn get_balance_leaf(acc: &str, amnt: &str) -> Result<[u8; 32], Box<dyn Error
4544
let encoded = encode_params(&types, &values, true)?;
4645

4746
let mut result = Keccak::new_keccak256();
48-
result.update(encoded.as_ref());
47+
result.update(&encoded);
4948

5049
let mut res: [u8; 32] = [0; 32];
5150
result.finalize(&mut res);
@@ -64,7 +63,7 @@ pub struct EthereumChannel {
6463
}
6564

6665
impl EthereumChannel {
67-
fn new(
66+
pub fn new(
6867
creator: &str,
6968
token_addr: &str,
7069
token_amount: String,
@@ -83,7 +82,7 @@ impl EthereumChannel {
8382
}
8483
}
8584

86-
fn hash(&self, contract_addr: &str) -> Result<[u8; 32], Box<dyn Error>> {
85+
pub fn hash(&self, contract_addr: &str) -> Result<[u8; 32], Box<dyn Error>> {
8786
let types: Vec<String> = vec![
8887
"address",
8988
"address",
@@ -108,20 +107,20 @@ impl EthereumChannel {
108107
];
109108
let encoded = encode_params(&types, &values, true)?;
110109
let mut result = Keccak::new_keccak256();
111-
result.update(encoded.as_ref());
110+
result.update(&encoded);
112111

113112
let mut res: [u8; 32] = [0; 32];
114113
result.finalize(&mut res);
115114

116115
Ok(res)
117116
}
118117

119-
fn hash_hex(&self, contract_addr: &str) -> Result<String, Box<dyn Error>> {
118+
pub fn hash_hex(&self, contract_addr: &str) -> Result<String, Box<dyn Error>> {
120119
let result = self.hash(contract_addr)?;
121120
Ok(format!("0x{}", hex::encode(result).to_string()))
122121
}
123122

124-
fn to_solidity_tuple(&self) -> Vec<String> {
123+
pub fn to_solidity_tuple(&self) -> Vec<String> {
125124
vec![
126125
self.creator.to_owned(),
127126
self.token_addr.to_owned(),
@@ -132,15 +131,15 @@ impl EthereumChannel {
132131
]
133132
}
134133

135-
fn hash_to_sign(
134+
pub fn hash_to_sign(
136135
&self,
137136
contract_addr: &str,
138137
balance_root: &str,
139138
) -> Result<[u8; 32], Box<dyn Error>> {
140139
get_signable_state_root(contract_addr, balance_root)
141140
}
142141

143-
fn hash_to_sign_hex(
142+
pub fn hash_to_sign_hex(
144143
&self,
145144
contract_addr: &str,
146145
balance_root: &str,
@@ -154,7 +153,7 @@ fn encode_params(
154153
types: &[String],
155154
values: &[String],
156155
lenient: bool,
157-
) -> Result<String, Box<dyn Error>> {
156+
) -> Result<Vec<u8>, Box<dyn Error>> {
158157
assert_eq!(types.len(), values.len());
159158

160159
let types: Vec<ParamType> = types
@@ -164,13 +163,13 @@ fn encode_params(
164163

165164
let params: Vec<_> = types
166165
.into_iter()
167-
.zip(values.iter().map(|v| v as &str))
166+
.zip(values.iter().map(|s| s as &str))
168167
.collect();
169168

170169
let tokens = parse_tokens(&params, lenient)?;
171170
let result = encode(&tokens);
172171

173-
Ok(hex::encode(result).to_string())
172+
Ok(result.to_vec())
174173
}
175174

176175
fn parse_tokens(params: &[(ParamType, &str)], lenient: bool) -> Result<Vec<Token>, Box<dyn Error>> {
@@ -186,3 +185,35 @@ fn parse_tokens(params: &[(ParamType, &str)], lenient: bool) -> Result<Vec<Token
186185
.collect::<Result<_, _>>()
187186
.map_err(From::from)
188187
}
188+
189+
#[cfg(test)]
190+
mod test {
191+
use super::*;
192+
use byteorder::{BigEndian, ByteOrder};
193+
use chrono::{TimeZone, Utc};
194+
use primitives::merkle_tree::MerkleTree;
195+
use std::convert::TryFrom;
196+
197+
#[test]
198+
fn test_get_signable_state_root_hash_is_aligned_with_js_impl() {
199+
let timestamp = Utc.ymd(2019, 9, 12).and_hms(17, 0, 0);
200+
let mut timestamp_buf = [0_u8; 32];
201+
let n: u64 = u64::try_from(timestamp.timestamp_millis())
202+
.expect("The timestamp should be able to be converted to u64");
203+
BigEndian::write_uint(&mut timestamp_buf[26..], n, 6);
204+
205+
let merkle_tree = MerkleTree::new(&[timestamp_buf]);
206+
let info_root_raw = hex::encode(merkle_tree.root());
207+
208+
let channel_id = "061d5e2a67d0a9a10f1c732bca12a676d83f79663a396f7d87b3e30b9b411088";
209+
210+
let state_root =
211+
get_signable_state_root(&channel_id, &info_root_raw).expect("Should get state_root");
212+
213+
let expected_hex =
214+
hex::decode("b68cde9b0c8b63ac7152e78a65c736989b4b99bfc252758b1c3fd6ca357e0d6b")
215+
.expect("Should decode valid expected hex");
216+
217+
assert_eq!(state_root.to_vec(), expected_hex);
218+
}
219+
}

primitives/src/adapter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub trait Adapter: ChannelValidator + Clone + Debug + Send + Sync {
4949
fn whoami(&self) -> String;
5050

5151
/// Signs the provided state_root
52-
fn sign(&self, state_root: String) -> AdapterResult<String>;
52+
fn sign(&self, state_root: &str) -> AdapterResult<String>;
5353

5454
/// Verify, based on the signature & state_root, that the signer is the same
5555
fn verify(&self, signer: &str, state_root: &str, signature: &str) -> AdapterResult<bool>;

primitives/src/asset.rs

Lines changed: 0 additions & 35 deletions
This file was deleted.

validator_worker/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ adapter = { version = "0.1", path = "../adapter" }
1717
chrono = { version = "0.4", features = ["serde"] }
1818
num = "0.2.0"
1919
num-traits = "0.2.0"
20+
# To/From Hex
21+
hex = {version = "0.3.2"}
22+
byteorder = "1.3"
2023
# Futures
2124
futures-preview = { version = "=0.3.0-alpha.16", features = ["compat", "io-compat"] }
2225
futures_legacy = { version = "0.1", package = "futures" }

0 commit comments

Comments
 (0)