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

Introduce state snapshot history #698

Merged
merged 8 commits into from
Apr 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ jobs:
# * `set -eo pipefail` is needed to return an error even if piped to `tee`.
shell: bash --noprofile --norc -eo pipefail {0}
run: |
touch ${{ env.LOG_DIR}}/local-setup.log
./local-setup/launch.py local-setup/github-action-config.json 2>&1 | tee ${{ env.LOG_DIR}}/local-setup.log &
touch ${{ env.LOG_DIR }}/local-setup.log
./local-setup/launch.py local-setup/github-action-config.json 2>&1 | tee -i ${{ env.LOG_DIR }}/local-setup.log &
clangenb marked this conversation as resolved.
Show resolved Hide resolved
sleep 150

- name: ${{ matrix.demo_name }}
Expand Down
2 changes: 2 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2205,6 +2205,7 @@ dependencies = [
"itp-enclave-metrics",
"itp-node-api-extensions",
"itp-settings",
"itp-stf-state-handler",
"itp-test",
"itp-types",
"its-consensus-slots",
Expand Down Expand Up @@ -2717,6 +2718,7 @@ dependencies = [
"itp-settings",
"itp-sgx-crypto",
"itp-sgx-io",
"itp-time-utils",
"itp-types",
"lazy_static",
"log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)",
Expand Down
7 changes: 7 additions & 0 deletions core-primitives/enclave-api/ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ extern "C" {
latest_header_size: usize,
) -> sgx_status_t;

pub fn init_shard(
eid: sgx_enclave_id_t,
retval: *mut sgx_status_t,
shard: *const u8,
shard_size: u32,
) -> sgx_status_t;
murerfel marked this conversation as resolved.
Show resolved Hide resolved

pub fn trigger_parentchain_block_import(
eid: sgx_enclave_id_t,
retval: *mut sgx_status_t,
Expand Down
15 changes: 15 additions & 0 deletions core-primitives/enclave-api/src/enclave_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ pub trait EnclaveBase: Send + Sync + 'static {
authority_proof: Vec<Vec<u8>>,
) -> EnclaveResult<SpHeader>;

/// Initialize a new shard.
fn init_shard(&self, shard: Vec<u8>) -> EnclaveResult<()>;

/// Trigger the import of parentchain block explicitly. Used when initializing a light-client
/// with a triggered import dispatcher.
fn trigger_parentchain_block_import(&self) -> EnclaveResult<()>;
Expand Down Expand Up @@ -145,6 +148,18 @@ impl EnclaveBase for Enclave {
Ok(latest)
}

fn init_shard(&self, shard: Vec<u8>) -> EnclaveResult<()> {
let mut retval = sgx_status_t::SGX_SUCCESS;

let result =
unsafe { ffi::init_shard(self.eid, &mut retval, shard.as_ptr(), shard.len() as u32) };

ensure!(result == sgx_status_t::SGX_SUCCESS, Error::Sgx(result));
ensure!(retval == sgx_status_t::SGX_SUCCESS, Error::Sgx(retval));

Ok(())
}

fn trigger_parentchain_block_import(&self) -> EnclaveResult<()> {
let mut retval = sgx_status_t::SGX_SUCCESS;

Expand Down
1 change: 1 addition & 0 deletions core-primitives/settings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub mod files {
pub static RA_API_KEY_FILE: &str = "key.txt";

pub const SPID_MIN_LENGTH: usize = 32;
pub const STATE_SNAPSHOTS_CACHE_SIZE: usize = 120;
}

/// Settings concerning the worker
Expand Down
25 changes: 19 additions & 6 deletions core-primitives/sgx/crypto/src/aes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use std::convert::{TryFrom, TryInto};

type AesOfb = Ofb<Aes128>;

#[derive(Debug, Default, Encode, Decode, Clone, Copy)]
#[derive(Debug, Default, Encode, Decode, Clone, Copy, PartialEq, Eq)]
pub struct Aes {
pub key: [u8; 16],
pub init_vec: [u8; 16],
Expand Down Expand Up @@ -78,24 +78,37 @@ pub mod sgx {

use super::*;
use itp_settings::files::AES_KEY_FILE_AND_INIT_V;
use itp_sgx_io::{seal, unseal, SealedIO};
use itp_sgx_io::{seal, unseal, SealedIO, StaticSealedIO};
use log::info;
use sgx_rand::{Rng, StdRng};
use std::sgxfs::SgxFile;

impl SealedIO for AesSeal {
impl StaticSealedIO for AesSeal {
type Error = Error;
type Unsealed = Aes;

fn unseal() -> Result<Self::Unsealed> {
fn unseal_from_static_file() -> Result<Self::Unsealed> {
Ok(unseal(AES_KEY_FILE_AND_INIT_V).map(|b| Decode::decode(&mut b.as_slice()))??)
}

fn seal(unsealed: Self::Unsealed) -> Result<()> {
fn seal_to_static_file(unsealed: Self::Unsealed) -> Result<()> {
Ok(unsealed.using_encoded(|bytes| seal(bytes, AES_KEY_FILE_AND_INIT_V))?)
}
}

impl SealedIO for AesSeal {
type Error = Error;
type Unsealed = Aes;

fn unseal(&self) -> Result<Self::Unsealed> {
Self::unseal_from_static_file()
}

fn seal(&self, unsealed: Self::Unsealed) -> Result<()> {
Self::seal_to_static_file(unsealed)
}
}

pub fn create_sealed_if_absent() -> Result<()> {
if SgxFile::open(AES_KEY_FILE_AND_INIT_V).is_err() {
info!("[Enclave] Keyfile not found, creating new! {}", AES_KEY_FILE_AND_INIT_V);
Expand All @@ -112,6 +125,6 @@ pub mod sgx {

rand.fill_bytes(&mut key);
rand.fill_bytes(&mut iv);
AesSeal::seal(Aes::new(key, iv))
AesSeal::seal_to_static_file(Aes::new(key, iv))
}
}
21 changes: 17 additions & 4 deletions core-primitives/sgx/crypto/src/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,17 @@ pub mod sgx {
use crate::error::{Error, Result};
use codec::Encode;
use itp_settings::files::SEALED_SIGNER_SEED_FILE;
use itp_sgx_io::{seal, unseal, SealedIO};
use itp_sgx_io::{seal, unseal, SealedIO, StaticSealedIO};
use log::*;
use sgx_rand::{Rng, StdRng};
use sp_core::{crypto::Pair, ed25519};
use std::{path::Path, sgxfs::SgxFile};

impl SealedIO for Ed25519Seal {
impl StaticSealedIO for Ed25519Seal {
type Error = Error;
type Unsealed = ed25519::Pair;

fn unseal() -> Result<ed25519::Pair> {
fn unseal_from_static_file() -> Result<ed25519::Pair> {
let raw = unseal(SEALED_SIGNER_SEED_FILE)?;

let key = ed25519::Pair::from_seed_slice(&raw)
Expand All @@ -49,11 +49,24 @@ pub mod sgx {
Ok(key.into())
}

fn seal(unsealed: Self::Unsealed) -> Result<()> {
fn seal_to_static_file(unsealed: Self::Unsealed) -> Result<()> {
Ok(unsealed.seed().using_encoded(|bytes| seal(bytes, SEALED_SIGNER_SEED_FILE))?)
}
}

impl SealedIO for Ed25519Seal {
type Error = Error;
type Unsealed = ed25519::Pair;

fn unseal(&self) -> Result<Self::Unsealed> {
Self::unseal_from_static_file()
}

fn seal(&self, unsealed: Self::Unsealed) -> Result<()> {
Self::seal_to_static_file(unsealed)
}
}

pub fn create_sealed_if_absent() -> Result<()> {
if SgxFile::open(SEALED_SIGNER_SEED_FILE).is_err() {
if Path::new(SEALED_SIGNER_SEED_FILE).exists() {
Expand Down
2 changes: 1 addition & 1 deletion core-primitives/sgx/crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ pub use self::rsa3072::*;
pub use error::*;
pub use traits::*;

#[cfg(all(feature = "mocks", feature = "sgx"))]
#[cfg(feature = "mocks")]
pub mod mocks;
61 changes: 46 additions & 15 deletions core-primitives/sgx/crypto/src/mocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,72 @@

*/

#[cfg(feature = "sgx")]
use std::sync::SgxRwLock as RwLock;

#[cfg(feature = "std")]
use std::sync::RwLock;

use crate::{
aes::Aes,
error::{Error, Result},
Aes,
};
use itp_sgx_io::SealedIO;
use sgx_crypto_helper::rsa3072::Rsa3072KeyPair;
use itp_sgx_io::{SealedIO, StaticSealedIO};

#[derive(Default)]
pub struct AesSealMock {}
pub struct AesSealMock {
aes: RwLock<Aes>,
}

impl SealedIO for AesSealMock {
impl StaticSealedIO for AesSealMock {
type Error = Error;
type Unsealed = Aes;

fn unseal() -> Result<Self::Unsealed> {
fn unseal_from_static_file() -> Result<Self::Unsealed> {
Ok(Aes::default())
}

fn seal(_unsealed: Self::Unsealed) -> Result<()> {
fn seal_to_static_file(_unsealed: Self::Unsealed) -> Result<()> {
Ok(())
}
}

#[derive(Default)]
pub struct Rsa3072SealMock {}

impl SealedIO for Rsa3072SealMock {
impl SealedIO for AesSealMock {
type Error = Error;
type Unsealed = Rsa3072KeyPair;
type Unsealed = Aes;

fn unseal() -> Result<Self::Unsealed> {
Ok(Rsa3072KeyPair::default())
fn unseal(&self) -> std::result::Result<Self::Unsealed, Self::Error> {
self.aes
.read()
.map_err(|e| Error::Other(format!("{:?}", e).into()))
.map(|k| k.clone())
}

fn seal(_unsealed: Self::Unsealed) -> Result<()> {
fn seal(&self, unsealed: Self::Unsealed) -> std::result::Result<(), Self::Error> {
let mut aes_lock = self.aes.write().map_err(|e| Error::Other(format!("{:?}", e).into()))?;
*aes_lock = unsealed;
Ok(())
}
}

#[cfg(feature = "sgx")]
pub mod sgx {
use super::*;
use sgx_crypto_helper::rsa3072::Rsa3072KeyPair;

#[derive(Default)]
pub struct Rsa3072SealMock {}

impl StaticSealedIO for Rsa3072SealMock {
type Error = Error;
type Unsealed = Rsa3072KeyPair;

fn unseal_from_static_file() -> Result<Self::Unsealed> {
Ok(Rsa3072KeyPair::default())
}

fn seal_to_static_file(_unsealed: Self::Unsealed) -> Result<()> {
Ok(())
}
}
}
25 changes: 19 additions & 6 deletions core-primitives/sgx/crypto/src/rsa3072.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::{
};
use derive_more::Display;
use itp_settings::files::RSA3072_SEALED_KEY_FILE;
use itp_sgx_io::{seal, unseal, SealedIO};
use itp_sgx_io::{seal, unseal, SealedIO, StaticSealedIO};
use log::*;
use sgx_crypto_helper::{
rsa3072::{Rsa3072KeyPair, Rsa3072PubKey},
Expand All @@ -34,23 +34,36 @@ use std::{sgxfs::SgxFile, vec::Vec};
#[derive(Copy, Clone, Debug, Display)]
pub struct Rsa3072Seal;

impl SealedIO for Rsa3072Seal {
impl StaticSealedIO for Rsa3072Seal {
type Error = Error;
type Unsealed = Rsa3072KeyPair;
fn unseal() -> Result<Self::Unsealed> {
fn unseal_from_static_file() -> Result<Self::Unsealed> {
let raw = unseal(RSA3072_SEALED_KEY_FILE)?;
let key: Rsa3072KeyPair =
serde_json::from_slice(&raw).map_err(|e| Error::Other(format!("{:?}", e).into()))?;
Ok(key.into())
}

fn seal(unsealed: Rsa3072KeyPair) -> Result<()> {
fn seal_to_static_file(unsealed: Rsa3072KeyPair) -> Result<()> {
let key_json =
serde_json::to_vec(&unsealed).map_err(|e| Error::Other(format!("{:?}", e).into()))?;
Ok(seal(&key_json, RSA3072_SEALED_KEY_FILE)?)
}
}

impl SealedIO for Rsa3072Seal {
type Error = Error;
type Unsealed = Rsa3072KeyPair;

fn unseal(&self) -> Result<Self::Unsealed> {
Self::unseal_from_static_file()
}

fn seal(&self, unsealed: Self::Unsealed) -> Result<()> {
Self::seal_to_static_file(unsealed)
}
}

impl ShieldingCrypto for Rsa3072KeyPair {
type Error = Error;

Expand All @@ -71,7 +84,7 @@ impl ShieldingCrypto for Rsa3072KeyPair {

impl Rsa3072Seal {
pub fn unseal_pubkey() -> Result<Rsa3072PubKey> {
let pair = Self::unseal()?;
let pair = Self::unseal_from_static_file()?;
let pubkey = pair.export_pubkey().map_err(|e| Error::Other(format!("{:?}", e).into()))?;
Ok(pubkey)
}
Expand All @@ -88,5 +101,5 @@ pub fn create_sealed_if_absent() -> Result<()> {
pub fn create_sealed() -> Result<()> {
let rsa_keypair = Rsa3072KeyPair::new().map_err(|e| Error::Other(format!("{:?}", e).into()))?;
// println!("[Enclave] generated RSA3072 key pair. Cleartext: {}", rsa_key_json);
Rsa3072Seal::seal(rsa_keypair)
Rsa3072Seal::seal_to_static_file(rsa_keypair)
}
Loading