Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix incomplete received tx_log response for v1 API #496

Merged
merged 6 commits into from
Oct 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 29 additions & 3 deletions full-service/src/json_rpc/v1/api/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,20 @@ where

let received_tx_logs: Vec<TransactionLog> = received_txos
.iter()
.map(|(txo, _)| TransactionLog::try_from(txo))
.map(|(txo, _)| {
let subaddress_b58 = match (txo.subaddress_index, txo.account_id.as_ref()) {
(Some(subaddress_index), Some(account_id)) => service
.get_address_for_account(
&AccountID(account_id.clone()),
subaddress_index,
)
.map(|assigned_sub| assigned_sub.public_address_b58)
.ok(),
_ => None,
};

TransactionLog::new_from_received_txo(txo, subaddress_b58)
})
.collect::<Result<Vec<TransactionLog>, _>>()
.map_err(format_error)?;

Expand Down Expand Up @@ -738,7 +751,7 @@ where

let received_txos = service
.list_txos(
Some(account_id),
Some(account_id.clone()),
None,
None,
Some(*Mob::ID),
Expand All @@ -751,7 +764,20 @@ where

let received_tx_logs: Vec<TransactionLog> = received_txos
.iter()
.map(|(txo, _)| TransactionLog::try_from(txo))
.map(|(txo, _)| {
let subaddress_b58 = match txo.subaddress_index {
briancorbin marked this conversation as resolved.
Show resolved Hide resolved
Some(subaddress_index) => service
.get_address_for_account(
&AccountID(account_id.clone()),
subaddress_index,
)
.map(|assigned_sub| assigned_sub.public_address_b58)
.ok(),
None => None,
};

TransactionLog::new_from_received_txo(txo, subaddress_b58)
})
.collect::<Result<Vec<TransactionLog>, _>>()
.map_err(format_error)?;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ mod e2e_transaction {
use crate::{
db::account::AccountID,
json_rpc,
json_rpc::v1::api::test_utils::{dispatch, setup},
json_rpc::v1::{
api::test_utils::{dispatch, setup},
models::transaction_log::{TransactionLog, TxoAbbrev},
},
test_utils::{add_block_to_ledger_db, add_block_with_tx, manually_sync_account, MOB},
util::b58::b58_decode_public_address,
};
Expand Down Expand Up @@ -209,6 +212,102 @@ mod e2e_transaction {
assert_eq!(spent, "0");
}

#[test_with_logger]
fn test_received_transaction_log(logger: Logger) {
let mut rng: StdRng = SeedableRng::from_seed([20u8; 32]);
let (client, mut ledger_db, db_ctx, _network_state) = setup(&mut rng, logger.clone());

// Add an account
let body = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "create_account",
"params": {
"name": "",
}
});
let res = dispatch(&client, body, &logger);
let result = res.get("result").unwrap();
let account_obj = result.get("account").unwrap();
let account_id = account_obj.get("account_id").unwrap().as_str().unwrap();
let b58_public_address = account_obj.get("main_address").unwrap().as_str().unwrap();
let public_address = b58_decode_public_address(b58_public_address).unwrap();

// Add some transactions.
add_block_to_ledger_db(
&mut ledger_db,
&vec![public_address.clone()],
100,
&vec![KeyImage::from(rng.next_u64())],
&mut rng,
);

assert_eq!(ledger_db.num_blocks().unwrap(), 13);
manually_sync_account(
&ledger_db,
&db_ctx.get_db_instance(logger.clone()),
&AccountID(account_id.to_string()),
&logger,
);

let body = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "get_transaction_logs_for_account",
"params": {
"account_id": account_id,
}
});
let res = dispatch(&client, body, &logger);
let result = res.get("result").unwrap();
let tx_log_id = result
.get("transaction_log_ids")
.unwrap()
.as_array()
.unwrap()
.get(0)
.unwrap()
.as_str()
.unwrap();

let tx_log_json = result
.get("transaction_log_map")
.unwrap()
.get(tx_log_id)
.unwrap();

let txo_abbrev_expected = TxoAbbrev {
txo_id_hex: tx_log_id.to_string(),
recipient_address_id: "".to_string(),
value_pmob: 100.to_string(),
};

let tx_log_expected = TransactionLog {
object: "transaction_log".to_string(),
transaction_log_id: tx_log_id.to_string(),
direction: "tx_direction_received".to_string(),
is_sent_recovered: None,
account_id: account_id.to_string(),
input_txos: vec![],
output_txos: vec![txo_abbrev_expected],
change_txos: vec![],
assigned_address_id: Some(b58_public_address.to_string()),
value_pmob: 100.to_string(),
fee_pmob: None,
submitted_block_index: None,
finalized_block_index: Some(12.to_string()),
status: "tx_status_succeeded".to_string(),
sent_time: None,
comment: "".to_string(),
failure_code: None,
failure_message: None,
};

let tx_log: TransactionLog = serde_json::from_value(tx_log_json.clone()).unwrap();

assert_eq!(tx_log, tx_log_expected);
}

#[test_with_logger]
fn test_paginate_transactions(logger: Logger) {
let mut rng: StdRng = SeedableRng::from_seed([20u8; 32]);
Expand Down
59 changes: 16 additions & 43 deletions full-service/src/json_rpc/v1/models/transaction_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! API definition for the TransactionLog object.

use serde::{Deserialize, Serialize};
use std::{convert::TryFrom, fmt};
use std::fmt;

use crate::{
db,
Expand Down Expand Up @@ -66,7 +66,7 @@ impl fmt::Display for TxDirection {

/// A log of a transaction that occurred on the MobileCoin network, constructed
/// and/or submitted from an account in this wallet.
#[derive(Deserialize, Serialize, Default, Debug, Clone)]
#[derive(Deserialize, PartialEq, Serialize, Default, Debug, Clone)]
pub struct TransactionLog {
/// String representing the object's type. Objects of the same type share
/// the same value.
Expand Down Expand Up @@ -139,37 +139,40 @@ pub struct TransactionLog {
pub failure_message: Option<String>,
}

impl TryFrom<&db::models::Txo> for TransactionLog {
type Error = String;

fn try_from(txo: &db::models::Txo) -> Result<Self, Self::Error> {
impl TransactionLog {
pub fn new_from_received_txo(
txo: &db::models::Txo,
assigned_address: Option<String>,
) -> Result<Self, String> {
Ok(TransactionLog {
object: "transaction_log".to_string(),
transaction_log_id: txo.id.to_string(),
transaction_log_id: txo.id.clone(),
direction: TxDirection::Received.to_string(),
is_sent_recovered: None,
account_id: txo
.clone()
.account_id
.ok_or("Txo has no account_id but it is required for a transaction log")?,
input_txos: vec![],
output_txos: vec![],
output_txos: vec![TxoAbbrev {
txo_id_hex: txo.id.to_string(),
recipient_address_id: "".to_string(),
value_pmob: txo.value.to_string(),
}],
change_txos: vec![],
assigned_address_id: None,
assigned_address_id: assigned_address,
value_pmob: txo.value.to_string(),
fee_pmob: None,
submitted_block_index: None,
finalized_block_index: None,
finalized_block_index: txo.received_block_index.map(|index| index.to_string()),
status: TxStatus::Succeeded.to_string(),
sent_time: None,
comment: "".to_string(),
failure_code: None,
failure_message: None,
})
}
}

impl TransactionLog {
pub fn new(
transaction_log: &db::models::TransactionLog,
associated_txos: &AssociatedTxos,
Expand Down Expand Up @@ -223,40 +226,10 @@ impl TransactionLog {
failure_code: None,
failure_message: None,
}
// let assigned_address_id =
// transaction_log.assigned_subaddress_b58.clone(); Self {
// object: "transaction_log".to_string(),
// transaction_log_id: transaction_log.transaction_id_hex.clone(),
// direction: transaction_log.direction.clone(),
// is_sent_recovered: None, // FIXME: WS-16 "Is Sent Recovered"
// account_id: transaction_log.account_id_hex.clone(),
// assigned_address_id,
// value_pmob: (transaction_log.value as u64).to_string(),
// fee_pmob: transaction_log.fee.map(|x| (x as u64).to_string()),
// submitted_block_index: transaction_log
// .submitted_block_index
// .map(|b| (b as u64).to_string()),
// finalized_block_index: transaction_log
// .finalized_block_index
// .map(|b| (b as u64).to_string()),
// status: transaction_log.status.clone(),
// input_txos:
// associated_txos.inputs.iter().map(TxoAbbrev::new).collect(),
// output_txos:
// associated_txos.outputs.iter().map(TxoAbbrev::new).collect(),
// change_txos:
// associated_txos.change.iter().map(TxoAbbrev::new).collect(),
// sent_time: transaction_log
// .sent_time
// .map(|t| Utc.timestamp(t, 0).to_string()),
// comment: transaction_log.comment.clone(),
// failure_code: None, // FIXME: WS-17 Failiure code
// failure_message: None, // FIXME: WS-17 Failure message
// }
}
}

#[derive(Deserialize, Serialize, Default, Debug, Clone)]
#[derive(Deserialize, PartialEq, Serialize, Default, Debug, Clone)]
pub struct TxoAbbrev {
pub txo_id_hex: String,

Expand Down