drive/util/batch/drive_op_batch/address_funds.rs
1use crate::drive::Drive;
2use crate::error::Error;
3use crate::fees::op::LowLevelDriveOperation;
4use crate::util::batch::drive_op_batch::DriveLowLevelOperationConverter;
5use dpp::address_funds::PlatformAddress;
6use dpp::block::block_info::BlockInfo;
7use dpp::fee::Credits;
8use dpp::prelude::AddressNonce;
9use grovedb::batch::KeyInfoPath;
10use grovedb::{EstimatedLayerInformation, TransactionArg};
11use platform_version::version::PlatformVersion;
12use std::collections::HashMap;
13
14/// Operations on Address Funds
15///
16/// A batch must write each address at most once. `AddBalanceToAddress` computes the new
17/// balance from the one committed before its batch, `SetBalanceToAddress` overwrites it, and
18/// GroveDB keeps only the last write of a key, so a second write to one address would replace
19/// the first. Every batch writes each address once today: an address may not be both an input
20/// and an output of a transition (`OutputAddressAlsoInputError`), inputs and outputs are maps,
21/// and the fee of a transition paid from its inputs is applied in a batch of its own.
22/// `DriveOperation::merge_balance_writes` does not merge these; a batch that needs two writes
23/// to one address must fold them into one.
24#[derive(Clone, Debug)]
25pub enum AddressFundsOperationType {
26 /// Sets a balance for a given address in the AddressBalances tree.
27 /// This operation directly sets (or overwrites) the balance for the address with the given nonce.
28 SetBalanceToAddress {
29 /// The platform address
30 address: PlatformAddress,
31 /// The nonce for the address
32 nonce: AddressNonce,
33 /// The balance value to set
34 balance: Credits,
35 },
36 /// Adds a balance for a given address in the AddressBalances tree.
37 /// This operation adds the balance for the address with the given nonce, that nonce is not changed.
38 AddBalanceToAddress {
39 /// The platform address
40 address: PlatformAddress,
41 /// The balance value to add
42 balance_to_add: Credits,
43 },
44}
45
46impl DriveLowLevelOperationConverter for AddressFundsOperationType {
47 fn into_low_level_drive_operations(
48 self,
49 drive: &Drive,
50 estimated_costs_only_with_layer_info: &mut Option<
51 HashMap<KeyInfoPath, EstimatedLayerInformation>,
52 >,
53 _block_info: &BlockInfo,
54 transaction: TransactionArg,
55 platform_version: &PlatformVersion,
56 ) -> Result<Vec<LowLevelDriveOperation>, Error> {
57 match self {
58 AddressFundsOperationType::SetBalanceToAddress {
59 address,
60 nonce,
61 balance,
62 } => drive.set_balance_to_address_operations(
63 address,
64 nonce,
65 balance,
66 estimated_costs_only_with_layer_info,
67 platform_version,
68 ),
69 AddressFundsOperationType::AddBalanceToAddress {
70 address,
71 balance_to_add,
72 } => drive.add_balance_to_address_operations(
73 address,
74 balance_to_add,
75 estimated_costs_only_with_layer_info,
76 transaction,
77 platform_version,
78 ),
79 }
80 }
81}