Skip to content

Commit 126db66

Browse files
guidiazaesedepece
authored andcommitted
fix(json_rpc): keep backwards compatibility on get_utxo_info
1 parent 6fc52fa commit 126db66

1 file changed

Lines changed: 71 additions & 55 deletions

File tree

  • node/src/actors/json_rpc

node/src/actors/json_rpc/api.rs

Lines changed: 71 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,66 +1577,82 @@ pub struct UtxoFilter {
15771577
}
15781578

15791579
/// Get utxos
1580-
pub async fn get_utxo_info(
1581-
params: Result<(PublicKeyHash, Option<UtxoFilter>), Error>,
1582-
) -> JsonRpcResult {
1583-
let chain_manager_addr = ChainManager::from_registry();
1584-
let (pkh, filter) = params?;
1580+
pub async fn get_utxo_info(params: Result<Params, Error>) -> JsonRpcResult {
1581+
if let Params::Array(values) = params? {
1582+
let mut values_iter = values.into_iter();
1583+
// Try to read a first param that must be a String representing a bech32 address
1584+
let pkh = values_iter.next().ok_or(Error::invalid_params(
1585+
"First argument must refer to a valid Bech32 address",
1586+
))?;
1587+
let pkh: PublicKeyHash = Deserialize::deserialize(pkh).map_err(internal_error)?;
1588+
let filter: Option<UtxoFilter> = if values_iter.len() > 0 {
1589+
let filter = values_iter.next().ok_or(Error::invalid_params(
1590+
"Cannot read the optional filter expected as second argument",
1591+
))?;
1592+
1593+
Deserialize::deserialize(filter).ok()
1594+
} else {
1595+
None
1596+
};
15851597

1586-
let mut utxos_info = chain_manager_addr
1587-
.send(GetUtxoInfo { pkh })
1588-
.await
1589-
.map_err(internal_error)?
1590-
.map_err(internal_error)?;
1598+
let chain_manager_addr = ChainManager::from_registry();
1599+
let mut utxos_info = chain_manager_addr
1600+
.send(GetUtxoInfo { pkh })
1601+
.await
1602+
.map_err(internal_error)?
1603+
.map_err(internal_error)?;
1604+
1605+
// If a value filter is applied, get rid of utxos smaller than the required value
1606+
if let Some(UtxoFilter {
1607+
min_value,
1608+
from_signer: _,
1609+
}) = filter
1610+
{
1611+
utxos_info.utxos.retain(|utxo| utxo.value >= min_value);
1612+
}
15911613

1592-
// If a value filter is applied, get rid of utxos smaller than the required value
1593-
if let Some(UtxoFilter {
1594-
min_value,
1595-
from_signer: _,
1596-
}) = filter
1597-
{
1598-
utxos_info.utxos.retain(|utxo| utxo.value >= min_value);
1599-
}
1614+
// If a signer filter is applied, get rid of utxos not created by the specified signer address
1615+
if let Some(UtxoFilter {
1616+
min_value: _,
1617+
from_signer: Some(from_signer),
1618+
}) = filter
1619+
{
1620+
let inventory_manager = InventoryManager::from_registry();
1621+
let futures = utxos_info.utxos.iter().map(|utxo| {
1622+
inventory_manager.send(GetItemTransaction {
1623+
hash: utxo.output_pointer.transaction_id,
1624+
})
1625+
});
1626+
// The strategy here is to first create a set containing only the hashes of the transactions
1627+
// that were signed by the specified signer address
1628+
let filtered_hashes = futures::future::join_all(futures)
1629+
.await
1630+
.into_iter()
1631+
.flatten()
1632+
.flatten()
1633+
.filter_map(|(transaction, _, _)| {
1634+
if transaction
1635+
.signatures()
1636+
.iter()
1637+
.any(|signature| signature.public_key.pkh().eq(&from_signer))
1638+
{
1639+
Some(transaction.hash())
1640+
} else {
1641+
None
1642+
}
1643+
})
1644+
.collect::<HashSet<Hash>>();
16001645

1601-
// If a signer filter is applied, get rid of utxos not created by the specified signer address
1602-
if let Some(UtxoFilter {
1603-
min_value: _,
1604-
from_signer: Some(from_signer),
1605-
}) = filter
1606-
{
1607-
let inventory_manager = InventoryManager::from_registry();
1608-
let futures = utxos_info.utxos.iter().map(|utxo| {
1609-
inventory_manager.send(GetItemTransaction {
1610-
hash: utxo.output_pointer.transaction_id,
1611-
})
1612-
});
1613-
// The strategy here is to first create a set containing only the hashes of the transactions
1614-
// that were signed by the specified signer address
1615-
let filtered_hashes = futures::future::join_all(futures)
1616-
.await
1617-
.into_iter()
1618-
.flatten()
1619-
.flatten()
1620-
.filter_map(|(transaction, _, _)| {
1621-
if transaction
1622-
.signatures()
1623-
.iter()
1624-
.any(|signature| signature.public_key.pkh().eq(&from_signer))
1625-
{
1626-
Some(transaction.hash())
1627-
} else {
1628-
None
1629-
}
1630-
})
1631-
.collect::<HashSet<Hash>>();
1646+
// And then we get rid of the utxos that don't point to any of those transactions
1647+
utxos_info
1648+
.utxos
1649+
.retain(|utxo| filtered_hashes.contains(&utxo.output_pointer.transaction_id));
1650+
}
16321651

1633-
// And then we get rid of the utxos that don't point to any of those transactions
1634-
utxos_info
1635-
.utxos
1636-
.retain(|utxo| filtered_hashes.contains(&utxo.output_pointer.transaction_id));
1652+
serde_json::to_value(utxos_info).map_err(internal_error_s)
1653+
} else {
1654+
Err(Error::invalid_params("Expected an array of arguments"))
16371655
}
1638-
1639-
serde_json::to_value(utxos_info).map_err(internal_error_s)
16401656
}
16411657

16421658
/// Get Reputation of one pkh

0 commit comments

Comments
 (0)