From 4512701672843317faa450d8fa5d8b1e5a0f2387 Mon Sep 17 00:00:00 2001 From: Axel Chalon Date: Wed, 25 Oct 2017 15:33:01 +0200 Subject: [PATCH 1/3] Refactor updater to use ethabi-derive --- Cargo.lock | 36 +- updater/Cargo.toml | 4 +- updater/res/operations.abi | 560 +++++++++++++++++++++++++++++ updater/src/lib.rs | 3 +- updater/src/operations.rs | 356 ------------------ updater/src/types/release_track.rs | 7 +- updater/src/updater.rs | 102 +++++- 7 files changed, 690 insertions(+), 378 deletions(-) create mode 100644 updater/res/operations.abi delete mode 100644 updater/src/operations.rs diff --git a/Cargo.lock b/Cargo.lock index 3a9f54190e1..548fc0160d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -467,6 +467,35 @@ dependencies = [ "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ethabi" +version = "4.1.0" +source = "git+https://github.com/paritytech/ethabi/?branch=call-function#6a07eb535c6c58c01e30db91e4d54a57c118e760" +dependencies = [ + "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ethabi-contract" +version = "4.1.0" +source = "git+https://github.com/paritytech/ethabi/?branch=call-function#6a07eb535c6c58c01e30db91e4d54a57c118e760" + +[[package]] +name = "ethabi-derive" +version = "4.1.0" +source = "git+https://github.com/paritytech/ethabi/?branch=call-function#6a07eb535c6c58c01e30db91e4d54a57c118e760" +dependencies = [ + "ethabi 4.1.0 (git+https://github.com/paritytech/ethabi/?branch=call-function)", + "heck 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ethash" version = "1.9.0" @@ -2248,7 +2277,9 @@ dependencies = [ name = "parity-updater" version = "1.9.0" dependencies = [ - "ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi 4.1.0 (git+https://github.com/paritytech/ethabi/?branch=call-function)", + "ethabi-contract 4.1.0 (git+https://github.com/paritytech/ethabi/?branch=call-function)", + "ethabi-derive 4.1.0 (git+https://github.com/paritytech/ethabi/?branch=call-function)", "ethcore 1.9.0", "ethcore-bigint 0.1.3", "ethcore-bytes 0.1.0", @@ -3555,6 +3586,9 @@ dependencies = [ "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum eth-secp256k1 0.5.6 (git+https://github.com/paritytech/rust-secp256k1)" = "" "checksum ethabi 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c819a3adef0413a2519cbd9a19a35dd1c20c7a0110705beaba8aa4aa87eda95f" +"checksum ethabi 4.1.0 (git+https://github.com/paritytech/ethabi/?branch=call-function)" = "" +"checksum ethabi-contract 4.1.0 (git+https://github.com/paritytech/ethabi/?branch=call-function)" = "" +"checksum ethabi-derive 4.1.0 (git+https://github.com/paritytech/ethabi/?branch=call-function)" = "" "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e6234dd4468ae5d1e2dbb06fe2b058696fdc50a339c68a393aefbf00bc81e423" "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" diff --git a/updater/Cargo.toml b/updater/Cargo.toml index a67559f6890..685e7ad6495 100644 --- a/updater/Cargo.toml +++ b/updater/Cargo.toml @@ -7,7 +7,9 @@ authors = ["Parity Technologies "] [dependencies] log = "0.3" -ethabi = "4.0" +ethabi = { git = "https://github.com/paritytech/ethabi/", branch = "call-function" } +ethabi-derive = { git = "https://github.com/paritytech/ethabi/", branch = "call-function" } +ethabi-contract = { git = "https://github.com/paritytech/ethabi/", branch = "call-function" } target_info = "0.1" semver = "0.6" ethcore = { path = "../ethcore" } diff --git a/updater/res/operations.abi b/updater/res/operations.abi new file mode 100644 index 00000000000..2a14e0f0a01 --- /dev/null +++ b/updater/res/operations.abi @@ -0,0 +1,560 @@ +[ + { + "constant": false, + "inputs": [ + { + "name": "_client", + "type": "bytes32" + }, + { + "name": "_newOwner", + "type": "address" + } + ], + "name": "resetClientOwner", + "outputs": [], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_client", + "type": "bytes32" + }, + { + "name": "_release", + "type": "bytes32" + } + ], + "name": "isLatest", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_txid", + "type": "bytes32" + } + ], + "name": "rejectTransaction", + "outputs": [], + "payable": false, + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_newOwner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "payable": false, + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_number", + "type": "uint32" + }, + { + "name": "_name", + "type": "bytes32" + }, + { + "name": "_hard", + "type": "bool" + }, + { + "name": "_spec", + "type": "bytes32" + } + ], + "name": "proposeFork", + "outputs": [], + "payable": false, + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_client", + "type": "bytes32" + } + ], + "name": "removeClient", + "outputs": [], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_client", + "type": "bytes32" + }, + { + "name": "_release", + "type": "bytes32" + } + ], + "name": "release", + "outputs": [ + { + "name": "o_forkBlock", + "type": "uint32" + }, + { + "name": "o_track", + "type": "uint8" + }, + { + "name": "o_semver", + "type": "uint24" + }, + { + "name": "o_critical", + "type": "bool" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_client", + "type": "bytes32" + }, + { + "name": "_checksum", + "type": "bytes32" + } + ], + "name": "build", + "outputs": [ + { + "name": "o_release", + "type": "bytes32" + }, + { + "name": "o_platform", + "type": "bytes32" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "rejectFork", + "outputs": [], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "name": "client", + "outputs": [ + { + "name": "owner", + "type": "address" + }, + { + "name": "required", + "type": "bool" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_newOwner", + "type": "address" + } + ], + "name": "setClientOwner", + "outputs": [], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint32" + } + ], + "name": "fork", + "outputs": [ + { + "name": "name", + "type": "bytes32" + }, + { + "name": "spec", + "type": "bytes32" + }, + { + "name": "hard", + "type": "bool" + }, + { + "name": "ratified", + "type": "bool" + }, + { + "name": "requiredCount", + "type": "uint256" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_release", + "type": "bytes32" + }, + { + "name": "_platform", + "type": "bytes32" + }, + { + "name": "_checksum", + "type": "bytes32" + } + ], + "name": "addChecksum", + "outputs": [], + "payable": false, + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_txid", + "type": "bytes32" + } + ], + "name": "confirmTransaction", + "outputs": [ + { + "name": "txSuccess", + "type": "uint256" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "name": "proxy", + "outputs": [ + { + "name": "requiredCount", + "type": "uint256" + }, + { + "name": "to", + "type": "address" + }, + { + "name": "data", + "type": "bytes" + }, + { + "name": "value", + "type": "uint256" + }, + { + "name": "gas", + "type": "uint256" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_client", + "type": "bytes32" + }, + { + "name": "_owner", + "type": "address" + } + ], + "name": "addClient", + "outputs": [], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "clientOwner", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_txid", + "type": "bytes32" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_data", + "type": "bytes" + }, + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_gas", + "type": "uint256" + } + ], + "name": "proposeTransaction", + "outputs": [ + { + "name": "txSuccess", + "type": "uint256" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "grandOwner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_release", + "type": "bytes32" + }, + { + "name": "_forkBlock", + "type": "uint32" + }, + { + "name": "_track", + "type": "uint8" + }, + { + "name": "_semver", + "type": "uint24" + }, + { + "name": "_critical", + "type": "bool" + } + ], + "name": "addRelease", + "outputs": [], + "payable": false, + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "acceptFork", + "outputs": [], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "clientsRequired", + "outputs": [ + { + "name": "", + "type": "uint32" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_client", + "type": "bytes32" + }, + { + "name": "_release", + "type": "bytes32" + } + ], + "name": "track", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_client", + "type": "bytes32" + }, + { + "name": "_r", + "type": "bool" + } + ], + "name": "setClientRequired", + "outputs": [], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "latestFork", + "outputs": [ + { + "name": "", + "type": "uint32" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_client", + "type": "bytes32" + }, + { + "name": "_track", + "type": "uint8" + } + ], + "name": "latestInTrack", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_client", + "type": "bytes32" + }, + { + "name": "_release", + "type": "bytes32" + }, + { + "name": "_platform", + "type": "bytes32" + } + ], + "name": "checksum", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "proposedFork", + "outputs": [ + { + "name": "", + "type": "uint32" + } + ], + "payable": false, + "type": "function" + } +] diff --git a/updater/src/lib.rs b/updater/src/lib.rs index c0da3b6a162..a7b79281a8b 100644 --- a/updater/src/lib.rs +++ b/updater/src/lib.rs @@ -24,6 +24,8 @@ extern crate parking_lot; extern crate parity_hash_fetch as hash_fetch; extern crate ethcore; extern crate ethabi; +#[macro_use] extern crate ethabi_derive; +#[macro_use] extern crate ethabi_contract; extern crate ethsync; extern crate futures; extern crate target_info; @@ -32,7 +34,6 @@ extern crate path; extern crate semver; mod updater; -mod operations; mod types; mod service; diff --git a/updater/src/operations.rs b/updater/src/operations.rs deleted file mode 100644 index b9bb01bd7b7..00000000000 --- a/updater/src/operations.rs +++ /dev/null @@ -1,356 +0,0 @@ -// Autogenerated from JSON contract definition using Rust contract convertor. - -use std::string::String; -use std::result::Result; -use std::fmt; -use ethabi; -use util; -use bigint; - -pub struct Operations { - contract: ethabi::Contract, - address: util::Address, - do_call: Box) -> Result, String> + Send + Sync + 'static>, -} -impl Operations { - pub fn new(address: util::Address, do_call: F) -> Self where F: Fn(util::Address, Vec) -> Result, String> + Send + Sync + 'static { - Operations { - contract: ethabi::Contract::load(b"[{\"constant\":false,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"resetClientOwner\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_release\",\"type\":\"bytes32\"}],\"name\":\"isLatest\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_txid\",\"type\":\"bytes32\"}],\"name\":\"rejectTransaction\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_number\",\"type\":\"uint32\"},{\"name\":\"_name\",\"type\":\"bytes32\"},{\"name\":\"_hard\",\"type\":\"bool\"},{\"name\":\"_spec\",\"type\":\"bytes32\"}],\"name\":\"proposeFork\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"}],\"name\":\"removeClient\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_release\",\"type\":\"bytes32\"}],\"name\":\"release\",\"outputs\":[{\"name\":\"o_forkBlock\",\"type\":\"uint32\"},{\"name\":\"o_track\",\"type\":\"uint8\"},{\"name\":\"o_semver\",\"type\":\"uint24\"},{\"name\":\"o_critical\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_checksum\",\"type\":\"bytes32\"}],\"name\":\"build\",\"outputs\":[{\"name\":\"o_release\",\"type\":\"bytes32\"},{\"name\":\"o_platform\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"rejectFork\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"client\",\"outputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"required\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"setClientOwner\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"name\":\"fork\",\"outputs\":[{\"name\":\"name\",\"type\":\"bytes32\"},{\"name\":\"spec\",\"type\":\"bytes32\"},{\"name\":\"hard\",\"type\":\"bool\"},{\"name\":\"ratified\",\"type\":\"bool\"},{\"name\":\"requiredCount\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_release\",\"type\":\"bytes32\"},{\"name\":\"_platform\",\"type\":\"bytes32\"},{\"name\":\"_checksum\",\"type\":\"bytes32\"}],\"name\":\"addChecksum\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_txid\",\"type\":\"bytes32\"}],\"name\":\"confirmTransaction\",\"outputs\":[{\"name\":\"txSuccess\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"proxy\",\"outputs\":[{\"name\":\"requiredCount\",\"type\":\"uint256\"},{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\"},{\"name\":\"value\",\"type\":\"uint256\"},{\"name\":\"gas\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"addClient\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"clientOwner\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_txid\",\"type\":\"bytes32\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_data\",\"type\":\"bytes\"},{\"name\":\"_value\",\"type\":\"uint256\"},{\"name\":\"_gas\",\"type\":\"uint256\"}],\"name\":\"proposeTransaction\",\"outputs\":[{\"name\":\"txSuccess\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"grandOwner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_release\",\"type\":\"bytes32\"},{\"name\":\"_forkBlock\",\"type\":\"uint32\"},{\"name\":\"_track\",\"type\":\"uint8\"},{\"name\":\"_semver\",\"type\":\"uint24\"},{\"name\":\"_critical\",\"type\":\"bool\"}],\"name\":\"addRelease\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"acceptFork\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"clientsRequired\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_release\",\"type\":\"bytes32\"}],\"name\":\"track\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_r\",\"type\":\"bool\"}],\"name\":\"setClientRequired\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"latestFork\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_track\",\"type\":\"uint8\"}],\"name\":\"latestInTrack\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_client\",\"type\":\"bytes32\"},{\"name\":\"_release\",\"type\":\"bytes32\"},{\"name\":\"_platform\",\"type\":\"bytes32\"}],\"name\":\"checksum\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"proposedFork\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"type\":\"function\"}]" as &[u8]).expect("JSON is autogenerated; qed"), - address: address, - do_call: Box::new(do_call), - } - } - fn as_string(e: T) -> String { format!("{:?}", e) } - - /// Auto-generated from: `{"constant":false,"inputs":[{"name":"_client","type":"bytes32"},{"name":"_newOwner","type":"address"}],"name":"resetClientOwner","outputs":[],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn reset_client_owner(&self, _client: &str, _new_owner: &util::Address) -> Result<(), String> { - let call = self.contract.function("resetClientOwner".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::Address(_new_owner.clone().0)] - ).map_err(Self::as_string)?; - call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - - Ok(()) - } - - /// Auto-generated from: `{"constant":true,"inputs":[{"name":"_client","type":"bytes32"},{"name":"_release","type":"bytes32"}],"name":"isLatest","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn is_latest(&self, _client: &str, _release: &bigint::hash::H256) -> Result { - let call = self.contract.function("isLatest".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::FixedBytes(_release.as_ref().to_owned())] - ).map_err(Self::as_string)?; - let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_bool().ok_or("Invalid type returned")?; r })) - } - - /// Auto-generated from: `{"constant":false,"inputs":[{"name":"_txid","type":"bytes32"}],"name":"rejectTransaction","outputs":[],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn reject_transaction(&self, _txid: &bigint::hash::H256) -> Result<(), String> { - let call = self.contract.function("rejectTransaction".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_txid.as_ref().to_owned())] - ).map_err(Self::as_string)?; - call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - - Ok(()) - } - - /// Auto-generated from: `{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn set_owner(&self, _new_owner: &util::Address) -> Result<(), String> { - let call = self.contract.function("setOwner".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::Address(_new_owner.clone().0)] - ).map_err(Self::as_string)?; - call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - - Ok(()) - } - - /// Auto-generated from: `{"constant":false,"inputs":[{"name":"_number","type":"uint32"},{"name":"_name","type":"bytes32"},{"name":"_hard","type":"bool"},{"name":"_spec","type":"bytes32"}],"name":"proposeFork","outputs":[],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn propose_fork(&self, _number: u32, _name: &bigint::hash::H256, _hard: bool, _spec: &bigint::hash::H256) -> Result<(), String> { - let call = self.contract.function("proposeFork".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::Uint({ let mut r = [0u8; 32]; bigint::prelude::U256::from(_number as u64).to_big_endian(&mut r); r }), ethabi::Token::FixedBytes(_name.as_ref().to_owned()), ethabi::Token::Bool(_hard), ethabi::Token::FixedBytes(_spec.as_ref().to_owned())] - ).map_err(Self::as_string)?; - call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - - Ok(()) - } - - /// Auto-generated from: `{"constant":false,"inputs":[{"name":"_client","type":"bytes32"}],"name":"removeClient","outputs":[],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn remove_client(&self, _client: &str) -> Result<(), String> { - let call = self.contract.function("removeClient".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned())] - ).map_err(Self::as_string)?; - call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - - Ok(()) - } - - /// Auto-generated from: `{"constant":true,"inputs":[{"name":"_client","type":"bytes32"},{"name":"_release","type":"bytes32"}],"name":"release","outputs":[{"name":"o_forkBlock","type":"uint32"},{"name":"o_track","type":"uint8"},{"name":"o_semver","type":"uint24"},{"name":"o_critical","type":"bool"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn release(&self, _client: &str, _release: &bigint::hash::H256) -> Result<(u32, u8, u32, bool), String> { - let call = self.contract.function("release".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::FixedBytes(_release.as_ref().to_owned())] - ).map_err(Self::as_string)?; - let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()).as_u64() as u32 }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()).as_u64() as u8 }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()).as_u64() as u32 }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_bool().ok_or("Invalid type returned")?; r })) - } - - /// Auto-generated from: `{"constant":true,"inputs":[{"name":"_client","type":"bytes32"},{"name":"_checksum","type":"bytes32"}],"name":"build","outputs":[{"name":"o_release","type":"bytes32"},{"name":"o_platform","type":"bytes32"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn build(&self, _client: &str, _checksum: &bigint::hash::H256) -> Result<(bigint::hash::H256, bigint::hash::H256), String> { - let call = self.contract.function("build".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::FixedBytes(_checksum.as_ref().to_owned())] - ).map_err(Self::as_string)?; - let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_fixed_bytes().ok_or("Invalid type returned")?; bigint::hash::H256::from_slice(r.as_ref()) }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_fixed_bytes().ok_or("Invalid type returned")?; bigint::hash::H256::from_slice(r.as_ref()) })) - } - - /// Auto-generated from: `{"constant":false,"inputs":[],"name":"rejectFork","outputs":[],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn reject_fork(&self) -> Result<(), String> { - let call = self.contract.function("rejectFork".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![] - ).map_err(Self::as_string)?; - call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - - Ok(()) - } - - /// Auto-generated from: `{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"client","outputs":[{"name":"owner","type":"address"},{"name":"required","type":"bool"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn client(&self, _1: &bigint::hash::H256) -> Result<(util::Address, bool), String> { - let call = self.contract.function("client".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_1.as_ref().to_owned())] - ).map_err(Self::as_string)?; - let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_address().ok_or("Invalid type returned")?; util::Address::from(r) }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_bool().ok_or("Invalid type returned")?; r })) - } - - /// Auto-generated from: `{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"setClientOwner","outputs":[],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn set_client_owner(&self, _new_owner: &util::Address) -> Result<(), String> { - let call = self.contract.function("setClientOwner".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::Address(_new_owner.clone().0)] - ).map_err(Self::as_string)?; - call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - - Ok(()) - } - - /// Auto-generated from: `{"constant":true,"inputs":[{"name":"","type":"uint32"}],"name":"fork","outputs":[{"name":"name","type":"bytes32"},{"name":"spec","type":"bytes32"},{"name":"hard","type":"bool"},{"name":"ratified","type":"bool"},{"name":"requiredCount","type":"uint256"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn fork(&self, _1: u32) -> Result<(bigint::hash::H256, bigint::hash::H256, bool, bool, bigint::prelude::U256), String> { - let call = self.contract.function("fork".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::Uint({ let mut r = [0u8; 32]; bigint::prelude::U256::from(_1 as u64).to_big_endian(&mut r); r })] - ).map_err(Self::as_string)?; - let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_fixed_bytes().ok_or("Invalid type returned")?; bigint::hash::H256::from_slice(r.as_ref()) }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_fixed_bytes().ok_or("Invalid type returned")?; bigint::hash::H256::from_slice(r.as_ref()) }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_bool().ok_or("Invalid type returned")?; r }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_bool().ok_or("Invalid type returned")?; r }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()) })) - } - - /// Auto-generated from: `{"constant":false,"inputs":[{"name":"_release","type":"bytes32"},{"name":"_platform","type":"bytes32"},{"name":"_checksum","type":"bytes32"}],"name":"addChecksum","outputs":[],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn add_checksum(&self, _release: &bigint::hash::H256, _platform: &str, _checksum: &bigint::hash::H256) -> Result<(), String> { - let call = self.contract.function("addChecksum".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_release.as_ref().to_owned()), ethabi::Token::FixedBytes(_platform.as_bytes().to_owned()), ethabi::Token::FixedBytes(_checksum.as_ref().to_owned())] - ).map_err(Self::as_string)?; - call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - - Ok(()) - } - - /// Auto-generated from: `{"constant":false,"inputs":[{"name":"_txid","type":"bytes32"}],"name":"confirmTransaction","outputs":[{"name":"txSuccess","type":"uint256"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn confirm_transaction(&self, _txid: &bigint::hash::H256) -> Result { - let call = self.contract.function("confirmTransaction".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_txid.as_ref().to_owned())] - ).map_err(Self::as_string)?; - let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()) })) - } - - /// Auto-generated from: `{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"proxy","outputs":[{"name":"requiredCount","type":"uint256"},{"name":"to","type":"address"},{"name":"data","type":"bytes"},{"name":"value","type":"uint256"},{"name":"gas","type":"uint256"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn proxy(&self, _1: &bigint::hash::H256) -> Result<(bigint::prelude::U256, util::Address, Vec, bigint::prelude::U256, bigint::prelude::U256), String> { - let call = self.contract.function("proxy".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_1.as_ref().to_owned())] - ).map_err(Self::as_string)?; - let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()) }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_address().ok_or("Invalid type returned")?; util::Address::from(r) }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_bytes().ok_or("Invalid type returned")?; r }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()) }, { let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()) })) - } - - /// Auto-generated from: `{"constant":false,"inputs":[{"name":"_client","type":"bytes32"},{"name":"_owner","type":"address"}],"name":"addClient","outputs":[],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn add_client(&self, _client: &str, _owner: &util::Address) -> Result<(), String> { - let call = self.contract.function("addClient".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::Address(_owner.clone().0)] - ).map_err(Self::as_string)?; - call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - - Ok(()) - } - - /// Auto-generated from: `{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"clientOwner","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn client_owner(&self, _1: &util::Address) -> Result { - let call = self.contract.function("clientOwner".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::Address(_1.clone().0)] - ).map_err(Self::as_string)?; - let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_fixed_bytes().ok_or("Invalid type returned")?; bigint::hash::H256::from_slice(r.as_ref()) })) - } - - /// Auto-generated from: `{"constant":false,"inputs":[{"name":"_txid","type":"bytes32"},{"name":"_to","type":"address"},{"name":"_data","type":"bytes"},{"name":"_value","type":"uint256"},{"name":"_gas","type":"uint256"}],"name":"proposeTransaction","outputs":[{"name":"txSuccess","type":"uint256"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn propose_transaction(&self, _txid: &bigint::hash::H256, _to: &util::Address, _data: &[u8], _value: bigint::prelude::U256, _gas: bigint::prelude::U256) -> Result { - let call = self.contract.function("proposeTransaction".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_txid.as_ref().to_owned()), ethabi::Token::Address(_to.clone().0), ethabi::Token::Bytes(_data.to_owned()), ethabi::Token::Uint({ let mut r = [0u8; 32]; _value.to_big_endian(&mut r); r }), ethabi::Token::Uint({ let mut r = [0u8; 32]; _gas.to_big_endian(&mut r); r })] - ).map_err(Self::as_string)?; - let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()) })) - } - - /// Auto-generated from: `{"constant":true,"inputs":[],"name":"grandOwner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn grand_owner(&self) -> Result { - let call = self.contract.function("grandOwner".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![] - ).map_err(Self::as_string)?; - let output = call.decode_output(&&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_address().ok_or("Invalid type returned")?; util::Address::from(r) })) - } - - /// Auto-generated from: `{"constant":false,"inputs":[{"name":"_release","type":"bytes32"},{"name":"_forkBlock","type":"uint32"},{"name":"_track","type":"uint8"},{"name":"_semver","type":"uint24"},{"name":"_critical","type":"bool"}],"name":"addRelease","outputs":[],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn add_release(&self, _release: &bigint::hash::H256, _fork_block: u32, _track: u8, _semver: u32, _critical: bool) -> Result<(), String> { - let call = self.contract.function("addRelease".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_release.as_ref().to_owned()), ethabi::Token::Uint({ let mut r = [0u8; 32]; bigint::prelude::U256::from(_fork_block as u64).to_big_endian(&mut r); r }), ethabi::Token::Uint({ let mut r = [0u8; 32]; bigint::prelude::U256::from(_track as u64).to_big_endian(&mut r); r }), ethabi::Token::Uint({ let mut r = [0u8; 32]; bigint::prelude::U256::from(_semver as u64).to_big_endian(&mut r); r }), ethabi::Token::Bool(_critical)] - ).map_err(Self::as_string)?; - call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - - Ok(()) - } - - /// Auto-generated from: `{"constant":false,"inputs":[],"name":"acceptFork","outputs":[],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn accept_fork(&self) -> Result<(), String> { - let call = self.contract.function("acceptFork".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![] - ).map_err(Self::as_string)?; - call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - - Ok(()) - } - - /// Auto-generated from: `{"constant":true,"inputs":[],"name":"clientsRequired","outputs":[{"name":"","type":"uint32"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn clients_required(&self) -> Result { - let call = self.contract.function("clientsRequired".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![] - ).map_err(Self::as_string)?; - let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()).as_u64() as u32 })) - } - - /// Auto-generated from: `{"constant":true,"inputs":[{"name":"_client","type":"bytes32"},{"name":"_release","type":"bytes32"}],"name":"track","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn track(&self, _client: &str, _release: &bigint::hash::H256) -> Result { - let call = self.contract.function("track".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::FixedBytes(_release.as_ref().to_owned())] - ).map_err(Self::as_string)?; - let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()).as_u64() as u8 })) - } - - /// Auto-generated from: `{"constant":false,"inputs":[{"name":"_client","type":"bytes32"},{"name":"_r","type":"bool"}],"name":"setClientRequired","outputs":[],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn set_client_required(&self, _client: &str, _r: bool) -> Result<(), String> { - let call = self.contract.function("setClientRequired".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::Bool(_r)] - ).map_err(Self::as_string)?; - call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - - Ok(()) - } - - /// Auto-generated from: `{"constant":true,"inputs":[],"name":"latestFork","outputs":[{"name":"","type":"uint32"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn latest_fork(&self) -> Result { - let call = self.contract.function("latestFork".into()).map_err(Self::as_string)?; - let data = call.encode_input(&[]).map_err(Self::as_string)?; - let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()).as_u64() as u32 })) - } - - /// Auto-generated from: `{"constant":true,"inputs":[{"name":"_client","type":"bytes32"},{"name":"_track","type":"uint8"}],"name":"latestInTrack","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn latest_in_track(&self, _client: &str, _track: u8) -> Result { - let call = self.contract.function("latestInTrack".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - &vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::Uint({ let mut r = [0u8; 32]; bigint::prelude::U256::from(_track as u64).to_big_endian(&mut r); r })] - ).map_err(Self::as_string)?; - let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_fixed_bytes().ok_or("Invalid type returned")?; bigint::hash::H256::from_slice(r.as_ref()) })) - } - - /// Auto-generated from: `{"constant":true,"inputs":[{"name":"_client","type":"bytes32"},{"name":"_release","type":"bytes32"},{"name":"_platform","type":"bytes32"}],"name":"checksum","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn checksum(&self, _client: &str, _release: &bigint::hash::H256, _platform: &str) -> Result { - let call = self.contract.function("checksum".into()).map_err(Self::as_string)?; - let data = call.encode_input(& - vec![ethabi::Token::FixedBytes(_client.as_bytes().to_owned()), ethabi::Token::FixedBytes(_release.as_ref().to_owned()), ethabi::Token::FixedBytes(_platform.as_bytes().to_owned())] - ).map_err(Self::as_string)?; - let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_fixed_bytes().ok_or("Invalid type returned")?; bigint::hash::H256::from_slice(r.as_ref()) })) - } - - /// Auto-generated from: `{"constant":true,"inputs":[],"name":"proposedFork","outputs":[{"name":"","type":"uint32"}],"payable":false,"type":"function"}` - #[allow(dead_code)] - pub fn proposed_fork(&self) -> Result { - let call = self.contract.function("proposedFork".into()).map_err(Self::as_string)?; - let data = call.encode_input(&[]).map_err(Self::as_string)?; - let output = call.decode_output(&(self.do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; - let mut result = output.into_iter().rev().collect::>(); - Ok(({ let r = result.pop().ok_or("Invalid return arity")?; let r = r.to_uint().ok_or("Invalid type returned")?; bigint::prelude::U256::from(r.as_ref()).as_u64() as u32 })) - } -} diff --git a/updater/src/types/release_track.rs b/updater/src/types/release_track.rs index 0eaf85d1447..5e9cd8581a9 100644 --- a/updater/src/types/release_track.rs +++ b/updater/src/types/release_track.rs @@ -69,9 +69,10 @@ impl From for ReleaseTrack { } } -impl Into for ReleaseTrack { - fn into(self) -> u8 { - match self { + +impl From for u8 { + fn from(rt: ReleaseTrack) -> Self { + match rt { ReleaseTrack::Stable => 1, ReleaseTrack::Beta => 2, ReleaseTrack::Nightly => 3, diff --git a/updater/src/updater.rs b/updater/src/updater.rs index 91c9181f849..98eaf6db8ee 100644 --- a/updater/src/updater.rs +++ b/updater/src/updater.rs @@ -24,7 +24,6 @@ use ethsync::{SyncProvider}; use futures::future; use hash_fetch::{self as fetch, HashFetch}; use hash_fetch::fetch::Client as FetchService; -use operations::Operations; use parity_reactor::Remote; use path::restrict_permissions_owner; use service::{Service}; @@ -36,6 +35,34 @@ use bytes::Bytes; use parking_lot::Mutex; use util::misc; +use_contract!(operations_contract,"Operations","./res/operations.abi"); + +mod updater_utils { + use ethabi; + use bigint; + use std::str::FromStr; + + pub fn str_to_ethabi_hash(s: &str) -> ethabi::Hash { + bigint::prelude::U256::from_str(s).unwrap().into() + } + + pub fn uint_to_u64(uint: [u8; 32]) -> u64 { + bigint::prelude::U256::from(uint.as_ref()).as_u64() + } + + pub fn uint_to_u32(uint: [u8; 32]) -> u32 { + bigint::prelude::U256::from(uint.as_ref()).as_u32() + } + + pub fn uint_to_u8(uint: [u8; 32]) -> u8 { + bigint::prelude::U256::from(uint.as_ref()).as_u32() as u8 + } + + pub fn uint_to_h256(uint: [u8; 32]) -> bigint::prelude::H256 { + bigint::prelude::H256::from(uint.as_ref()) + } +} + /// Filter for releases. #[derive(Debug, Eq, PartialEq, Clone)] pub enum UpdateFilter { @@ -95,7 +122,8 @@ pub struct Updater { client: Weak, sync: Weak, fetcher: Mutex>, - operations: Mutex>, + operations_contract: operations_contract::Operations, + do_call: Mutex) -> Result, String> + Send + Sync + 'static>>>, exit_handler: Mutex>>, // Our version info (static) @@ -127,7 +155,8 @@ impl Updater { client: client.clone(), sync: sync.clone(), fetcher: Mutex::new(None), - operations: Mutex::new(None), + operations_contract: operations_contract::Operations::default(), + do_call: Mutex::new(None), exit_handler: Mutex::new(None), this: VersionInfo::this(), state: Mutex::new(Default::default()), @@ -143,9 +172,24 @@ impl Updater { *self.exit_handler.lock() = Some(Box::new(f)); } - fn collect_release_info(operations: &Operations, release_id: &H256) -> Result { - let (fork, track, semver, is_critical) = operations.release(CLIENT_ID, release_id)?; - let latest_binary = operations.checksum(CLIENT_ID, release_id, &platform())?; + fn collect_release_info(operations_contract: &operations_contract::Operations, do_call: &Box) -> Result, String> + Send + Sync + 'static>, release_id: &H256) -> Result { + let (fork, track, semver, is_critical) = operations_contract.functions().release() + .call( + updater_utils::str_to_ethabi_hash(&CLIENT_ID), + release_id.to_owned(), + &**do_call) + .map_err(|e| format!("{:?}", e))?; + let (fork, track, semver) = (updater_utils::uint_to_u32(fork), updater_utils::uint_to_u8(track), updater_utils::uint_to_u32(semver)); + + let latest_binary = operations_contract.functions().checksum() + .call( + updater_utils::str_to_ethabi_hash(&CLIENT_ID), + release_id.to_owned(), + updater_utils::str_to_ethabi_hash(&platform()), + &**do_call) + .map_err(|e| format!("{:?}", e))?; + let latest_binary = ::bigint::hash::H256::from(latest_binary); + Ok(ReleaseInfo { version: VersionInfo::from_raw(semver, track, release_id.clone().into()), is_critical: is_critical, @@ -162,21 +206,34 @@ impl Updater { } fn collect_latest(&self) -> Result { - if let Some(ref operations) = *self.operations.lock() { + if let &Some(ref do_call) = &*self.do_call.lock() { let hh: H256 = self.this.hash.into(); trace!(target: "updater", "Looking up this_fork for our release: {}/{:?}", CLIENT_ID, hh); - let this_fork = operations.release(CLIENT_ID, &self.this.hash.into()).ok() + let this_fork = self.operations_contract.functions().release() + .call( + updater_utils::str_to_ethabi_hash(&CLIENT_ID), + ::bigint::prelude::H256::from(self.this.hash), + &**do_call) + .ok() .and_then(|(fork, track, _, _)| { - trace!(target: "updater", "Operations returned fork={}, track={}", fork as u64, track); - if track > 0 {Some(fork as u64)} else {None} + let fork_u64 : u64 = updater_utils::uint_to_u64(fork); + let track_u64 : u64 = updater_utils::uint_to_u64(track); + trace!(target: "updater", "Operations returned fork={}, track={}", fork_u64, track_u64); + if track_u64 > 0 {Some(fork_u64)} else {None} }); if self.track() == ReleaseTrack::Unknown { return Err(format!("Current executable ({}) is unreleased.", H160::from(self.this.hash))); } - let latest_in_track = operations.latest_in_track(CLIENT_ID, self.track().into())?; - let in_track = Self::collect_release_info(operations, &latest_in_track)?; + let latest_in_track = self.operations_contract.functions().latest_in_track() + .call( + updater_utils::str_to_ethabi_hash(&CLIENT_ID), + ::bigint::prelude::U256::from(u8::from(self.track())), + &**do_call) + .map(|x| updater_utils::uint_to_h256(x)) + .map_err(|e| format!("{:?}", e))?; + let in_track = Self::collect_release_info(&self.operations_contract, do_call, &latest_in_track)?; let mut in_minor = Some(in_track.clone()); const PROOF: &'static str = "in_minor initialised and assigned with Some; loop breaks if None assigned; qed"; while in_minor.as_ref().expect(PROOF).version.track != self.track() { @@ -185,11 +242,24 @@ impl Updater { ReleaseTrack::Nightly => ReleaseTrack::Beta, _ => { in_minor = None; break; } }; - in_minor = Some(Self::collect_release_info(operations, &operations.latest_in_track(CLIENT_ID, track.into())?)?); + in_minor = Some(Self::collect_release_info( + &self.operations_contract, + do_call, + &::bigint::hash::H256::from( + self.operations_contract + .functions() + .latest_in_track() + .call( + updater_utils::str_to_ethabi_hash(&CLIENT_ID), + ::bigint::prelude::U256::from(u8::from(track)), + &**do_call) + .map_err(|e| format!("{:?}", e))? + ) + )?); } Ok(OperationsInfo { - fork: operations.latest_fork()? as u64, + fork: updater_utils::uint_to_u64(self.operations_contract.functions().latest_fork().call(&**do_call).map_err(|e| format!("{:?}", e))?), this_fork: this_fork, track: in_track, minor: in_minor, @@ -247,11 +317,11 @@ impl Updater { return; } - if self.operations.lock().is_none() { + if self.do_call.lock().is_none() { if let Some(ops_addr) = self.client.upgrade().and_then(|c| c.registry_address("operations".into())) { trace!(target: "updater", "Found operations at {}", ops_addr); let client = self.client.clone(); - *self.operations.lock() = Some(Operations::new(ops_addr, move |a, d| client.upgrade().ok_or("No client!".into()).and_then(|c| c.call_contract(BlockId::Latest, a, d)))); + *self.do_call.lock() = Some(Box::new(move |input| client.upgrade().ok_or("No client!".into()).and_then(|c| c.call_contract(BlockId::Latest, ops_addr, input)).map_err(|e| format!("{:?}", e)))); } else { // No Operations contract - bail. return; From 6f583c5e2cb6e221d252e1b9bd6a2bb02862c739 Mon Sep 17 00:00:00 2001 From: Axel Chalon Date: Thu, 2 Nov 2017 12:51:26 +0100 Subject: [PATCH 2/3] Grumble: do_call type alias --- updater/src/updater.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/updater/src/updater.rs b/updater/src/updater.rs index 98eaf6db8ee..2982dffb707 100644 --- a/updater/src/updater.rs +++ b/updater/src/updater.rs @@ -63,6 +63,8 @@ mod updater_utils { } } +pub type DoCallFn = Fn(Vec) -> Result, String> + Send + Sync + 'static; + /// Filter for releases. #[derive(Debug, Eq, PartialEq, Clone)] pub enum UpdateFilter { @@ -123,7 +125,7 @@ pub struct Updater { sync: Weak, fetcher: Mutex>, operations_contract: operations_contract::Operations, - do_call: Mutex) -> Result, String> + Send + Sync + 'static>>>, + do_call: Mutex>>, exit_handler: Mutex>>, // Our version info (static) @@ -172,7 +174,7 @@ impl Updater { *self.exit_handler.lock() = Some(Box::new(f)); } - fn collect_release_info(operations_contract: &operations_contract::Operations, do_call: &Box) -> Result, String> + Send + Sync + 'static>, release_id: &H256) -> Result { + fn collect_release_info(operations_contract: &operations_contract::Operations, do_call: &Box, release_id: &H256) -> Result { let (fork, track, semver, is_critical) = operations_contract.functions().release() .call( updater_utils::str_to_ethabi_hash(&CLIENT_ID), From a970c45119b63f082a6aaa0808bf572ae6d39a88 Mon Sep 17 00:00:00 2001 From: Axel Chalon Date: Fri, 3 Nov 2017 12:55:05 +0100 Subject: [PATCH 3/3] Empty commit to trigger test re-run