Skip to content

Commit

Permalink
Add authentication compatibility tests with fixed bytes (#751)
Browse files Browse the repository at this point in the history
  • Loading branch information
maciejnems authored Nov 23, 2022
1 parent 57cefa2 commit 321f44b
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 34 deletions.
95 changes: 84 additions & 11 deletions finality-aleph/src/network/manager/compatibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,34 +130,107 @@ impl Display for Error {

#[cfg(test)]
mod test {
use std::sync::Arc;

use codec::{Decode, Encode};
use sp_keystore::testing::KeyStore;

use super::{DiscoveryMessage, VersionedAuthentication};
use crate::{
crypto::AuthorityVerifier,
network::{
manager::{compatibility::MAX_AUTHENTICATION_SIZE, SessionHandler},
mock::{crypto_basics, MockMultiaddress, MockNetworkIdentity},
mock::MockMultiaddress,
NetworkIdentity,
},
SessionId, Version,
nodes::testing::new_pen,
tcp_network::{testing::new_identity, TcpMultiaddress},
NodeIndex, SessionId, Version,
};

#[tokio::test]
async fn correctly_decodes_v1() {
let crypto_basics = crypto_basics(1).await;
let handler = SessionHandler::new(
Some(crypto_basics.0[0].clone()),
crypto_basics.1.clone(),
SessionId(43),
MockNetworkIdentity::new().identity().0,
/// Session Handler used for generating versioned authentication in `raw_authentication_v1`
async fn handler() -> SessionHandler<TcpMultiaddress> {
let mnemonic = "ring cool spatial rookie need wing opinion pond fork garbage more april";
let external_addresses = vec![
String::from("addr1"),
String::from("addr2"),
String::from("addr3"),
];

let keystore = Arc::new(KeyStore::new());
let pen = new_pen(mnemonic, keystore).await;
let identity = new_identity(
external_addresses.into_iter().map(String::from).collect(),
pen.authority_id(),
);

SessionHandler::new(
Some((NodeIndex(21), pen)),
AuthorityVerifier::new(vec![]),
SessionId(37),
identity.identity().0,
)
.await
.unwrap();
.unwrap()
}

/// Versioned authentication for authority with:
/// external_addresses: [String::from("addr1"), String::from("addr2"), String::from("addr3")]
/// derived from mnemonic "ring cool spatial rookie need wing opinion pond fork garbage more april"
/// for node index 21 and session id 37
/// encoded at version of Aleph Node from r-8.0
fn raw_authentication_v1() -> Vec<u8> {
vec![
1, 0, 192, 0, 1, 12, 50, 40, 192, 239, 72, 72, 119, 156, 76, 37, 212, 220, 76, 165, 39,
73, 20, 89, 77, 66, 171, 174, 61, 31, 254, 137, 186, 1, 7, 141, 187, 219, 20, 97, 100,
100, 114, 49, 50, 40, 192, 239, 72, 72, 119, 156, 76, 37, 212, 220, 76, 165, 39, 73,
20, 89, 77, 66, 171, 174, 61, 31, 254, 137, 186, 1, 7, 141, 187, 219, 20, 97, 100, 100,
114, 50, 50, 40, 192, 239, 72, 72, 119, 156, 76, 37, 212, 220, 76, 165, 39, 73, 20, 89,
77, 66, 171, 174, 61, 31, 254, 137, 186, 1, 7, 141, 187, 219, 20, 97, 100, 100, 114,
51, 21, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 166, 39, 166, 74, 57, 190, 80, 240, 169, 85,
240, 126, 250, 119, 54, 24, 244, 91, 199, 127, 32, 78, 52, 98, 159, 182, 227, 170, 251,
49, 47, 89, 13, 171, 79, 190, 220, 22, 65, 254, 25, 115, 232, 103, 177, 252, 161, 222,
74, 18, 216, 213, 105, 220, 223, 247, 221, 85, 31, 146, 177, 96, 254, 9,
]
}

#[tokio::test]
async fn correcly_encodes_v1_to_bytes() {
let handler = handler().await;
let raw = raw_authentication_v1();

let authentication_v1 = VersionedAuthentication::V1(DiscoveryMessage::Authentication(
handler.authentication().unwrap(),
));

assert_eq!(authentication_v1.encode(), raw);
}

#[tokio::test]
async fn correcly_decodes_v1_from_bytes() {
let handler = handler().await;
let raw = raw_authentication_v1();

let authentication_v1 = VersionedAuthentication::V1(DiscoveryMessage::Authentication(
handler.authentication().unwrap(),
));

let decoded = VersionedAuthentication::decode(&mut raw.as_slice());

assert_eq!(decoded, Ok(authentication_v1));
}

#[tokio::test]
async fn correctly_decodes_v1_roundtrip() {
let handler = handler().await;

let authentication_v1 = VersionedAuthentication::V1(DiscoveryMessage::Authentication(
handler.authentication().unwrap(),
));

let encoded = authentication_v1.encode();
let decoded = VersionedAuthentication::decode(&mut encoded.as_slice());

assert_eq!(decoded, Ok(authentication_v1))
}

Expand Down
5 changes: 5 additions & 0 deletions finality-aleph/src/nodes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ use crate::{
JustificationNotification, Metrics, MillisecsPerBlock, SessionPeriod,
};

#[cfg(test)]
pub mod testing {
pub use super::validator_node::new_pen;
}

/// Max amount of tries we can not update a finalized block number before we will clear requests queue
const MAX_ATTEMPTS: u32 = 5;

Expand Down
31 changes: 18 additions & 13 deletions finality-aleph/src/nodes/validator_node.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::marker::PhantomData;
use std::{marker::PhantomData, sync::Arc};

use bip39::{Language, Mnemonic, MnemonicType};
use futures::channel::oneshot;
use log::{debug, error};
use sc_client_api::Backend;
use sc_network::ExHashT;
use sp_consensus::SelectChain;
use sp_keystore::CryptoStore;
use sp_runtime::traits::Block;

use crate::{
Expand All @@ -26,6 +27,16 @@ use crate::{
AlephConfig,
};

pub async fn new_pen(mnemonic: &str, keystore: Arc<dyn CryptoStore>) -> AuthorityPen {
let validator_peer_id = keystore
.ed25519_generate_new(KEY_TYPE, Some(mnemonic))
.await
.expect("generating a key should work");
AuthorityPen::new_with_key_type(validator_peer_id.into(), keystore, KEY_TYPE)
.await
.expect("we just generated this key so everything should work")
}

pub async fn run_validator_node<B, H, C, BE, SC>(aleph_config: AlephConfig<B, H, C, SC>)
where
B: Block,
Expand Down Expand Up @@ -55,21 +66,15 @@ where
// We generate the phrase manually to only save the key in RAM, we don't want to have these
// relatively low-importance keys getting spammed around the absolutely crucial Aleph keys.
// The interface of `ed25519_generate_new` only allows to save in RAM by providing a mnemonic.
let validator_peer_id = keystore
.ed25519_generate_new(
KEY_TYPE,
Some(Mnemonic::new(MnemonicType::Words12, Language::English).phrase()),
)
.await
.expect("generating a key should work");
let network_authority_pen =
AuthorityPen::new_with_key_type(validator_peer_id.into(), keystore.clone(), KEY_TYPE)
.await
.expect("we just generated this key so everything should work");
let network_authority_pen = new_pen(
Mnemonic::new(MnemonicType::Words12, Language::English).phrase(),
keystore.clone(),
)
.await;
let (dialer, listener, network_identity) = new_tcp_network(
("0.0.0.0", validator_port),
external_addresses,
validator_peer_id.into(),
network_authority_pen.authority_id(),
)
.await
.expect("we should have working networking");
Expand Down
41 changes: 31 additions & 10 deletions finality-aleph/src/tcp_network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,21 @@ impl NetworkIdentity for TcpNetworkIdentity {
}
}

impl TcpNetworkIdentity {
fn new(external_addresses: Vec<String>, peer_id: AuthorityId) -> TcpNetworkIdentity {
TcpNetworkIdentity {
addresses: external_addresses
.into_iter()
.map(|address| TcpMultiaddress {
peer_id: peer_id.clone(),
address,
})
.collect(),
peer_id,
}
}
}

/// Create a new tcp network, including an identity that can be used for constructing
/// authentications for other peers.
pub async fn new_tcp_network<A: ToSocketAddrs>(
Expand All @@ -139,15 +154,21 @@ pub async fn new_tcp_network<A: ToSocketAddrs>(
impl NetworkIdentity<Multiaddress = TcpMultiaddress, PeerId = AuthorityId>,
)> {
let listener = TcpListener::bind(listening_addresses).await?;
let identity = TcpNetworkIdentity {
addresses: external_addresses
.into_iter()
.map(|address| TcpMultiaddress {
peer_id: peer_id.clone(),
address,
})
.collect(),
peer_id,
};
let identity = TcpNetworkIdentity::new(external_addresses, peer_id);
Ok((TcpDialer {}, listener, identity))
}

#[cfg(test)]
pub mod testing {
use aleph_primitives::AuthorityId;

use super::{TcpMultiaddress, TcpNetworkIdentity};
use crate::network::NetworkIdentity;

pub fn new_identity(
external_addresses: Vec<String>,
peer_id: AuthorityId,
) -> impl NetworkIdentity<Multiaddress = TcpMultiaddress, PeerId = AuthorityId> {
TcpNetworkIdentity::new(external_addresses, peer_id)
}
}

0 comments on commit 321f44b

Please sign in to comment.