1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Copyright 2025 The Tari Project
// SPDX-License-Identifier: BSD-3-Clause
pub const WASM_LIMITS: WasmLimits = WasmLimits ;
/// Maximum Wasmer metering points a single template invocation may consume. Enforced by the
/// metering middleware compiled into the engine (see `tari_engine::wasm::module::create_engine`):
/// exceeding it traps the call with an out-of-gas error.
pub const MAX_WASM_POINTS_PER_CALL: u64 = 100_000_000;
/// Maximum Wasmer metering points a whole transaction may consume, summed across every template
/// invocation it makes (top-level instructions and nested cross-template calls). Each invocation
/// otherwise gets a fresh per-call budget, so without this a transaction could multiply its
/// execution time by stacking instructions or recursing to `ENGINE_LIMITS.max_call_depth`. Enforced
/// in `WasmProcess::invoke` by capping each call's allowance to the budget remaining for the
/// transaction. Kept equal to the per-call cap: a transaction gets one compute budget, shared across
/// all its calls. The aggregate across a *block* still needs a separate per-block budget.
pub const MAX_WASM_POINTS_PER_TRANSACTION: u64 = 100_000_000;
/// Wasmer metering points a transaction may consume *before* its fee payments cover them. A
/// transaction sources its fee in the fee intent (withdraw, claim-burn, AMM swap to TARI, stealth
/// transfer, …) and only then calls `pay_fee`, so it must be allowed to run some compute on credit;
/// this bounds that credit. Beyond it, each WASM call's metering allowance is capped to the points
/// the fees paid so far can cover (`WasmProcess::invoke`), so a transaction that does not pay traps
/// out-of-gas here rather than consuming the full [`MAX_WASM_POINTS_PER_TRANSACTION`] for free. This
/// is the bound on free compute a non-paying transaction can extract from a validator. Payments
/// raise the allowance above this value proportionally to the WASM fee rate.
///
/// Sized with generous margin over the most expensive legitimate fee-sourcing flow: acquiring TARI
/// by swapping another resource through an AMM pool inside the fee intent costs ~143k points (see
/// `tari_engine`'s `complex_fee_payment` test, which guards that this stays comfortably above it),
/// so this is ~14x that worst case while staying far below the per-transaction cap.
pub const FREE_COMPUTE_GRACE_POINTS: u64 = 2_000_000;
pub const ENGINE_LIMITS: EngineLimits = EngineLimits ;
pub const MAX_DIVISIBILITY: u8 = 18;
pub const MAX_TOKEN_SYMBOL_LEN: usize = 10;
/// Maximum number of `PublishTemplate` instructions a single transaction may contain.
///
/// Publishing a template registers a new global substate and carries a WASM binary up to
/// [`ENGINE_LIMITS`]`.max_template_binary_size_bytes`. Capping at one keeps each publishing transaction to a single,
/// bounded template registration; multiple publishes would stack several large binaries and their validation/storage
/// cost into one transaction with no benefit a caller cannot get from separate transactions. The engine enforces this
/// during execution — a consensus rule applied uniformly by every validator — and the mempool mirrors it to reject
/// such transactions at ingress.
pub const MAX_PUBLISH_TEMPLATES_PER_TRANSACTION: usize = 1;
/// Verifying a stealth transfer is native, unmetered work dominated by the per-output bulletproof range proof and
/// ElGamal viewable-balance proof (~1ms per output on x86-class hardware). The per-transfer limits bound one statement;
/// the per-transaction limits bound the aggregate so a single transaction cannot stack enough stealth verification to
/// exceed the block execution budget and stall the proposing leader. The per-transaction caps are a consensus-relevant
/// execution rule enforced uniformly during execution, not just a mempool heuristic.
pub const STEALTH_LIMITS: StealthLimits = StealthLimits ;
/// Spending confidential outputs is native, unmetered work: each input commitment is a separate substate that must be
/// locked and read plus folded into the balance-proof point aggregation, and each withdraw verifies a bulletproof range
/// proof over its (at most two) outputs. The per-withdraw limit bounds one proof; the per-transaction limits bound the
/// aggregate so a single transaction cannot stack enough native verification and substate access to stall the proposing
/// leader. These are consensus-relevant execution rules enforced uniformly during execution, not mempool heuristics.
pub const CONFIDENTIAL_LIMITS: ConfidentialLimits = ConfidentialLimits ;