1use arb_primitives::multigas::{MultiGas, ResourceKind};
2
3use crate::util::TracingInfo;
4
5pub trait Burner {
11 fn burn(&mut self, kind: ResourceKind, amount: u64) -> Result<(), BurnError>;
12 fn burn_multi_gas(&mut self, amount: MultiGas) -> Result<(), BurnError>;
13 fn burned(&self) -> u64;
14 fn gas_left(&self) -> u64;
15 fn burn_out(&mut self) -> Result<(), BurnError>;
16 fn restrict(&mut self, err: BurnError);
17 fn handle_error(&self, err: BurnError) -> Result<(), BurnError>;
18 fn read_only(&self) -> bool;
19 fn tracing_info(&self) -> Option<&TracingInfo>;
20}
21
22#[derive(Debug, Clone, thiserror::Error)]
24pub enum BurnError {
25 #[error("out of gas")]
26 OutOfGas,
27}
28
29#[derive(Debug, Clone)]
34pub struct SystemBurner {
35 gas_burnt: MultiGas,
36 tracing_info: Option<TracingInfo>,
37 read_only: bool,
38}
39
40impl SystemBurner {
41 pub fn new(tracing_info: Option<TracingInfo>, read_only: bool) -> Self {
42 Self {
43 gas_burnt: MultiGas::zero(),
44 tracing_info,
45 read_only,
46 }
47 }
48}
49
50impl Burner for SystemBurner {
51 fn burn(&mut self, kind: ResourceKind, amount: u64) -> Result<(), BurnError> {
52 self.gas_burnt.saturating_increment_into(kind, amount);
53 Ok(())
54 }
55
56 fn burn_multi_gas(&mut self, amount: MultiGas) -> Result<(), BurnError> {
57 self.gas_burnt.saturating_add_into(amount);
58 Ok(())
59 }
60
61 fn burned(&self) -> u64 {
62 self.gas_burnt.total()
63 }
64
65 fn gas_left(&self) -> u64 {
66 unreachable!("SystemBurner has no notion of gas left")
67 }
68
69 fn burn_out(&mut self) -> Result<(), BurnError> {
70 Err(BurnError::OutOfGas)
71 }
72
73 fn restrict(&mut self, _err: BurnError) {
74 }
76
77 fn handle_error(&self, err: BurnError) -> Result<(), BurnError> {
78 Err(err)
79 }
80
81 fn read_only(&self) -> bool {
82 self.read_only
83 }
84
85 fn tracing_info(&self) -> Option<&TracingInfo> {
86 self.tracing_info.as_ref()
87 }
88}