Module sui::accumulator_settlement
- Struct EventStreamHead
- Constants
- Function settlement_prologue
- Function settle_u128
- Function record_settlement_sui_conservation
- Function add_to_mmr
- Function u256_from_bytes
- Function hash_two_to_one_u256
- Function new_stream_head
- Function settle_events
use std::ascii;
use std::bcs;
use std::option;
use std::string;
use std::vector;
use sui::accumulator;
use sui::accumulator_metadata;
use sui::address;
use sui::bag;
use sui::bcs;
use sui::dynamic_field;
use sui::hash;
use sui::hex;
use sui::object;
use sui::party;
use sui::transfer;
use sui::tx_context;
use sui::vec_map;
Struct EventStreamHead
public struct EventStreamHead has store
Click to open
Fields
-
mmr: vector<u256>
- Merkle Mountain Range of all events in the stream.
-
checkpoint_seq: u64
- Checkpoint sequence number at which the event stream was written.
-
num_events: u64
- Number of events in the stream.
Constants
const ENotSystemAddress: u64 = 0;
const EInvalidSplitAmount: u64 = 1;
Function settlement_prologue
Called by settlement transactions to ensure that the settlement transaction has a unique digest.
fun settlement_prologue(_accumulator_root: &mut sui::accumulator::AccumulatorRoot, _epoch: u64, _checkpoint_height: u64, _idx: u64, input_sui: u64, output_sui: u64, ctx: &sui::tx_context::TxContext)
Click to open
Implementation
fun settlement_prologue(
_accumulator_root: &mut AccumulatorRoot,
_epoch: u64,
_checkpoint_height: u64,
_idx: u64,
// Total input sui received from user transactions
input_sui: u64,
// Total output sui withdrawn by user transactions
output_sui: u64,
ctx: &TxContext,
) {
assert!(ctx.sender() == @0x0, ENotSystemAddress);
record_settlement_sui_conservation(input_sui, output_sui);
}
Function settle_u128
fun settle_u128<T>(accumulator_root: &mut sui::accumulator::AccumulatorRoot, owner: address, merge: u128, split: u128, ctx: &mut sui::tx_context::TxContext)
Click to open
Implementation
fun settle_u128<T>(
accumulator_root: &mut AccumulatorRoot,
owner: address,
merge: u128,
split: u128,
ctx: &mut 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 = accumulator_key<T>(owner);
if (accumulator_root.has_accumulator<T, U128>(name)) {
let is_zero = {
let value: &mut U128 = accumulator_root.borrow_accumulator_mut(name);
value.update(merge, split);
value.is_zero()
};
if (is_zero) {
let value = accumulator_root.remove_accumulator<T, U128>(name);
destroy_u128(value);
accumulator_root.remove_metadata<T>(owner);
}
} else {
// cannot split if the field does not yet exist
assert!(split == 0, EInvalidSplitAmount);
let value = create_u128(merge);
accumulator_root.add_accumulator(name, value);
accumulator_root.create_metadata<T>(owner, ctx);
};
}
Function record_settlement_sui_conservation
Called by the settlement transaction to track conservation of SUI.
fun record_settlement_sui_conservation(input_sui: u64, output_sui: u64)
Click to open
Implementation
native fun record_settlement_sui_conservation(input_sui: u64, output_sui: u64);
Function add_to_mmr
fun add_to_mmr(new_val: u256, mmr: &mut vector<u256>)
Click to open
Implementation
fun add_to_mmr(new_val: u256, mmr: &mut vector<u256>) {
let mut i = 0;
let mut cur = new_val;
while (i < vector::length(mmr)) {
let r = vector::borrow_mut(mmr, i);
if (*r == 0) {
*r = cur;
return
} else {
cur = hash_two_to_one_u256(*r, cur);
*r = 0;
};
i = i + 1;
};
// Vector length insufficient. Increase by 1.
vector::push_back(mmr, cur);
}
Function u256_from_bytes
fun u256_from_bytes(bytes: vector<u8>): u256
Click to open
Implementation
fun u256_from_bytes(bytes: vector<u8>): u256 {
bcs::new(bytes).peel_u256()
}
Function hash_two_to_one_u256
fun hash_two_to_one_u256(left: u256, right: u256): u256
Click to open
Implementation
fun hash_two_to_one_u256(left: u256, right: u256): u256 {
let left_bytes = bcs::to_bytes(&left);
let right_bytes = bcs::to_bytes(&right);
let mut concatenated = left_bytes;
vector::append(&mut concatenated, right_bytes);
u256_from_bytes(hash::blake2b256(&concatenated))
}
Function new_stream_head
fun new_stream_head(new_root: u256, event_count_delta: u64, checkpoint_seq: u64): sui::accumulator_settlement::EventStreamHead
Click to open
Implementation
fun new_stream_head(new_root: u256, event_count_delta: u64, checkpoint_seq: u64): EventStreamHead {
let mut initial_mmr = vector::empty();
add_to_mmr(new_root, &mut initial_mmr);
EventStreamHead {
mmr: initial_mmr,
checkpoint_seq: checkpoint_seq,
num_events: event_count_delta,
}
}
Function settle_events
entry fun settle_events(accumulator_root: &mut sui::accumulator::AccumulatorRoot, stream_id: address, new_root: u256, event_count_delta: u64, checkpoint_seq: u64, ctx: &sui::tx_context::TxContext)
Click to open
Implementation
entry fun settle_events(
accumulator_root: &mut AccumulatorRoot,
stream_id: address,
new_root: u256,
event_count_delta: u64,
checkpoint_seq: u64,
ctx: &TxContext,
) {
assert!(ctx.sender() == @0x0, ENotSystemAddress);
let name = accumulator_key<EventStreamHead>(stream_id);
if (accumulator_root.has_accumulator<EventStreamHead, EventStreamHead>(copy name)) {
let head: &mut EventStreamHead = accumulator_root.borrow_accumulator_mut(name);
add_to_mmr(new_root, &mut head.mmr);
head.num_events = head.num_events + event_count_delta;
head.checkpoint_seq = checkpoint_seq;
} else {
let head = new_stream_head(new_root, event_count_delta, checkpoint_seq);
accumulator_root.add_accumulator(name, head);
};
}