Personal World Fee Research
TL;DR
- CreateWorld gas: ~7.5M at N=1 -> ~19.1M at N=1,000 (+154.7%), storage ~448Kugnot (constant)
- UpdateWorld gas: ~6.4M at N=1 -> ~14.7M at N=1,000 (+129.2%), storage 0
- ExpandWorld gas: ~6.8M (nearly constant), storage ~700ugnot
- DeleteWorld gas: ~5.5M at N=1 -> ~17.1M at N=1,000 (+214.2%), storage 0
- GrantRole / RevokeRole: ~5.5M gas each (fixed-scale)
- SetChunkVerifier vs SetChunkVerifiers: batch is ~50x more gas-efficient per item
1) Background and Goal
Measure gas/storage costs for the Personal World contract actions across different data scales.
Actions:
- WorldLifecycle: CreateWorld, UpdateWorld, ExpandWorld, DeleteWorld (N = existing world count)
- GrantRole / RevokeRole: fixed-scale, paired grant+revoke
- SetChunkVerifier: single verifier set (N = existing verifier count)
- SetChunkVerifiers: batch verifier set, batch=100 (N = existing verifier count)
Goals:
- Identify gas cost growth pattern as N increases
- Identify storage fee change pattern
- Compare single vs batch chunk verifier efficiency
- Establish a basis for production cost estimation
2) Test Environment
- Date: 2026-02-09
- Execution: gnodev (local machine)
- Gno RPC:
localhost:26657 - Chain ID:
dev - Script:
bin/gno/research/personal_world.sh all - Milestones: 1, 500, 1,000
- Repeat: 3
- Batch size (SetChunkVerifiers): 100 (fixed)
- Max chunks per world: 784
3) Results
CreateWorld
| N (worlds) | Gas (avg) | Gas Q1 | Gas Q3 | Storage (avg) | Storage Q1 | Storage Q3 |
|---|---|---|---|---|---|---|
| 1 | 7,508,908 | -0.0% | +0.0% | 444,666 | -0.1% | +0.0% |
| 500 | 13,699,977 | -0.4% | +0.2% | 448,200 | -0.1% | +0.0% |
| 1,000 | 19,119,646 | -0.3% | +0.1% | 448,366 | -0.1% | +0.1% |
UpdateWorld
| N (worlds) | Gas (avg) | Gas Q1 | Gas Q3 | Storage (avg) | Storage Q1 | Storage Q3 |
|---|---|---|---|---|---|---|
| 1 | 6,403,734 | -0.0% | +0.0% | 0 | 0.0% | 0.0% |
| 500 | 10,669,401 | +0.0% | +0.0% | 0 | 0.0% | 0.0% |
| 1,000 | 14,678,268 | +0.0% | +0.0% | 0 | 0.0% | 0.0% |
ExpandWorld
| N (worlds) | Gas (avg) | Gas Q1 | Gas Q3 | Storage (avg) | Storage Q1 | Storage Q3 |
|---|---|---|---|---|---|---|
| 1 | 6,793,959 | -0.0% | +0.0% | 733 | -4.5% | +2.3% |
| 500 | 7,098,209 | +0.0% | +0.0% | 700 | +0.0% | +0.0% |
| 1,000 | 7,130,964 | +0.0% | +0.0% | 700 | +0.0% | +0.0% |
DeleteWorld
| N (worlds) | Gas (avg) | Gas Q1 | Gas Q3 | Storage (avg) | Storage Q1 | Storage Q3 |
|---|---|---|---|---|---|---|
| 1 | 5,459,141 | -0.0% | +0.0% | 0 | 0.0% | 0.0% |
| 500 | 11,718,632 | -0.0% | +0.0% | 0 | 0.0% | 0.0% |
| 1,000 | 17,146,263 | -0.0% | +0.0% | 0 | 0.0% | 0.0% |
GrantRole / RevokeRole
| Action | Gas (avg) | Gas Q1 | Gas Q3 | Storage (avg) | Storage Q1 | Storage Q3 |
|---|---|---|---|---|---|---|
| GrantRole | 5,585,163 | -0.0% | +0.0% | 106,833 | -0.2% | +0.1% |
| RevokeRole | 5,534,711 | +0.0% | +0.0% | 0 | 0.0% | 0.0% |
SetChunkVerifier
| N (verifiers) | Gas (avg) | Gas Q1 | Gas Q3 | Storage (avg) | Storage Q1 | Storage Q3 |
|---|---|---|---|---|---|---|
| 1 | 5,349,601 | -4.3% | +4.3% | 15,066 | -1.4% | +0.9% |
| 500 | 9,096,359 | -2.6% | +2.6% | 15,000 | +0.0% | +0.0% |
| 1,000 | 5,932,222 | -0.0% | +0.0% | 15,000 | +0.0% | +0.0% |
SetChunkVerifiers (batch=100)
| N (verifiers) | Gas (avg) | Gas Q1 | Gas Q3 | Storage (avg) | Storage Q1 | Storage Q3 |
|---|---|---|---|---|---|---|
| 1 | 10,576,510 | -2.2% | +2.2% | 1,398,066 | -0.0% | +0.0% |
| 500 | 14,323,217 | -1.6% | +1.6% | 1,398,000 | +0.0% | +0.0% |
| 1,000 | 17,067,563 | -1.3% | +1.3% | 1,398,000 | +0.0% | +0.0% |
4) Analysis
WorldLifecycle Gas Growth
| Action | 1 -> 500 | 500 -> 1,000 |
|---|---|---|
| CreateWorld | +6,191,069 (+82.5%) | +5,419,669 (+39.6%) |
| UpdateWorld | +4,265,667 (+66.6%) | +4,008,867 (+37.6%) |
| ExpandWorld | +304,250 (+4.5%) | +32,755 (+0.5%) |
| DeleteWorld | +6,259,491 (+114.7%) | +5,427,631 (+46.3%) |
- CreateWorld, UpdateWorld, DeleteWorld: gas grows significantly with world count — these traverse the world registry (avl tree)
- ExpandWorld: nearly constant gas — does not depend on total world count
WorldLifecycle Storage
- CreateWorld: ~448K ugnot (constant) — new world always allocates the same storage
- UpdateWorld, DeleteWorld: 0 ugnot — no new storage allocation
- ExpandWorld: ~700 ugnot — minimal storage change
GrantRole / RevokeRole
- Fixed cost: ~5.5M gas each
- GrantRole incurs ~107K ugnot storage (new role entry), RevokeRole incurs 0
Single vs Batch Chunk Verifier Comparison
| Metric | Single (SetChunkVerifier) | Batch (SetChunkVerifiers, 100) | Ratio |
|---|---|---|---|
| Gas per call (N=1) | 5,349,601 | 10,576,510 | 2.0x |
| Gas per item (N=1) | 5,349,601 | 105,765 | 50.6x |
| Storage per call | ~15,000ugnot | ~1,398,000ugnot | 93.2x |
| Storage per item | ~15,000ugnot | ~13,980ugnot | ~1.07x |
- Batch is ~98% cheaper per item in gas
- Per-item storage cost is nearly identical
Variance
- WorldLifecycle: Q1/Q3 < 0.5% — extremely stable
- GrantRole/RevokeRole: Q1/Q3 < 0.2% — deterministic
- SetChunkVerifier: Q1/Q3 < 4.3% — stable
- SetChunkVerifiers: Q1/Q3 < 2.2% — stable
5) Conclusions
- World registry operations scale linearly: CreateWorld, UpdateWorld, DeleteWorld gas grows proportionally to world count due to avl tree traversal
- ExpandWorld is constant-cost: independent of world count (~7M gas)
- Role operations are lightweight: ~5.5M gas for grant/revoke regardless of scale
- Batch chunk verifiers strongly preferred: ~50x gas efficiency per item vs single calls
- Storage is predictable: CreateWorld ~448K, GrantRole ~107K, chunk verifiers ~14-15K per item — all constant regardless of data scale
Last updated on