Remove mutex from TG instance (#31)

This commit is contained in:
Aleksey Proshutisnkiy 2021-11-24 18:35:38 +03:00 committed by GitHub
parent 1f31ffecc7
commit 7528256e78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 52 additions and 58 deletions

View File

@ -55,8 +55,8 @@ pub enum ServiceError {
#[source]
TrustError,
),
#[error("you should use host peer.timestamp_sec to pass timestamp")]
InvalidTimestampTetraplet,
#[error("you should use host peer.timestamp_sec to pass timestamp: {0}")]
InvalidTimestampTetraplet(String),
#[error("{0} can't be issued later than the current timestamp")]
InvalidTimestamp(String),
#[error("Root could add only by trust graph service owner")]

View File

@ -14,8 +14,7 @@ mod service_api;
mod storage_impl;
mod tests;
pub static TRUSTED_TIMESTAMP_SERVICE_ID: &str = "peer";
pub static TRUSTED_TIMESTAMP_FUNCTION_NAME: &str = "timestamp_sec";
pub static TRUSTED_TIMESTAMP: (&str, &str) = ("peer", "timestamp_sec");
pub fn main() {
WasmLoggerBuilder::new()

View File

@ -15,13 +15,14 @@
*/
use crate::error::ServiceError;
use crate::error::ServiceError::*;
use crate::storage_impl::{get_data, SQLiteStorage};
use crate::{TRUSTED_TIMESTAMP_FUNCTION_NAME, TRUSTED_TIMESTAMP_SERVICE_ID};
use crate::storage_impl::{SQLiteStorage, DB_PATH};
use crate::TRUSTED_TIMESTAMP;
use fluence_keypair::PublicKey;
use libp2p_core::PeerId;
use marine_rs_sdk::CallParameters;
use parking_lot::MutexGuard;
use std::cell::RefCell;
use std::convert::TryFrom;
use std::ops::DerefMut;
use std::str::FromStr;
use trust_graph::TrustGraph;
@ -33,13 +34,14 @@ pub(crate) fn check_timestamp_tetraplets(
let tetraplets = call_parameters
.tetraplets
.get(arg_number)
.ok_or(InvalidTimestampTetraplet)?;
let tetraplet = tetraplets.get(0).ok_or(InvalidTimestampTetraplet)?;
(tetraplet.service_id == TRUSTED_TIMESTAMP_SERVICE_ID
&& tetraplet.function_name == TRUSTED_TIMESTAMP_FUNCTION_NAME
.ok_or_else(|| InvalidTimestampTetraplet(format!("{:?}", call_parameters.tetraplets)))?;
let tetraplet = tetraplets
.get(0)
.ok_or_else(|| InvalidTimestampTetraplet(format!("{:?}", call_parameters.tetraplets)))?;
(TRUSTED_TIMESTAMP.eq(&(&tetraplet.service_id, &tetraplet.function_name))
&& tetraplet.peer_pk == call_parameters.host_id)
.then(|| ())
.ok_or(InvalidTimestampTetraplet)
.ok_or_else(|| InvalidTimestampTetraplet(format!("{:?}", tetraplet)))
}
fn parse_peer_id(peer_id: String) -> Result<PeerId, ServiceError> {
@ -47,13 +49,15 @@ fn parse_peer_id(peer_id: String) -> Result<PeerId, ServiceError> {
.map_err(|e| ServiceError::PeerIdParseError(format!("{:?}", e)))
}
thread_local!(static INSTANCE: RefCell<TrustGraph<SQLiteStorage>> = RefCell::new(TrustGraph::new(
SQLiteStorage::new(marine_sqlite_connector::open(DB_PATH).unwrap()),
)));
pub fn with_tg<F, T>(func: F) -> T
where
F: FnOnce(MutexGuard<TrustGraph<SQLiteStorage>>) -> T,
F: FnOnce(&mut TrustGraph<SQLiteStorage>) -> T,
{
let tg = get_data().lock();
func(tg)
INSTANCE.with(|tg| func(tg.borrow_mut().deref_mut()))
}
pub fn wrapped_try<F, T>(func: F) -> T

View File

@ -6,12 +6,13 @@ use crate::results::{
InsertResult, IssueRevocationResult, IssueTrustResult, RevokeResult, VerifyTrustResult,
WeightResult,
};
use crate::storage_impl::SQLiteStorage;
use fluence_keypair::Signature;
use marine_rs_sdk::{get_call_parameters, marine, CallParameters};
use std::convert::{TryFrom, TryInto};
use std::str::FromStr;
use std::time::Duration;
use trust_graph::MAX_WEIGHT_FACTOR;
use trust_graph::{TrustGraph, MAX_WEIGHT_FACTOR};
#[marine]
fn get_weight_factor(max_chain_len: u32) -> u32 {
@ -24,7 +25,7 @@ fn add_root(peer_id: String, weight_factor: u32) -> AddRootResult {
let call_parameters: CallParameters = marine_rs_sdk::get_call_parameters();
let init_peer_id = call_parameters.init_peer_id;
if call_parameters.service_creator_peer_id == init_peer_id {
with_tg(|mut tg| {
with_tg(|tg| {
let public_key = extract_public_key(peer_id)?;
tg.add_root_weight_factor(public_key, weight_factor)?;
Ok(())
@ -42,7 +43,7 @@ fn add_root(peer_id: String, weight_factor: u32) -> AddRootResult {
/// add a certificate in string representation to trust graph if it is valid
/// see `trust_graph::Certificate` class for string encoding/decoding
fn insert_cert_raw(certificate: String, timestamp_sec: u64) -> InsertResult {
with_tg(|mut tg| {
with_tg(|tg| {
let certificate = trust_graph::Certificate::from_str(&certificate)?;
let timestamp_sec = Duration::from_secs(timestamp_sec);
tg.add(certificate, timestamp_sec)?;
@ -55,7 +56,7 @@ fn insert_cert_raw(certificate: String, timestamp_sec: u64) -> InsertResult {
/// add a certificate in JSON representation to trust graph if it is valid
/// see `dto::Certificate` class for structure
fn insert_cert(certificate: Certificate, timestamp_sec: u64) -> InsertResult {
with_tg(|mut tg| {
with_tg(|tg| {
let timestamp_sec = Duration::from_secs(timestamp_sec);
tg.add(
trust_graph::Certificate::try_from(certificate)?,
@ -66,48 +67,51 @@ fn insert_cert(certificate: Certificate, timestamp_sec: u64) -> InsertResult {
.into()
}
fn get_certs(
tg: &mut TrustGraph<SQLiteStorage>,
issued_for: String,
timestamp_sec: u64,
) -> Result<impl Iterator<Item = Certificate>, ServiceError> {
let public_key = extract_public_key(issued_for)?;
let certs = tg.get_all_certs(public_key, Duration::from_secs(timestamp_sec))?;
Ok(certs.into_iter().map(|c| c.into()))
}
#[marine]
fn get_all_certs(issued_for: String, timestamp_sec: u64) -> AllCertsResult {
with_tg(|mut tg| {
with_tg(|tg| {
check_timestamp_tetraplets(&marine_rs_sdk::get_call_parameters(), 1)?;
let public_key = extract_public_key(issued_for)?;
let certs = tg.get_all_certs(public_key, Duration::from_secs(timestamp_sec))?;
Ok(certs.into_iter().map(|c| c.into()).collect())
get_certs(tg, issued_for, timestamp_sec).map(|iter| iter.collect())
})
.into()
}
#[marine]
fn get_host_certs(timestamp_sec: u64) -> AllCertsResult {
with_tg(|mut tg| {
with_tg(|tg| {
let cp = marine_rs_sdk::get_call_parameters();
check_timestamp_tetraplets(&cp, 0)?;
let public_key = extract_public_key(cp.host_id)?;
let certs = tg.get_all_certs(public_key, Duration::from_secs(timestamp_sec))?;
Ok(certs.into_iter().map(|c| c.into()).collect())
get_certs(tg, cp.host_id, timestamp_sec).map(|iter| iter.collect())
})
.into()
}
#[marine]
fn get_host_certs_from(issuer: String, timestamp_sec: u64) -> AllCertsResult {
with_tg(|mut tg| {
with_tg(|tg| {
let cp = get_call_parameters();
check_timestamp_tetraplets(&cp, 1)?;
let public_key = extract_public_key(cp.host_id)?;
let certs = tg.get_all_certs(public_key, Duration::from_secs(timestamp_sec))?;
Ok(certs
.into_iter()
.map(|c| c.into())
.filter(|cert: &Certificate| cert.chain.iter().any(|t| t.issued_for == issuer))
.collect())
get_certs(tg, cp.host_id, timestamp_sec).map(|c| {
c.filter(|cert: &Certificate| cert.chain.iter().any(|t| t.issued_for == issuer))
.collect()
})
})
.into()
}
#[marine]
fn get_weight(peer_id: String, timestamp_sec: u64) -> WeightResult {
with_tg(|mut tg| {
with_tg(|tg| {
check_timestamp_tetraplets(&marine_rs_sdk::get_call_parameters(), 1)?;
let public_key = extract_public_key(peer_id.clone())?;
let weight = tg.weight(public_key, Duration::from_secs(timestamp_sec))?;
@ -175,12 +179,12 @@ fn verify_trust(trust: Trust, issuer_peer_id: String, timestamp_sec: u64) -> Ver
#[marine]
fn add_trust(trust: Trust, issuer_peer_id: String, timestamp_sec: u64) -> AddTrustResult {
with_tg(|mut tg| {
with_tg(|tg| {
let public_key = extract_public_key(issuer_peer_id)?;
check_timestamp_tetraplets(&marine_rs_sdk::get_call_parameters(), 2)?;
if trust.issued_at > timestamp_sec {
return Err(ServiceError::InvalidTimestamp("Trust".to_string()));
return Err(ServiceError::InvalidTimestamp("trust".to_string()));
}
tg.add_trust(
@ -225,11 +229,11 @@ fn issue_revocation(
#[marine]
fn revoke(revoke: Revoke, timestamp_sec: u64) -> RevokeResult {
with_tg(|mut tg| {
with_tg(|tg| {
check_timestamp_tetraplets(&marine_rs_sdk::get_call_parameters(), 1)?;
if revoke.revoked_at > timestamp_sec {
return Err(ServiceError::InvalidTimestamp("Revoke".to_string()));
return Err(ServiceError::InvalidTimestamp("revoke".to_string()));
}
tg.revoke(revoke.try_into()?).map_err(ServiceError::TGError)

View File

@ -10,8 +10,6 @@ use core::convert::TryFrom;
use fluence_keypair::error::DecodingError;
use fluence_keypair::Signature;
use marine_sqlite_connector::{Connection, Error as InternalSqliteError, Value};
use once_cell::sync::OnceCell;
use parking_lot::Mutex;
use rmp_serde::decode::Error as RmpDecodeError;
use rmp_serde::encode::Error as RmpEncodeError;
use std::convert::From;
@ -20,12 +18,9 @@ use std::time::Duration;
use thiserror::Error as ThisError;
use trust_graph::{
Auth, PublicKeyHashable as PK, PublicKeyHashable, Revoke, Storage, StorageError, Trust,
TrustGraph, TrustRelation, WeightFactor,
TrustRelation, WeightFactor,
};
#[allow(dead_code)]
static INSTANCE: OnceCell<Mutex<TrustGraph<SQLiteStorage>>> = OnceCell::new();
static AUTH_TYPE: i64 = 0;
static REVOKE_TYPE: i64 = 1;
pub static DB_PATH: &str = "/tmp/trust-graph.sqlite";
@ -56,14 +51,6 @@ pub fn create_tables() {
.unwrap();
}
#[allow(dead_code)]
pub fn get_data() -> &'static Mutex<TrustGraph<SQLiteStorage>> {
INSTANCE.get_or_init(|| {
let connection = marine_sqlite_connector::open(DB_PATH).unwrap();
Mutex::new(TrustGraph::new(SQLiteStorage::new(connection)))
})
}
pub struct SQLiteStorage {
connection: Connection,
}

View File

@ -19,7 +19,7 @@ mod service_tests {
marine_rs_sdk_test::include_test_env!("/marine_test_env.rs");
use crate::error::ServiceError;
use crate::storage_impl::DB_PATH;
use crate::{TRUSTED_TIMESTAMP_FUNCTION_NAME, TRUSTED_TIMESTAMP_SERVICE_ID};
use crate::TRUSTED_TIMESTAMP;
use fluence_keypair::KeyPair;
use libp2p_core::PeerId;
use marine_rs_sdk::{CallParameters, SecurityTetraplet};
@ -79,8 +79,8 @@ mod service_tests {
cp.tetraplets.push(vec![SecurityTetraplet {
peer_pk: host_id,
service_id: TRUSTED_TIMESTAMP_SERVICE_ID.to_string(),
function_name: TRUSTED_TIMESTAMP_FUNCTION_NAME.to_string(),
service_id: TRUSTED_TIMESTAMP.0.to_string(),
function_name: TRUSTED_TIMESTAMP.1.to_string(),
json_path: "".to_string(),
}]);