Skip to content

Commit

Permalink
Only fail transaction logs for specified account. (#1011)
Browse files Browse the repository at this point in the history
Co-authored-by: Henry Holtzman <[email protected]>
  • Loading branch information
nick-mobilecoin and holtzman authored Sep 23, 2024
1 parent b95cb7f commit a04bcb0
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 13 deletions.
110 changes: 98 additions & 12 deletions full-service/src/db/transaction_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ pub trait TransactionLogModel {
/// # Returns
/// * unit
fn update_pending_exceeding_tombstone_block_index_to_failed(
account_id: &AccountID,
block_index: u64,
conn: Conn,
) -> Result<(), WalletDbError>;
Expand Down Expand Up @@ -802,13 +803,15 @@ impl TransactionLogModel for TransactionLog {
}

fn update_pending_exceeding_tombstone_block_index_to_failed(
account_id: &AccountID,
block_index: u64,
conn: Conn,
) -> Result<(), WalletDbError> {
use crate::db::schema::transaction_logs;

diesel::update(
transaction_logs::table
.filter(transaction_logs::account_id.eq(&account_id.0))
.filter(transaction_logs::tombstone_block_index.lt(block_index as i64))
.filter(transaction_logs::failed.eq(false))
.filter(transaction_logs::finalized_block_index.is_null()),
Expand Down Expand Up @@ -847,21 +850,21 @@ impl TransactionLogModel for TransactionLog {

#[cfg(test)]
mod tests {
use std::{
assert_matches::assert_matches,
collections::HashMap,
ops::DerefMut,
sync::{Arc, Mutex},
};

use mc_account_keys::{AccountKey, PublicAddress, RootIdentity, CHANGE_SUBADDRESS_INDEX};
use mc_common::logger::{async_test_with_logger, Logger};
use mc_common::logger::{async_test_with_logger, test_with_logger, Logger};
use mc_ledger_db::Ledger;
use mc_transaction_core::{ring_signature::KeyImage, tokens::Mob, tx::Tx, Token};
use mc_transaction_extra::TxOutConfirmationNumber;
use mc_util_from_random::FromRandom;
use rand::{rngs::StdRng, SeedableRng};
use std::{
assert_matches::assert_matches,
collections::HashMap,
ops::DerefMut,
sync::{Arc, Mutex},
};

use super::*;
use crate::{
db::{account::AccountID, transaction_log::TransactionId, txo::TxoStatus},
service::{
Expand All @@ -870,14 +873,12 @@ mod tests {
},
test_utils::{
add_block_with_tx_outs, builder_for_random_recipient, create_test_txo_for_recipient,
get_resolver_factory, get_test_ledger, manually_sync_account,
random_account_with_seed_values, WalletDbTestContext, MOB,
create_test_unsigned_txproposal_and_log, get_resolver_factory, get_test_ledger,
manually_sync_account, random_account_with_seed_values, WalletDbTestContext, MOB,
},
util::b58::b58_encode_public_address,
};

use super::*;

#[async_test_with_logger]
// Test the happy path for log_submitted. When a transaction is submitted to the
// MobileCoin network, several things must happen for Full-Service to
Expand Down Expand Up @@ -2020,4 +2021,89 @@ mod tests {

assert_matches!(transaction_log_id, Err("no valid payload_txo"));
}

#[test_with_logger]
fn fail_by_tombstone_block_only_fails_for_given_account(logger: Logger) {
let mut rng: StdRng = SeedableRng::from_seed([20u8; 32]);

let db_test_context = WalletDbTestContext::default();
let mut ledger_db = get_test_ledger(5, &[], 12, &mut rng);
let wallet_db = db_test_context.get_db_instance(logger.clone());
let mut pooled_conn = wallet_db.get_pooled_conn().unwrap();
let conn = pooled_conn.deref_mut();
let account_keys = (0..3)
.into_iter()
.map(|_| {
random_account_with_seed_values(
&wallet_db,
&mut ledger_db,
&[70 * MOB],
&mut rng,
&logger,
)
})
.collect::<Vec<_>>();
let accounts_and_logs: Vec<_> = account_keys
.iter()
.map(|account_key| {
let account_id = AccountID::from(account_key);
let (_, unsigned_tx_proposal) = create_test_unsigned_txproposal_and_log(
account_key.clone(),
account_key.default_subaddress(),
1 * MOB,
wallet_db.clone(),
ledger_db.clone(),
);
let tx_proposal = unsigned_tx_proposal
.sign_with_local_signer(&account_key)
.unwrap();

let _ = TransactionLog::log_signed(
tx_proposal.clone(),
"".to_string(),
&AccountID::from(account_key).to_string(),
conn,
)
.unwrap();

let transaction_log = TransactionLog::log_submitted(
&tx_proposal,
ledger_db.num_blocks().unwrap(),
"".to_string(),
&AccountID::from(account_key).to_string(),
conn,
)
.unwrap();
(account_id, transaction_log)
})
.collect();

let (account_ids, transaction_logs) = accounts_and_logs
.iter()
.cloned()
.unzip::<_, _, Vec<_>, Vec<_>>();

// Sanity check that all have the same tombstone block
let tombstone_block_index = transaction_logs[0].tombstone_block_index.unwrap();
for tx_log in &transaction_logs {
assert_eq!(tx_log.tombstone_block_index, Some(tombstone_block_index));
}

TransactionLog::update_pending_exceeding_tombstone_block_index_to_failed(
&account_ids[0],
tombstone_block_index as u64 + 1,
conn,
)
.unwrap();

let updated_transaction_logs = transaction_logs
.iter()
.map(|t| TransactionLog::get(&TransactionId::from(t), conn).unwrap())
.collect::<Vec<_>>();

assert_eq!(updated_transaction_logs[0].status(), TxStatus::Failed);
for tx_log in &updated_transaction_logs[1..] {
assert_eq!(tx_log.status(), TxStatus::Pending);
}
}
}
1 change: 1 addition & 0 deletions full-service/src/db/txo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4178,6 +4178,7 @@ mod tests {
// spendable again
let block_index = transaction_log.tombstone_block_index.unwrap() as u64;
TransactionLog::update_pending_exceeding_tombstone_block_index_to_failed(
&account_id,
block_index + 1,
conn,
)
Expand Down
5 changes: 4 additions & 1 deletion full-service/src/service/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ pub fn sync_account_next_chunk(
exclusive_transaction(conn, |conn| {
// Get the account data. If it is no longer available, the account has been
// removed and we can simply return.
let account = Account::get(&AccountID(account_id_hex.to_string()), conn)?;
let account_id = AccountID(account_id_hex.to_string());
let account = Account::get(&account_id, conn)?;

let start_time = Instant::now();
let start_block_index = account.next_block_index as u64;
Expand Down Expand Up @@ -284,6 +285,7 @@ pub fn sync_account_next_chunk(
}

TransactionLog::update_pending_exceeding_tombstone_block_index_to_failed(
&account_id,
end_block_index + 1,
conn,
)?;
Expand Down Expand Up @@ -373,6 +375,7 @@ pub fn sync_account_next_chunk(
}

TransactionLog::update_pending_exceeding_tombstone_block_index_to_failed(
&account_id,
end_block_index + 1,
conn,
)?;
Expand Down

0 comments on commit a04bcb0

Please sign in to comment.