|
| 1 | +use actix::MailboxError; |
| 2 | +#[cfg(not(test))] |
| 3 | +use actix::SystemService; |
| 4 | +use futures::FutureExt; |
| 5 | +use itertools::Itertools; |
| 6 | +use jsonrpc_core::{BoxFuture, Error, Params, Value}; |
| 7 | +use jsonrpc_pubsub::{Subscriber, SubscriptionId}; |
| 8 | +use serde::{Deserialize, Serialize}; |
1 | 9 | use std::{ |
2 | | - collections::{HashMap, HashSet}, |
| 10 | + collections::{hash_map::Entry, HashMap, HashSet}, |
3 | 11 | convert::TryFrom, |
4 | 12 | fmt::Debug, |
5 | 13 | net::SocketAddr, |
6 | 14 | path::PathBuf, |
7 | 15 | str::FromStr, |
8 | 16 | sync::{ |
9 | | - Arc, |
10 | 17 | atomic::{AtomicUsize, Ordering}, |
| 18 | + Arc, |
11 | 19 | }, |
12 | 20 | }; |
13 | 21 |
|
14 | | -#[cfg(not(test))] |
15 | | -use actix::SystemService; |
16 | | -use actix::MailboxError; |
17 | | -use futures::FutureExt; |
18 | | -use itertools::Itertools; |
19 | | -use jsonrpc_core::{BoxFuture, Error, Params, Value}; |
20 | | -use jsonrpc_pubsub::{Subscriber, SubscriptionId}; |
21 | | -use serde::{Deserialize, Serialize}; |
22 | | - |
23 | 22 | #[cfg(test)] |
24 | 23 | use self::mock_actix::SystemService; |
25 | 24 | use crate::{ |
@@ -49,14 +48,14 @@ use crate::{ |
49 | 48 | use witnet_crypto::{hash::calculate_sha256, key::KeyPath}; |
50 | 49 | use witnet_data_structures::{ |
51 | 50 | chain::{ |
52 | | - Block, DataRequestInfo, DataRequestOutput, DataRequestStage, Epoch, EpochConstants, Hash, |
53 | | - Hashable, KeyedSignature, PublicKeyHash, RADType, StakeOutput, StateMachine, |
54 | | - SyncStatus, ValueTransferOutput, tapi::ActiveWips, |
| 51 | + tapi::ActiveWips, Block, DataRequestInfo, DataRequestOutput, DataRequestStage, Epoch, EpochConstants, |
| 52 | + Hash, Hashable, KeyedSignature, PublicKeyHash, RADType, StakeOutput, StateMachine, |
| 53 | + SyncStatus, ValueTransferOutput, |
55 | 54 | }, |
56 | 55 | get_environment, get_protocol_version, |
57 | 56 | proto::{ |
58 | | - ProtobufConvert, |
59 | 57 | versioning::{ProtocolVersion, VersionedHashable}, |
| 58 | + ProtobufConvert, |
60 | 59 | }, |
61 | 60 | serialization_helpers::number_from_string, |
62 | 61 | staking::prelude::*, |
@@ -2648,30 +2647,40 @@ pub async fn get_value_transfer(params: Result<GetValueTransferParams, Error>) - |
2648 | 2647 | let mut input_value = 0u64; |
2649 | 2648 | let mut input_transactions: HashMap<Hash, Transaction> = HashMap::new(); |
2650 | 2649 | // Fetch each different input transaction just once, even when referred multiples times |
2651 | | - for input in vtt.body.inputs.clone() { |
| 2650 | + for input in &vtt.body.inputs { |
2652 | 2651 | let hash = input.output_pointer().transaction_id; |
2653 | | - if let std::collections::hash_map::Entry::Vacant(e) = input_transactions.entry(hash) { |
2654 | | - let transaction = get_transaction(Ok((hash,))).await?; |
2655 | | - let transaction = |
2656 | | - serde_json::from_value::<GetTransactionOutput>(transaction) |
2657 | | - .map_err(internal_error)? |
2658 | | - .transaction; |
2659 | | - e.insert(transaction.clone()); |
2660 | | - } |
2661 | | - } |
2662 | | - // Sum up the value of every single input |
2663 | | - for input in vtt.body.inputs.clone() { |
2664 | | - let hash = input.output_pointer().transaction_id; |
2665 | | - if let Some(transaction) = input_transactions.get(&hash) { |
2666 | | - input_value += get_transaction_output_value( |
2667 | | - transaction, |
2668 | | - input.output_pointer().output_index as usize, |
2669 | | - ); |
2670 | | - } |
| 2652 | + |
| 2653 | + // Sum up the value of every single input |
| 2654 | + input_value += match input_transactions.entry(hash) { |
| 2655 | + Entry::Occupied(entry) => { |
| 2656 | + let transaction = entry.get(); |
| 2657 | + |
| 2658 | + get_transaction_output_value( |
| 2659 | + transaction, |
| 2660 | + input.output_pointer().output_index as usize, |
| 2661 | + ) |
| 2662 | + } |
| 2663 | + Entry::Vacant(entry) => { |
| 2664 | + let transaction = get_transaction(Ok((hash,))).await?; |
| 2665 | + let transaction = |
| 2666 | + serde_json::from_value::<GetTransactionOutput>(transaction) |
| 2667 | + .map_err(internal_error)? |
| 2668 | + .transaction; |
| 2669 | + let transaction_value = get_transaction_output_value( |
| 2670 | + &transaction, |
| 2671 | + input.output_pointer().output_index as usize, |
| 2672 | + ); |
| 2673 | + |
| 2674 | + entry.insert(transaction); |
| 2675 | + |
| 2676 | + transaction_value |
| 2677 | + } |
| 2678 | + }; |
2671 | 2679 | } |
| 2680 | + let fee = input_value.saturating_sub(vtt.body.value()); |
2672 | 2681 |
|
2673 | 2682 | GetValueTransfersOutput::Simple(GetValueTransferSimpleOutput { |
2674 | | - fee: input_value.saturating_sub(vtt.body.value()), |
| 2683 | + fee, |
2675 | 2684 | metadata, |
2676 | 2685 | recipient, |
2677 | 2686 | sender, |
|
0 commit comments