Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

teerex refactor 3 #193

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,9 @@ jobs:
matrix:
os: [ ubuntu-latest ]
check: [ cargo build --release,
cargo build --release --features skip-ias-check,
cargo build --release --features dot,
cargo build --release --features ksm,
cargo test --all --features runtime-benchmarks,
cargo test --all --features skip-ias-check,
cargo test --all --features dot,
cargo test --all --features ksm,
cargo fmt --all -- --check,
Expand Down
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions primitives/teerex/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ edition = "2021"
[dependencies]
codec = { version = "3.0.0", default-features = false, features = ["derive"], package = "parity-scale-codec" }
common-primitives = { path = "../common", default-features = false }
derive_more = "0.99.16"
scale-info = { version = "2.0.1", default-features = false, features = ["derive"] }
serde = { version = "1.0.13", default-features = false }

# substrate dependencies
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" }
sp-io = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" }
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" }
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" }

[dev-dependencies]
Expand All @@ -31,5 +33,6 @@ std = [
# substrate
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
"sp-std/std",
]
111 changes: 109 additions & 2 deletions primitives/teerex/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@

//!Primitives for teerex
#![cfg_attr(not(feature = "std"), no_std)]
extern crate derive_more;
use codec::{Decode, Encode};
use derive_more::From;
use scale_info::TypeInfo;
use sp_core::H256;
use sp_core::{bounded_vec::BoundedVec, ConstU32, H256};
use sp_runtime::MultiSigner;
use sp_std::prelude::*;

#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, sp_core::RuntimeDebug, TypeInfo)]
Expand Down Expand Up @@ -75,7 +78,7 @@ impl AsRef<[u8; 64]> for SgxReportData {
}

impl SgxReportData {
fn lower32(&self) -> [u8; 32] {
pub fn lower32(&self) -> [u8; 32] {
let mut lower = [0u8; 32];
lower.copy_from_slice(&self.d[..32]);
lower
Expand All @@ -92,6 +95,96 @@ pub enum SgxStatus {
ConfigurationNeeded,
}

pub type OpaqueSigner = BoundedVec<u8, ConstU32<66>>;
pub type EnclaveFingerprint = H256;

#[derive(Encode, Decode, Clone, PartialEq, Eq, From, sp_core::RuntimeDebug, TypeInfo)]
pub enum AnySigner {
Opaque(OpaqueSigner),
Known(MultiSigner),
}
impl Default for AnySigner {
fn default() -> Self {
AnySigner::Opaque(OpaqueSigner::default())
}
}

impl From<[u8; 32]> for AnySigner {
fn from(pubkey: [u8; 32]) -> Self {
// zero padding is necessary because the chain storage does that anyway for bounded vec
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this concerns me. if we don't zero-pad, the tests fail. but why are BoundedVecs bloated by the onchain state backend?

let mut zero_padded_pubkey = pubkey.to_vec();
zero_padded_pubkey.append(&mut vec![0; 34]);
AnySigner::Opaque(
OpaqueSigner::try_from(zero_padded_pubkey).expect("66 >= 32 + 34. q.e.d."),
)
}
}

impl From<[u8; 64]> for AnySigner {
fn from(pubkey: [u8; 64]) -> Self {
// zero padding is necessary because the chain storage does that anyway for bounded vec
let mut zero_padded_pubkey = pubkey.to_vec();
zero_padded_pubkey.append(&mut vec![0; 2]);
AnySigner::Opaque(OpaqueSigner::try_from(zero_padded_pubkey).expect("66 > 64 + 2. q.e.d."))
}
}

#[derive(Encode, Decode, Copy, Clone, PartialEq, From, Eq, sp_core::RuntimeDebug, TypeInfo)]
pub enum MultiEnclave<Url> {
Sgx(SgxEnclave<Url>),
}

impl<Url> MultiEnclave<Url>
where
Url: Clone,
{
pub fn author(&self) -> AnySigner {
match self {
MultiEnclave::Sgx(enclave) => AnySigner::Opaque(
OpaqueSigner::try_from(enclave.mr_signer.to_vec()).unwrap_or_default(),
),
}
}

pub fn fingerprint(&self) -> EnclaveFingerprint {
match self {
MultiEnclave::Sgx(enclave) => EnclaveFingerprint::from(enclave.mr_enclave),
}
}

pub fn instance_signer(&self) -> AnySigner {
match self {
MultiEnclave::Sgx(enclave) => match enclave.maybe_pubkey() {
Some(pubkey) =>
AnySigner::from(MultiSigner::from(sp_core::ed25519::Public::from_raw(pubkey))),
None => AnySigner::try_from(enclave.report_data.d).unwrap_or_default(),
},
}
}

pub fn instance_url(&self) -> Option<Url> {
match self {
MultiEnclave::Sgx(enclave) => enclave.url.clone(),
}
}

pub fn attestation_timestamp(&self) -> u64 {
match self {
MultiEnclave::Sgx(enclave) => enclave.timestamp,
}
}

pub fn attestaion_proxied(&self) -> bool {
match self {
MultiEnclave::Sgx(enclave) => matches!(
enclave.attestation_method,
SgxAttestationMethod::Skip { proxied: true } |
SgxAttestationMethod::Dcap { proxied: true }
),
}
}
}

#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, sp_core::RuntimeDebug, TypeInfo)]
pub struct SgxEnclave<Url> {
pub report_data: SgxReportData,
Expand Down Expand Up @@ -285,6 +378,20 @@ pub struct Request {
pub cyphertext: Vec<u8>,
}

#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, sp_core::RuntimeDebug, TypeInfo)]
pub struct ShardSignerStatus<AccountId, BlockNumber> {
pub signer: AccountId,
pub fingerprint: EnclaveFingerprint,
pub last_activity: BlockNumber,
}

#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, sp_core::RuntimeDebug, TypeInfo)]
pub struct EnclaveInstanceAddress<AccountId> {
pub fingerprint: EnclaveFingerprint,
pub registrar: AccountId,
pub signer: AnySigner,
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
13 changes: 7 additions & 6 deletions sidechain/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,12 @@

use super::*;

use crate::Pallet as Sidechain;
use frame_benchmarking::{account, benchmarks};
use frame_system::RawOrigin;
use test_utils::test_data::ias::*;

fn assert_latest_worker_update<T: Config>(sender: &T::AccountId, shard: &ShardIdentifier) {
assert_eq!(Sidechain::<T>::worker_for_shard(shard), Teerex::<T>::enclave_index(sender));
assert_eq!(Teerex::<T>::most_recent_shard_update(shard).unwrap().signer, *sender);
}

fn generate_accounts<T: Config>(amount: u32) -> Vec<T::AccountId> {
Expand All @@ -38,9 +37,11 @@ fn add_enclaves_to_registry<T: Config>(accounts: &[T::AccountId]) {
for a in accounts.iter() {
Teerex::<T>::add_enclave(
a,
&SgxEnclave::test_enclave()
.with_pubkey(&a.encode())
.with_mr_enclave(TEST4_SETUP.mrenclave),
MultiEnclave::from(
SgxEnclave::test_enclave()
.with_pubkey(&a.encode())
.with_mr_enclave(TEST4_SETUP.mrenclave),
),
)
.unwrap();
}
Expand Down Expand Up @@ -68,7 +69,7 @@ use crate::{Config, Pallet as PalletModule};

#[cfg(test)]
use frame_benchmarking::impl_benchmark_test_suite;
use teerex_primitives::SgxEnclave;
use teerex_primitives::{MultiEnclave, SgxEnclave};
use test_utils::TestEnclave;

#[cfg(test)]
Expand Down
28 changes: 10 additions & 18 deletions sidechain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,6 @@ pub mod pallet {
FinalizedSidechainBlock(T::AccountId, H256),
}

// Enclave index of the worker that recently committed an update.
#[pallet::storage]
#[pallet::getter(fn worker_for_shard)]
pub type WorkerForShard<T: Config> =
StorageMap<_, Blake2_128Concat, ShardIdentifier, u64, ValueQuery>;

#[pallet::storage]
#[pallet::getter(fn latest_sidechain_block_confirmation)]
pub type LatestSidechainBlockConfirmation<T: Config> =
Expand All @@ -92,19 +86,19 @@ pub mod pallet {

let sender = ensure_signed(origin)?;
Teerex::<T>::ensure_registered_enclave(&sender)?;
let sender_index = Teerex::<T>::enclave_index(&sender);
let sender_enclave = Teerex::<T>::enclave(sender_index)
.ok_or(pallet_teerex::Error::<T>::EmptyEnclaveRegistry)?;
let enclave = Teerex::<T>::sovereign_enclaves(&sender)
.ok_or(pallet_teerex::Error::<T>::EnclaveIsNotRegistered)?;
ensure!(
sender_enclave.mr_enclave.encode() == shard_id.encode(),
pallet_teerex::Error::<T>::WrongMrenclaveForShard
enclave.fingerprint().encode() == shard_id.encode(),
pallet_teerex::Error::<T>::WrongFingerprintForShard
);
let shard_status = Teerex::<T>::touch_shard(enclave.fingerprint(), &sender)?;

// Simple logic for now: only accept blocks from first registered enclave.
if sender_index != 1 {
// TODO: Simple logic for now: only accept blocks from first registered enclave.
if sender != shard_status[0].signer {
log::debug!(
"Ignore block confirmation from registered enclave with index {:?}",
sender_index
"Ignore block confirmation from registered enclave with index > 1: {:}",
sender
);
return Ok(().into())
}
Expand All @@ -127,7 +121,7 @@ pub mod pallet {
next_finalization_candidate_block_number,
);

Self::finalize_block(shard_id, confirmation, &sender, sender_index);
Self::finalize_block(shard_id, confirmation, &sender);
Ok(().into())
}
}
Expand All @@ -146,10 +140,8 @@ impl<T: Config> Pallet<T> {
shard_id: ShardIdentifier,
confirmation: SidechainBlockConfirmation,
sender: &T::AccountId,
sender_index: u64,
) {
<LatestSidechainBlockConfirmation<T>>::insert(shard_id, confirmation);
<WorkerForShard<T>>::insert(shard_id, sender_index);
let block_header_hash = confirmation.block_header_hash;
log::debug!(
"Imported sidechain block confirmed with shard {:?}, block header hash {:?}",
Expand Down
2 changes: 1 addition & 1 deletion sidechain/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ pub type Moment = u64;

impl pallet_timestamp::Config for Test {
type Moment = Moment;
type OnTimestampSet = Teerex;
type OnTimestampSet = ();
type MinimumPeriod = MinimumPeriod;
type WeightInfo = ();
}
Expand Down
23 changes: 12 additions & 11 deletions sidechain/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ limitations under the License.
use crate::{mock::*, Error, Event as SidechainEvent, Teerex};
use frame_support::{assert_err, assert_ok, dispatch::DispatchResultWithPostInfo};
use sp_core::H256;
use teerex_primitives::MrSigner;
use teerex_primitives::{MrSigner, SgxAttestationMethod};
use test_utils::test_data::consts::*;

// give get_signer a concrete type
Expand Down Expand Up @@ -98,7 +98,7 @@ fn confirm_imported_sidechain_block_from_shard_neq_mrenclave_errs() {
block_number,
hash
),
pallet_teerex::Error::<Test>::WrongMrenclaveForShard
pallet_teerex::Error::<Test>::WrongFingerprintForShard
);
})
}
Expand Down Expand Up @@ -187,28 +187,29 @@ fn dont_process_confirmation_of_second_registered_enclave() {
Timestamp::set_timestamp(TEST7_TIMESTAMP);
let shard7 = H256::from_slice(&TEST7_MRENCLAVE);

register_ias_enclave(TEST7_SIGNER_PUB, TEST7_CERT, 1);
register_ias_enclave(TEST6_SIGNER_PUB, TEST6_CERT, 2);
register_ias_enclave(TEST7_SIGNER_PUB, TEST7_CERT);
register_ias_enclave(TEST6_SIGNER_PUB, TEST6_CERT);

assert_ok!(confirm_block(shard7, TEST6_SIGNER_PUB, 1, 2, H256::default(), false));
assert_eq!(Sidechain::latest_sidechain_block_confirmation(shard7).block_number, 0);
})
}

fn register_ias_enclave7() {
register_ias_enclave(TEST7_SIGNER_PUB, TEST7_CERT, 1);
register_ias_enclave(TEST7_SIGNER_PUB, TEST7_CERT);
}

fn register_ias_enclave(signer_pub_key: &MrSigner, cert: &[u8], expected_enclave_count: u64) {
let signer7 = get_signer(signer_pub_key);
fn register_ias_enclave(signer_pub_key: &MrSigner, cert: &[u8]) {
let signer = get_signer(signer_pub_key);

//Ensure that enclave is registered
assert_ok!(Teerex::<Test>::register_ias_enclave(
RuntimeOrigin::signed(signer7),
assert_ok!(Teerex::<Test>::register_sgx_enclave(
RuntimeOrigin::signed(signer.clone()),
cert.to_vec(),
URL.to_vec(),
Some(URL.to_vec()),
SgxAttestationMethod::Ias,
));
assert_eq!(Teerex::<Test>::enclave_count(), expected_enclave_count);
assert!(Teerex::<Test>::sovereign_enclaves(signer).is_some());
}

fn confirm_block7(
Expand Down
1 change: 1 addition & 0 deletions teeracle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ scale-info = { version = "2.0.1", default-features = false, features = ["derive"
# local
pallet-teerex = { path = "../teerex", default-features = false }
teeracle-primitives = { path = "../primitives/teeracle", default-features = false }
teerex-primitives = { path = "../primitives/teerex", default-features = false }

# encointer
substrate-fixed = { tag = "v0.5.9", default-features = false, git = "https://github.com/encointer/substrate-fixed.git" }
Expand Down
Loading