Skip to content

Commit

Permalink
test: redelegation db
Browse files Browse the repository at this point in the history
  • Loading branch information
mateuszjasiuk committed Sep 4, 2024
1 parent a6a0452 commit d3c26f6
Show file tree
Hide file tree
Showing 5 changed files with 235 additions and 81 deletions.
5 changes: 1 addition & 4 deletions chain/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,7 @@ async fn crawling_fn(
transaction_conn,
redelegations,
)?;
repository::pos::delete_old_redelegations(
transaction_conn,
epoch,
)?;
repository::pos::clear_redelegations(transaction_conn, epoch)?;
repository::pos::remove_withdraws(
transaction_conn,
epoch,
Expand Down
235 changes: 232 additions & 3 deletions chain/src/repository/pos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ pub fn insert_redelegations(
anyhow::Ok(())
}

pub fn delete_old_redelegations(
pub fn clear_redelegations(
transaction_conn: &mut PgConnection,
current_epoch: Epoch,
) -> anyhow::Result<()> {
Expand Down Expand Up @@ -254,11 +254,11 @@ pub fn update_validator_metadata(
#[cfg(test)]
mod tests {
use orm::bond::BondDb;
use orm::redelegation::RedelegationDb;
use orm::unbond::UnbondDb;
use orm::validators::ValidatorInsertDb;
use shared::balance::Amount;
use shared::bond::Bond;
use shared::unbond::Unbond;
use shared::pos::{Bond, Redelegation, Unbond};
use shared::validator::Validator;
use test_helpers::db::TestDb;

Expand Down Expand Up @@ -612,6 +612,200 @@ mod tests {
.expect("Failed to run test");
}

/// Test that the insert_redelegations function panics if validator is not in db.
#[tokio::test]
#[should_panic]
async fn test_insert_redelegations_with_missing_validator() {
let db = TestDb::new();

db.run_test(|conn| {
let fake_validator = Validator::fake();
let fake_redelegations: Vec<Redelegation> = (0..10)
.map(|_| Redelegation::fake(fake_validator.clone().address))
.collect();

insert_redelegations(conn, fake_redelegations)?;

anyhow::Ok(())
})
.await
.expect("Failed to run test");
}

/// Test that the insert_redelegations function correctly inserts redelegations into the empty db.
#[tokio::test]
async fn test_insert_redelegations_with_empty_db() {
let db = TestDb::new();

db.run_test(|conn| {
let fake_validator = Validator::fake();
let fake_redelegations_len = 10;
let fake_redelegations: Vec<Redelegation> = (0
..fake_redelegations_len)
.map(|_| Redelegation::fake(fake_validator.clone().address))
.collect();

seed_validator(conn, fake_validator)?;

insert_redelegations(conn, fake_redelegations)?;

let queried_redelegations = query_redelegations(conn);

assert_eq!(queried_redelegations.len(), fake_redelegations_len);

anyhow::Ok(())
})
.await
.expect("Failed to run test");
}

/// Test that the insert_redelegations function updates the raw_amount on conflict
#[tokio::test]
async fn test_insert_redelegations_with_conflict() {
let db = TestDb::new();

db.run_test(|conn| {
let fake_validator = Validator::fake();
let fake_redelegations_len = 10;
let fake_redelegations: Vec<Redelegation> = (0
..fake_redelegations_len)
.map(|_| Redelegation::fake(fake_validator.clone().address))
.collect();

seed_redelegations(
conn,
fake_validator.clone(),
fake_redelegations.clone(),
)?;

let new_epoch = 123 as Epoch;
let mut updated_redelegations = fake_redelegations.clone();
updated_redelegations
.iter_mut()
.for_each(|unbond| unbond.epoch = new_epoch);

insert_redelegations(conn, updated_redelegations)?;

let queried_redelegations = query_redelegations(conn);
let queried_redelegations_len = queried_redelegations.len();

assert_eq!(queried_redelegations_len, fake_redelegations_len);
assert_eq!(
queried_redelegations
.into_iter()
.map(|b| b.epoch as Epoch)
.collect::<Vec<_>>(),
vec![new_epoch; queried_redelegations_len]
);

anyhow::Ok(())
})
.await
.expect("Failed to run test");
}

/// Test that the insert_redelegations function correctly handles empty redelegations input.
#[tokio::test]
async fn test_insert_redelegations_with_empty_redelegations() {
let db = TestDb::new();

db.run_test(|conn| {
let fake_redelegations_len = 10;
let fake_validator = Validator::fake();
let fake_redelegations: Vec<Redelegation> = (0
..fake_redelegations_len)
.map(|_| Redelegation::fake(fake_validator.clone().address))
.collect();
seed_redelegations(conn, fake_validator, fake_redelegations)?;

insert_redelegations(conn, vec![])?;

let queried_bonds = query_redelegations(conn);

assert_eq!(queried_bonds.len(), fake_redelegations_len);

anyhow::Ok(())
})
.await
.expect("Failed to run test");
}

/// Test that the function correctly handles epoch 0 input.
#[tokio::test]
async fn test_clear_redelegations_with_empty_addresses() {
let db = TestDb::new();

db.run_test(|conn| {
let validator = Validator::fake();
let redelegations = (0..10)
.map(|_| Redelegation::fake(validator.clone().address))
.collect();

seed_redelegations(conn, validator, redelegations)?;
clear_redelegations(conn, 0)?;

let queried_redelegations = query_redelegations(conn);

assert_eq!(queried_redelegations.len(), 10);

anyhow::Ok(())
})
.await
.expect("Failed to run test");
}

/// Test that the clear_redelegations function does nothing when there are not redelegations
/// in the db.
#[tokio::test]
async fn test_clear_redelegations_with_no_redelegations() {
let db = TestDb::new();

db.run_test(|conn| {
clear_redelegations(conn, 99999)?;

let queried_redelegations = query_redelegations(conn);

assert_eq!(queried_redelegations.len(), 0);

anyhow::Ok(())
})
.await
.expect("Failed to run test");
}

/// Test that the clear_redelegations function removes the correct redelegations from the
/// db.
#[tokio::test]
async fn test_clear_redelegations() {
let db = TestDb::new();

db.run_test(|conn| {
let validator = Validator::fake();
let redelegations: Vec<Redelegation> = (0..10)
.map(|i| {
let red = Redelegation::fake(validator.clone().address);
Redelegation {
epoch: i as Epoch,
..red
}
})
.collect();

seed_redelegations(conn, validator.clone(), redelegations.clone())?;

clear_redelegations(conn, 5)?;

let queried_redelegations = query_redelegations(conn);

// We removed all redelegations with epoch <= 5, so we have 6,7,8,9 left
assert_eq!(queried_redelegations.len(), 4);

anyhow::Ok(())
})
.await
.expect("Failed to run test");
}

fn seed_bonds(
conn: &mut PgConnection,
validator: Validator,
Expand Down Expand Up @@ -660,6 +854,34 @@ mod tests {
anyhow::Ok(())
}

fn seed_redelegations(
conn: &mut PgConnection,
validator: Validator,
redelegations: Redelegations,
) -> anyhow::Result<()> {
let validator: ValidatorDb = diesel::insert_into(validators::table)
.values(ValidatorInsertDb::from_validator(validator))
.get_result(conn)
.context("Failed to insert validator")?;

diesel::insert_into(redelegation::table)
.values::<&Vec<RedelegationInsertDb>>(
&redelegations
.into_iter()
.map(|unbond| {
RedelegationInsertDb::from_redelegation(
unbond,
validator.id,
)
})
.collect::<Vec<_>>(),
)
.execute(conn)
.context("Failed to update balances in db")?;

anyhow::Ok(())
}

fn seed_validator(
conn: &mut PgConnection,
validator: Validator,
Expand All @@ -685,4 +907,11 @@ mod tests {
.load::<UnbondDb>(conn)
.expect("Failed to query bonds")
}

fn query_redelegations(conn: &mut PgConnection) -> Vec<RedelegationDb> {
redelegation::table
.select(RedelegationDb::as_select())
.load::<RedelegationDb>(conn)
.expect("Failed to query bonds")
}
}
35 changes: 0 additions & 35 deletions shared/src/bond.rs

This file was deleted.

6 changes: 2 additions & 4 deletions shared/src/pos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,13 @@ pub struct Redelegation {
}

impl Redelegation {
pub fn fake() -> Self {
pub fn fake(validator_address: Id) -> Self {
let delegator =
namada_core::address::gen_established_address("delegator");
let validator =
namada_core::address::gen_established_address("validator");

Self {
delegator: Id::from(delegator),
validator: Id::from(validator),
validator: validator_address,
epoch: (1..1000).fake::<u32>(),
}
}
Expand Down
35 changes: 0 additions & 35 deletions shared/src/unbond.rs

This file was deleted.

0 comments on commit d3c26f6

Please sign in to comment.