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 sui_types::{
7 accumulator_root::AccumulatorObjId,
8 base_types::SequenceNumber,
9 error::{SuiErrorKind, SuiResult, UserInputError},
10};
11
12pub trait AccountFundsRead: Send + Sync {
13 /// Gets latest amount in account together with the version of the accumulator root object.
14 /// If the account does not exist, returns the current root accumulator version.
15 /// It guarantees no data race between the read of the account object and the root accumulator version.
16 fn get_latest_account_amount(&self, account_id: &AccumulatorObjId) -> (u128, SequenceNumber);
17
18 /// Read the amount at a precise version. Care must be taken to only call this function if we
19 /// can guarantee that objects behind this version have not yet been pruned.
20 fn get_account_amount_at_version(
21 &self,
22 account_id: &AccumulatorObjId,
23 version: SequenceNumber,
24 ) -> u128;
25
26 /// Checks if given amounts are available in the latest versions of the referenced acccumulator
27 /// objects. This does un-sequenced reads and can only be used on the signing/voting path
28 /// where deterministic results are not required.
29 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}