Skip to content

Commit

Permalink
Introduce max height configuration option that stops signing at confi…
Browse files Browse the repository at this point in the history
…gured height
  • Loading branch information
zmanian committed Apr 21, 2019
1 parent 8dba213 commit 14e46e3
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 28 deletions.
22 changes: 18 additions & 4 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,15 @@ fn client_loop(config: ValidatorConfig, should_term: &Arc<AtomicBool>) {
host,
port,
} => match &secret_key {
Some(path) => tcp_session(chain_id, max_height, *peer_id, host, *port, path, should_term),
Some(path) => tcp_session(
chain_id,
max_height,
*peer_id,
host,
*port,
path,
should_term,
),
None => {
error!(
"config error: missing field `secret_key` for validator {}",
Expand Down Expand Up @@ -108,7 +116,7 @@ fn client_loop(config: ValidatorConfig, should_term: &Arc<AtomicBool>) {
/// Create a TCP connection to a validator (encrypted with SecretConnection)
fn tcp_session(
chain_id: chain::Id,
max_height:Option<i64>,
max_height: Option<i64>,
validator_peer_id: Option<node::Id>,
host: &str,
port: u16,
Expand All @@ -123,8 +131,14 @@ fn tcp_session(
info!("KMS node ID: {}", &node_public_key);

panic::catch_unwind(move || {
let mut session =
Session::connect_tcp(chain_id,max_height, validator_peer_id, host, port, &secret_key)?;
let mut session = Session::connect_tcp(
chain_id,
max_height,
validator_peer_id,
host,
port,
&secret_key,
)?;

info!(
"[{}@tcp://{}:{}] connected to validator successfully",
Expand Down
1 change: 0 additions & 1 deletion src/config/chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,4 @@ pub struct ChainConfig {
/// this chain. This will be executed at launch time to populate the
/// initial block height if configured
pub state_hook: Option<HookConfig>,

}
4 changes: 2 additions & 2 deletions src/config/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ pub struct ValidatorConfig {

/// Path to our Ed25519 identity key (if applicable)
pub secret_key: Option<PathBuf>,

/// Height at which to stop signing
pub max_height:Option<i64>,
pub max_height: Option<i64>,
}

/// Default value for the `ValidatorConfig` reconnect field
Expand Down
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
)]

#[cfg(not(any(feature = "softsign", feature = "yubihsm", feature = "ledgertm")))]
compile_error!(
"please enable one of the following backends with cargo's --features argument: \
yubihsm, ledgertm, softsign (e.g. --features=yubihsm)"
);
compile_error!(
"please enable one of the following backends with cargo's --features argument: \
yubihsm, ledgertm, softsign (e.g. --features=yubihsm)"
);

extern crate prost_amino as prost;
#[macro_use]
Expand Down
21 changes: 14 additions & 7 deletions src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
use crate::{
chain,
error::{KmsError, KmsErrorKind::{VerificationError, ExceedMaxHeight}},
error::{
KmsError,
KmsErrorKind::{ExceedMaxHeight, VerificationError},
},
prost::Message,
rpc::{Request, Response, TendermintRequest},
unix_connection::UnixConnection,
Expand Down Expand Up @@ -87,7 +90,11 @@ impl Session<SecretConnection<TcpStream>> {
}

impl Session<UnixConnection<UnixStream>> {
pub fn connect_unix(chain_id: chain::Id, max_height:Option<i64>, socket_path: &Path) -> Result<Self, KmsError> {
pub fn connect_unix(
chain_id: chain::Id,
max_height: Option<i64>,
socket_path: &Path,
) -> Result<Self, KmsError> {
debug!(
"{}: Connecting to socket at {}...",
chain_id,
Expand Down Expand Up @@ -158,18 +165,18 @@ where
chain_state.update_consensus_state(request_state.clone())?;
}

if let Some(max_height) = self.max_height{
if let Some(max_height) = self.max_height {
if let Some(height) = request.height() {
if height > max_height{
fail!(
if height > max_height {
fail!(
ExceedMaxHeight,
"attempted to sign at height {} which is greater than {}",
height,
max_height,
);
}
}
}
}
}

let mut to_sign = vec![];
request.sign_bytes(self.chain_id, &mut to_sign)?;
Expand Down
8 changes: 3 additions & 5 deletions tendermint-rs/src/amino_types/proposal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,11 @@ impl SignableMsg for SignProposalRequest {
}
}

fn height(&self) -> Option<i64>{

if let Some(proposal) =&self.proposal{
return Some(proposal.height)
fn height(&self) -> Option<i64> {
if let Some(proposal) = &self.proposal {
return Some(proposal.height);
}
None

}
}

Expand Down
2 changes: 1 addition & 1 deletion tendermint-rs/src/amino_types/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub trait SignableMsg {
fn set_signature(&mut self, sig: &ed25519::Signature);
fn validate(&self) -> Result<(), ValidationError>;
fn consensus_state(&self) -> Option<ConsensusState>;
fn height(&self)-> Option<i64>;
fn height(&self) -> Option<i64>;
}

/// Signed message types. This follows:
Expand Down
7 changes: 3 additions & 4 deletions tendermint-rs/src/amino_types/vote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,11 @@ impl SignableMsg for SignVoteRequest {
None => None,
}
}
fn height(&self) -> Option<i64>{
if let Some(vote) =&self.vote{
return Some(vote.height)
fn height(&self) -> Option<i64> {
if let Some(vote) = &self.vote {
return Some(vote.height);
}
None

}
}

Expand Down
70 changes: 70 additions & 0 deletions tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ impl KmsProcess {
[[validator]]
addr = "tcp://{}@127.0.0.1:{}"
chain_id = "test_chain_id"
max_height = 500000
reconnect = false
secret_key = "tests/support/secret_connection.key"
Expand Down Expand Up @@ -165,6 +166,8 @@ impl KmsProcess {
[[validator]]
addr = "unix://{}"
chain_id = "test_chain_id"
max_height = 500000
[[providers.softsign]]
chain_ids = ["test_chain_id"]
Expand Down Expand Up @@ -415,6 +418,73 @@ fn test_handle_and_sign_vote() {
});
}

#[test]
#[should_panic]
fn test_exceed_max_height() {
let chain_id = "test_chain_id";
let (pub_key, _) = test_key();

let dt = "2018-02-11T07:09:22.765Z".parse::<DateTime<Utc>>().unwrap();
let t = TimeMsg {
seconds: dt.timestamp(),
nanos: dt.timestamp_subsec_nanos() as i32,
};

ProtocolTester::apply(|mut pt| {
let vote_msg = amino_types::vote::Vote {
vote_type: 0x01,
height: 500001,
round: 2,
timestamp: Some(t),
block_id: Some(BlockId {
hash: b"some hash00000000000000000000000".to_vec(),
parts_header: Some(PartsSetHeader {
total: 1000000,
hash: b"parts_hash0000000000000000000000".to_vec(),
}),
}),
validator_address: vec![
0xa3, 0xb2, 0xcc, 0xdd, 0x71, 0x86, 0xf1, 0x68, 0x5f, 0x21, 0xf2, 0x48, 0x2a, 0xf4,
0xfb, 0x34, 0x46, 0xa8, 0x4b, 0x35,
],
validator_index: 56789,
signature: vec![],
};

let svr = amino_types::vote::SignVoteRequest {
vote: Some(vote_msg),
};
let mut buf = vec![];
svr.encode(&mut buf).unwrap();
pt.write_all(&buf).unwrap();

// receive response:
let mut resp_buf = vec![0u8; 1024];
pt.read(&mut resp_buf).unwrap();

let actual_len = extract_actual_len(&resp_buf).unwrap();
let mut resp = vec![0u8; actual_len as usize];
resp.copy_from_slice(&resp_buf[..actual_len as usize]);

let v_resp = vote::SignedVoteResponse::decode(&resp).expect("decoding vote failed");
let mut sign_bytes: Vec<u8> = vec![];
svr.sign_bytes(chain_id.into(), &mut sign_bytes).unwrap();

let vote_msg: amino_types::vote::Vote = v_resp
.vote
.expect("vote should be embedded int the response but none was found");

let sig: Vec<u8> = vote_msg.signature;
assert_ne!(sig.len(), 0);

let verifier = Ed25519Verifier::from(&pub_key);
let signature = ed25519::Signature::from_bytes(sig).unwrap();
let msg: &[u8] = sign_bytes.as_slice();

ed25519::verify(&verifier, msg, &signature).unwrap();
});
}

#[test]
fn test_handle_and_sign_get_publickey() {
ProtocolTester::apply(|mut pt| {
Expand Down

0 comments on commit 14e46e3

Please sign in to comment.