Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Merge pull request #7101 from paritytech/secretstore_kovan
Browse files Browse the repository at this point in the history
SecretStore: Kovan integration initial version
  • Loading branch information
debris committed Dec 29, 2017
2 parents 48a15ce + fc0eb60 commit f8bd6b9
Show file tree
Hide file tree
Showing 35 changed files with 1,704 additions and 629 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions ethcore/native_contracts/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const REGISTRY_ABI: &'static str = include_str!("res/registrar.json");
const URLHINT_ABI: &'static str = include_str!("res/urlhint.json");
const SERVICE_TRANSACTION_ABI: &'static str = include_str!("res/service_transaction.json");
const SECRETSTORE_ACL_STORAGE_ABI: &'static str = include_str!("res/secretstore_acl_storage.json");
const SECRETSTORE_SERVICE_ABI: &'static str = include_str!("res/secretstore_service.json");
const VALIDATOR_SET_ABI: &'static str = include_str!("res/validator_set.json");
const VALIDATOR_REPORT_ABI: &'static str = include_str!("res/validator_report.json");
const PEER_SET_ABI: &'static str = include_str!("res/peer_set.json");
Expand Down Expand Up @@ -53,6 +54,7 @@ fn main() {
build_file("Urlhint", URLHINT_ABI, "urlhint.rs");
build_file("ServiceTransactionChecker", SERVICE_TRANSACTION_ABI, "service_transaction.rs");
build_file("SecretStoreAclStorage", SECRETSTORE_ACL_STORAGE_ABI, "secretstore_acl_storage.rs");
build_file("SecretStoreService", SECRETSTORE_SERVICE_ABI, "secretstore_service.rs");
build_file("ValidatorSet", VALIDATOR_SET_ABI, "validator_set.rs");
build_file("ValidatorReport", VALIDATOR_REPORT_ABI, "validator_report.rs");
build_file("PeerSet", PEER_SET_ABI, "peer_set.rs");
Expand Down
36 changes: 25 additions & 11 deletions ethcore/native_contracts/generator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub fn generate_module(struct_name: &str, abi: &str) -> Result<String, Error> {
Ok(format!(r##"
use byteorder::{{BigEndian, ByteOrder}};
use futures::{{future, Future, IntoFuture}};
use ethabi::{{Contract, Token, Event}};
use ethabi::{{Bytes, Contract, Token, Event}};
use bigint;
type BoxFuture<A, B> = Box<Future<Item = A, Error = B> + Send>;
Expand Down Expand Up @@ -96,7 +96,7 @@ fn generate_functions(contract: &Contract) -> Result<String, Error> {
let inputs: Vec<_> = function.inputs.iter().map(|i| i.kind.clone()).collect();
let outputs: Vec<_> = function.outputs.iter().map(|i| i.kind.clone()).collect();

let (input_params, to_tokens) = input_params_codegen(&inputs)
let (input_params, input_names, to_tokens) = input_params_codegen(&inputs)
.map_err(|bad_type| Error::UnsupportedType(name.clone(), bad_type))?;

let (output_type, decode_outputs) = output_params_codegen(&outputs)
Expand All @@ -113,27 +113,37 @@ pub fn {snake_name}<F, U>(&self, call: F, {params}) -> BoxFuture<{output_type},
U: IntoFuture<Item=Vec<u8>, Error=String>,
U::Future: Send + 'static
{{
let function = self.contract.function(r#"{abi_name}"#)
.expect("function existence checked at compile-time; qed").clone();
let call_addr = self.address;
let call_future = match function.encode_input(&{to_tokens}) {{
let call_future = match self.encode_{snake_name}_input({params_names}) {{
Ok(call_data) => (call)(call_addr, call_data),
Err(e) => return Box::new(future::err(format!("Error encoding call: {{:?}}", e))),
Err(e) => return Box::new(future::err(e)),
}};
let function = self.contract.function(r#"{abi_name}"#)
.expect("function existence checked at compile-time; qed").clone();
Box::new(call_future
.into_future()
.and_then(move |out| function.decode_output(&out).map_err(|e| format!("{{:?}}", e)))
.map(Vec::into_iter)
.and_then(|mut outputs| {decode_outputs}))
}}
/// Encode "{abi_name}" function arguments.
/// Arguments: {abi_inputs:?}
pub fn encode_{snake_name}_input(&self, {params}) -> Result<Vec<u8>, String> {{
self.contract.function(r#"{abi_name}"#)
.expect("function existence checked at compile-time; qed")
.encode_input(&{to_tokens})
.map_err(|e| format!("Error encoding call: {{:?}}", e))
}}
"##,
abi_name = name,
abi_inputs = inputs,
abi_outputs = outputs,
snake_name = snake_name,
params = input_params,
params_names = input_names,
output_type = output_type,
to_tokens = to_tokens,
decode_outputs = decode_outputs,
Expand All @@ -145,15 +155,17 @@ pub fn {snake_name}<F, U>(&self, call: F, {params}) -> BoxFuture<{output_type},

// generate code for params in function signature and turning them into tokens.
//
// two pieces of code are generated: the first gives input types for the function signature,
// and the second gives code to tokenize those inputs.
// three pieces of code are generated: the first gives input types for the function signature,
// the second one gives input parameter names to pass to another method,
// and the third gives code to tokenize those inputs.
//
// params of form `param_0: type_0, param_1: type_1, ...`
// tokenizing code of form `{let mut tokens = Vec::new(); tokens.push({param_X}); tokens }`
//
// returns any unsupported param type encountered.
fn input_params_codegen(inputs: &[ParamType]) -> Result<(String, String), ParamType> {
fn input_params_codegen(inputs: &[ParamType]) -> Result<(String, String, String), ParamType> {
let mut params = String::new();
let mut params_names = String::new();
let mut to_tokens = "{ let mut tokens = Vec::new();".to_string();

for (index, param_type) in inputs.iter().enumerate() {
Expand All @@ -164,11 +176,13 @@ fn input_params_codegen(inputs: &[ParamType]) -> Result<(String, String), ParamT
params.push_str(&format!("{}{}: {}, ",
if needs_mut { "mut " } else { "" }, param_name, rust_type));

params_names.push_str(&format!("{}, ", param_name));

to_tokens.push_str(&format!("tokens.push({{ {} }});", tokenize_code));
}

to_tokens.push_str(" tokens }");
Ok((params, to_tokens))
Ok((params, params_names, to_tokens))
}

// generate code for outputs of the function and detokenizing them.
Expand Down
8 changes: 8 additions & 0 deletions ethcore/native_contracts/res/secretstore_service.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{"constant":true,"inputs":[],"name":"serverKeyGenerationRequestsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},
{"constant":true,"inputs":[{"name":"index","type":"uint256"}],"name":"getServerKeyId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},
{"constant":false,"inputs":[{"name":"serverKeyId","type":"bytes32"},{"name":"serverKeyPublic","type":"bytes"},{"name":"v","type":"uint8"},{"name":"r","type":"bytes32"},{"name":"s","type":"bytes32"}],"name":"serverKeyGenerated","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},
{"constant":true,"inputs":[{"name":"serverKeyId","type":"bytes32"}],"name":"getServerKeyThreshold","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},
{"constant":true,"inputs":[{"name":"serverKeyId","type":"bytes32"},{"name":"authority","type":"address"}],"name":"getServerKeyConfirmationStatus","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},
{"anonymous":false,"inputs":[{"indexed":true,"name":"serverKeyId","type":"bytes32"},{"indexed":true,"name":"threshold","type":"uint256"}],"name":"ServerKeyRequested","type":"event"}
]
2 changes: 2 additions & 0 deletions ethcore/native_contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ mod registry;
mod urlhint;
mod service_transaction;
mod secretstore_acl_storage;
mod secretstore_service;
mod validator_set;
mod validator_report;
mod peer_set;
Expand All @@ -40,6 +41,7 @@ pub use self::registry::Registry;
pub use self::urlhint::Urlhint;
pub use self::service_transaction::ServiceTransactionChecker;
pub use self::secretstore_acl_storage::SecretStoreAclStorage;
pub use self::secretstore_service::SecretStoreService;
pub use self::validator_set::ValidatorSet;
pub use self::validator_report::ValidatorReport;
pub use self::peer_set::PeerSet;
Expand Down
21 changes: 21 additions & 0 deletions ethcore/native_contracts/src/secretstore_service.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.

// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

#![allow(unused_mut, unused_variables, unused_imports)]

//! Secret store service contract.

include!(concat!(env!("OUT_DIR"), "/secretstore_service.rs"));
7 changes: 7 additions & 0 deletions parity/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,10 @@ usage! {
"--no-acl-check",
"Disable ACL check (useful for test environments).",

ARG arg_secretstore_contract: (String) = "none", or |c: &Config| otry!(c.secretstore).service_contract.clone(),
"--secretstore-contract=[SOURCE]",
"Secret Store Service contract address source: none, registry (contract address is read from registry) or address.",

ARG arg_secretstore_nodes: (String) = "", or |c: &Config| otry!(c.secretstore).nodes.as_ref().map(|vec| vec.join(",")),
"--secretstore-nodes=[NODES]",
"Comma-separated list of other secret store cluster nodes in form NODE_PUBLIC_KEY_IN_HEX@NODE_IP_ADDR:NODE_PORT.",
Expand Down Expand Up @@ -1093,6 +1097,7 @@ struct SecretStore {
disable: Option<bool>,
disable_http: Option<bool>,
disable_acl_check: Option<bool>,
service_contract: Option<String>,
self_secret: Option<String>,
admin_public: Option<String>,
nodes: Option<Vec<String>>,
Expand Down Expand Up @@ -1494,6 +1499,7 @@ mod tests {
flag_no_secretstore: false,
flag_no_secretstore_http: false,
flag_no_secretstore_acl_check: false,
arg_secretstore_contract: "none".into(),
arg_secretstore_secret: None,
arg_secretstore_admin_public: None,
arg_secretstore_nodes: "".into(),
Expand Down Expand Up @@ -1737,6 +1743,7 @@ mod tests {
disable: None,
disable_http: None,
disable_acl_check: None,
service_contract: None,
self_secret: None,
admin_public: None,
nodes: None,
Expand Down
1 change: 1 addition & 0 deletions parity/cli/tests/config.full.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ pass = "test_pass"
disable = false
disable_http = false
disable_acl_check = false
service_contract = "none"
nodes = []
http_interface = "local"
http_port = 8082
Expand Down
11 changes: 10 additions & 1 deletion parity/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ use ethcore_logger::Config as LogConfig;
use dir::{self, Directories, default_hypervisor_path, default_local_path, default_data_path};
use dapps::Configuration as DappsConfiguration;
use ipfs::Configuration as IpfsConfiguration;
use secretstore::{Configuration as SecretStoreConfiguration, NodeSecretKey};
use secretstore::{NodeSecretKey, Configuration as SecretStoreConfiguration, ContractAddress as SecretStoreContractAddress};
use updater::{UpdatePolicy, UpdateFilter, ReleaseTrack};
use run::RunCmd;
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockchain, ExportState, DataFormat};
Expand Down Expand Up @@ -608,6 +608,7 @@ impl Configuration {
enabled: self.secretstore_enabled(),
http_enabled: self.secretstore_http_enabled(),
acl_check_enabled: self.secretstore_acl_check_enabled(),
service_contract_address: self.secretstore_service_contract_address()?,
self_secret: self.secretstore_self_secret()?,
nodes: self.secretstore_nodes()?,
interface: self.secretstore_interface(),
Expand Down Expand Up @@ -1085,6 +1086,14 @@ impl Configuration {
!self.args.flag_no_secretstore_acl_check
}

fn secretstore_service_contract_address(&self) -> Result<Option<SecretStoreContractAddress>, String> {
Ok(match self.args.arg_secretstore_contract.as_ref() {
"none" => None,
"registry" => Some(SecretStoreContractAddress::Registry),
a => Some(SecretStoreContractAddress::Address(a.parse().map_err(|e| format!("{}", e))?)),
})
}

fn ui_enabled(&self) -> bool {
if self.args.flag_force_ui {
return true;
Expand Down
1 change: 1 addition & 0 deletions parity/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
// secret store key server
let secretstore_deps = secretstore::Dependencies {
client: client.clone(),
sync: sync_provider.clone(),
account_provider: account_provider,
accounts_passwords: &passwords,
};
Expand Down
25 changes: 22 additions & 3 deletions parity/secretstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,28 @@ use dir::default_data_path;
use ethcore::account_provider::AccountProvider;
use ethcore::client::Client;
use ethkey::{Secret, Public};
use ethsync::SyncProvider;
use helpers::replace_home;
use util::Address;

#[derive(Debug, PartialEq, Clone)]
/// This node secret key.
#[derive(Debug, PartialEq, Clone)]
pub enum NodeSecretKey {
/// Stored as plain text in configuration file.
Plain(Secret),
/// Stored as account in key store.
KeyStore(Address),
}

/// Secret store service contract address.
#[derive(Debug, PartialEq, Clone)]
pub enum ContractAddress {
/// Contract address is read from registry.
Registry,
/// Contract address is specified.
Address(Address),
}

#[derive(Debug, PartialEq, Clone)]
/// Secret store configuration
pub struct Configuration {
Expand All @@ -41,6 +51,8 @@ pub struct Configuration {
pub http_enabled: bool,
/// Is ACL check enabled.
pub acl_check_enabled: bool,
/// Service contract address.
pub service_contract_address: Option<ContractAddress>,
/// This node secret.
pub self_secret: Option<NodeSecretKey>,
/// Other nodes IDs + addresses.
Expand All @@ -63,6 +75,8 @@ pub struct Configuration {
pub struct Dependencies<'a> {
/// Blockchain client.
pub client: Arc<Client>,
/// Sync provider.
pub sync: Arc<SyncProvider>,
/// Account provider.
pub account_provider: Arc<AccountProvider>,
/// Passed accounts passwords.
Expand Down Expand Up @@ -90,7 +104,7 @@ mod server {
use ethcore_secretstore;
use ethkey::KeyPair;
use ansi_term::Colour::Red;
use super::{Configuration, Dependencies, NodeSecretKey};
use super::{Configuration, Dependencies, NodeSecretKey, ContractAddress};

/// Key server
pub struct KeyServer {
Expand Down Expand Up @@ -134,6 +148,10 @@ mod server {
address: conf.http_interface.clone(),
port: conf.http_port,
}) } else { None },
service_contract_address: conf.service_contract_address.map(|c| match c {
ContractAddress::Registry => ethcore_secretstore::ContractAddress::Registry,
ContractAddress::Address(address) => ethcore_secretstore::ContractAddress::Address(address),
}),
data_path: conf.data_path.clone(),
acl_check_enabled: conf.acl_check_enabled,
cluster_config: ethcore_secretstore::ClusterConfiguration {
Expand All @@ -153,7 +171,7 @@ mod server {

cconf.cluster_config.nodes.insert(self_secret.public().clone(), cconf.cluster_config.listener_address.clone());

let key_server = ethcore_secretstore::start(deps.client, self_secret, cconf)
let key_server = ethcore_secretstore::start(deps.client, deps.sync, self_secret, cconf)
.map_err(|e| format!("Error starting KeyServer {}: {}", key_server_name, e))?;

Ok(KeyServer {
Expand All @@ -172,6 +190,7 @@ impl Default for Configuration {
enabled: true,
http_enabled: true,
acl_check_enabled: true,
service_contract_address: None,
self_secret: None,
admin_public: None,
nodes: BTreeMap::new(),
Expand Down
1 change: 1 addition & 0 deletions secret_store/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ ethcore = { path = "../ethcore" }
ethcore-bytes = { path = "../util/bytes" }
ethcore-util = { path = "../util" }
ethcore-bigint = { path = "../util/bigint" }
ethsync = { path = "../sync" }
kvdb = { path = "../util/kvdb" }
kvdb-rocksdb = { path = "../util/kvdb-rocksdb" }
keccak-hash = { path = "../util/hash" }
Expand Down

0 comments on commit f8bd6b9

Please sign in to comment.