sui_core/accumulators/
funds_read.rs1use std::{collections::BTreeMap, sync::Arc};
5
6use sui_types::{
7 accumulator_root::{AccumulatorObjId, AccumulatorValue, U128},
8 base_types::SequenceNumber,
9 error::{SuiErrorKind, SuiResult, UserInputError},
10 storage::ChildObjectResolver,
11};
12
13pub(crate) trait AccountFundsRead: Send + Sync {
14 fn get_account_amount(
15 &self,
16 account_id: &AccumulatorObjId,
17 accumulator_version: SequenceNumber,
20 ) -> u128;
21
22 fn get_latest_account_amount(&self, account_id: &AccumulatorObjId) -> u128;
25
26 fn check_amounts_available(
30 &self,
31 requested_amounts: &BTreeMap<AccumulatorObjId, u64>,
32 ) -> SuiResult {
33 for (object_id, requested_amount) in requested_amounts {
34 let actual_amount = self.get_latest_account_amount(object_id);
35
36 if actual_amount < *requested_amount as u128 {
37 return Err(SuiErrorKind::UserInputError {
38 error: UserInputError::InvalidWithdrawReservation {
39 error: format!(
40 "Available amount in account for object id {} is less than requested: {} < {}",
41 object_id, actual_amount, requested_amount
42 ),
43 },
44 }
45 .into());
46 }
47 }
48
49 Ok(())
50 }
51}
52
53impl AccountFundsRead for Arc<dyn ChildObjectResolver + Send + Sync> {
54 fn get_account_amount(
55 &self,
56 account_id: &AccumulatorObjId,
57 accumulator_version: SequenceNumber,
58 ) -> u128 {
59 let value: U128 =
66 AccumulatorValue::load_by_id(self.as_ref(), Some(accumulator_version), *account_id)
67 .expect("read cannot fail")
70 .unwrap_or(U128 { value: 0 });
71
72 value.value
73 }
74
75 fn get_latest_account_amount(&self, account_id: &AccumulatorObjId) -> u128 {
76 let value = AccumulatorValue::load_by_id(self.as_ref(), None, *account_id)
77 .expect("read cannot fail")
78 .unwrap_or(U128 { value: 0 });
79
80 value.value
81 }
82}