sui_core/accumulators/
funds_read.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use std::collections::BTreeMap;
5
6use move_core_types::language_storage::TypeTag;
7use sui_types::{
8    accumulator_root::AccumulatorObjId,
9    base_types::SequenceNumber,
10    error::{SuiErrorKind, SuiResult, UserInputError},
11};
12
13pub trait AccountFundsRead: Send + Sync {
14    /// Gets latest amount in account together with the version of the accumulator root object.
15    /// If the account does not exist, returns the current root accumulator version.
16    /// It guarantees no data race between the read of the account object and the root accumulator version.
17    fn get_latest_account_amount(&self, account_id: &AccumulatorObjId) -> (u128, SequenceNumber);
18
19    /// Read the amount at a precise version. Care must be taken to only call this function if we
20    /// can guarantee that objects behind this version have not yet been pruned.
21    fn get_account_amount_at_version(
22        &self,
23        account_id: &AccumulatorObjId,
24        version: SequenceNumber,
25    ) -> u128;
26
27    /// Checks if given amounts are available in the latest versions of the referenced acccumulator
28    /// objects. This does un-sequenced reads and can only be used on the signing/voting path
29    /// where deterministic results are not required.
30    fn check_amounts_available(
31        &self,
32        requested_amounts: &BTreeMap<AccumulatorObjId, (u64, TypeTag)>,
33    ) -> SuiResult {
34        for (object_id, (requested_amount, _type_tag)) in requested_amounts {
35            let (actual_amount, _) = self.get_latest_account_amount(object_id);
36
37            if actual_amount < *requested_amount as u128 {
38                return Err(SuiErrorKind::UserInputError {
39                    error: UserInputError::InvalidWithdrawReservation {
40                        error: format!(
41                            "Available amount in account for object id {} is less than requested: {} < {}",
42                            object_id, actual_amount, requested_amount
43                        ),
44                    },
45                }
46                .into());
47            }
48        }
49
50        Ok(())
51    }
52}