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 #[error("restricted: {0}")]
28 Restricted(String),
29 #[error("{0}")]
30 Other(String),
31}
32
33#[derive(Debug, Clone)]
38pub struct SystemBurner {
39 gas_burnt: MultiGas,
40 tracing_info: Option<TracingInfo>,
41 read_only: bool,
42}
43
44impl SystemBurner {
45 pub fn new(tracing_info: Option<TracingInfo>, read_only: bool) -> Self {
46 Self {
47 gas_burnt: MultiGas::zero(),
48 tracing_info,
49 read_only,
50 }
51 }
52}
53
54impl Burner for SystemBurner {
55 fn burn(&mut self, kind: ResourceKind, amount: u64) -> Result<(), BurnError> {
56 self.gas_burnt.saturating_increment_into(kind, amount);
57 Ok(())
58 }
59
60 fn burn_multi_gas(&mut self, amount: MultiGas) -> Result<(), BurnError> {
61 self.gas_burnt.saturating_add_into(amount);
62 Ok(())
63 }
64
65 fn burned(&self) -> u64 {
66 self.gas_burnt.total()
67 }
68
69 fn gas_left(&self) -> u64 {
70 unreachable!("SystemBurner has no notion of gas left")
71 }
72
73 fn burn_out(&mut self) -> Result<(), BurnError> {
74 Err(BurnError::OutOfGas)
75 }
76
77 fn restrict(&mut self, _err: BurnError) {
78 }
80
81 fn handle_error(&self, err: BurnError) -> Result<(), BurnError> {
82 Err(err)
83 }
84
85 fn read_only(&self) -> bool {
86 self.read_only
87 }
88
89 fn tracing_info(&self) -> Option<&TracingInfo> {
90 self.tracing_info.as_ref()
91 }
92}