Skip to content
This repository has been archived by the owner on Jul 27, 2022. It is now read-only.

Commit

Permalink
Problem (WIP #1616): keypackage not verified in nodejointx / council …
Browse files Browse the repository at this point in the history
…node data

Solution:
- record most recent isv_svn in chain state, warn when a new version appears
- use mock keypackage and make unit/integration tests running
  tempararily
  • Loading branch information
yihuang committed May 27, 2020
1 parent 26fb9ee commit 5f1020b
Show file tree
Hide file tree
Showing 41 changed files with 352 additions and 343 deletions.
10 changes: 8 additions & 2 deletions Cargo.lock

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

1 change: 0 additions & 1 deletion chain-abci/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ structopt = "0.3"
secp256k1zkp = { git = "https://github.com/crypto-com/rust-secp256k1-zkp.git", rev = "f8759809f6e3fed793b37166f7cd91c57cdb2eab", features = ["recovery", "endomorphism"] }
parity-scale-codec = { features = ["derive"], version = "1.3" }
thiserror = "1.0"
rustls = { version = "0.17", features = ["dangerous_configuration"] }

[target.'cfg(target_os = "linux")'.dependencies]
enclave-u-common = { path = "../chain-tx-enclave/enclave-u-common" }
Expand Down
2 changes: 2 additions & 0 deletions chain-abci/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ kvdb = "0.6"
kvdb-memorydb = "0.6"
chain-storage = { path = "../../chain-storage" }
chain-core = { path = "../../chain-core" }
test-common = { path = "../../test-common" }
abci = "0.7"
protobuf = "2.10.0"
serde_json = "1.0"
hex = "0.4"
base64 = "0.11"

[dependencies.chain-abci]
path = ".."
Expand Down
9 changes: 7 additions & 2 deletions chain-abci/fuzz/fuzz_targets/abci_cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use parity_scale_codec::Decode;
use protobuf;
use std::convert::TryInto;
use std::sync::Arc;
use test_common::chain_env::KEYPACKAGE_VECTOR;

pub fn get_enclave_bridge_mock() -> MockClient {
MockClient::new(0)
Expand Down Expand Up @@ -75,7 +76,7 @@ const TEST_GENESIS: &str = "{
\"value\": \"MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA=\"
},
{
\"keypackage\": \"RklYTUU=\"
\"keypackage\": \"{}\"
}
]
}
Expand All @@ -99,7 +100,11 @@ fn init_request() -> RequestInitChain {
let t = ::protobuf::well_known_types::Timestamp::new();
let mut req = RequestInitChain::default();
req.set_time(t);
req.set_app_state_bytes(TEST_GENESIS.as_bytes().to_vec());
req.set_app_state_bytes(
format!(TEST_GENESIS, base64::encode(KEYPACKAGE_VECTOR))
.as_bytes()
.to_vec(),
);
req.set_chain_id(String::from(TEST_CHAIN_ID));
req.set_validators(vec![validator].into());
req.set_consensus_params(ConsensusParams {
Expand Down
40 changes: 20 additions & 20 deletions chain-abci/src/app/app_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ use chain_storage::buffer::{
};
use chain_storage::jellyfish::{compute_staking_root, sum_staking_coins, StakingGetter, Version};
use chain_storage::{Storage, StoredChainState};
use ra_client::EnclaveCertVerifier;

/// ABCI app state snapshot
#[derive(Serialize, Deserialize, Clone, Encode, Decode)]
Expand All @@ -55,6 +54,9 @@ pub struct ChainNodeState {
pub staking_version: Version,
/// Record the sum of all the coins in UTxO set
pub utxo_coins: Coin,
/// Record the biggest enclave ISVSVN (Security Version Number of the Enclave) we've seen in
/// keypackage so far
pub enclave_isv_svn: u16,

/// The parts of states which involved in computing app_hash
pub top_level: ChainState,
Expand Down Expand Up @@ -87,6 +89,7 @@ impl ChainNodeState {
rewards_pool: RewardsPoolState,
network_params: NetworkParameters,
staking_table: StakingTable,
enclave_isv_svn: u16,
) -> Self {
ChainNodeState {
last_block_height: BlockHeight::genesis(),
Expand All @@ -98,6 +101,7 @@ impl ChainNodeState {
max_evidence_age,
staking_version: 0,
utxo_coins: Coin::zero(),
enclave_isv_svn,
top_level: ChainState {
account_root,
rewards_pool,
Expand Down Expand Up @@ -137,8 +141,6 @@ pub struct ChainNodeApp<T: EnclaveProxy> {
pub rewards_pool_updated: bool,
/// address of tx query enclave to supply to clients (if any)
pub tx_query_address: Option<String>,
/// Enclave certificate verifier
pub enclave_cert_verifier: EnclaveCertVerifier,

/// consensus buffer of staking merkle trie storage
pub staking_buffer: StakingBuffer,
Expand Down Expand Up @@ -225,14 +227,14 @@ fn get_voting_power(
}

pub fn init_app_hash(conf: &InitConfig, genesis_time: Timespec) -> H256 {
let (accounts, rp, _nodes) = conf
let state = conf
.validate_config_get_genesis(genesis_time)
.expect("distribution validation error");

compute_app_hash(
&MerkleTree::empty(),
&compute_staking_root(&accounts),
&rp,
&compute_staking_root(&state.accounts),
&state.rewards_pool,
&NetworkParameters::Genesis(conf.network_params.clone()),
)
}
Expand All @@ -245,7 +247,6 @@ impl<T: EnclaveProxy> ChainNodeApp<T> {
chain_id: &str,
storage: Storage,
tx_query_address: Option<String>,
enclave_cert_verifier: EnclaveCertVerifier,
) -> Self {
let stored_genesis = storage.get_genesis_app_hash();

Expand Down Expand Up @@ -276,7 +277,6 @@ impl<T: EnclaveProxy> ChainNodeApp<T> {
tx_validator,
rewards_pool_updated: false,
tx_query_address,
enclave_cert_verifier,

staking_buffer: HashMap::new(),
mempool_staking_buffer: HashMap::new(),
Expand Down Expand Up @@ -315,9 +315,6 @@ impl<T: EnclaveProxy> ChainNodeApp<T> {
let _ = start_zmq(_conn_str, chain_hex_id, storage.get_read_only());
}

let enclave_cert_verifier = EnclaveCertVerifier::new(Default::default())
.expect("enclave cert verifier init failed");

if let Some(data) = storage.get_last_app_state() {
info!("last app state stored");
let mut last_state =
Expand Down Expand Up @@ -365,7 +362,6 @@ impl<T: EnclaveProxy> ChainNodeApp<T> {
chain_id,
storage,
tx_query_address,
enclave_cert_verifier,
)
} else {
info!("no last app state stored");
Expand All @@ -390,7 +386,6 @@ impl<T: EnclaveProxy> ChainNodeApp<T> {
tx_validator,
rewards_pool_updated: false,
tx_query_address,
enclave_cert_verifier,

staking_buffer: HashMap::new(),
mempool_staking_buffer: HashMap::new(),
Expand Down Expand Up @@ -426,7 +421,7 @@ impl<T: EnclaveProxy> ChainNodeApp<T> {
.get_seconds()
.try_into()
.expect("invalid genesis time");
let (accounts, rp, nodes) = conf
let state = conf
.validate_config_get_genesis(genesis_time)
.expect("distribution validation error");

Expand All @@ -440,11 +435,11 @@ impl<T: EnclaveProxy> ChainNodeApp<T> {
}

let network_params = NetworkParameters::Genesis(conf.network_params);
let new_account_root = self.storage.put_stakings(0, &accounts);
let new_account_root = self.storage.put_stakings(0, &state.accounts);
let genesis_app_hash = compute_app_hash(
&MerkleTree::empty(),
&new_account_root,
&rp,
&state.rewards_pool,
&network_params,
);

Expand All @@ -454,19 +449,23 @@ impl<T: EnclaveProxy> ChainNodeApp<T> {

check_and_store_consensus_params(
req.consensus_params.as_ref(),
&nodes,
&state.validators,
&network_params,
&mut self.storage,
);

check_validators(
&nodes,
&state.validators,
req.validators.clone().into_vec(),
&conf.distribution,
)
.expect("validators in genesis configuration are not consistent with app_state");

let val_addresses = nodes.iter().map(|(addr, _)| *addr).collect::<Vec<_>>();
let val_addresses = state
.validators
.iter()
.map(|(addr, _)| *addr)
.collect::<Vec<_>>();
let staking_table = StakingTable::from_genesis(
&staking_getter!(self, 0),
network_params.get_required_council_node_stake(),
Expand All @@ -479,9 +478,10 @@ impl<T: EnclaveProxy> ChainNodeApp<T> {
genesis_time,
max_evidence_age,
new_account_root,
rp,
state.rewards_pool,
network_params,
staking_table,
state.isv_svn,
);
chain_storage::store_genesis_state(
&mut kv_store!(self),
Expand Down
8 changes: 5 additions & 3 deletions chain-abci/src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,9 +404,11 @@ fn generate_tx_staking_change_event(tx_action: TxAction) -> Option<abci::Event>
fee,
..
} => Some(StakingEvent::Unbond(&unbond.0, unbond.1, unbonded_from, fee).into()),
TxPublicAction::NodeJoin(staking_address, council_node) => {
Some(StakingEvent::NodeJoin(&staking_address, council_node).into())
}
TxPublicAction::NodeJoin {
address,
council_node,
..
} => Some(StakingEvent::NodeJoin(&address, council_node).into()),
TxPublicAction::Unjail(staking_address) => {
Some(StakingEvent::Unjail(&staking_address).into())
}
Expand Down
13 changes: 11 additions & 2 deletions chain-abci/src/app/validate_tx.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use super::{BufferType, ChainNodeApp, ChainNodeState};
use crate::enclave_bridge::EnclaveProxy;
use crate::storage::{process_public_tx, verify_enclave_tx, TxAction, TxEnclaveAction};
use crate::storage::{
process_public_tx, verify_enclave_tx, TxAction, TxEnclaveAction, TxPublicAction,
};
use crate::tx_error::TxError;
use abci::*;
use chain_core::tx::data::TxId;
Expand Down Expand Up @@ -118,11 +120,18 @@ impl<T: EnclaveProxy> ChainNodeApp<T> {
let action = process_public_tx(
&mut staking_store!(self, state.staking_version, buffer_type),
&mut state.staking_table,
&self.enclave_cert_verifier,
state.enclave_isv_svn,
&extra_info,
&tx,
)?;

match action {
TxPublicAction::NodeJoin { isv_svn, .. } => {
state.enclave_isv_svn = isv_svn;
}
_ => {}
};

TxAction::Public(action)
}
};
Expand Down
Loading

0 comments on commit 5f1020b

Please sign in to comment.