diff --git a/documentation/api/api-explorer.yml b/documentation/api/api-explorer.yml index 55e4b504b..1368c563f 100644 --- a/documentation/api/api-explorer.yml +++ b/documentation/api/api-explorer.yml @@ -277,7 +277,7 @@ components: description: >- The total value held in unspent outputs owned by the given address (includes funds held in storage deposit). - sigLockedBalance: + availableBalance: type: string description: >- The sum of value held in unspent outputs owned by the given address @@ -585,7 +585,7 @@ components: balance-example: value: totalBalance: 100000 - sigLockedBalance: 99900 + availableBalance: 99900 ledgerIndex: 500000 ledger-updates-address-example: value: diff --git a/src/bin/inx-chronicle/api/explorer/responses.rs b/src/bin/inx-chronicle/api/explorer/responses.rs index e2198f455..ca519aa8a 100644 --- a/src/bin/inx-chronicle/api/explorer/responses.rs +++ b/src/bin/inx-chronicle/api/explorer/responses.rs @@ -78,7 +78,7 @@ impl From for LedgerUpdateByMilestoneDto { #[serde(rename_all = "camelCase")] pub struct BalanceResponse { pub total_balance: String, - pub sig_locked_balance: String, + pub available_balance: String, pub ledger_index: MilestoneIndex, } diff --git a/src/bin/inx-chronicle/api/explorer/routes.rs b/src/bin/inx-chronicle/api/explorer/routes.rs index 76eb721af..2cb3283b8 100644 --- a/src/bin/inx-chronicle/api/explorer/routes.rs +++ b/src/bin/inx-chronicle/api/explorer/routes.rs @@ -155,22 +155,22 @@ async fn ledger_updates_by_milestone( } async fn balance(database: Extension, Path(address): Path) -> ApiResult { - let ledger_index = database + let ledger_ms = database .collection::() - .get_ledger_index() + .get_newest_milestone() .await? .ok_or(MissingError::NoResults)?; let address = Address::from_str(&address).map_err(RequestError::from)?; let res = database .collection::() - .get_address_balance(address, ledger_index) + .get_address_balance(address, ledger_ms) .await? .ok_or(MissingError::NoResults)?; Ok(BalanceResponse { total_balance: res.total_balance, - sig_locked_balance: res.sig_locked_balance, - ledger_index, + available_balance: res.available_balance, + ledger_index: ledger_ms.milestone_index, }) } diff --git a/src/db/mongodb/collections/outputs/mod.rs b/src/db/mongodb/collections/outputs/mod.rs index 7da45972b..00458fff9 100644 --- a/src/db/mongodb/collections/outputs/mod.rs +++ b/src/db/mongodb/collections/outputs/mod.rs @@ -168,7 +168,7 @@ pub struct OutputWithMetadataResult { #[allow(missing_docs)] pub struct BalanceResult { pub total_balance: String, - pub sig_locked_balance: String, + pub available_balance: String, } #[derive(Clone, Debug, Default, Deserialize)] @@ -422,27 +422,53 @@ impl OutputCollection { pub async fn get_address_balance( &self, address: Address, - ledger_index: MilestoneIndex, + ledger_ms: MilestoneIndexTimestamp, ) -> Result, Error> { self .aggregate( [ // Look at all (at ledger index o'clock) unspent output documents for the given address. doc! { "$match": { - "details.address": &address, - "metadata.booked.milestone_index": { "$lte": ledger_index }, - "metadata.spent_metadata.spent.milestone_index": { "$not": { "$lte": ledger_index } } + "$or": [ + { "details.address": &address }, + { "output.expiration_unlock_condition.return_address": &address } + ], + "metadata.booked.milestone_index": { "$lte": ledger_ms.milestone_index }, + "metadata.spent_metadata.spent.milestone_index": { "$not": { "$lte": ledger_ms.milestone_index } } } }, doc! { "$group": { "_id": null, - "total_balance": { "$sum": { "$toDecimal": "$output.amount" } }, - "sig_locked_balance": { "$sum": { - "$cond": [ { "$eq": [ "$details.is_trivial_unlock", true] }, { "$toDecimal": "$output.amount" }, 0 ] + "total_balance": { "$sum": { + "$cond": [ + { "$or": [ + { "$eq": [ "$details.address", &address ] }, + { "$not": { "$lt": [ "$output.expiration_unlock_condition.timestamp", ledger_ms.milestone_timestamp ] } } + ] }, + { "$toDecimal": "$output.amount" }, 0 + ] + } }, + "available_balance": { "$sum": { + "$cond": [ + { "$or": [ + { "$and": [ + { "$eq": [ "$details.address", &address ] }, + { "$or": [ + { "$eq": [ "$details.is_trivial_unlock", true ] }, + { "$not": { "$lt": [ "$output.timelock_unlock_condition.timestamp", ledger_ms.milestone_timestamp ] } } + ] } + ] }, + { "$and": [ + { "$eq": [ "$output.expiration_unlock_condition.return_address", &address ] }, + { "$not": { "$lt": [ "$output.expiration_unlock_condition.timestamp", ledger_ms.milestone_timestamp ] } }, + ] }, + ] }, + { "$toDecimal": "$output.amount" }, 0 + ] } }, } }, doc! { "$project": { "total_balance": { "$toString": "$total_balance" }, - "sig_locked_balance": { "$toString": "$sig_locked_balance" }, + "available_balance": { "$toString": "$available_balance" }, } }, ], None,