Skip to content

Commit 53f4cf1

Browse files
authored
Merge pull request #342 from input-output-hk/whankinsiv/accounts-endpoints-using-address-state
feat: account UTxOs REST handler
2 parents 66c9892 + 0b65a09 commit 53f4cf1

21 files changed

+428
-82
lines changed

common/src/queries/accounts.rs

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,19 @@ pub const DEFAULT_HISTORICAL_ACCOUNTS_QUERY_TOPIC: (&str, &str) = (
1616
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
1717
pub enum AccountsStateQuery {
1818
GetAccountInfo { account: StakeAddress },
19+
GetAccountsUtxoValuesMap { stake_addresses: Vec<StakeAddress> },
20+
GetAccountsUtxoValuesSum { stake_addresses: Vec<StakeAddress> },
21+
GetAccountsBalancesMap { stake_addresses: Vec<StakeAddress> },
22+
GetAccountsBalancesSum { stake_addresses: Vec<StakeAddress> },
23+
24+
// Served from historical accounts state
1925
GetAccountRewardHistory { account: StakeAddress },
2026
GetAccountHistory { stake_key: Vec<u8> },
2127
GetAccountRegistrationHistory { account: StakeAddress },
2228
GetAccountDelegationHistory { account: StakeAddress },
2329
GetAccountMIRHistory { account: StakeAddress },
2430
GetAccountWithdrawalHistory { account: StakeAddress },
2531
GetAccountAssociatedAddresses { account: StakeAddress },
26-
GetAccountAssets { stake_key: Vec<u8> },
27-
GetAccountAssetsTotals { stake_key: Vec<u8> },
28-
GetAccountUTxOs { stake_key: Vec<u8> },
29-
GetAccountsUtxoValuesMap { stake_addresses: Vec<StakeAddress> },
30-
GetAccountsUtxoValuesSum { stake_addresses: Vec<StakeAddress> },
31-
GetAccountsBalancesMap { stake_addresses: Vec<StakeAddress> },
32-
GetAccountsBalancesSum { stake_addresses: Vec<StakeAddress> },
3332

3433
// Epochs-related queries
3534
GetActiveStakes {},
@@ -50,20 +49,19 @@ pub enum AccountsStateQuery {
5049
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
5150
pub enum AccountsStateQueryResponse {
5251
AccountInfo(AccountInfo),
52+
AccountsUtxoValuesMap(HashMap<StakeAddress, u64>),
53+
AccountsUtxoValuesSum(u64),
54+
AccountsBalancesMap(HashMap<StakeAddress, u64>),
55+
AccountsBalancesSum(u64),
56+
57+
// Served from historical accounts state
5358
AccountRewardHistory(Vec<AccountReward>),
5459
AccountHistory(AccountHistory),
5560
AccountRegistrationHistory(Vec<RegistrationUpdate>),
5661
AccountDelegationHistory(Vec<DelegationUpdate>),
5762
AccountMIRHistory(Vec<AccountWithdrawal>),
5863
AccountWithdrawalHistory(Vec<AccountWithdrawal>),
5964
AccountAssociatedAddresses(Vec<ShelleyAddress>),
60-
AccountAssets(AccountAssets),
61-
AccountAssetsTotals(AccountAssetsTotals),
62-
AccountUTxOs(AccountUTxOs),
63-
AccountsUtxoValuesMap(HashMap<StakeAddress, u64>),
64-
AccountsUtxoValuesSum(u64),
65-
AccountsBalancesMap(HashMap<StakeAddress, u64>),
66-
AccountsBalancesSum(u64),
6765

6866
// Epochs-related responses
6967
ActiveStakes(u64),
@@ -162,21 +160,6 @@ pub struct AccountReward {
162160
pub reward_type: RewardType,
163161
}
164162

165-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
166-
pub struct AccountWithdrawalHistory {}
167-
168-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
169-
pub struct AccountAssociatedAddresses {}
170-
171-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
172-
pub struct AccountAssets {}
173-
174-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
175-
pub struct AccountAssetsTotals {}
176-
177-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
178-
pub struct AccountUTxOs {}
179-
180163
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
181164
pub struct OptimalPoolSizing {
182165
pub total_supply: u64, // total_supply - reserves

common/src/queries/addresses.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::queries::errors::QueryError;
2-
use crate::{Address, AddressTotals, TxIdentifier, UTxOIdentifier};
2+
use crate::{
3+
Address, AddressTotals, NativeAssets, ShelleyAddress, TxIdentifier, UTxOIdentifier, ValueDelta,
4+
};
35

46
pub const DEFAULT_ADDRESS_QUERY_TOPIC: (&str, &str) =
57
("address-state-query-topic", "cardano.query.address");
@@ -9,12 +11,22 @@ pub enum AddressStateQuery {
911
GetAddressTotals { address: Address },
1012
GetAddressUTxOs { address: Address },
1113
GetAddressTransactions { address: Address },
14+
15+
// Accounts related queries
16+
GetAddressesAssets { addresses: Vec<ShelleyAddress> },
17+
GetAddressesTotals { addresses: Vec<ShelleyAddress> },
18+
GetAddressesUTxOs { addresses: Vec<ShelleyAddress> },
1219
}
1320

1421
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
1522
pub enum AddressStateQueryResponse {
1623
AddressTotals(AddressTotals),
1724
AddressUTxOs(Vec<UTxOIdentifier>),
1825
AddressTransactions(Vec<TxIdentifier>),
26+
27+
// Accounts related queries
28+
AddressesAssets(NativeAssets),
29+
AddressesTotals(ValueDelta),
30+
AddressesUTxOs(Vec<UTxOIdentifier>),
1931
Error(QueryError),
2032
}

common/src/queries/blocks.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use crate::queries::errors::QueryError;
22
use crate::{
33
queries::misc::Order,
44
serialization::{Bech32Conversion, Bech32WithHrp},
5-
Address, BlockHash, GenesisDelegate, HeavyDelegate, KeyHash, TxHash, TxIdentifier, VrfKeyHash,
5+
Address, BlockHash, GenesisDelegate, HeavyDelegate, KeyHash, TxHash, TxIdentifier,
6+
UTxOIdentifier, VrfKeyHash,
67
};
78
use cryptoxide::hashing::blake2b::Blake2b;
89
use serde::ser::{Serialize, SerializeStruct, Serializer};
@@ -68,6 +69,9 @@ pub enum BlocksStateQuery {
6869
GetTransactionHashes {
6970
tx_ids: Vec<TxIdentifier>,
7071
},
72+
GetUTxOHashes {
73+
utxo_ids: Vec<UTxOIdentifier>,
74+
},
7175
}
7276

7377
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
@@ -91,6 +95,7 @@ pub enum BlocksStateQueryResponse {
9195
BlockInvolvedAddresses(BlockInvolvedAddresses),
9296
BlockHashes(BlockHashes),
9397
TransactionHashes(TransactionHashes),
98+
UTxOHashes(UTxOHashes),
9499
Error(QueryError),
95100
}
96101

@@ -229,3 +234,9 @@ pub struct BlockHashes {
229234
pub struct TransactionHashes {
230235
pub tx_hashes: HashMap<TxIdentifier, TxHash>,
231236
}
237+
238+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
239+
pub struct UTxOHashes {
240+
pub block_hashes: Vec<BlockHash>,
241+
pub tx_hashes: Vec<TxHash>,
242+
}

common/src/queries/utxos.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::queries::errors::QueryError;
2-
use crate::{UTxOIdentifier, Value};
2+
use crate::{UTXOValue, UTxOIdentifier, Value};
33

44
pub const DEFAULT_UTXOS_QUERY_TOPIC: (&str, &str) =
55
("utxo-state-query-topic", "cardano.query.utxos");
@@ -9,10 +9,14 @@ pub enum UTxOStateQuery {
99
GetUTxOsSum {
1010
utxo_identifiers: Vec<UTxOIdentifier>,
1111
},
12+
GetUTxOs {
13+
utxo_identifiers: Vec<UTxOIdentifier>,
14+
},
1215
}
1316

1417
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
1518
pub enum UTxOStateQueryResponse {
1619
UTxOsSum(Value),
20+
UTxOs(Vec<UTXOValue>),
1721
Error(QueryError),
1822
}

common/src/types.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,22 @@ impl Neg for ValueDelta {
446446
}
447447
}
448448

449+
/// Value stored in UTXO
450+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
451+
pub struct UTXOValue {
452+
/// Address in binary
453+
pub address: Address,
454+
455+
/// Value in Lovelace
456+
pub value: Value,
457+
458+
/// Datum
459+
pub datum: Option<Datum>,
460+
461+
/// Reference script
462+
pub reference_script: Option<ReferenceScript>,
463+
}
464+
449465
/// Transaction output (UTXO)
450466
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
451467
pub struct TxOutput {

modules/address_state/src/address_state.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,30 @@ impl AddressState {
251251
)),
252252
}
253253
}
254+
AddressStateQuery::GetAddressesAssets { addresses } => {
255+
match state.get_addresses_assets(addresses).await {
256+
Ok(assets) => AddressStateQueryResponse::AddressesAssets(assets),
257+
Err(e) => AddressStateQueryResponse::Error(QueryError::internal_error(
258+
e.to_string(),
259+
)),
260+
}
261+
}
262+
AddressStateQuery::GetAddressesTotals { addresses } => {
263+
match state.get_addresses_totals(addresses).await {
264+
Ok(totals) => AddressStateQueryResponse::AddressesTotals(totals),
265+
Err(e) => AddressStateQueryResponse::Error(QueryError::internal_error(
266+
e.to_string(),
267+
)),
268+
}
269+
}
270+
AddressStateQuery::GetAddressesUTxOs { addresses } => {
271+
match state.get_addresses_utxos(addresses).await {
272+
Ok(utxos) => AddressStateQueryResponse::AddressesUTxOs(utxos),
273+
Err(e) => AddressStateQueryResponse::Error(QueryError::internal_error(
274+
e.to_string(),
275+
)),
276+
}
277+
}
254278
};
255279
Arc::new(Message::StateQueryResponse(StateQueryResponse::Addresses(
256280
response,

modules/address_state/src/state.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use std::{
55
};
66

77
use acropolis_common::{
8-
Address, AddressDelta, AddressTotals, BlockInfo, TxIdentifier, UTxOIdentifier, ValueDelta,
8+
Address, AddressDelta, AddressTotals, BlockInfo, NativeAssets, ShelleyAddress, TxIdentifier,
9+
UTxOIdentifier, ValueDelta,
910
};
1011
use anyhow::Result;
1112

@@ -199,6 +200,31 @@ impl State {
199200

200201
Ok(())
201202
}
203+
204+
pub async fn get_addresses_assets(
205+
&self,
206+
_addresses: &[ShelleyAddress],
207+
) -> Result<NativeAssets> {
208+
Ok(NativeAssets::default())
209+
}
210+
211+
pub async fn get_addresses_totals(&self, _addresses: &[ShelleyAddress]) -> Result<ValueDelta> {
212+
Ok(ValueDelta::default())
213+
}
214+
215+
pub async fn get_addresses_utxos(
216+
&self,
217+
addresses: &[ShelleyAddress],
218+
) -> Result<Vec<UTxOIdentifier>> {
219+
let mut utxos = Vec::new();
220+
221+
for addr in addresses {
222+
if let Some(list) = self.get_address_utxos(&Address::Shelley(addr.clone())).await? {
223+
utxos.extend(list);
224+
}
225+
}
226+
Ok(utxos)
227+
}
202228
}
203229

204230
#[cfg(test)]

modules/chain_store/src/chain_store.rs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ use acropolis_common::queries::errors::QueryError;
66
use acropolis_common::{
77
crypto::keyhash_224,
88
messages::{CardanoMessage, Message, StateQuery, StateQueryResponse},
9-
queries::blocks::{
10-
BlockHashes, BlockInfo, BlockInvolvedAddress, BlockInvolvedAddresses, BlockKey,
11-
BlockTransaction, BlockTransactions, BlockTransactionsCBOR, BlocksStateQuery,
12-
BlocksStateQueryResponse, NextBlocks, PreviousBlocks, TransactionHashes,
13-
DEFAULT_BLOCKS_QUERY_TOPIC,
9+
queries::{
10+
blocks::{
11+
BlockHashes, BlockInfo, BlockInvolvedAddress, BlockInvolvedAddresses, BlockKey,
12+
BlockTransaction, BlockTransactions, BlockTransactionsCBOR, BlocksStateQuery,
13+
BlocksStateQueryResponse, NextBlocks, PreviousBlocks, TransactionHashes, UTxOHashes,
14+
DEFAULT_BLOCKS_QUERY_TOPIC,
15+
},
16+
misc::Order,
1417
},
15-
queries::misc::Order,
1618
state_history::{StateHistory, StateHistoryStore},
1719
BechOrdAddress, BlockHash, GenesisDelegate, HeavyDelegate, PoolId, TxHash,
1820
};
@@ -323,6 +325,32 @@ impl ChainStore {
323325
TransactionHashes { tx_hashes },
324326
))
325327
}
328+
BlocksStateQuery::GetUTxOHashes { utxo_ids } => {
329+
let mut tx_hashes = Vec::with_capacity(utxo_ids.len());
330+
let mut block_hashes = Vec::with_capacity(utxo_ids.len());
331+
332+
for utxo in utxo_ids {
333+
if let Ok(Some(block)) = store.get_block_by_number(utxo.block_number().into()) {
334+
if let Ok(hash) = Self::get_block_hash(&block) {
335+
if let Ok(tx_hashes_in_block) =
336+
Self::to_block_transaction_hashes(&block)
337+
{
338+
if let Some(tx_hash) =
339+
tx_hashes_in_block.get(utxo.tx_index() as usize)
340+
{
341+
tx_hashes.push(*tx_hash);
342+
block_hashes.push(hash);
343+
}
344+
}
345+
}
346+
}
347+
}
348+
349+
Ok(BlocksStateQueryResponse::UTxOHashes(UTxOHashes {
350+
block_hashes,
351+
tx_hashes,
352+
}))
353+
}
326354
}
327355
}
328356

modules/governance_state/src/conway_voting.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ mod tests {
632632
expiration_epoch: None,
633633
};
634634
voting.action_status.insert(oc2.voting.procedure.gov_action_id.clone(), as2.clone());
635-
match voting.update_action_status_with_outcomes(2, &vec![oc2.clone()]) {
635+
match voting.update_action_status_with_outcomes(2, std::slice::from_ref(&oc2)) {
636636
Err(e) => assert_eq!(
637637
e.to_string(),
638638
"Impossible outcome: gov_action1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\
@@ -645,7 +645,7 @@ mod tests {
645645
*voting.action_status.get(&oc2.voting.procedure.gov_action_id).unwrap(),
646646
as2
647647
);
648-
voting.update_action_status_with_outcomes(5, &vec![oc2.clone()])?;
648+
voting.update_action_status_with_outcomes(5, std::slice::from_ref(&oc2))?;
649649
assert_eq!(
650650
voting.action_status.get(&oc2.voting.procedure.gov_action_id).unwrap().expiration_epoch,
651651
Some(5)

0 commit comments

Comments
 (0)