Skip to content

Commit

Permalink
Feature/vo account balance improvements (#328)
Browse files Browse the repository at this point in the history
  • Loading branch information
briancorbin authored May 26, 2022
1 parent e9cff49 commit 4db9500
Show file tree
Hide file tree
Showing 8 changed files with 391 additions and 128 deletions.
1 change: 1 addition & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
* [Export Secrets](view-only-accounts/account-secrets/export\_view\_only\_account\_secrets.md)
* [Balance](view-only-accounts/balance/README.md)
* [Get Balance](view-only-accounts/balance/get\_balance\_for\_view\_only\_account.md)
* [Get Balance For Address](view-only-accounts/balance/get\_balance\_for\_view\_only\_address.md)
* [Syncing](view-only-accounts/syncing/README.md)
* [Create Account Sync Request](view-only-accounts/syncing/create\_view\_only\_account\_sync\_request.md)
* [Sync Account](view-only-accounts/syncing/sync\_view\_only\_account.md)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: Get the current balance for a given view only account.
description: Get the current balance for a given account.
---

# Get Balance For View Only Account
Expand All @@ -8,7 +8,7 @@ description: Get the current balance for a given view only account.

| Required Param | Purpose | Requirements |
| :--- | :--- | :--- |
| `account_id` | The account on which to perform this action. | Account must exist in the wallet. |
| `account_id` | The account on which to perform this action. | Account must exist in the wallet as a view only account. |

## Example

Expand All @@ -32,12 +32,17 @@ description: Get the current balance for a given view only account.
"method": "get_balance_for_view_only_account",
"result": {
"balance": {
"object": "balance",
"balance": "10000000000000",
"network_block_height": "468847",
"local_block_height": "468847",
"account_block_height": "468847",
"is_synced": true
"object": "balance",
"network_block_height": "152918",
"local_block_height": "152918",
"account_block_height": "152003",
"is_synced": false,
"unspent_pmob": "110000000000000000",
"max_spendable_pmob": "110000000000000000",
"pending_pmob": "0",
"spent_pmob": "0",
"secreted_pmob": "0",
"orphaned_pmob": "0"
}
},
"error": null,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
description: Get the current balance for a given address.
---

# Get Balance For Address

| Required Param | Purpose | Requirements |
| :--- | :--- | :--- |
| `address` | The address on which to perform this action. | Address must be assigned for an account in the wallet. |

{% tabs %}
{% tab title="Request Body" %}
```text
{
"method": "get_balance_for_view_only_address",
"params": {
"address": "3P4GtGkp5UVBXUzBqirgj7QFetWn4PsFPsHBXbC6A8AXw1a9CMej969jneiN1qKcwdn6e1VtD64EruGVSFQ8wHk5xuBHndpV9WUGQ78vV7Z"
},
"jsonrpc": "2.0",
"api_version": "2",
"id": 1
}
```
{% endtab %}

{% tab title="Response" %}
```text
{
"method": "get_balance_for_view_only_address",
"result": {
"balance": {
"object": "balance",
"network_block_height": "152961",
"local_block_height": "152961",
"account_block_height": "152961",
"is_synced": true,
"unspent_pmob": "11881402222024",
"max_spendable_pmob": "11881402222024",
"pending_pmob": "0",
"spent_pmob": "84493835554166",
"secreted_pmob": "0",
"orphaned_pmob": "0"
}
},
"error": null,
"jsonrpc": "2.0",
"id": 1,
"api_version": "2"
}
```
{% endtab %}
{% endtabs %}

104 changes: 104 additions & 0 deletions full-service/src/db/view_only_txo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,26 @@ pub trait ViewOnlyTxoModel {
conn: &Conn,
) -> Result<Vec<ViewOnlyTxo>, WalletDbError>;

fn list_orphaned(account_id_hex: &str, conn: &Conn) -> Result<Vec<ViewOnlyTxo>, WalletDbError>;

fn list_unspent(
account_id_hex: &str,
assigned_subaddress_b58: Option<&str>,
conn: &Conn,
) -> Result<Vec<ViewOnlyTxo>, WalletDbError>;

fn list_pending(
account_id_hex: &str,
assigned_subaddress_b58: Option<&str>,
conn: &Conn,
) -> Result<Vec<ViewOnlyTxo>, WalletDbError>;

fn list_spent(
account_id_hex: &str,
assigned_subaddress_b58: Option<&str>,
conn: &Conn,
) -> Result<Vec<ViewOnlyTxo>, WalletDbError>;

/// Select a set of unspent view only Txos to reach a given value.
///
/// Returns:
Expand Down Expand Up @@ -259,6 +279,90 @@ impl ViewOnlyTxoModel for ViewOnlyTxo {
Ok(results)
}

fn list_orphaned(account_id_hex: &str, conn: &Conn) -> Result<Vec<ViewOnlyTxo>, WalletDbError> {
use schema::view_only_txos;

let txos: Vec<ViewOnlyTxo> = view_only_txos::table
.filter(view_only_txos::view_only_account_id_hex.eq(account_id_hex))
.filter(view_only_txos::key_image.is_null())
.filter(view_only_txos::subaddress_index.is_null())
.load(conn)?;

Ok(txos)
}

fn list_unspent(
account_id_hex: &str,
assigned_subaddress_b58: Option<&str>,
conn: &Conn,
) -> Result<Vec<ViewOnlyTxo>, WalletDbError> {
use schema::view_only_txos;

let results = view_only_txos::table
.filter(view_only_txos::view_only_account_id_hex.eq(account_id_hex))
.filter(view_only_txos::received_block_index.is_not_null())
.filter(view_only_txos::pending_tombstone_block_index.is_null())
.filter(view_only_txos::spent_block_index.is_null());

let txos = if let Some(assigned_subaddress_b58) = assigned_subaddress_b58 {
let subaddress = ViewOnlySubaddress::get(assigned_subaddress_b58, conn)?;
results
.filter(view_only_txos::subaddress_index.eq(subaddress.subaddress_index))
.load(conn)?
} else {
results.load(conn)?
};

Ok(txos)
}

fn list_pending(
account_id_hex: &str,
assigned_subaddress_b58: Option<&str>,
conn: &Conn,
) -> Result<Vec<ViewOnlyTxo>, WalletDbError> {
use schema::view_only_txos;

let results = view_only_txos::table
.filter(view_only_txos::view_only_account_id_hex.eq(account_id_hex))
.filter(view_only_txos::pending_tombstone_block_index.is_not_null())
.filter(view_only_txos::spent_block_index.is_null());

let txos = if let Some(assigned_subaddress_b58) = assigned_subaddress_b58 {
let subaddress = ViewOnlySubaddress::get(assigned_subaddress_b58, conn)?;
results
.filter(view_only_txos::subaddress_index.eq(subaddress.subaddress_index))
.load(conn)?
} else {
results.load(conn)?
};

Ok(txos)
}

fn list_spent(
account_id_hex: &str,
assigned_subaddress_b58: Option<&str>,
conn: &Conn,
) -> Result<Vec<ViewOnlyTxo>, WalletDbError> {
use schema::view_only_txos;

let results = view_only_txos::table
.filter(view_only_txos::view_only_account_id_hex.eq(account_id_hex))
.filter(view_only_txos::spent_block_index.is_not_null());

let txos = if let Some(assigned_subaddress_b58) = assigned_subaddress_b58 {
let subaddress = ViewOnlySubaddress::get(assigned_subaddress_b58, conn)?;
results
.filter(view_only_txos::subaddress_index.eq(subaddress.subaddress_index))
.load(conn)?
} else {
results.load(conn)?
};

Ok(txos)
}

// This is a direct port of txo selection and
// the whole things needs a nice big refactor
// to make it happy.
Expand Down
44 changes: 0 additions & 44 deletions full-service/src/json_rpc/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,47 +76,3 @@ impl From<&service::balance::Balance> for Balance {
}
}
}

/// The "balance" for a view-only-account, as well as some information about
/// syncing status needed to interpret the balance correctly. In order for the
/// balance to be accurate, you must mark view_only_txos as spent
#[derive(Deserialize, Serialize, Default, Debug, Clone)]
pub struct ViewOnlyBalance {
/// String representing the object's type. Objects of the same type share
/// the same value.
pub object: String,

/// Total pico MOB sent to this account minus the total amount marked as
/// spent
pub balance: String,

/// The block count of MobileCoin's distributed ledger.
pub network_block_height: String,

/// The local block count downloaded from the ledger. The local database
/// is synced when the local_block_height reaches the network_block_height.
/// The account_block_height can only sync up to local_block_height.
pub local_block_height: String,

/// The scanned local block count for this account. This value will never
/// be greater than the local_block_height. At fully synced, it will match
/// network_block_height.
pub account_block_height: String,

/// Whether the account is synced with the network_block_height. Balances
/// may not appear correct if the account is still syncing.
pub is_synced: bool,
}

impl From<&service::balance::ViewOnlyBalance> for ViewOnlyBalance {
fn from(src: &service::balance::ViewOnlyBalance) -> ViewOnlyBalance {
ViewOnlyBalance {
object: "balance".to_string(),
balance: src.balance.to_string(),
network_block_height: src.network_block_height.to_string(),
local_block_height: src.local_block_height.to_string(),
account_block_height: src.synced_blocks.to_string(),
is_synced: src.synced_blocks == src.network_block_height,
}
}
}
6 changes: 3 additions & 3 deletions full-service/src/json_rpc/json_rpc_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
account::Account,
account_secrets::AccountSecrets,
address::Address,
balance::{Balance, ViewOnlyBalance},
balance::Balance,
block::{Block, BlockContents},
confirmation_number::Confirmation,
gift_code::GiftCode,
Expand Down Expand Up @@ -251,10 +251,10 @@ pub enum JsonCommandResponse {
balance: Balance,
},
get_balance_for_view_only_account {
balance: ViewOnlyBalance,
balance: Balance,
},
get_balance_for_view_only_address {
balance: ViewOnlyBalance,
balance: Balance,
},
get_block {
block: Block,
Expand Down
6 changes: 3 additions & 3 deletions full-service/src/json_rpc/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
json_rpc::{
account_secrets::AccountSecrets,
address::Address,
balance::{Balance, ViewOnlyBalance},
balance::Balance,
block::{Block, BlockContents},
confirmation_number::Confirmation,
gift_code::GiftCode,
Expand Down Expand Up @@ -750,7 +750,7 @@ where
}
JsonCommandRequest::get_balance_for_view_only_account { account_id } => {
JsonCommandResponse::get_balance_for_view_only_account {
balance: ViewOnlyBalance::from(
balance: Balance::from(
&service
.get_balance_for_view_only_account(&account_id)
.map_err(format_error)?,
Expand All @@ -759,7 +759,7 @@ where
}
JsonCommandRequest::get_balance_for_view_only_address { address } => {
JsonCommandResponse::get_balance_for_view_only_address {
balance: ViewOnlyBalance::from(
balance: Balance::from(
&service
.get_balance_for_view_only_address(&address)
.map_err(format_error)?,
Expand Down
Loading

0 comments on commit 4db9500

Please sign in to comment.