From c779b0883cef43987b192331c58f01f261c70a47 Mon Sep 17 00:00:00 2001 From: Alain Brenzikofer Date: Tue, 23 Jun 2020 22:11:42 +0200 Subject: [PATCH] fixes #7 --- client/src/main.rs | 12 ++-- enclave/src/lib.rs | 24 ++++--- stf/src/cli.rs | 115 ++++++++++++++---------------- stf/src/lib.rs | 57 ++++++++++++++- stf/src/sgx.rs | 67 +++++++++-------- worker/src/ws_server.rs | 4 +- worker/worker-api/src/lib.rs | 4 +- worker/worker-api/src/requests.rs | 4 +- 8 files changed, 173 insertions(+), 114 deletions(-) diff --git a/client/src/main.rs b/client/src/main.rs index 18b75dfa87..61af286ca7 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -67,7 +67,7 @@ use encointer_currencies::{CurrencyIdentifier, CurrencyPropertiesType, Location, use substratee_stf::{ cli::get_identifiers, ShardIdentifier, TrustedCallSigned, TrustedGetterSigned, - TrustedOperationSigned, + TrustedOperation, Getter }; use substratee_worker_api::Api as WorkerApi; @@ -521,18 +521,18 @@ fn get_worker_api(matches: &ArgMatches<'_>) -> WorkerApi { fn perform_trusted_operation( matches: &ArgMatches<'_>, - top: &TrustedOperationSigned, + top: &TrustedOperation, ) -> Option> { match top { - TrustedOperationSigned::call(call) => send_request(matches, call.clone()), - TrustedOperationSigned::get(getter) => get_state(matches, getter.clone()), + TrustedOperation::call(call) => send_request(matches, call.clone()), + TrustedOperation::get(getter) => get_state(matches, getter.clone()), } } -fn get_state(matches: &ArgMatches<'_>, getter: TrustedGetterSigned) -> Option> { +fn get_state(matches: &ArgMatches<'_>, getter: Getter) -> Option> { let worker_api = get_worker_api(matches); let (_mrenclave, shard) = get_identifiers(matches); - debug!("calling workerapi to get state value, {:?}", getter.getter); + debug!("calling workerapi to get state value, {:?}", getter); let ret = worker_api .get_stf_state(getter, &shard) .expect("getting value failed"); diff --git a/enclave/src/lib.rs b/enclave/src/lib.rs index 2975ce6c59..5c51d7b682 100644 --- a/enclave/src/lib.rs +++ b/enclave/src/lib.rs @@ -38,7 +38,7 @@ use sgx_types::{sgx_epid_group_id_t, sgx_status_t, sgx_target_info_t, size_t, Sg use substrate_api_client::{compose_extrinsic_offline, utils::storage_key}; use substratee_node_primitives::CallWorkerFn; use substratee_stf::{ - ShardIdentifier, Stf, TrustedCallSigned, TrustedGetterSigned, + ShardIdentifier, Stf, TrustedCallSigned, Getter, }; use codec::{Decode, Encode}; @@ -210,12 +210,14 @@ pub unsafe extern "C" fn get_state( let shard = ShardIdentifier::from_slice(slice::from_raw_parts(shard, shard_size as usize)); let mut trusted_op_slice = slice::from_raw_parts(trusted_op, trusted_op_size as usize); let value_slice = slice::from_raw_parts_mut(value, value_size as usize); - let tusted_getter_signed = TrustedGetterSigned::decode(&mut trusted_op_slice).unwrap(); - - debug!("verifying signature of TrustedCallSigned"); - if let false = tusted_getter_signed.verify_signature() { - error!("bad signature"); - return sgx_status_t::SGX_ERROR_UNEXPECTED; + let getter = Getter::decode(&mut trusted_op_slice).unwrap(); + + if let Getter::trusted(trusted_getter_signed) = getter.clone() { + debug!("verifying signature of TrustedGetterSigned"); + if let false = trusted_getter_signed.verify_signature() { + error!("bad signature"); + return sgx_status_t::SGX_ERROR_UNEXPECTED; + } } if !state::exists(&shard) { @@ -237,9 +239,11 @@ pub unsafe extern "C" fn get_state( let latest_header = validator.latest_header(validator.num_relays).unwrap(); + // FIXME: not sure we will ever need this as we are querying trusted state, not onchain state + // i.e. demurrage could be correctly applied with this, but the client could do that too. debug!("Update STF storage!"); let requests: Vec = - Stf::get_storage_hashes_to_update_for_getter(&tusted_getter_signed) + Stf::get_storage_hashes_to_update_for_getter(&getter) .into_iter() .map(|key| WorkerRequest::ChainStorage(key, Some(latest_header.hash()))) .collect(); @@ -259,7 +263,7 @@ pub unsafe extern "C" fn get_state( } debug!("calling into STF to get state"); - let value_opt = Stf::get_state(&mut state, tusted_getter_signed.getter); + let value_opt = Stf::get_state(&mut state, getter); debug!("returning getter result"); write_slice_and_whitespace_pad(value_slice, value_opt.encode()); @@ -356,7 +360,7 @@ pub unsafe extern "C" fn sync_chain_relay( } if update_states(signed_block.block.header.clone()).is_err() { - error!("Error performing state updates upon block import") + error!("Error performing state updates upon block import"); return sgx_status_t::SGX_ERROR_UNEXPECTED; } diff --git a/stf/src/cli.rs b/stf/src/cli.rs index c4c5ca1b65..d8b351fea8 100644 --- a/stf/src/cli.rs +++ b/stf/src/cli.rs @@ -15,7 +15,7 @@ */ -use crate::{AccountId, ShardIdentifier, TrustedCall, TrustedGetter, TrustedOperationSigned, Attestation}; +use crate::{AccountId, ShardIdentifier, TrustedCall, TrustedGetter, PublicGetter, TrustedOperation, Attestation}; use base58::{FromBase58, ToBase58}; use clap::{Arg, ArgMatches}; use clap_nested::{Command, Commander, MultiCommand}; @@ -38,7 +38,7 @@ type Moment = u64; const KEYSTORE_PATH: &str = "my_trusted_keystore"; pub fn cmd<'a>( - perform_operation: &'a dyn Fn(&ArgMatches<'_>, &TrustedOperationSigned) -> Option>, + perform_operation: &'a dyn Fn(&ArgMatches<'_>, &TrustedOperation) -> Option>, ) -> MultiCommand<'a, str, str> { Commander::new() .options(|app| { @@ -146,24 +146,22 @@ pub fn cmd<'a>( info!("from ss58 is {}", from.public().to_ss58check()); info!("to ss58 is {}", to.to_ss58check()); - let (mrenclave, shard) = get_identifiers(matches); - - let tcall = TrustedCall::balance_transfer( - sr25519_core::Public::from(from.public()), - to, - shard, // for encointer we assume that every currency has its own shard. so shard == cid - BalanceType::from_num(amount), - ); - let nonce = 0; // FIXME: hard coded for now - let tscall = - tcall.sign(&sr25519_core::Pair::from(from), nonce, &mrenclave, &shard); println!( "send trusted call transfer from {} to {}: {}", - tscall.call.account(), + from.public(), to, amount ); - let _ = perform_operation(matches, &TrustedOperationSigned::call(tscall)); + let (mrenclave, shard) = get_identifiers(matches); + let nonce = 0; // FIXME: hard coded for now + let top: TrustedOperation = TrustedCall::balance_transfer( + sr25519_core::Public::from(from.public()), + to, + shard, // for encointer we assume that every currency has its own shard. so shard == cid + BalanceType::from_num(amount)) + .sign(&sr25519_core::Pair::from(from), nonce, &mrenclave, &shard) + .into(); + let _ = perform_operation(matches, &top); Ok(()) }), ) @@ -184,10 +182,10 @@ pub fn cmd<'a>( println!("arg_who = {:?}", arg_who); let who = get_pair_from_str(matches, arg_who); let (_mrenclave, shard) = get_identifiers(matches); - let tgetter = - TrustedGetter::balance(sr25519_core::Public::from(who.public()), shard); - let tsgetter = tgetter.sign(&sr25519_core::Pair::from(who)); - let res = perform_operation(matches, &TrustedOperationSigned::get(tsgetter)); + let top: TrustedOperation = TrustedGetter::balance(sr25519_core::Public::from(who.public()), shard) + .sign(&sr25519_core::Pair::from(who)) + .into(); + let res = perform_operation(matches, &top); let bal = if let Some(v) = res { if let Ok(vd) = ::decode(&mut v.as_slice()) { vd @@ -218,19 +216,18 @@ pub fn cmd<'a>( let arg_who = matches.value_of("accountid").unwrap(); let who = get_pair_from_str(matches, arg_who); let (mrenclave, shard) = get_identifiers(matches); - let tcall = TrustedCall::ceremonies_register_participant( - sr25519_core::Public::from(who.public()), - shard, // for encointer we assume that every currency has its own shard. so shard == cid - None - ); let nonce = 0; // FIXME: hard coded for now - let tscall = - tcall.sign(&sr25519_core::Pair::from(who), nonce, &mrenclave, &shard); println!( "send TrustedCall::register_participant for {}", - tscall.call.account(), + who.public(), ); - perform_operation(matches, &TrustedOperationSigned::call(tscall)); + let top: TrustedOperation = TrustedCall::ceremonies_register_participant( + sr25519_core::Public::from(who.public()), + shard, // for encointer we assume that every currency has its own shard. so shard == cid + None) + .sign(&sr25519_core::Pair::from(who), nonce, &mrenclave, &shard) + .into(); + perform_operation(matches, &top); Ok(()) }), ) @@ -250,18 +247,17 @@ pub fn cmd<'a>( let arg_who = matches.value_of("accountid").unwrap(); let who = get_pair_from_str(matches, arg_who); let (_mrenclave, shard) = get_identifiers(matches); - let tgetter = TrustedGetter::registration( - sr25519_core::Public::from(who.public()), - shard, // for encointer we assume that every currency has its own shard. so shard == cid - ); - let tsgetter = - tgetter.sign(&sr25519_core::Pair::from(who)); println!( "send TrustedGetter::get_registration for {}", - tsgetter.getter.account(), + who.public() ); - - let part = perform_operation(matches, &TrustedOperationSigned::get(tsgetter)).unwrap(); + let top: TrustedOperation = TrustedGetter::registration( + sr25519_core::Public::from(who.public()), + shard, // for encointer we assume that every currency has its own shard. so shard == cid + ) + .sign(&sr25519_core::Pair::from(who)) + .into(); + let part = perform_operation(matches, &top).unwrap(); let participant: ParticipantIndexType = Decode::decode(&mut part.as_slice()).unwrap(); println!("Participant index: {:?}", participant); Ok(()) @@ -290,26 +286,24 @@ pub fn cmd<'a>( let arg_who = matches.value_of("accountid").unwrap(); let who = get_pair_from_str(matches, arg_who); let (mrenclave, shard) = get_identifiers(matches); - + let nonce = 0; // FIXME: hard coded for now let attestation_args: Vec<_> = matches.values_of("attestations").unwrap().collect(); let mut attestations: Vec> = vec![]; for arg in attestation_args.iter() { let w = Attestation::decode(&mut &hex::decode(arg).unwrap()[..]).unwrap(); attestations.push(w); } - - let tcall = TrustedCall::ceremonies_register_attestations( - sr25519_core::Public::from(who.public()), - attestations - ); - let nonce = 0; // FIXME: hard coded for now - let tscall = - tcall.sign(&sr25519_core::Pair::from(who), nonce, &mrenclave, &shard); println!( "send TrustedCall::register_attestations for {}", - tscall.call.account(), + who.public() ); - perform_operation(matches, &TrustedOperationSigned::call(tscall)); + let top: TrustedOperation = TrustedCall::ceremonies_register_attestations( + sr25519_core::Public::from(who.public()), + attestations + ) + .sign(&sr25519_core::Pair::from(who), nonce, &mrenclave, &shard) + .into(); + perform_operation(matches, &top); Ok(()) }), ) @@ -329,18 +323,17 @@ pub fn cmd<'a>( let arg_who = matches.value_of("accountid").unwrap(); let who = get_pair_from_str(matches, arg_who); let (_mrenclave, shard) = get_identifiers(matches); - let tgetter = TrustedGetter::attestations( - sr25519_core::Public::from(who.public()), - shard, // for encointer we assume that every currency has its own shard. so shard == cid - ); - let tsgetter = - tgetter.sign(&sr25519_core::Pair::from(who)); println!( "send TrustedGetter::get_attestations for {}", - tsgetter.getter.account(), + who.public(), ); - - let attestations = perform_operation(matches, &TrustedOperationSigned::get(tsgetter)).unwrap(); + let top: TrustedOperation = TrustedGetter::attestations( + sr25519_core::Public::from(who.public()), + shard, // for encointer we assume that every currency has its own shard. so shard == cid + ) + .sign(&sr25519_core::Pair::from(who)) + .into(); + let attestations = perform_operation(matches, &top).unwrap(); println!("Attestations: {:?}", hex::encode(attestations)); Ok(()) }), @@ -374,11 +367,11 @@ pub fn cmd<'a>( .unwrap(); let (_mrenclave, shard) = get_identifiers(matches); + let top: TrustedOperation = TrustedGetter::meetup_index_time_and_location(who.public().into(), shard) + .sign(&sr25519_core::Pair::from(who.clone())) + .into(); - let tgetter = TrustedGetter::meetup_index_time_and_location(who.public().into(), shard); - let tsgetter = tgetter.sign(&sr25519_core::Pair::from(who.clone())); - - let res = perform_operation(matches, &TrustedOperationSigned::get(tsgetter)).unwrap(); + let res = perform_operation(matches, &top).unwrap(); let (mindex, mlocation, mtime): (MeetupIndexType, Option, Option) = Decode::decode(&mut res.as_slice()).unwrap(); info!("got mindex: {:?}", mindex); info!("got time: {:?}", mtime); diff --git a/stf/src/lib.rs b/stf/src/lib.rs index 62620c9e11..a641e76e9f 100644 --- a/stf/src/lib.rs +++ b/stf/src/lib.rs @@ -63,9 +63,60 @@ pub type State = sp_io::SgxExternalities; #[derive(Encode, Decode, Clone)] #[allow(non_camel_case_types)] -pub enum TrustedOperationSigned { +pub enum TrustedOperation { call(TrustedCallSigned), - get(TrustedGetterSigned), + get(Getter), +} + +impl From for TrustedOperation { + fn from(item: TrustedCallSigned) -> Self { + TrustedOperation::call(item) + } +} + +impl From for TrustedOperation { + fn from(item: Getter) -> Self { + TrustedOperation::get(item) + } +} + +impl From for TrustedOperation { + fn from(item: TrustedGetterSigned) -> Self { + TrustedOperation::get(item.into()) + } +} + +impl From for TrustedOperation { + fn from(item: PublicGetter) -> Self { + TrustedOperation::get(item.into()) + } +} + + + +#[derive(Encode, Decode, Clone, Debug)] +#[allow(non_camel_case_types)] +pub enum Getter { + public(PublicGetter), + trusted(TrustedGetterSigned) +} + +impl From for Getter { + fn from(item: PublicGetter) -> Self { + Getter::public(item) + } +} + +impl From for Getter { + fn from(item: TrustedGetterSigned) -> Self { + Getter::trusted(item) + } +} + +#[derive(Encode, Decode, Clone, Debug)] +#[allow(non_camel_case_types)] +pub enum PublicGetter { + total_issuance(CurrencyIdentifier), } #[derive(Encode, Decode, Clone, Debug)] @@ -113,7 +164,7 @@ pub enum TrustedGetter { balance(AccountId, CurrencyIdentifier), registration(AccountId, CurrencyIdentifier), meetup_index_time_and_location(AccountId, CurrencyIdentifier), - attestations(AccountId, CurrencyIdentifier) + attestations(AccountId, CurrencyIdentifier), } impl TrustedGetter { diff --git a/stf/src/sgx.rs b/stf/src/sgx.rs index 8ddaf5823a..1dd1360636 100644 --- a/stf/src/sgx.rs +++ b/stf/src/sgx.rs @@ -16,7 +16,7 @@ use encointer_currencies::{CurrencyIdentifier, Location}; use encointer_ceremonies::{ParticipantIndexType, MeetupIndexType}; use sgx_runtime::Moment; -use crate::{AccountId, State, Stf, TrustedCall, TrustedCallSigned, TrustedGetter, TrustedGetterSigned, ShardIdentifier}; +use crate::{AccountId, State, Stf, TrustedCall, TrustedCallSigned, Getter, PublicGetter, TrustedGetter, TrustedGetterSigned, ShardIdentifier}; /// Simple blob that holds a call in encoded format #[derive(Clone, Debug)] @@ -129,32 +129,43 @@ impl Stf { }) } - pub fn get_state(ext: &mut State, getter: TrustedGetter) -> Option> { - ext.execute_with(|| match getter { - TrustedGetter::balance(who, cid) => { - let balance: BalanceType = encointer_balances::Module::::balance(cid, &who.into()); - Some(balance.encode()) - }, - TrustedGetter::registration(who, cid) => { - let c_index = encointer_scheduler::Module::::current_ceremony_index(); - let part: ParticipantIndexType = encointer_ceremonies::Module::::participant_index((cid, c_index), AccountId32::from(who)); - Some(part.encode()) - } - TrustedGetter::meetup_index_time_and_location(who, cid) => { - let c_index = encointer_scheduler::Module::::current_ceremony_index(); - let meetup_index: MeetupIndexType = encointer_ceremonies::Module::::meetup_index((cid, c_index), AccountId32::from(who)); - let time: Option = encointer_ceremonies::Module::::get_meetup_time(&cid, meetup_index); - let location: Option = encointer_ceremonies::Module::::get_meetup_location(&cid, meetup_index); - let enc = (meetup_index, location, time).encode(); - Some(enc) - } - TrustedGetter::attestations(who, cid) => { - let c_index = encointer_scheduler::Module::::current_ceremony_index(); - let attestation_index = encointer_ceremonies::Module::::attestation_index((cid, c_index), AccountId32::from(who)); - let attestations = encointer_ceremonies::Module::::attestation_registry((cid, c_index), attestation_index); - Some(attestations.encode()) + pub fn get_state(ext: &mut State, getter: Getter) -> Option> { + ext.execute_with(|| + match getter { + Getter::trusted(g) => match g.getter { + TrustedGetter::balance(who, cid) => { + let balance: BalanceType = encointer_balances::Module::::balance(cid, &who.into()); + Some(balance.encode()) + }, + TrustedGetter::registration(who, cid) => { + let c_index = encointer_scheduler::Module::::current_ceremony_index(); + let part: ParticipantIndexType = encointer_ceremonies::Module::::participant_index((cid, c_index), AccountId32::from(who)); + Some(part.encode()) + } + TrustedGetter::meetup_index_time_and_location(who, cid) => { + let c_index = encointer_scheduler::Module::::current_ceremony_index(); + let meetup_index: MeetupIndexType = encointer_ceremonies::Module::::meetup_index((cid, c_index), AccountId32::from(who)); + let time: Option = encointer_ceremonies::Module::::get_meetup_time(&cid, meetup_index); + let location: Option = encointer_ceremonies::Module::::get_meetup_location(&cid, meetup_index); + let enc = (meetup_index, location, time).encode(); + Some(enc) + } + TrustedGetter::attestations(who, cid) => { + let c_index = encointer_scheduler::Module::::current_ceremony_index(); + let attestation_index = encointer_ceremonies::Module::::attestation_index((cid, c_index), AccountId32::from(who)); + let attestations = encointer_ceremonies::Module::::attestation_registry((cid, c_index), attestation_index); + Some(attestations.encode()) + } + }, + Getter::public(g) => match g { + PublicGetter::total_issuance(cid) => { + let c_index = encointer_scheduler::Module::::current_ceremony_index(); + let balance: BalanceType = encointer_balances::Module::::total_issuance(cid); + Some(balance.encode()) + } + } } - }) + ) } fn ensure_ceremony_master(account: AccountId) -> Result<(), StfError> { @@ -189,8 +200,8 @@ impl Stf { key_hashes } - pub fn get_storage_hashes_to_update_for_getter(getter: &TrustedGetterSigned) -> Vec> { - info!("No specific storage updates needed for getter. Returning those for on block: {:?}", getter.getter); + pub fn get_storage_hashes_to_update_for_getter(getter: &Getter) -> Vec> { + info!("No specific storage updates needed for getter. Returning those for on block: {:?}", getter); Self::storage_hashes_to_update_on_block() } diff --git a/worker/src/ws_server.rs b/worker/src/ws_server.rs index fdc5fb7662..24354221e7 100644 --- a/worker/src/ws_server.rs +++ b/worker/src/ws_server.rs @@ -23,7 +23,7 @@ use sgx_types::*; use codec::{Decode, Encode}; use log::*; use std::sync::mpsc::Sender as MpscSender; -use substratee_stf::{ShardIdentifier, TrustedGetter, TrustedGetterSigned}; +use substratee_stf::{ShardIdentifier, Getter}; use substratee_worker_api::requests::*; use ws::{listen, CloseCode, Handler, Message, Result, Sender}; @@ -98,7 +98,7 @@ pub fn handle_request( fn get_stf_state( eid: sgx_enclave_id_t, - getter: TrustedGetterSigned, + getter: Getter, shard: ShardIdentifier, ) -> Message { info!(" [WS Server] Query state"); diff --git a/worker/worker-api/src/lib.rs b/worker/worker-api/src/lib.rs index acfb9db98e..1d549f9824 100644 --- a/worker/worker-api/src/lib.rs +++ b/worker/worker-api/src/lib.rs @@ -26,7 +26,7 @@ use ws::connect; use client::WsClient; use requests::*; -use substratee_stf::{ShardIdentifier, TrustedGetterSigned}; +use substratee_stf::{ShardIdentifier, Getter}; pub mod client; pub mod requests; @@ -56,7 +56,7 @@ impl Api { pub fn get_stf_state( &self, - getter: TrustedGetterSigned, + getter: Getter, shard: &ShardIdentifier, ) -> Result, ()> { let req = ClientRequest::StfState(getter, shard.to_owned()); diff --git a/worker/worker-api/src/requests.rs b/worker/worker-api/src/requests.rs index 8dbbfd1149..f49caccb9e 100644 --- a/worker/worker-api/src/requests.rs +++ b/worker/worker-api/src/requests.rs @@ -16,11 +16,11 @@ */ use codec::{Encode, Decode}; -use substratee_stf::{TrustedGetterSigned, ShardIdentifier}; +use substratee_stf::{Getter, ShardIdentifier}; #[derive(Encode, Decode, Clone, Debug)] pub enum ClientRequest { PubKeyWorker, MuRaPortWorker, - StfState(TrustedGetterSigned, ShardIdentifier), // (trusted_getter_encrypted, shard) + StfState(Getter, ShardIdentifier), // (trusted_getter_encrypted, shard) } \ No newline at end of file