Skip to content

Commit

Permalink
Introduce state snapshot history (#698)
Browse files Browse the repository at this point in the history
Closes #688
  • Loading branch information
Felix Müller authored Apr 12, 2022
1 parent a83cd2a commit 2523ccd
Show file tree
Hide file tree
Showing 61 changed files with 2,814 additions and 638 deletions.
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 &
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;

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

0 comments on commit 2523ccd

Please sign in to comment.