use crate::{
db::{finalize_block, insert_block, with_tx},
test_utils::{
register_contracts_block, test_big_bang, test_block_with_contracts, test_conn_pool,
test_conn_pool_with_big_bang, test_invalid_block, test_invalid_block_with_contract,
},
validate::{self, InvalidOutcome, ValidOutcome, ValidateFailure, ValidateOutcome},
};
use essential_check::solution::{PredicateError, PredicatesError};
use std::time::Duration;
#[tokio::test]
async fn valid_block() {
let conn_pool = test_conn_pool_with_big_bang().await;
let mut conn = conn_pool.acquire().await.unwrap();
let block = test_block_with_contracts(1, Duration::from_secs(1));
with_tx(&mut conn, |tx| {
let block_ca = insert_block(tx, &block).unwrap();
finalize_block(tx, &block_ca)
})
.unwrap();
let big_bang = test_big_bang();
let contract_registry = big_bang.contract_registry.contract;
let program_registry = big_bang.program_registry.contract;
let outcome =
validate::validate_dry_run(&conn_pool, &contract_registry, &program_registry, &block)
.await
.unwrap();
match outcome {
ValidateOutcome::Valid(ValidOutcome { total_gas }) => {
assert!(total_gas > 0);
}
ValidateOutcome::Invalid(_) => {
panic!("expected ValidateOutcome::Valid, found {:?}", outcome)
}
}
}
#[tokio::test]
async fn invalid_block() {
#[cfg(feature = "tracing")]
let _ = tracing_subscriber::fmt::try_init();
let conn_pool = test_conn_pool_with_big_bang().await;
let mut conn = conn_pool.acquire().await.unwrap();
let block = test_invalid_block_with_contract(1, Duration::from_secs(1));
with_tx(&mut conn, |tx| {
let block_ca = insert_block(tx, &block).unwrap();
finalize_block(tx, &block_ca)
})
.unwrap();
let big_bang = test_big_bang();
let contract_registry = big_bang.contract_registry.contract;
let program_registry = big_bang.program_registry.contract;
let outcome =
validate::validate_dry_run(&conn_pool, &contract_registry, &program_registry, &block)
.await
.unwrap();
match outcome {
ValidateOutcome::Invalid(InvalidOutcome {
failure,
solution_set_index,
}) => {
assert_eq!(solution_set_index, 0);
match failure {
ValidateFailure::PredicatesError(err) => match err {
PredicatesError::Failed(errs) => {
assert_eq!(errs.0.len(), 1);
let (solution_index, predicate_err) = &errs.0[0];
assert_eq!(*solution_index, 0);
match predicate_err {
PredicateError::ConstraintsUnsatisfied(indices) => {
assert_eq!(indices.0.len(), 1);
assert_eq!(indices.0[0], 0);
}
_ => panic!(
"expected PredicateError::ConstraintsUnsatisfied, found {:?}",
predicate_err
),
}
}
_ => panic!("expected PredicatesError::Failed, found {:?}", err),
},
_ => panic!(
"expected ValidateFailure::PredicatesError, found {:?}",
failure
),
}
}
_ => {
panic!("expected ValidateOutcome::Invalid, found {:?}", outcome)
}
}
}
#[tokio::test]
async fn predicate_not_found() {
let conn_pool = test_conn_pool();
let (block, _, _) = test_invalid_block(0, Duration::from_secs(0));
let big_bang = test_big_bang();
let contract_registry = big_bang.contract_registry.contract;
let program_registry = big_bang.program_registry.contract;
let res =
validate::validate_dry_run(&conn_pool, &contract_registry, &program_registry, &block).await;
match res {
Ok(ValidateOutcome::Invalid(InvalidOutcome {
failure: ValidateFailure::MissingPredicate(addr),
solution_set_index: 0,
})) => {
assert_eq!(addr, block.solution_sets[0].solutions[0].predicate_to_solve)
}
_ => panic!(
"expected ValidateFailure::MissingPredicate, found {:?}",
res
),
}
}
#[tokio::test]
async fn program_not_found() {
let conn_pool = test_conn_pool_with_big_bang().await;
let mut conn = conn_pool.acquire().await.unwrap();
let (block, contract, _) = test_invalid_block(1, Duration::from_secs(1));
let big_bang = test_big_bang();
let contract_registry = big_bang.contract_registry;
let program_registry = big_bang.program_registry;
let register_block = register_contracts_block(
contract_registry.clone(),
Some(&contract),
1,
Duration::from_secs(1),
)
.unwrap();
with_tx(&mut conn, |tx| {
let block_ca = insert_block(tx, ®ister_block).unwrap();
finalize_block(tx, &block_ca)
})
.unwrap();
let res = validate::validate_dry_run(
&conn_pool,
&contract_registry.contract,
&program_registry.contract,
&block,
)
.await;
match res {
Ok(ValidateOutcome::Invalid(InvalidOutcome {
failure: ValidateFailure::MissingProgram(addr),
solution_set_index: 0,
})) => {
assert_eq!(addr, contract.predicates[0].nodes[0].program_address)
}
_ => panic!("expected ValidateFailure::MissingProgram, found {:?}", res),
}
}
#[tokio::test]
async fn validate_dry_run() {
let conn_pool = test_conn_pool_with_big_bang().await;
let block = test_block_with_contracts(1, Duration::from_secs(1));
let big_bang = test_big_bang();
let contract_registry = big_bang.contract_registry.contract;
let program_registry = big_bang.program_registry.contract;
let outcome =
validate::validate_dry_run(&conn_pool, &contract_registry, &program_registry, &block)
.await
.unwrap();
match outcome {
ValidateOutcome::Valid(ValidOutcome { total_gas }) => {
assert!(total_gas > 0);
}
ValidateOutcome::Invalid(_) => {
panic!("expected ValidateOutcome::Valid, found {:?}", outcome)
}
}
}