Read registry_address from block with REQUEST_CONFIRMATIONS_REQUIRED (#8309)
* Read registry_address from block with REQUEST_CONFIRMATIONS_REQUIRED * Require confirmation blocks in key_server_set * Add license preamble * TODO item for constant confirmation required number * Change license year in helpers.rs to 2015-2018
This commit is contained in:
parent
27c32d3629
commit
d7a7f034db
29
secret_store/src/helpers.rs
Normal file
29
secret_store/src/helpers.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2015-2018 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 ethcore::client::{Client, BlockChainClient, BlockId};
|
||||||
|
use ethereum_types::H256;
|
||||||
|
|
||||||
|
// TODO: Instead of a constant, make this based on consensus finality.
|
||||||
|
/// Number of confirmations required before request can be processed.
|
||||||
|
pub const REQUEST_CONFIRMATIONS_REQUIRED: u64 = 3;
|
||||||
|
|
||||||
|
/// Get hash of the last block with at least n confirmations.
|
||||||
|
pub fn get_confirmed_block_hash(client: &Client, confirmations: u64) -> Option<H256> {
|
||||||
|
client.block_number(BlockId::Latest)
|
||||||
|
.map(|b| b.saturating_sub(confirmations))
|
||||||
|
.and_then(|b| client.block_hash(BlockId::Number(b)))
|
||||||
|
}
|
@ -26,6 +26,7 @@ use ethereum_types::{H256, Address};
|
|||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use types::all::{Error, Public, NodeAddress, NodeId};
|
use types::all::{Error, Public, NodeAddress, NodeId};
|
||||||
use trusted_client::TrustedClient;
|
use trusted_client::TrustedClient;
|
||||||
|
use helpers::{get_confirmed_block_hash, REQUEST_CONFIRMATIONS_REQUIRED};
|
||||||
use {NodeKeyPair};
|
use {NodeKeyPair};
|
||||||
|
|
||||||
use_contract!(key_server, "KeyServerSet", "res/key_server_set.json");
|
use_contract!(key_server, "KeyServerSet", "res/key_server_set.json");
|
||||||
@ -325,7 +326,7 @@ impl CachedContract {
|
|||||||
|
|
||||||
fn read_from_registry_if_required(&mut self, client: &Client, enacted: Vec<H256>, retracted: Vec<H256>) {
|
fn read_from_registry_if_required(&mut self, client: &Client, enacted: Vec<H256>, retracted: Vec<H256>) {
|
||||||
// read new contract from registry
|
// read new contract from registry
|
||||||
let new_contract_addr = client.registry_address(KEY_SERVER_SET_CONTRACT_REGISTRY_NAME.to_owned(), BlockId::Latest);
|
let new_contract_addr = get_confirmed_block_hash(&*client, REQUEST_CONFIRMATIONS_REQUIRED).and_then(|block_hash| client.registry_address(KEY_SERVER_SET_CONTRACT_REGISTRY_NAME.to_owned(), BlockId::Hash(block_hash)));
|
||||||
|
|
||||||
// new contract installed => read nodes set from the contract
|
// new contract installed => read nodes set from the contract
|
||||||
if self.contract_address.as_ref() != new_contract_addr.as_ref() {
|
if self.contract_address.as_ref() != new_contract_addr.as_ref() {
|
||||||
|
@ -54,6 +54,7 @@ extern crate log;
|
|||||||
|
|
||||||
mod key_server_cluster;
|
mod key_server_cluster;
|
||||||
mod types;
|
mod types;
|
||||||
|
mod helpers;
|
||||||
|
|
||||||
mod traits;
|
mod traits;
|
||||||
mod acl_storage;
|
mod acl_storage;
|
||||||
|
@ -26,6 +26,7 @@ use ethereum_types::{H256, U256, Address};
|
|||||||
use listener::ApiMask;
|
use listener::ApiMask;
|
||||||
use listener::service_contract_listener::ServiceTask;
|
use listener::service_contract_listener::ServiceTask;
|
||||||
use trusted_client::TrustedClient;
|
use trusted_client::TrustedClient;
|
||||||
|
use helpers::{get_confirmed_block_hash, REQUEST_CONFIRMATIONS_REQUIRED};
|
||||||
use {ServerKeyId, NodeKeyPair, ContractAddress};
|
use {ServerKeyId, NodeKeyPair, ContractAddress};
|
||||||
|
|
||||||
use_contract!(service, "Service", "res/service.json");
|
use_contract!(service, "Service", "res/service.json");
|
||||||
@ -52,9 +53,6 @@ const DOCUMENT_KEY_COMMON_PART_RETRIEVAL_REQUESTED_EVENT_NAME: &'static [u8] = &
|
|||||||
/// Document key personal part retrieval has been requested.
|
/// Document key personal part retrieval has been requested.
|
||||||
const DOCUMENT_KEY_PERSONAL_PART_RETRIEVAL_REQUESTED_EVENT_NAME: &'static [u8] = &*b"DocumentKeyPersonalRetrievalRequested(bytes32,bytes)";
|
const DOCUMENT_KEY_PERSONAL_PART_RETRIEVAL_REQUESTED_EVENT_NAME: &'static [u8] = &*b"DocumentKeyPersonalRetrievalRequested(bytes32,bytes)";
|
||||||
|
|
||||||
/// Number of confirmations required before request can be processed.
|
|
||||||
const REQUEST_CONFIRMATIONS_REQUIRED: u64 = 3;
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref SERVER_KEY_GENERATION_REQUESTED_EVENT_NAME_HASH: H256 = keccak(SERVER_KEY_GENERATION_REQUESTED_EVENT_NAME);
|
pub static ref SERVER_KEY_GENERATION_REQUESTED_EVENT_NAME_HASH: H256 = keccak(SERVER_KEY_GENERATION_REQUESTED_EVENT_NAME);
|
||||||
pub static ref SERVER_KEY_RETRIEVAL_REQUESTED_EVENT_NAME_HASH: H256 = keccak(SERVER_KEY_RETRIEVAL_REQUESTED_EVENT_NAME);
|
pub static ref SERVER_KEY_RETRIEVAL_REQUESTED_EVENT_NAME_HASH: H256 = keccak(SERVER_KEY_RETRIEVAL_REQUESTED_EVENT_NAME);
|
||||||
@ -234,12 +232,11 @@ impl OnChainServiceContract {
|
|||||||
|
|
||||||
impl ServiceContract for OnChainServiceContract {
|
impl ServiceContract for OnChainServiceContract {
|
||||||
fn update(&self) -> bool {
|
fn update(&self) -> bool {
|
||||||
// TODO [Sec]: registry_address currently reads from BlockId::Latest, instead of
|
|
||||||
// from block with REQUEST_CONFIRMATIONS_REQUIRED confirmations
|
|
||||||
if let &ContractAddress::Registry = &self.address {
|
if let &ContractAddress::Registry = &self.address {
|
||||||
if let Some(client) = self.client.get() {
|
if let Some(client) = self.client.get() {
|
||||||
|
if let Some(block_hash) = get_confirmed_block_hash(&*client, REQUEST_CONFIRMATIONS_REQUIRED) {
|
||||||
// update contract address from registry
|
// update contract address from registry
|
||||||
let service_contract_addr = client.registry_address(self.name.clone(), BlockId::Latest).unwrap_or_default();
|
let service_contract_addr = client.registry_address(self.name.clone(), BlockId::Hash(block_hash)).unwrap_or_default();
|
||||||
if self.data.read().contract_address != service_contract_addr {
|
if self.data.read().contract_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(), self.name, service_contract_addr);
|
self.self_key_pair.public(), self.name, service_contract_addr);
|
||||||
@ -247,6 +244,7 @@ impl ServiceContract for OnChainServiceContract {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.data.read().contract_address != Default::default()
|
self.data.read().contract_address != Default::default()
|
||||||
&& self.client.get().is_some()
|
&& self.client.get().is_some()
|
||||||
@ -460,13 +458,6 @@ pub fn mask_topics(mask: &ApiMask) -> Vec<H256> {
|
|||||||
topics
|
topics
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get hash of the last block with at least n confirmations.
|
|
||||||
fn get_confirmed_block_hash(client: &Client, confirmations: u64) -> Option<H256> {
|
|
||||||
client.block_number(BlockId::Latest)
|
|
||||||
.map(|b| b.saturating_sub(confirmations))
|
|
||||||
.and_then(|b| client.block_hash(BlockId::Number(b)))
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ServerKeyGenerationService {
|
impl ServerKeyGenerationService {
|
||||||
/// Parse request log entry.
|
/// Parse request log entry.
|
||||||
pub fn parse_log(origin: &Address, contract: &service::Service, raw_log: RawLog) -> Result<ServiceTask, String> {
|
pub fn parse_log(origin: &Address, contract: &service::Service, raw_log: RawLog) -> Result<ServiceTask, String> {
|
||||||
|
Loading…
Reference in New Issue
Block a user