SecretStore: ACL checker now requires blockchain to be fully synchronized
This commit is contained in:
parent
14686f2652
commit
009e350fc7
@ -20,6 +20,7 @@ use futures::{future, Future};
|
|||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
use ethkey::public_to_address;
|
use ethkey::public_to_address;
|
||||||
use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify};
|
use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify};
|
||||||
|
use ethsync::SyncProvider;
|
||||||
use native_contracts::SecretStoreAclStorage;
|
use native_contracts::SecretStoreAclStorage;
|
||||||
use bigint::hash::H256;
|
use bigint::hash::H256;
|
||||||
use util::Address;
|
use util::Address;
|
||||||
@ -44,6 +45,8 @@ pub struct OnChainAclStorage {
|
|||||||
struct CachedContract {
|
struct CachedContract {
|
||||||
/// Blockchain client.
|
/// Blockchain client.
|
||||||
client: Weak<Client>,
|
client: Weak<Client>,
|
||||||
|
/// Sync provider.
|
||||||
|
sync: Weak<SyncProvider>,
|
||||||
/// Contract address.
|
/// Contract address.
|
||||||
contract_addr: Option<Address>,
|
contract_addr: Option<Address>,
|
||||||
/// Contract at given address.
|
/// Contract at given address.
|
||||||
@ -57,9 +60,9 @@ pub struct DummyAclStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl OnChainAclStorage {
|
impl OnChainAclStorage {
|
||||||
pub fn new(client: &Arc<Client>) -> Arc<Self> {
|
pub fn new(client: &Arc<Client>, sync: &Arc<SyncProvider>) -> Arc<Self> {
|
||||||
let acl_storage = Arc::new(OnChainAclStorage {
|
let acl_storage = Arc::new(OnChainAclStorage {
|
||||||
contract: Mutex::new(CachedContract::new(client)),
|
contract: Mutex::new(CachedContract::new(client, sync)),
|
||||||
});
|
});
|
||||||
client.add_notify(acl_storage.clone());
|
client.add_notify(acl_storage.clone());
|
||||||
acl_storage
|
acl_storage
|
||||||
@ -81,9 +84,10 @@ impl ChainNotify for OnChainAclStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CachedContract {
|
impl CachedContract {
|
||||||
pub fn new(client: &Arc<Client>) -> Self {
|
pub fn new(client: &Arc<Client>, sync: &Arc<SyncProvider>) -> Self {
|
||||||
CachedContract {
|
CachedContract {
|
||||||
client: Arc::downgrade(client),
|
client: Arc::downgrade(client),
|
||||||
|
sync: Arc::downgrade(sync),
|
||||||
contract_addr: None,
|
contract_addr: None,
|
||||||
contract: None,
|
contract: None,
|
||||||
}
|
}
|
||||||
@ -105,20 +109,27 @@ impl CachedContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn check(&mut self, public: &Public, document: &ServerKeyId) -> Result<bool, Error> {
|
pub fn check(&mut self, public: &Public, document: &ServerKeyId) -> Result<bool, Error> {
|
||||||
|
match (self.client.upgrade(), self.sync.upgrade()) {
|
||||||
|
(Some(client), Some(sync)) => {
|
||||||
|
// we can not tell if access to document is allowed until fully synchronized
|
||||||
|
if sync.status().is_syncing(client.queue_info()) {
|
||||||
|
return Err(Error::Internal("Trying to check access by non-synchronized client".to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// call contract to check accesss
|
||||||
match self.contract.as_ref() {
|
match self.contract.as_ref() {
|
||||||
Some(contract) => {
|
Some(contract) => {
|
||||||
let address = public_to_address(&public);
|
let address = public_to_address(&public);
|
||||||
let do_call = |a, d| future::done(
|
let do_call = |a, d| future::done(client.call_contract(BlockId::Latest, a, d));
|
||||||
self.client
|
|
||||||
.upgrade()
|
|
||||||
.ok_or("Calling contract without client".into())
|
|
||||||
.and_then(|c| c.call_contract(BlockId::Latest, a, d)));
|
|
||||||
contract.check_permissions(do_call, address, document.clone())
|
contract.check_permissions(do_call, address, document.clone())
|
||||||
.map_err(|err| Error::Internal(err))
|
.map_err(|err| Error::Internal(err))
|
||||||
.wait()
|
.wait()
|
||||||
},
|
},
|
||||||
None => Err(Error::Internal("ACL checker contract is not configured".to_owned())),
|
None => Err(Error::Internal("ACL checker contract is not configured".to_owned())),
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
_ => Err(Error::Internal("Calling ACL contract without client".into())),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ pub use self::node_key_pair::{PlainNodeKeyPair, KeyStoreNodeKeyPair};
|
|||||||
/// Start new key server instance
|
/// Start new key server instance
|
||||||
pub fn start(client: Arc<Client>, sync: Arc<SyncProvider>, self_key_pair: Arc<NodeKeyPair>, config: ServiceConfiguration) -> Result<Box<KeyServer>, Error> {
|
pub fn start(client: Arc<Client>, sync: Arc<SyncProvider>, self_key_pair: Arc<NodeKeyPair>, config: ServiceConfiguration) -> Result<Box<KeyServer>, Error> {
|
||||||
let acl_storage: Arc<acl_storage::AclStorage> = if config.acl_check_enabled {
|
let acl_storage: Arc<acl_storage::AclStorage> = if config.acl_check_enabled {
|
||||||
acl_storage::OnChainAclStorage::new(&client/*, &sync*/) // TODO: return false until fully synced
|
acl_storage::OnChainAclStorage::new(&client, &sync)
|
||||||
} else {
|
} else {
|
||||||
Arc::new(acl_storage::DummyAclStorage::default())
|
Arc::new(acl_storage::DummyAclStorage::default())
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user