Skip to content

Commit

Permalink
updating to pass network fee map when available online
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Corbin committed Jan 24, 2023
1 parent be9e3ef commit ab35a1a
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 47 deletions.
23 changes: 16 additions & 7 deletions full-service/src/db/transaction_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,10 @@ mod tests {
builder.set_tombstone(0).unwrap();
builder.select_txos(&conn, None).unwrap();
let unsigned_tx_proposal = builder.build(TransactionMemo::RTH(None), &conn).unwrap();
let tx_proposal = unsigned_tx_proposal.clone().sign(&account_key).unwrap();
let tx_proposal = unsigned_tx_proposal
.clone()
.sign(&account_key, None)
.unwrap();

assert_eq!(
TransactionId::from(&tx_proposal),
Expand Down Expand Up @@ -929,7 +932,7 @@ mod tests {
builder.set_tombstone(0).unwrap();
builder.select_txos(&conn, None).unwrap();
let unsigned_tx_proposal = builder.build(TransactionMemo::RTH(None), &conn).unwrap();
let tx_proposal = unsigned_tx_proposal.sign(&account_key).unwrap();
let tx_proposal = unsigned_tx_proposal.sign(&account_key, None).unwrap();

let tx_log = TransactionLog::log_submitted(
&tx_proposal,
Expand Down Expand Up @@ -1008,7 +1011,7 @@ mod tests {
builder.set_tombstone(0).unwrap();
builder.select_txos(&conn, None).unwrap();
let unsigned_tx_proposal = builder.build(TransactionMemo::RTH(None), &conn).unwrap();
let tx_proposal = unsigned_tx_proposal.sign(&account_key).unwrap();
let tx_proposal = unsigned_tx_proposal.sign(&account_key, None).unwrap();

// Log submitted transaction from tx_proposal
TransactionLog::log_submitted(
Expand Down Expand Up @@ -1106,7 +1109,7 @@ mod tests {
builder.set_tombstone(0).unwrap();
builder.select_txos(&conn, None).unwrap();
let unsigned_tx_proposal = builder.build(TransactionMemo::RTH(None), &conn).unwrap();
let tx_proposal = unsigned_tx_proposal.sign(&account_key).unwrap();
let tx_proposal = unsigned_tx_proposal.sign(&account_key, None).unwrap();

assert_eq!(
tx_proposal.payload_txos[0].amount.value,
Expand Down Expand Up @@ -1173,7 +1176,7 @@ mod tests {
builder.set_tombstone(0).unwrap();
builder.select_txos(&conn, None).unwrap();
let unsigned_tx_proposal = builder.build(TransactionMemo::RTH(None), &conn).unwrap();
let tx_proposal = unsigned_tx_proposal.sign(&account_key).unwrap();
let tx_proposal = unsigned_tx_proposal.sign(&account_key, None).unwrap();

// Log submitted transaction from tx_proposal
let tx_log = TransactionLog::log_submitted(
Expand Down Expand Up @@ -1411,7 +1414,10 @@ mod tests {

assert_eq!(tx_log, expected_tx_log);

let tx_proposal = unsigned_tx_proposal.clone().sign(&account_key).unwrap();
let tx_proposal = unsigned_tx_proposal
.clone()
.sign(&account_key, None)
.unwrap();
let tx_bytes = mc_util_serial::encode(&tx_proposal.tx);

assert_eq!(
Expand Down Expand Up @@ -1631,7 +1637,10 @@ mod tests {

assert_eq!(tx_log, expected_tx_log);

let tx_proposal = unsigned_tx_proposal.clone().sign(&account_key).unwrap();
let tx_proposal = unsigned_tx_proposal
.clone()
.sign(&account_key, None)
.unwrap();
let tx_bytes = mc_util_serial::encode(&tx_proposal.tx);

assert_eq!(
Expand Down
4 changes: 3 additions & 1 deletion full-service/src/db/txo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2187,7 +2187,9 @@ mod tests {
builder.select_txos(&conn, None).unwrap();
builder.set_tombstone(0).unwrap();
let unsigned_tx_proposal = builder.build(TransactionMemo::RTH(None), &conn).unwrap();
let proposal = unsigned_tx_proposal.sign(&sender_account_key).unwrap();
let proposal = unsigned_tx_proposal
.sign(&sender_account_key, None)
.unwrap();

// Sleep to make sure that the foreign keys exist
std::thread::sleep(Duration::from_secs(3));
Expand Down
2 changes: 1 addition & 1 deletion full-service/src/json_rpc/v1/models/network_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl TryFrom<&service::balance::NetworkStatus> for NetworkStatus {
type Error = String;

fn try_from(src: &service::balance::NetworkStatus) -> Result<NetworkStatus, String> {
let fee = match src.fees.get(&Mob::ID) {
let fee = match src.fees.get_fee_for_token(&Mob::ID) {
Some(fee) => fee,
None => return Err(format!("Could not find fee for token {}", Mob::ID)),
};
Expand Down
43 changes: 31 additions & 12 deletions full-service/src/service/balance.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2020-2021 MobileCoin Inc.

//! Service for managing balances.
use std::collections::BTreeMap;
use std::{collections::BTreeMap, convert::TryFrom};

use crate::{
db::{
Expand All @@ -23,7 +23,7 @@ use mc_common::HashMap;
use mc_connection::{BlockchainConnection, UserTxConnection};
use mc_fog_report_validation::FogPubkeyResolver;
use mc_ledger_db::Ledger;
use mc_transaction_core::{tokens::Mob, Token, TokenId};
use mc_transaction_core::{tokens::Mob, FeeMap, FeeMapError, Token, TokenId};

/// Errors for the Address Service.
#[derive(Display, Debug)]
Expand All @@ -46,6 +46,9 @@ pub enum BalanceServiceError {

/// AccountServiceError
AccountServiceError(AccountServiceError),

/// FeeMapError: {0}
FeeMap(FeeMapError),
}

impl From<WalletDbError> for BalanceServiceError {
Expand Down Expand Up @@ -78,6 +81,12 @@ impl From<AccountServiceError> for BalanceServiceError {
}
}

impl From<FeeMapError> for BalanceServiceError {
fn from(src: FeeMapError) -> Self {
Self::FeeMap(src)
}
}

/// The balance object returned by balance services.
///
/// This must be a service object because there is no "Balance" table in our
Expand Down Expand Up @@ -113,7 +122,7 @@ pub struct NetworkStatus {
pub network_block_height: u64,
pub local_block_height: u64,
pub local_num_txos: u64,
pub fees: BTreeMap<TokenId, u64>,
pub fees: FeeMap,
pub block_version: u32,
}

Expand Down Expand Up @@ -172,12 +181,15 @@ where
let balances = distinct_token_ids
.into_iter()
.map(|token_id| {
let default_token_fee = network_status.fees.get(&token_id).unwrap_or(&0);
let default_token_fee = network_status
.fees
.get_fee_for_token(&token_id)
.unwrap_or(0);
let balance = Self::get_balance_inner(
Some(&account_id.to_string()),
None,
token_id,
default_token_fee,
&default_token_fee,
conn,
)?;
Ok((token_id, balance))
Expand All @@ -201,12 +213,15 @@ where
let balances = distinct_token_ids
.into_iter()
.map(|token_id| {
let default_token_fee = network_status.fees.get(&token_id).unwrap_or(&0);
let default_token_fee = network_status
.fees
.get_fee_for_token(&token_id)
.unwrap_or(0);
let balance = Self::get_balance_inner(
None,
Some(address),
token_id,
default_token_fee,
&default_token_fee,
conn,
)?;
Ok((token_id, balance))
Expand All @@ -217,12 +232,13 @@ where
}

fn get_network_status(&self) -> Result<NetworkStatus, BalanceServiceError> {
let (network_block_height, fees, block_version) = match self.offline {
let (network_block_height, fee_map, block_version) = match self.offline {
true => {
let mut fees = BTreeMap::new();
fees.insert(Mob::ID, Mob::MINIMUM_FEE);
fees.insert(TokenId::from(1), 2560);
(0, fees, *BlockVersion::MAX)
let fee_map = FeeMap::try_from(fees)?;
(0, fee_map, *BlockVersion::MAX)
}
false => (
self.get_network_block_height()?,
Expand All @@ -235,7 +251,7 @@ where
network_block_height,
local_block_height: self.ledger_db.num_blocks()?,
local_num_txos: self.ledger_db.num_txos()?,
fees,
fees: fee_map,
block_version,
})
}
Expand All @@ -258,12 +274,15 @@ where
let token_ids = account.clone().get_token_ids(&conn)?;

for token_id in token_ids {
let default_token_fee = network_status.fees.get(&token_id).unwrap_or(&0);
let default_token_fee = network_status
.fees
.get_fee_for_token(&token_id)
.unwrap_or(0);
let balance = Self::get_balance_inner(
Some(&account_id.to_string()),
None,
token_id,
default_token_fee,
&default_token_fee,
&conn,
)?;
balance_per_token
Expand Down
7 changes: 6 additions & 1 deletion full-service/src/service/gift_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,12 @@ where
)?;

let account_key: AccountKey = mc_util_serial::decode(&from_account.account_key)?;
let tx_proposal = signing_data.sign(&account_key)?;
let fee_map = if self.offline {
None
} else {
Some(self.get_network_fees()?)
};
let tx_proposal = signing_data.sign(&account_key, fee_map.as_ref())?;

if tx_proposal.payload_txos.len() != 1 {
return Err(GiftCodeServiceError::UnexpectedTxProposalFormat);
Expand Down
21 changes: 16 additions & 5 deletions full-service/src/service/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ use mc_ledger_sync::NetworkState;
use mc_transaction_core::{
ring_signature::KeyImage,
tx::{Tx, TxOut, TxOutMembershipProof},
TokenId,
FeeMap, FeeMapError,
};
use rand::Rng;

use crate::db::WalletDbError;
use displaydoc::Display;
use rayon::prelude::*; // For par_iter
use std::{collections::BTreeMap, convert::TryFrom};
use std::convert::TryFrom;

/// Errors for the Address Service.
#[derive(Display, Debug)]
Expand Down Expand Up @@ -74,6 +74,9 @@ pub enum LedgerServiceError {

/// Ledger inconsistent
LedgerInconsistent,

/// Error with FeeMap: {0}
FeeMap(FeeMapError),
}

impl From<mc_ledger_db::Error> for LedgerServiceError {
Expand Down Expand Up @@ -112,6 +115,12 @@ impl From<BlockVersionError> for LedgerServiceError {
}
}

impl From<FeeMapError> for LedgerServiceError {
fn from(src: FeeMapError) -> Self {
Self::FeeMap(src)
}
}

/// Trait defining the ways in which the wallet can interact with and manage
/// ledger objects and interfaces.
pub trait LedgerService {
Expand Down Expand Up @@ -142,7 +151,7 @@ pub trait LedgerService {

fn get_latest_block_info(&self) -> Result<BlockInfo, LedgerServiceError>;

fn get_network_fees(&self) -> Result<BTreeMap<TokenId, u64>, LedgerServiceError>;
fn get_network_fees(&self) -> Result<FeeMap, LedgerServiceError>;

fn get_network_block_version(&self) -> Result<BlockVersion, LedgerServiceError>;

Expand Down Expand Up @@ -291,8 +300,10 @@ where
.ok_or(LedgerServiceError::NoLastBlockInfo)
}

fn get_network_fees(&self) -> Result<BTreeMap<TokenId, u64>, LedgerServiceError> {
Ok(self.get_latest_block_info()?.minimum_fees)
fn get_network_fees(&self) -> Result<FeeMap, LedgerServiceError> {
Ok(FeeMap::try_from(
self.get_latest_block_info()?.minimum_fees,
)?)
}

fn get_network_block_version(&self) -> Result<BlockVersion, LedgerServiceError> {
Expand Down
10 changes: 7 additions & 3 deletions full-service/src/service/models/tx_proposal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use mc_transaction_core::{
ring_signature::KeyImage,
tokens::Mob,
tx::{Tx, TxOut},
Amount, Token,
Amount, FeeMap, Token,
};
use mc_transaction_extra::{TxOutConfirmationNumber, UnsignedTx};
use protobuf::Message;
Expand Down Expand Up @@ -56,7 +56,11 @@ pub struct UnsignedTxProposal {
}

impl UnsignedTxProposal {
pub fn sign(self, account_key: &AccountKey) -> Result<TxProposal, TransactionServiceError> {
pub fn sign(
self,
account_key: &AccountKey,
fee_map: Option<&FeeMap>,
) -> Result<TxProposal, TransactionServiceError> {
let input_txos = self
.unsigned_input_txos
.iter()
Expand All @@ -81,7 +85,7 @@ impl UnsignedTxProposal {

let signer = LocalRingSigner::from(account_key);
let mut rng = rand::thread_rng();
let tx = self.unsigned_tx.sign(&signer, None, &mut rng)?;
let tx = self.unsigned_tx.sign(&signer, fee_map, &mut rng)?;

Ok(TxProposal {
tx,
Expand Down
18 changes: 14 additions & 4 deletions full-service/src/service/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,9 +390,12 @@ where

let fee_value = match fee_value {
Some(f) => f.parse::<u64>()?,
None => *self.get_network_fees()?.get(&fee_token_id).ok_or(
TransactionServiceError::DefaultFeeNotFoundForToken(fee_token_id),
)?,
None => self
.get_network_fees()?
.get_fee_for_token(&fee_token_id)
.ok_or(TransactionServiceError::DefaultFeeNotFoundForToken(
fee_token_id,
))?,
};

builder.set_fee(fee_value, fee_token_id)?;
Expand Down Expand Up @@ -446,7 +449,14 @@ where
transaction(&conn, || {
let account = Account::get(&AccountID(account_id_hex.to_string()), &conn)?;
let account_key: AccountKey = mc_util_serial::decode(&account.account_key)?;
let tx_proposal = unsigned_tx_proposal.sign(&account_key)?;

let fee_map = if self.offline {
None
} else {
Some(self.get_network_fees()?)
};

let tx_proposal = unsigned_tx_proposal.sign(&account_key, fee_map.as_ref())?;

TransactionLog::log_signed(tx_proposal.clone(), "".to_string(), account_id_hex, &conn)?;

Expand Down
Loading

0 comments on commit ab35a1a

Please sign in to comment.