SecretStore: cli option to configure service contract
This commit is contained in:
parent
30816d8155
commit
14686f2652
@ -551,6 +551,10 @@ usage! {
|
|||||||
"--no-acl-check",
|
"--no-acl-check",
|
||||||
"Disable ACL check (useful for test environments).",
|
"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 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(",")),
|
ARG arg_secretstore_nodes: (String) = "", or |c: &Config| otry!(c.secretstore).nodes.as_ref().map(|vec| vec.join(",")),
|
||||||
"--secretstore-nodes=[NODES]",
|
"--secretstore-nodes=[NODES]",
|
||||||
"Comma-separated list of other secret store cluster nodes in form NODE_PUBLIC_KEY_IN_HEX@NODE_IP_ADDR:NODE_PORT.",
|
"Comma-separated list of other secret store cluster nodes in form NODE_PUBLIC_KEY_IN_HEX@NODE_IP_ADDR:NODE_PORT.",
|
||||||
@ -1088,6 +1092,7 @@ struct SecretStore {
|
|||||||
disable: Option<bool>,
|
disable: Option<bool>,
|
||||||
disable_http: Option<bool>,
|
disable_http: Option<bool>,
|
||||||
disable_acl_check: Option<bool>,
|
disable_acl_check: Option<bool>,
|
||||||
|
service_contract: Option<String>,
|
||||||
self_secret: Option<String>,
|
self_secret: Option<String>,
|
||||||
admin_public: Option<String>,
|
admin_public: Option<String>,
|
||||||
nodes: Option<Vec<String>>,
|
nodes: Option<Vec<String>>,
|
||||||
@ -1488,6 +1493,7 @@ mod tests {
|
|||||||
flag_no_secretstore: false,
|
flag_no_secretstore: false,
|
||||||
flag_no_secretstore_http: false,
|
flag_no_secretstore_http: false,
|
||||||
flag_no_secretstore_acl_check: false,
|
flag_no_secretstore_acl_check: false,
|
||||||
|
arg_secretstore_contract: "none".into(),
|
||||||
arg_secretstore_secret: None,
|
arg_secretstore_secret: None,
|
||||||
arg_secretstore_admin_public: None,
|
arg_secretstore_admin_public: None,
|
||||||
arg_secretstore_nodes: "".into(),
|
arg_secretstore_nodes: "".into(),
|
||||||
@ -1730,6 +1736,7 @@ mod tests {
|
|||||||
disable: None,
|
disable: None,
|
||||||
disable_http: None,
|
disable_http: None,
|
||||||
disable_acl_check: None,
|
disable_acl_check: None,
|
||||||
|
service_contract: None,
|
||||||
self_secret: None,
|
self_secret: None,
|
||||||
admin_public: None,
|
admin_public: None,
|
||||||
nodes: None,
|
nodes: None,
|
||||||
|
@ -80,6 +80,7 @@ pass = "test_pass"
|
|||||||
disable = false
|
disable = false
|
||||||
disable_http = false
|
disable_http = false
|
||||||
disable_acl_check = false
|
disable_acl_check = false
|
||||||
|
service_contract = "none"
|
||||||
nodes = []
|
nodes = []
|
||||||
http_interface = "local"
|
http_interface = "local"
|
||||||
http_port = 8082
|
http_port = 8082
|
||||||
|
@ -45,7 +45,7 @@ use ethcore_logger::Config as LogConfig;
|
|||||||
use dir::{self, Directories, default_hypervisor_path, default_local_path, default_data_path};
|
use dir::{self, Directories, default_hypervisor_path, default_local_path, default_data_path};
|
||||||
use dapps::Configuration as DappsConfiguration;
|
use dapps::Configuration as DappsConfiguration;
|
||||||
use ipfs::Configuration as IpfsConfiguration;
|
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 updater::{UpdatePolicy, UpdateFilter, ReleaseTrack};
|
||||||
use run::RunCmd;
|
use run::RunCmd;
|
||||||
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockchain, ExportState, DataFormat};
|
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockchain, ExportState, DataFormat};
|
||||||
@ -606,6 +606,7 @@ impl Configuration {
|
|||||||
enabled: self.secretstore_enabled(),
|
enabled: self.secretstore_enabled(),
|
||||||
http_enabled: self.secretstore_http_enabled(),
|
http_enabled: self.secretstore_http_enabled(),
|
||||||
acl_check_enabled: self.secretstore_acl_check_enabled(),
|
acl_check_enabled: self.secretstore_acl_check_enabled(),
|
||||||
|
service_contract_address: self.secretstore_service_contract_address()?,
|
||||||
self_secret: self.secretstore_self_secret()?,
|
self_secret: self.secretstore_self_secret()?,
|
||||||
nodes: self.secretstore_nodes()?,
|
nodes: self.secretstore_nodes()?,
|
||||||
interface: self.secretstore_interface(),
|
interface: self.secretstore_interface(),
|
||||||
@ -1076,6 +1077,14 @@ impl Configuration {
|
|||||||
!self.args.flag_no_secretstore_acl_check
|
!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 {
|
fn ui_enabled(&self) -> bool {
|
||||||
if self.args.flag_force_ui {
|
if self.args.flag_force_ui {
|
||||||
return true;
|
return true;
|
||||||
|
@ -24,8 +24,8 @@ use ethsync::SyncProvider;
|
|||||||
use helpers::replace_home;
|
use helpers::replace_home;
|
||||||
use util::Address;
|
use util::Address;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
|
||||||
/// This node secret key.
|
/// This node secret key.
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum NodeSecretKey {
|
pub enum NodeSecretKey {
|
||||||
/// Stored as plain text in configuration file.
|
/// Stored as plain text in configuration file.
|
||||||
Plain(Secret),
|
Plain(Secret),
|
||||||
@ -33,6 +33,15 @@ pub enum NodeSecretKey {
|
|||||||
KeyStore(Address),
|
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)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
/// Secret store configuration
|
/// Secret store configuration
|
||||||
pub struct Configuration {
|
pub struct Configuration {
|
||||||
@ -42,6 +51,8 @@ pub struct Configuration {
|
|||||||
pub http_enabled: bool,
|
pub http_enabled: bool,
|
||||||
/// Is ACL check enabled.
|
/// Is ACL check enabled.
|
||||||
pub acl_check_enabled: bool,
|
pub acl_check_enabled: bool,
|
||||||
|
/// Service contract address.
|
||||||
|
pub service_contract_address: Option<ContractAddress>,
|
||||||
/// This node secret.
|
/// This node secret.
|
||||||
pub self_secret: Option<NodeSecretKey>,
|
pub self_secret: Option<NodeSecretKey>,
|
||||||
/// Other nodes IDs + addresses.
|
/// Other nodes IDs + addresses.
|
||||||
@ -93,7 +104,7 @@ mod server {
|
|||||||
use ethcore_secretstore;
|
use ethcore_secretstore;
|
||||||
use ethkey::KeyPair;
|
use ethkey::KeyPair;
|
||||||
use ansi_term::Colour::Red;
|
use ansi_term::Colour::Red;
|
||||||
use super::{Configuration, Dependencies, NodeSecretKey};
|
use super::{Configuration, Dependencies, NodeSecretKey, ContractAddress};
|
||||||
|
|
||||||
/// Key server
|
/// Key server
|
||||||
pub struct KeyServer {
|
pub struct KeyServer {
|
||||||
@ -137,6 +148,10 @@ mod server {
|
|||||||
address: conf.http_interface.clone(),
|
address: conf.http_interface.clone(),
|
||||||
port: conf.http_port,
|
port: conf.http_port,
|
||||||
}) } else { None },
|
}) } 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(),
|
data_path: conf.data_path.clone(),
|
||||||
acl_check_enabled: conf.acl_check_enabled,
|
acl_check_enabled: conf.acl_check_enabled,
|
||||||
cluster_config: ethcore_secretstore::ClusterConfiguration {
|
cluster_config: ethcore_secretstore::ClusterConfiguration {
|
||||||
@ -175,6 +190,7 @@ impl Default for Configuration {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
http_enabled: true,
|
http_enabled: true,
|
||||||
acl_check_enabled: true,
|
acl_check_enabled: true,
|
||||||
|
service_contract_address: None,
|
||||||
self_secret: None,
|
self_secret: None,
|
||||||
admin_public: None,
|
admin_public: None,
|
||||||
nodes: BTreeMap::new(),
|
nodes: BTreeMap::new(),
|
||||||
|
@ -433,6 +433,7 @@ pub mod tests {
|
|||||||
let tempdir = TempDir::new("").unwrap();
|
let tempdir = TempDir::new("").unwrap();
|
||||||
let config = ServiceConfiguration {
|
let config = ServiceConfiguration {
|
||||||
listener_address: None,
|
listener_address: None,
|
||||||
|
service_contract_address: None,
|
||||||
acl_check_enabled: true,
|
acl_check_enabled: true,
|
||||||
data_path: tempdir.path().display().to_string(),
|
data_path: tempdir.path().display().to_string(),
|
||||||
cluster_config: ClusterConfiguration {
|
cluster_config: ClusterConfiguration {
|
||||||
|
@ -66,7 +66,7 @@ use ethcore::client::Client;
|
|||||||
use ethsync::SyncProvider;
|
use ethsync::SyncProvider;
|
||||||
|
|
||||||
pub use types::all::{ServerKeyId, EncryptedDocumentKey, RequestSignature, Public,
|
pub use types::all::{ServerKeyId, EncryptedDocumentKey, RequestSignature, Public,
|
||||||
Error, NodeAddress, ServiceConfiguration, ClusterConfiguration};
|
Error, NodeAddress, ContractAddress, ServiceConfiguration, ClusterConfiguration};
|
||||||
pub use traits::{NodeKeyPair, KeyServer};
|
pub use traits::{NodeKeyPair, KeyServer};
|
||||||
pub use self::node_key_pair::{PlainNodeKeyPair, KeyStoreNodeKeyPair};
|
pub use self::node_key_pair::{PlainNodeKeyPair, KeyStoreNodeKeyPair};
|
||||||
|
|
||||||
@ -81,20 +81,24 @@ pub fn start(client: Arc<Client>, sync: Arc<SyncProvider>, self_key_pair: Arc<No
|
|||||||
let key_storage = Arc::new(key_storage::PersistentKeyStorage::new(&config)?);
|
let key_storage = Arc::new(key_storage::PersistentKeyStorage::new(&config)?);
|
||||||
let key_server = Arc::new(key_server::KeyServerImpl::new(&config.cluster_config, key_server_set.clone(), self_key_pair.clone(), acl_storage, key_storage.clone())?);
|
let key_server = Arc::new(key_server::KeyServerImpl::new(&config.cluster_config, key_server_set.clone(), self_key_pair.clone(), acl_storage, key_storage.clone())?);
|
||||||
let cluster = key_server.cluster();
|
let cluster = key_server.cluster();
|
||||||
|
|
||||||
|
// prepare listeners
|
||||||
let http_listener = match config.listener_address {
|
let http_listener = match config.listener_address {
|
||||||
Some(listener_address) => Some(listener::http_listener::KeyServerHttpListener::start(listener_address, key_server.clone())?),
|
Some(listener_address) => Some(listener::http_listener::KeyServerHttpListener::start(listener_address, key_server.clone())?),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
let service_contract = Arc::new(listener::service_contract::OnChainServiceContract::new(&client, &sync, self_key_pair.clone()));
|
let contract_listener = config.service_contract_address.map(|service_contract_address| {
|
||||||
let contract_listener = listener::service_contract_listener::ServiceContractListener::new(listener::service_contract_listener::ServiceContractListenerParams {
|
let service_contract = Arc::new(listener::service_contract::OnChainServiceContract::new(&client, &sync, service_contract_address, self_key_pair.clone()));
|
||||||
contract: service_contract,
|
let contract_listener = listener::service_contract_listener::ServiceContractListener::new(listener::service_contract_listener::ServiceContractListenerParams {
|
||||||
key_server: key_server.clone(),
|
contract: service_contract,
|
||||||
self_key_pair: self_key_pair,
|
key_server: key_server.clone(),
|
||||||
key_server_set: key_server_set,
|
self_key_pair: self_key_pair,
|
||||||
cluster: cluster,
|
key_server_set: key_server_set,
|
||||||
key_storage: key_storage,
|
cluster: cluster,
|
||||||
|
key_storage: key_storage,
|
||||||
|
});
|
||||||
|
client.add_notify(contract_listener.clone());
|
||||||
|
contract_listener
|
||||||
});
|
});
|
||||||
client.add_notify(contract_listener.clone());
|
Ok(Box::new(listener::Listener::new(key_server, http_listener, contract_listener)))
|
||||||
let listener = listener::Listener::new(key_server, http_listener, Some(contract_listener));
|
|
||||||
Ok(Box::new(listener))
|
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ use hash::keccak;
|
|||||||
use bigint::hash::H256;
|
use bigint::hash::H256;
|
||||||
use bigint::prelude::U256;
|
use bigint::prelude::U256;
|
||||||
use listener::service_contract_listener::ServiceTask;
|
use listener::service_contract_listener::ServiceTask;
|
||||||
use {ServerKeyId, NodeKeyPair};
|
use {ServerKeyId, NodeKeyPair, ContractAddress};
|
||||||
|
|
||||||
/// Name of the SecretStore contract in the registry.
|
/// Name of the SecretStore contract in the registry.
|
||||||
const SERVICE_CONTRACT_REGISTRY_NAME: &'static str = "secretstore_service";
|
const SERVICE_CONTRACT_REGISTRY_NAME: &'static str = "secretstore_service";
|
||||||
@ -60,6 +60,8 @@ pub struct OnChainServiceContract {
|
|||||||
sync: Weak<SyncProvider>,
|
sync: Weak<SyncProvider>,
|
||||||
/// This node key pair.
|
/// This node key pair.
|
||||||
self_key_pair: Arc<NodeKeyPair>,
|
self_key_pair: Arc<NodeKeyPair>,
|
||||||
|
/// Contract addresss.
|
||||||
|
address: ContractAddress,
|
||||||
/// Contract.
|
/// Contract.
|
||||||
contract: RwLock<Arc<SecretStoreService>>,
|
contract: RwLock<Arc<SecretStoreService>>,
|
||||||
}
|
}
|
||||||
@ -80,19 +82,27 @@ struct PendingRequestsIterator {
|
|||||||
|
|
||||||
impl OnChainServiceContract {
|
impl OnChainServiceContract {
|
||||||
/// Create new on-chain service contract.
|
/// Create new on-chain service contract.
|
||||||
pub fn new(client: &Arc<Client>, sync: &Arc<SyncProvider>, self_key_pair: Arc<NodeKeyPair>) -> Self {
|
pub fn new(client: &Arc<Client>, sync: &Arc<SyncProvider>, address: ContractAddress, self_key_pair: Arc<NodeKeyPair>) -> Self {
|
||||||
let contract_addr = client.registry_address(SERVICE_CONTRACT_REGISTRY_NAME.to_owned())
|
let contract_addr = match &address {
|
||||||
.map(|address| {
|
&ContractAddress::Registry => client.registry_address(SERVICE_CONTRACT_REGISTRY_NAME.to_owned())
|
||||||
|
.map(|address| {
|
||||||
|
trace!(target: "secretstore", "{}: installing service contract from address {}",
|
||||||
|
self_key_pair.public(), address);
|
||||||
|
address
|
||||||
|
})
|
||||||
|
.unwrap_or_default(),
|
||||||
|
&ContractAddress::Address(ref address) => {
|
||||||
trace!(target: "secretstore", "{}: installing service contract from address {}",
|
trace!(target: "secretstore", "{}: installing service contract from address {}",
|
||||||
self_key_pair.public(), address);
|
self_key_pair.public(), address);
|
||||||
address
|
address.clone()
|
||||||
})
|
},
|
||||||
.unwrap_or_default();
|
};
|
||||||
|
|
||||||
OnChainServiceContract {
|
OnChainServiceContract {
|
||||||
client: Arc::downgrade(client),
|
client: Arc::downgrade(client),
|
||||||
sync: Arc::downgrade(sync),
|
sync: Arc::downgrade(sync),
|
||||||
self_key_pair: self_key_pair,
|
self_key_pair: self_key_pair,
|
||||||
|
address: address,
|
||||||
contract: RwLock::new(Arc::new(SecretStoreService::new(contract_addr))),
|
contract: RwLock::new(Arc::new(SecretStoreService::new(contract_addr))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,18 +110,20 @@ impl OnChainServiceContract {
|
|||||||
|
|
||||||
impl ServiceContract for OnChainServiceContract {
|
impl ServiceContract for OnChainServiceContract {
|
||||||
fn update(&self) {
|
fn update(&self) {
|
||||||
if let (Some(client), Some(sync)) = (self.client.upgrade(), self.sync.upgrade()) {
|
if let &ContractAddress::Registry = &self.address {
|
||||||
// do nothing until synced
|
if let (Some(client), Some(sync)) = (self.client.upgrade(), self.sync.upgrade()) {
|
||||||
if sync.status().is_syncing(client.queue_info()) {
|
// do nothing until synced
|
||||||
return;
|
if sync.status().is_syncing(client.queue_info()) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// update contract address from registry
|
// update contract address from registry
|
||||||
let service_contract_addr = client.registry_address(SERVICE_CONTRACT_REGISTRY_NAME.to_owned()).unwrap_or_default();
|
let service_contract_addr = client.registry_address(SERVICE_CONTRACT_REGISTRY_NAME.to_owned()).unwrap_or_default();
|
||||||
if self.contract.read().address != service_contract_addr {
|
if self.contract.read().address != service_contract_addr {
|
||||||
trace!(target: "secretstore", "{}: installing service contract from address {}",
|
trace!(target: "secretstore", "{}: installing service contract from address {}",
|
||||||
self.self_key_pair.public(), service_contract_addr);
|
self.self_key_pair.public(), service_contract_addr);
|
||||||
*self.contract.write() = Arc::new(SecretStoreService::new(service_contract_addr));
|
*self.contract.write() = Arc::new(SecretStoreService::new(service_contract_addr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,11 +61,22 @@ pub struct NodeAddress {
|
|||||||
pub port: u16,
|
pub port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Contract address.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum ContractAddress {
|
||||||
|
/// Address is read from registry.
|
||||||
|
Registry,
|
||||||
|
/// Address is specified.
|
||||||
|
Address(ethkey::Address),
|
||||||
|
}
|
||||||
|
|
||||||
/// Secret store configuration
|
/// Secret store configuration
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ServiceConfiguration {
|
pub struct ServiceConfiguration {
|
||||||
/// HTTP listener address. If None, HTTP API is disabled.
|
/// HTTP listener address. If None, HTTP API is disabled.
|
||||||
pub listener_address: Option<NodeAddress>,
|
pub listener_address: Option<NodeAddress>,
|
||||||
|
/// Service contract address. If None, service contract API is disabled.
|
||||||
|
pub service_contract_address: Option<ContractAddress>,
|
||||||
/// Is ACL check enabled. If false, everyone has access to all keys. Useful for tests only.
|
/// Is ACL check enabled. If false, everyone has access to all keys. Useful for tests only.
|
||||||
pub acl_check_enabled: bool,
|
pub acl_check_enabled: bool,
|
||||||
/// Data directory path for secret store
|
/// Data directory path for secret store
|
||||||
|
Loading…
Reference in New Issue
Block a user