Module sui::accumulator
- Struct
AccumulatorRoot
- Struct
Key
- Struct
U128
- Constants
- Function
create
- Function
accumulator_address
- Function
root_has_accumulator
- Function
root_add_accumulator
- Function
root_borrow_accumulator_mut
- Function
root_remove_accumulator
- Function
settlement_prologue
- Function
settle_u128
- Function
emit_deposit_event
- Function
emit_withdraw_event
use std::ascii;
use std::bcs;
use std::option;
use std::string;
use std::vector;
use sui::address;
use sui::dynamic_field;
use sui::hex;
use sui::object;
use sui::party;
use sui::transfer;
use sui::tx_context;
use sui::vec_map;
Struct AccumulatorRoot
public struct AccumulatorRoot has key
Click to open
Fields
- id: sui::object::UID
Struct Key
Key is used only for computing the field id of accumulator objects. T is the type of the accumulated value, e.g. Balance<SUI>
public struct Key<phantom T> has copy, drop, store
Click to open
Fields
- address: address
Struct U128
Storage for 128-bit accumulator values.
Currently only used to represent the sum of 64 bit values (such as Balance<T>). The additional bits are necessary to prevent overflow, as it would take 2^64 deposits of U64_MAX to cause an overflow.
public struct U128 has store
Click to open
Fields
- value: u128
Constants
const ENotSystemAddress: u64 = 0;
const EInvalidSplitAmount: u64 = 1;
Function create
fun create(ctx: &sui::tx_context::TxContext)
Click to open
Implementation
fun create(ctx: &TxContext) {
assert!(ctx.sender() == @0x0, ENotSystemAddress);
transfer::share_object(AccumulatorRoot {
id: object::sui_accumulator_root_object_id(),
})
}
Function accumulator_address
public(package) fun accumulator_address<T>(address: address): address
Click to open
Implementation
public(package) fun accumulator_address<T>(address: address): address {
let key = Key<T> { address };
dynamic_field::hash_type_and_key(sui_accumulator_root_address(), key)
}
Function root_has_accumulator
Balance object methods
fun root_has_accumulator<K, V: store>(accumulator_root: &sui::accumulator::AccumulatorRoot, name: sui::accumulator::Key<K>): bool
Click to open
Implementation
fun root_has_accumulator<K, V: store>(accumulator_root: &AccumulatorRoot, name: Key<K>): bool {
dynamic_field::exists_with_type<Key<K>, V>(&accumulator_root.id, name)
}
Function root_add_accumulator
fun root_add_accumulator<K, V: store>(accumulator_root: &mut sui::accumulator::AccumulatorRoot, name: sui::accumulator::Key<K>, value: V)
Click to open
Implementation
fun root_add_accumulator<K, V: store>(
accumulator_root: &mut AccumulatorRoot,
name: Key<K>,
value: V,
) {
dynamic_field::add(&mut accumulator_root.id, name, value);
}
Function root_borrow_accumulator_mut
fun root_borrow_accumulator_mut<K, V: store>(accumulator_root: &mut sui::accumulator::AccumulatorRoot, name: sui::accumulator::Key<K>): &mut V
Click to open
Implementation
fun root_borrow_accumulator_mut<K, V: store>(
accumulator_root: &mut AccumulatorRoot,
name: Key<K>,
): &mut V {
dynamic_field::borrow_mut<Key<K>, V>(&mut accumulator_root.id, name)
}
Function root_remove_accumulator
fun root_remove_accumulator<K, V: store>(accumulator_root: &mut sui::accumulator::AccumulatorRoot, name: sui::accumulator::Key<K>): V
Click to open
Implementation
fun root_remove_accumulator<K, V: store>(accumulator_root: &mut AccumulatorRoot, name: Key<K>): V {
dynamic_field::remove<Key<K>, V>(&mut accumulator_root.id, name)
}
Function settlement_prologue
Called by settlement transactions to ensure that the settlement transaction has a unique digest.
fun settlement_prologue(_epoch: u64, _checkpoint_height: u64, _idx: u64, ctx: &sui::tx_context::TxContext)
Click to open
Implementation
fun settlement_prologue(_epoch: u64, _checkpoint_height: u64, _idx: u64, ctx: &TxContext) {
assert!(ctx.sender() == @0x0, ENotSystemAddress);
}
Function settle_u128
fun settle_u128<T>(accumulator_root: &mut sui::accumulator::AccumulatorRoot, owner: address, merge: u128, split: u128, ctx: &sui::tx_context::TxContext)
Click to open
Implementation
fun settle_u128<T>(
accumulator_root: &mut AccumulatorRoot,
owner: address,
merge: u128,
split: u128,
ctx: &TxContext,
) {
assert!(ctx.sender() == @0x0, ENotSystemAddress);
// Merge and split should be netted out prior to calling this function.
assert!((merge == 0 ) != (split == 0), EInvalidSplitAmount);
let name = Key<T> { address: owner };
if (accumulator_root.has_accumulator<T, U128>(name)) {
let is_zero = {
let value: &mut U128 = accumulator_root.borrow_accumulator_mut(name);
value.value = value.value + merge - split;
value.value == 0
};
if (is_zero) {
let U128 { value: _ } = accumulator_root.remove_accumulator<T, U128>(
name,
);
}
} else {
// cannot split if the field does not yet exist
assert!(split == 0, EInvalidSplitAmount);
let value = U128 {
value: merge,
};
accumulator_root.add_accumulator(name, value);
};
}
Function emit_deposit_event
public(package) fun emit_deposit_event<T>(accumulator: address, recipient: address, amount: u64)
Click to open
Implementation
public(package) native fun emit_deposit_event<T>(
accumulator: address,
recipient: address,
amount: u64,
);
Function emit_withdraw_event
public(package) fun emit_withdraw_event<T>(accumulator: address, owner: address, amount: u64)
Click to open
Implementation
public(package) native fun emit_withdraw_event<T>(
accumulator: address,
owner: address,
amount: u64,
);