Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

fuel.gno

1.83 Kb · 58 lines
 1package vmkit
 2
 3// Unmetered is the fuel value that disables the budget: a [Meter] built with
 4// it never reports exhaustion. It exists so a benchmark can measure the
 5// dispatch loop without the meter in it, and so a trusted caller can run a
 6// program to completion in one slice. Gas remains the real backstop.
 7const Unmetered int64 = -1
 8
 9// Meter is a fuel budget being spent. It allocates nothing after
10// construction, because it sits in the hot path of every guest instruction.
11type Meter struct {
12	budget int64 // Unmetered, or the number of units this slice may spend
13	used   int64
14}
15
16// NewMeter returns a meter good for `budget` units, or an unmetered one when
17// budget is [Unmetered]. A budget of zero is a meter with nothing to spend,
18// which is a legitimate way to ask "is this instance still runnable".
19func NewMeter(budget int64) *Meter {
20	if budget < 0 {
21		budget = Unmetered
22	}
23	return &Meter{budget: budget}
24}
25
26// Charge spends n units and reports whether they were available. On false
27// nothing is spent, so the caller can stop before executing the instruction
28// it could not pay for. That ordering is what makes a resumed machine
29// re-execute exactly the instruction it stopped at, and no other.
30func (m *Meter) Charge(n int64) bool {
31	if m.budget == Unmetered {
32		m.used += n
33		return true
34	}
35	if m.used+n > m.budget {
36		return false
37	}
38	m.used += n
39	return true
40}
41
42// Used reports how much fuel has been spent.
43func (m *Meter) Used() int64 { return m.used }
44
45// Remaining reports what is left, or [Unmetered].
46func (m *Meter) Remaining() int64 {
47	if m.budget == Unmetered {
48		return Unmetered
49	}
50	return m.budget - m.used
51}
52
53// Exhausted reports whether the next single unit would fail.
54func (m *Meter) Exhausted() bool { return !m.affordable(1) }
55
56func (m *Meter) affordable(n int64) bool {
57	return m.budget == Unmetered || m.used+n <= m.budget
58}