openethereum/secret_store/src/listener/service_contract_aggregate.rs

101 lines
4.2 KiB
Rust

// 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/>.
use std::sync::Arc;
use bytes::Bytes;
use ethereum_types::Address;
use ethkey::Public;
use listener::service_contract::ServiceContract;
use listener::service_contract_listener::ServiceTask;
use {ServerKeyId};
/// Aggregated on-chain service contract.
pub struct OnChainServiceContractAggregate {
/// All hosted service contracts.
contracts: Vec<Arc<ServiceContract>>,
}
impl OnChainServiceContractAggregate {
/// Create new aggregated service contract listener.
pub fn new(contracts: Vec<Arc<ServiceContract>>) -> Self {
debug_assert!(contracts.len() > 1);
OnChainServiceContractAggregate {
contracts: contracts,
}
}
}
impl ServiceContract for OnChainServiceContractAggregate {
fn update(&self) -> bool {
let mut result = false;
for contract in &self.contracts {
result = contract.update() || result;
}
result
}
fn read_logs(&self) -> Box<Iterator<Item=ServiceTask>> {
self.contracts.iter()
.fold(Box::new(::std::iter::empty()) as Box<Iterator<Item=ServiceTask>>, |i, c|
Box::new(i.chain(c.read_logs())))
}
fn read_pending_requests(&self) -> Box<Iterator<Item=(bool, ServiceTask)>> {
self.contracts.iter()
.fold(Box::new(::std::iter::empty()) as Box<Iterator<Item=(bool, ServiceTask)>>, |i, c|
Box::new(i.chain(c.read_pending_requests())))
}
// in current implementation all publish methods are independent of actual contract adddress
// (tx is sent to origin) => we do not care which contract to use for publish data in methods below
fn publish_generated_server_key(&self, origin: &Address, server_key_id: &ServerKeyId, server_key: Public) -> Result<(), String> {
self.contracts[0].publish_generated_server_key(origin, server_key_id, server_key)
}
fn publish_server_key_generation_error(&self, origin: &Address, server_key_id: &ServerKeyId) -> Result<(), String> {
self.contracts[0].publish_server_key_generation_error(origin, server_key_id)
}
fn publish_retrieved_server_key(&self, origin: &Address, server_key_id: &ServerKeyId, server_key: Public, threshold: usize) -> Result<(), String> {
self.contracts[0].publish_retrieved_server_key(origin, server_key_id, server_key, threshold)
}
fn publish_server_key_retrieval_error(&self, origin: &Address, server_key_id: &ServerKeyId) -> Result<(), String> {
self.contracts[0].publish_server_key_retrieval_error(origin, server_key_id)
}
fn publish_stored_document_key(&self, origin: &Address, server_key_id: &ServerKeyId) -> Result<(), String> {
self.contracts[0].publish_stored_document_key(origin, server_key_id)
}
fn publish_document_key_store_error(&self, origin: &Address, server_key_id: &ServerKeyId) -> Result<(), String> {
self.contracts[0].publish_document_key_store_error(origin, server_key_id)
}
fn publish_retrieved_document_key_common(&self, origin: &Address, server_key_id: &ServerKeyId, requester: &Address, common_point: Public, threshold: usize) -> Result<(), String> {
self.contracts[0].publish_retrieved_document_key_common(origin, server_key_id, requester, common_point, threshold)
}
fn publish_retrieved_document_key_personal(&self, origin: &Address, server_key_id: &ServerKeyId, requester: &Address, participants: &[Address], decrypted_secret: Public, shadow: Bytes) -> Result<(), String> {
self.contracts[0].publish_retrieved_document_key_personal(origin, server_key_id, requester, participants, decrypted_secret, shadow)
}
fn publish_document_key_retrieval_error(&self, origin: &Address, server_key_id: &ServerKeyId, requester: &Address) -> Result<(), String> {
self.contracts[0].publish_document_key_retrieval_error(origin, server_key_id, requester)
}
}