sui_types/
accumulator_event.rs1use move_core_types::ident_str;
5use move_core_types::identifier::IdentStr;
6use mysten_common::{fatal, in_test_configuration};
7
8use crate::TypeTag;
9use crate::accumulator_root::AccumulatorObjId;
10use crate::balance::Balance;
11use crate::base_types::SuiAddress;
12use crate::effects::{
13 AccumulatorAddress, AccumulatorOperation, AccumulatorValue, AccumulatorWriteV1,
14};
15use crate::error::{SuiError, SuiErrorKind};
16use crate::gas_coin::GasCoin;
17
18pub const ACCUMULATOR_MODULE_NAME: &IdentStr = ident_str!("accumulator");
19
20#[derive(Debug, Clone)]
21pub struct AccumulatorEvent {
22 pub accumulator_obj: AccumulatorObjId,
23 pub write: AccumulatorWriteV1,
24}
25
26impl AccumulatorEvent {
27 pub fn new(accumulator_obj: AccumulatorObjId, write: AccumulatorWriteV1) -> Self {
28 if in_test_configuration()
29 && let Ok(expected_obj) = crate::accumulator_root::AccumulatorValue::get_field_id(
30 write.address.address,
31 &write.address.ty,
32 )
33 {
34 debug_assert_eq!(
35 *accumulator_obj.inner(),
36 *expected_obj.inner(),
37 "Accumulator object ID {:?} does not match expected ID {:?} for address {:?} and type {:?}",
38 accumulator_obj.inner(),
39 expected_obj.inner(),
40 write.address.address,
41 write.address.ty
42 );
43 }
44 Self {
45 accumulator_obj,
46 write,
47 }
48 }
49
50 pub fn from_balance_change(
51 address: SuiAddress,
52 balance_type: TypeTag,
53 net_change: i64,
54 ) -> Result<Self, SuiError> {
55 if !Balance::is_balance_type(&balance_type) {
56 return Err(SuiErrorKind::TypeError {
57 error: "only Balance<T> is supported".to_string(),
58 }
59 .into());
60 }
61 let accumulator_obj =
62 crate::accumulator_root::AccumulatorValue::get_field_id(address, &balance_type)?;
63
64 let accumulator_address = AccumulatorAddress::new(address, balance_type);
65
66 let (operation, amount) = if net_change > 0 {
67 (AccumulatorOperation::Split, net_change as u64)
68 } else {
69 (AccumulatorOperation::Merge, (-net_change) as u64)
70 };
71
72 let accumulator_write = AccumulatorWriteV1 {
73 address: accumulator_address,
74 operation,
75 value: AccumulatorValue::Integer(amount),
76 };
77
78 Ok(Self::new(accumulator_obj, accumulator_write))
79 }
80
81 pub fn total_sui_in_event(&self) -> (u64 , u64 ) {
82 let Self {
83 write:
84 AccumulatorWriteV1 {
85 address: AccumulatorAddress { ty, .. },
86 operation,
87 value,
88 },
89 ..
90 } = self;
91
92 let sui = match ty {
93 TypeTag::Struct(struct_tag) => {
94 if !GasCoin::is_gas_balance(struct_tag) {
95 0
96 } else {
97 match value {
98 AccumulatorValue::Integer(v) => *v,
99 AccumulatorValue::IntegerTuple(_, _) => fatal!("invalid accumulator value"),
100 AccumulatorValue::EventDigest(_, _) => fatal!("invalid accumulator value"),
101 }
102 }
103 }
104 _ => 0,
105 };
106
107 match operation {
108 AccumulatorOperation::Merge => (0, sui),
109 AccumulatorOperation::Split => (sui, 0),
110 }
111 }
112}