5 Commits

Author SHA1 Message Date
Luke Parker
cca9e8cf16 fmt 2024-06-10 13:46:57 -04:00
Luke Parker
97ef70fbd7 Correct ThresholdParams assert_eq 2024-06-10 13:44:44 -04:00
Luke Parker
92275988dd Add note on origin of publish_tx function in tests/coordinator 2024-06-10 13:36:32 -04:00
Luke Parker
c8f690e2f8 Minor nits 2024-06-10 08:45:38 -04:00
Luke Parker
70add5b270 Remove EPOCH_INTERVAL 2024-06-10 08:40:31 -04:00
7 changed files with 49 additions and 41 deletions

View File

@@ -196,10 +196,10 @@ impl Serai {
} }
async fn active_network_validators(&self, network: NetworkId) -> Result<Vec<Public>, SeraiError> { async fn active_network_validators(&self, network: NetworkId) -> Result<Vec<Public>, SeraiError> {
let hash: String = self let validators: String = self
.call("state_call", ["SeraiRuntimeApi_validators".to_string(), hex::encode(network.encode())]) .call("state_call", ["SeraiRuntimeApi_validators".to_string(), hex::encode(network.encode())])
.await?; .await?;
let bytes = Self::hex_decode(hash)?; let bytes = Self::hex_decode(validators)?;
let r = Vec::<Public>::decode(&mut bytes.as_slice()) let r = Vec::<Public>::decode(&mut bytes.as_slice())
.map_err(|e| SeraiError::ErrorInResponse(e.to_string()))?; .map_err(|e| SeraiError::ErrorInResponse(e.to_string()))?;
Ok(r) Ok(r)

View File

@@ -14,10 +14,6 @@ use serai_client::{
mod common; mod common;
use common::validator_sets::{set_keys, allocate_stake, deallocate_stake}; use common::validator_sets::{set_keys, allocate_stake, deallocate_stake};
// TODO: get rid of this is constant and retrive the epoch numbers from sthe node directly
// since epochs doesn't always change at the exact intervals.
const EPOCH_INTERVAL: u64 = 300;
serai_test!( serai_test!(
set_keys_test: (|serai: Serai| async move { set_keys_test: (|serai: Serai| async move {
let network = NetworkId::Bitcoin; let network = NetworkId::Bitcoin;
@@ -225,20 +221,38 @@ async fn validator_set_rotation() {
.await; .await;
} }
async fn epoch_for_block(serai: &Serai, block: [u8; 32]) -> u64 {
let epoch: String = serai
.call("state_call", ["BabeApi_current_epoch".to_string(), String::new(), hex::encode(block)])
.await
.unwrap();
<u64 as scale::Decode>::decode(
&mut hex::decode(epoch.strip_prefix("0x").unwrap()).unwrap().as_slice(),
)
.unwrap()
}
async fn verify_session_and_active_validators( async fn verify_session_and_active_validators(
serai: &Serai, serai: &Serai,
network: NetworkId, network: NetworkId,
session: u64, session: u64,
participants: &[Public], participants: &[Public],
) { ) {
// wait untill the epoch block finalized // wait untill the epoch block finalizes
let epoch_block = (session * EPOCH_INTERVAL) + 1; let block = loop {
while serai.finalized_block_by_number(epoch_block).await.unwrap().is_none() { let mut block = serai.latest_finalized_block_hash().await.unwrap();
// sleep 1 block if epoch_for_block(serai, block).await < session {
tokio::time::sleep(tokio::time::Duration::from_secs(6)).await; // Sleep a block
} tokio::time::sleep(tokio::time::Duration::from_secs(6)).await;
let serai_for_block = continue;
serai.as_of(serai.finalized_block_by_number(epoch_block).await.unwrap().unwrap().hash()); }
while epoch_for_block(serai, block).await > session {
block = serai.block(block).await.unwrap().unwrap().header.parent_hash.0;
}
assert_eq!(epoch_for_block(serai, block).await, session);
break block;
};
let serai_for_block = serai.as_of(block);
// verify session // verify session
let s = serai_for_block.validator_sets().session(network).await.unwrap().unwrap(); let s = serai_for_block.validator_sets().session(network).await.unwrap().unwrap();
@@ -251,9 +265,10 @@ async fn verify_session_and_active_validators(
assert_eq!(validators, participants); assert_eq!(validators, participants);
// make sure finalization continues as usual after the changes // make sure finalization continues as usual after the changes
let current_finalized_block = serai.latest_finalized_block().await.unwrap().header.number;
tokio::time::timeout(tokio::time::Duration::from_secs(60), async move { tokio::time::timeout(tokio::time::Duration::from_secs(60), async move {
let mut finalized_block = serai.latest_finalized_block().await.unwrap().header.number; let mut finalized_block = serai.latest_finalized_block().await.unwrap().header.number;
while finalized_block <= epoch_block + 2 { while finalized_block <= current_finalized_block + 2 {
tokio::time::sleep(tokio::time::Duration::from_secs(6)).await; tokio::time::sleep(tokio::time::Duration::from_secs(6)).await;
finalized_block = serai.latest_finalized_block().await.unwrap().header.number; finalized_block = serai.latest_finalized_block().await.unwrap().header.number;
} }
@@ -265,8 +280,7 @@ async fn verify_session_and_active_validators(
} }
async fn get_active_session(serai: &Serai, network: NetworkId, hash: [u8; 32]) -> u64 { async fn get_active_session(serai: &Serai, network: NetworkId, hash: [u8; 32]) -> u64 {
let block_number = serai.block(hash).await.unwrap().unwrap().header.number; let epoch = epoch_for_block(serai, hash).await;
let epoch = block_number / EPOCH_INTERVAL;
// changes should be active in the next session // changes should be active in the next session
if network == NetworkId::Serai { if network == NetworkId::Serai {

View File

@@ -350,7 +350,7 @@ impl Processor {
/// Receive a message from the coordinator as a processor. /// Receive a message from the coordinator as a processor.
pub async fn recv_message(&mut self) -> CoordinatorMessage { pub async fn recv_message(&mut self) -> CoordinatorMessage {
// Set a timeout of 30 minutes to allow effectively any protocol to occur without a fear of // Set a timeout of 20 minutes to allow effectively any protocol to occur without a fear of
// an arbitrary timeout cutting it short // an arbitrary timeout cutting it short
tokio::time::timeout(Duration::from_secs(20 * 60), self.msgs.recv()).await.unwrap().unwrap() tokio::time::timeout(Duration::from_secs(20 * 60), self.msgs.recv()).await.unwrap().unwrap()
} }

View File

@@ -262,7 +262,7 @@ pub async fn batch(
async fn batch_test() { async fn batch_test() {
new_test( new_test(
|mut processors: Vec<Processor>| async move { |mut processors: Vec<Processor>| async move {
// pop the last participant since genesis keygen has only 4 participant. // pop the last participant since genesis keygen has only 4 participants
processors.pop().unwrap(); processors.pop().unwrap();
assert_eq!(processors.len(), COORDINATORS); assert_eq!(processors.len(), COORDINATORS);

View File

@@ -32,16 +32,20 @@ pub async fn key_gen<C: Ciphersuite>(
let id = KeyGenId { session: set.session, attempt: 0 }; let id = KeyGenId { session: set.session, attempt: 0 };
for (i, processor) in processors.iter_mut().enumerate() { for (i, processor) in processors.iter_mut().enumerate() {
let mut found = false; loop {
while !found {
let msg = processor.recv_message().await; let msg = processor.recv_message().await;
match &msg { match &msg {
CoordinatorMessage::KeyGen(messages::key_gen::CoordinatorMessage::GenerateKey { CoordinatorMessage::KeyGen(messages::key_gen::CoordinatorMessage::GenerateKey {
id: this_id,
params, params,
.. shares,
}) => { }) => {
assert_eq!(id, *this_id);
assert_eq!(params.t(), u16::try_from(((coordinators * 2) / 3) + 1).unwrap(),);
assert_eq!(params.n(), u16::try_from(coordinators).unwrap(),);
assert_eq!(*shares, 1);
participant_is.push(params.i()); participant_is.push(params.i());
found = true; break;
} }
CoordinatorMessage::Substrate( CoordinatorMessage::Substrate(
messages::substrate::CoordinatorMessage::ConfirmKeyPair { .. }, messages::substrate::CoordinatorMessage::ConfirmKeyPair { .. },
@@ -50,20 +54,6 @@ pub async fn key_gen<C: Ciphersuite>(
} }
_ => panic!("unexpected message: {msg:?}"), _ => panic!("unexpected message: {msg:?}"),
} }
assert_eq!(
msg,
CoordinatorMessage::KeyGen(messages::key_gen::CoordinatorMessage::GenerateKey {
id,
params: ThresholdParams::new(
u16::try_from(((coordinators * 2) / 3) + 1).unwrap(),
u16::try_from(coordinators).unwrap(),
participant_is[i],
)
.unwrap(),
shares: 1,
})
);
} }
processor processor
@@ -193,14 +183,14 @@ pub async fn key_gen<C: Ciphersuite>(
.unwrap() .unwrap()
.as_secs() .as_secs()
.abs_diff(context.serai_time) < .abs_diff(context.serai_time) <
(60 * 60 * 3) // 3hrs (60 * 60 * 3) // 3 hours, which should exceed the length of any test we run
); );
assert_eq!(context.network_latest_finalized_block.0, [0; 32]); assert_eq!(context.network_latest_finalized_block.0, [0; 32]);
assert_eq!(set.session, session); assert_eq!(set.session, session);
assert_eq!(key_pair.0 .0, substrate_key); assert_eq!(key_pair.0 .0, substrate_key);
assert_eq!(&key_pair.1, &network_key); assert_eq!(&key_pair.1, &network_key);
} }
_ => panic!("coordinator didn't respond with ConfirmKeyPair msg: {msg:?}"), _ => panic!("coordinator didn't respond with ConfirmKeyPair. msg: {msg:?}"),
} }
message = Some(msg); message = Some(msg);
} else { } else {
@@ -233,7 +223,7 @@ pub async fn key_gen<C: Ciphersuite>(
async fn key_gen_test() { async fn key_gen_test() {
new_test( new_test(
|mut processors: Vec<Processor>| async move { |mut processors: Vec<Processor>| async move {
// pop the last participant since genesis keygen has only 4 participant. // pop the last participant since genesis keygen has only 4 participants
processors.pop().unwrap(); processors.pop().unwrap();
assert_eq!(processors.len(), COORDINATORS); assert_eq!(processors.len(), COORDINATORS);

View File

@@ -47,7 +47,9 @@ pub(crate) async fn new_test(test_body: impl TestBody, fast_epoch: bool) {
let mut coordinators = vec![]; let mut coordinators = vec![];
let mut test = DockerTest::new().with_network(dockertest::Network::Isolated); let mut test = DockerTest::new().with_network(dockertest::Network::Isolated);
let mut coordinator_compositions = vec![]; let mut coordinator_compositions = vec![];
for i in 0 .. 5 { // Spawn one extra coordinator which isn't in-set
#[allow(clippy::range_plus_one)]
for i in 0 .. (COORDINATORS + 1) {
let name = match i { let name = match i {
0 => "Alice", 0 => "Alice",
1 => "Bob", 1 => "Bob",

View File

@@ -11,8 +11,10 @@ use serai_client::{
}, },
Amount, Pair, Transaction, Amount, Pair, Transaction,
}; };
use crate::{*, tests::*}; use crate::{*, tests::*};
// TODO: This is duplicated with serai-client's tests
async fn publish_tx(serai: &Serai, tx: &Transaction) -> [u8; 32] { async fn publish_tx(serai: &Serai, tx: &Transaction) -> [u8; 32] {
let mut latest = serai let mut latest = serai
.block(serai.latest_finalized_block_hash().await.unwrap()) .block(serai.latest_finalized_block_hash().await.unwrap())