tests: relayer tests (#153)

* refactor: separates prover and prover_sync; all agents compiling except watcher

* refactor: adds EthereumReplica variant and fixes agents

* refactor: adds MockReplica variant to Replicas

* fmt: runs cargo fmt

* test: adds updater poll_and_handle_update test

* test: adds polls_and_relays_update test to relayer

* test: adds poll_confirm test to relayer

* fix: removes duplicated additions after rebase

* fix: removes TxOutcome::default after rebase
buddies-main-deployment
Luke Tchang 4 years ago committed by GitHub
parent 2587cfbe99
commit e7e25db05f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      rust/Cargo.lock
  2. 36
      rust/optics-test/src/mocks/replica.rs
  3. 4
      rust/relayer/Cargo.toml
  4. 122
      rust/relayer/src/relayer.rs
  5. 4
      rust/updater/src/updater.rs

2
rust/Cargo.lock generated

@ -1835,10 +1835,12 @@ dependencies = [
"log", "log",
"optics-base", "optics-base",
"optics-core", "optics-core",
"optics-test",
"serde 1.0.123", "serde 1.0.123",
"serde_json", "serde_json",
"thiserror", "thiserror",
"tokio", "tokio",
"tokio-test",
"tracing", "tracing",
"tracing-futures", "tracing-futures",
"tracing-subscriber", "tracing-subscriber",

@ -14,52 +14,52 @@ use optics_core::{
mock! { mock! {
pub ReplicaContract { pub ReplicaContract {
// Replica // Replica
fn _destination_domain(&self) -> u32 {} pub fn _destination_domain(&self) -> u32 {}
fn _next_pending(&self) -> Result<Option<(H256, U256)>, ChainCommunicationError> {} pub fn _next_pending(&self) -> Result<Option<(H256, U256)>, ChainCommunicationError> {}
fn _can_confirm(&self) -> Result<bool, ChainCommunicationError> {} pub fn _can_confirm(&self) -> Result<bool, ChainCommunicationError> {}
fn _confirm(&self) -> Result<TxOutcome, ChainCommunicationError> {} pub fn _confirm(&self) -> Result<TxOutcome, ChainCommunicationError> {}
fn _previous_root(&self) -> Result<H256, ChainCommunicationError> {} pub fn _previous_root(&self) -> Result<H256, ChainCommunicationError> {}
fn _last_processed(&self) -> Result<U256, ChainCommunicationError> {} pub fn _last_processed(&self) -> Result<U256, ChainCommunicationError> {}
fn _prove(&self, proof: &Proof) -> Result<TxOutcome, ChainCommunicationError> {} pub fn _prove(&self, proof: &Proof) -> Result<TxOutcome, ChainCommunicationError> {}
fn _process(&self, message: &StampedMessage) -> Result<TxOutcome, ChainCommunicationError> {} pub fn _process(&self, message: &StampedMessage) -> Result<TxOutcome, ChainCommunicationError> {}
fn _prove_and_process( pub fn _prove_and_process(
&self, &self,
message: &StampedMessage, message: &StampedMessage,
proof: &Proof, proof: &Proof,
) -> Result<TxOutcome, ChainCommunicationError> {} ) -> Result<TxOutcome, ChainCommunicationError> {}
// Common // Common
fn _name(&self) -> &str {} pub fn _name(&self) -> &str {}
fn _status(&self, txid: H256) -> Result<Option<TxOutcome>, ChainCommunicationError> {} pub fn _status(&self, txid: H256) -> Result<Option<TxOutcome>, ChainCommunicationError> {}
fn _updater(&self) -> Result<H256, ChainCommunicationError> {} pub fn _updater(&self) -> Result<H256, ChainCommunicationError> {}
fn _state(&self) -> Result<State, ChainCommunicationError> {} pub fn _state(&self) -> Result<State, ChainCommunicationError> {}
fn _current_root(&self) -> Result<H256, ChainCommunicationError> {} pub fn _current_root(&self) -> Result<H256, ChainCommunicationError> {}
fn _signed_update_by_old_root( pub fn _signed_update_by_old_root(
&self, &self,
old_root: H256, old_root: H256,
) -> Result<Option<SignedUpdate>, ChainCommunicationError> {} ) -> Result<Option<SignedUpdate>, ChainCommunicationError> {}
fn _signed_update_by_new_root( pub fn _signed_update_by_new_root(
&self, &self,
new_root: H256, new_root: H256,
) -> Result<Option<SignedUpdate>, ChainCommunicationError> {} ) -> Result<Option<SignedUpdate>, ChainCommunicationError> {}
fn _update(&self, update: &SignedUpdate) -> Result<TxOutcome, ChainCommunicationError> {} pub fn _update(&self, update: &SignedUpdate) -> Result<TxOutcome, ChainCommunicationError> {}
fn _double_update( pub fn _double_update(
&self, &self,
double: &DoubleUpdate, double: &DoubleUpdate,
) -> Result<TxOutcome, ChainCommunicationError> {} ) -> Result<TxOutcome, ChainCommunicationError> {}

@ -21,3 +21,7 @@ tracing-subscriber = "0.2.15"
optics-core = { path = "../optics-core" } optics-core = { path = "../optics-core" }
optics-base = { path = "../optics-base" } optics-base = { path = "../optics-base" }
[dev-dependencies]
tokio-test = "0.4.0"
optics-test = { path = "../optics-test" }

@ -39,7 +39,7 @@ impl Relayer {
} }
#[tracing::instrument(err)] #[tracing::instrument(err)]
async fn poll_updates(home: Arc<Homes>, replica: Arc<Replicas>) -> Result<()> { async fn poll_and_relay_update(home: Arc<Homes>, replica: Arc<Replicas>) -> Result<()> {
// Get replica's current root // Get replica's current root
let old_root = replica.current_root().await?; let old_root = replica.current_root().await?;
@ -55,7 +55,7 @@ impl Relayer {
} }
#[tracing::instrument(err)] #[tracing::instrument(err)]
async fn poll_confirms(replica: Arc<Replicas>) -> Result<()> { async fn poll_confirm(replica: Arc<Replicas>) -> Result<()> {
// Check for pending update that can be confirmed // Check for pending update that can be confirmed
let can_confirm = replica.can_confirm().await?; let can_confirm = replica.can_confirm().await?;
@ -99,8 +99,8 @@ impl OpticsAgent for Relayer {
loop { loop {
let (updated, confirmed) = tokio::join!( let (updated, confirmed) = tokio::join!(
Self::poll_updates(home.clone(), replica.clone()), Self::poll_and_relay_update(home.clone(), replica.clone()),
Self::poll_confirms(replica.clone()) Self::poll_confirm(replica.clone())
); );
if let Err(ref e) = updated { if let Err(ref e) = updated {
@ -116,3 +116,117 @@ impl OpticsAgent for Relayer {
}) })
} }
} }
#[cfg(test)]
mod test {
use ethers::{core::types::H256, prelude::LocalWallet};
use std::sync::Arc;
use super::*;
use optics_core::{traits::TxOutcome, SignedUpdate, Update};
use optics_test::mocks::{MockHomeContract, MockReplicaContract};
#[tokio::test]
async fn polls_and_relays_updates() {
let signer: LocalWallet =
"1111111111111111111111111111111111111111111111111111111111111111"
.parse()
.unwrap();
let first_root = H256::from([1; 32]);
let second_root = H256::from([2; 32]);
let signed_update = Update {
origin_domain: 1,
previous_root: first_root,
new_root: second_root,
}
.sign_with(&signer)
.await
.expect("!sign");
let mut mock_home = MockHomeContract::new();
let mut mock_replica = MockReplicaContract::new();
{
let signed_update = signed_update.clone();
// home.signed_update_by_old_root(first_root) called once and
// returns mock value signed_update
mock_home
.expect__signed_update_by_old_root()
.withf(move |r: &H256| *r == first_root)
.times(1)
.return_once(move |_| Ok(Some(signed_update)));
}
{
let signed_update = signed_update.clone();
// replica.current_root called once and returns mock value
// first_root
mock_replica
.expect__current_root()
.times(1)
.returning(move || Ok(first_root));
// replica.update(signed_update) called once and returns
// mock default value
mock_replica
.expect__update()
.withf(move |s: &SignedUpdate| *s == signed_update)
.times(1)
.returning(|_| {
Ok(TxOutcome {
txid: H256::default(),
executed: true,
})
});
}
let mut home: Arc<Homes> = Arc::new(mock_home.into());
let mut replica: Arc<Replicas> = Arc::new(mock_replica.into());
Relayer::poll_and_relay_update(home.clone(), replica.clone())
.await
.expect("Should have returned Ok(())");
let mock_home = Arc::get_mut(&mut home).unwrap();
if let Homes::Mock(home) = mock_home {
home.checkpoint();
} else {
panic!("Home should be mock variant!");
}
let mock_replica = Arc::get_mut(&mut replica).unwrap();
if let Replicas::Mock(replica) = mock_replica {
replica.checkpoint();
} else {
panic!("Replica should be mock variant!");
}
}
#[tokio::test]
async fn confirms_updates() {
let mut mock_replica = MockReplicaContract::new();
// replica.can_confirm called once and returns mock true
mock_replica
.expect__can_confirm()
.times(1)
.returning(|| Ok(true));
// replica.confirm called once and returns mock default
mock_replica.expect__confirm().times(1).returning(|| {
Ok(TxOutcome {
txid: H256::default(),
executed: true,
})
});
let mut replica: Arc<Replicas> = Arc::new(mock_replica.into());
Relayer::poll_confirm(replica.clone())
.await
.expect("Should have returned Ok(())");
let mock_replica = Arc::get_mut(&mut replica).unwrap();
if let Replicas::Mock(replica) = mock_replica {
replica.checkpoint();
} else {
panic!("Replica should be mock variant!");
}
}
}

@ -121,7 +121,7 @@ mod test {
use optics_test::mocks::MockHomeContract; use optics_test::mocks::MockHomeContract;
#[tokio::test] #[tokio::test]
async fn polls_and_signs_update() { async fn polls_and_submits_update() {
let signer: LocalWallet = let signer: LocalWallet =
"1111111111111111111111111111111111111111111111111111111111111111" "1111111111111111111111111111111111111111111111111111111111111111"
.parse() .parse()
@ -135,7 +135,7 @@ mod test {
previous_root, previous_root,
new_root, new_root,
}; };
let signed_update = update.sign_with(&signer).await.unwrap(); let signed_update = update.sign_with(&signer).await.expect("!sign");
let mut mock_home = MockHomeContract::new(); let mut mock_home = MockHomeContract::new();

Loading…
Cancel
Save