|
|
@@ -25,18 +25,6 @@ pub fn total_gas_used(&self) -> u64 {
|
|
|
.saturating_add(self.signatures)
|
|
|
.saturating_add(self.deployments)
|
|
|
}
|
|
|
-
|
|
|
-pub fn minimum_fee(gas: u64) -> FeeResult<u64> {
|
|
|
- gas.checked_mul(FEE_PER_GAS).ok_or(FeeError::ArithmeticOverflow)
|
|
|
-}
|
|
|
-
|
|
|
-pub fn burn_fee(minimum_fee: u64) -> FeeResult<u64> {
|
|
|
- let burned =
|
|
|
- (minimum_fee as u128).checked_mul(BURN_NUM as u128).ok_or(FeeError::ArithmeticOverflow)?
|
|
|
- / BURN_DEN as u128;
|
|
|
-
|
|
|
- u64::try_from(burned).map_err(|_| FeeError::ArithmeticOverflow)
|
|
|
-}
|
|
|
```
|
|
|
|
|
|
# Fee burning
|
|
|
@@ -52,6 +40,20 @@ inclusion_fee(g) = base_fee(g) - burn_fee(g)
|
|
|
tip_fee = paid - base_fee(g)
|
|
|
```
|
|
|
|
|
|
+```rust
|
|
|
+pub fn minimum_fee(gas: u64) -> FeeResult<u64> {
|
|
|
+ gas.checked_mul(FEE_PER_GAS).ok_or(FeeError::ArithmeticOverflow)
|
|
|
+}
|
|
|
+
|
|
|
+pub fn burn_fee(minimum_fee: u64) -> FeeResult<u64> {
|
|
|
+ let burned =
|
|
|
+ (minimum_fee as u128).checked_mul(BURN_NUM as u128).ok_or(FeeError::ArithmeticOverflow)?
|
|
|
+ / BURN_DEN as u128;
|
|
|
+
|
|
|
+ u64::try_from(burned).map_err(|_| FeeError::ArithmeticOverflow)
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
| Constant | Value | Description |
|
|
|
|--------------------------|------------|----------------------------------------|
|
|
|
| `FEE_PER_GAS` | 5 | Fee per gas unit |
|
|
|
@@ -98,13 +100,10 @@ Overpayment is settled against the fee values the transaction declares,
|
|
|
not against what the chain actually required. The miner always receives
|
|
|
`paid - burned`:
|
|
|
|
|
|
-* A deliberate tip above the builder's own estimated minimum raises
|
|
|
- `paid` only, so it goes entirely to the miner.
|
|
|
-* Estimation error raises `paid` and the declared `burned` together,
|
|
|
- since the burn is declared from the estimate while the floor is
|
|
|
- enforced from the actual requirement. Over-estimated gas therefore
|
|
|
- splits the slack: 75% is burned and 25% accrues to the miner's
|
|
|
- inclusion fee. Under-estimation makes the transaction invalid.
|
|
|
+* A deliberate tip raises `paid` only, so it goes entirely to the miner.
|
|
|
+* Estimation error raises `paid` and the declared `burned` together, so
|
|
|
+ the slack splits the same way as the fee: 75% burned, 25% to the
|
|
|
+ miner. Under-estimation makes the transaction invalid.
|
|
|
|
|
|
| Extra payment from… | Burned | Miner |
|
|
|
|------------------------------------|--------|-------|
|
|
|
@@ -248,7 +247,7 @@ so the gas value is the ratio of an operation's cost to that baseline.
|
|
|
| `READ_GAS_PER_BYTE` | 7 | On-chain read multiplier |
|
|
|
| `WRITE_GAS_PER_BYTE` | 70 | On-chain storage multiplier |
|
|
|
| `STATE_GROWTH_GAS` | 20000 | New on-chain key |
|
|
|
-| `TREE_GAS` | 300 | New sled tree |
|
|
|
+| `TREE_GAS` | 300 | New DB tree |
|
|
|
| `POSEIDON_HASH_GAS` | 150 | Per SMT hash |
|
|
|
| `SINSEMILLA_HASH_GAS` | 800 | Per Merkle hash |
|
|
|
| `COMPILE_GAS_PER_ROW` | 7800 | Per row of zkas compilation |
|
|
|
@@ -259,23 +258,15 @@ so the gas value is the ratio of an operation's cost to that baseline.
|
|
|
|
|
|
Every fee-paying transaction includes a `Money::FeeV1` call. Its gas
|
|
|
cannot be measured before verification, since the fee depends on total
|
|
|
-gas which includes the fee call itself. The fee call's real execution
|
|
|
-cost (~34.1M gas) also varies between builds of the same transaction
|
|
|
-in fixed ~36K-gas steps (33.9M to 34.15M), and shifts with the fee
|
|
|
-value's bit pattern. The variance is local to the fee call — the rest
|
|
|
-of the transaction is gas-identical across builds — and comes from its
|
|
|
-value-conservation check, which, unlike other calls, runs Pedersen
|
|
|
-arithmetic as plain contract code instead of inside the ZK proof.
|
|
|
-
|
|
|
-Because of this, the validator charges the fee call a fixed gas cost
|
|
|
-instead of metering its opcodes:
|
|
|
+gas which includes the fee call itself. The validator therefore charges
|
|
|
+the fee call a fixed gas cost instead of metering its opcodes:
|
|
|
|
|
|
```
|
|
|
fee_call_gas = FEE_CALL_GAS = 35_000_000
|
|
|
```
|
|
|
|
|
|
-The call still executes normally and is still capped by the per-call
|
|
|
-runtime gas limit; only the charge is constant. This makes gas
|
|
|
+The call executes normally within the per-call runtime gas limit; only
|
|
|
+its charge is fixed. This makes gas
|
|
|
accounting deterministic and lets wallets estimate the final gas
|
|
|
closely: the fee-less transaction's measured gas plus the fixed charge
|
|
|
and the fee call's circuit, signature, and size overhead
|