PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/moul/x/storagecost/v1

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v1
Namespace
moul / x / storagecost
Files
4 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/moul/x/storagecost/v1
gno
0.9

Files (4)

  • README.mdmarkdown
  • gnomod.tomltoml
  • storagecost.gnogno
  • storagecost_test.gnogno
storagecost_test.gnogno
1package storagecost23import (4	"testing"56	"gno.land/p/nt/uassert/v0"7)89func TestRefund(t *testing.T) {10	tests := []struct {11		name  string12		bytes int6413		price int6414		want  int6415	}{16		{"one byte at the default price", 1, DefaultStoragePrice, 100},17		{"the measured reap", 17835, DefaultStoragePrice, 1783500},18		{"the measured compact", 830, DefaultStoragePrice, 83000},19		{"zero bytes", 0, DefaultStoragePrice, 0},20		{"negative bytes are not a credit", -100, DefaultStoragePrice, 0},21		{"a free chain refunds nothing", 1000, 0, 0},22		{"a ten-fold price rise", 1000, 1000, 1000000},23	}24	for _, tt := range tests {25		t.Run(tt.name, func(t *testing.T) {26			uassert.Equal(t, tt.want, Refund(tt.bytes, tt.price))27		})28	}29}3031func TestBreakEvenBytes(t *testing.T) {32	tests := []struct {33		name string34		fee  int6435		want int6436	}{37		// A 2.6M gas call at the floor costs 2,600 ugnot, so 26 bytes.38		{"the canonical 2.6M gas call", 2600, 26},39		{"rounds up, never down", 101, 2},40		{"exactly one byte", 100, 1},41		{"a fee below one byte still needs a byte", 1, 1},42		{"no fee, no threshold", 0, 0},43	}44	for _, tt := range tests {45		t.Run(tt.name, func(t *testing.T) {46			got := BreakEvenBytes(tt.fee, DefaultStoragePrice)47			uassert.Equal(t, tt.want, got)48			// The definition: this many bytes covers the fee, one fewer does not.49			if tt.want > 0 {50				uassert.True(t, Refund(got, DefaultStoragePrice) >= tt.fee)51				uassert.False(t, Refund(got-1, DefaultStoragePrice) >= tt.fee)52			}53		})54	}55	uassert.Equal(t, int64(0), BreakEvenBytes(1000, 0))56}5758func TestGasFee(t *testing.T) {59	// The floor mainnet has actually accepted: 1 ugnot per 1000 gas.60	uassert.Equal(t, int64(5000), FloorGasFee(5_000_000))61	uassert.Equal(t, int64(2500), FloorGasFee(2_500_000))62	// Rounds up, so a fee is never short.63	uassert.Equal(t, int64(1), FloorGasFee(1))64	uassert.Equal(t, int64(0), FloorGasFee(0))65	// The harness price used in the measurements, 1.2 ugnot per gas.66	uassert.Equal(t, int64(6_000_000), GasFee(5_000_000, 12, 10))67	uassert.Equal(t, int64(0), GasFee(5_000_000, 0, 10))68	uassert.Equal(t, int64(0), GasFee(5_000_000, 1, 0))69}7071func TestEvaluateReproducesTheMeasuredReap(t *testing.T) {72	// The measured run: 17,835 bytes freed by a call that used 4,120,876 gas,73	// so gas_wanted 5,000,000 at the floor. Net +1,778,500 ugnot.74	q := EvaluateAtFloor(17835, 5_000_000)75	uassert.Equal(t, int64(1783500), q.Refund)76	uassert.Equal(t, int64(5000), q.Fee)77	uassert.Equal(t, int64(1778500), q.Net)78	uassert.Equal(t, int64(50), q.BreakEven)79	uassert.True(t, q.Worth())80}8182func TestEvaluateReproducesTheMeasuredCompact(t *testing.T) {83	q := EvaluateAtFloor(830, 2_500_000)84	uassert.Equal(t, int64(83000), q.Refund)85	uassert.Equal(t, int64(2500), q.Fee)86	uassert.Equal(t, int64(80500), q.Net)87	uassert.True(t, q.Worth())88}8990func TestEvaluateAtTheHarnessPriceIsALoss(t *testing.T) {91	// The same reap priced at 1.2 ugnot/gas, 1200x the floor, loses money.92	// This is why the gas price cannot be baked into a contract.93	q := Evaluate(17835, DefaultStoragePrice, 5_000_000, 12, 10)94	uassert.Equal(t, int64(6_000_000), q.Fee)95	uassert.False(t, q.Worth())96	uassert.True(t, q.Net < 0)97}9899func TestQuoteString(t *testing.T) {100	worth := EvaluateAtFloor(17835, 5_000_000)101	uassert.Equal(t,102		"17835 bytes, refunds 1.7835 GNOT against 0.005 GNOT of gas, break-even 50 bytes: worth 1.7785 GNOT",103		worth.String())104105	loss := Evaluate(10, DefaultStoragePrice, 5_000_000, 12, 10)106	uassert.Equal(t,107		"10 bytes, refunds 0.001 GNOT against 6 GNOT of gas, break-even 60000 bytes: not worth it yet",108		loss.String())109}110111func TestFormatGNOT(t *testing.T) {112	tests := []struct {113		amount int64114		want   string115	}{116		{0, "0 GNOT"},117		{1, "0.000001 GNOT"},118		{100, "0.0001 GNOT"},119		{1_000_000, "1 GNOT"},120		{1_500_000, "1.5 GNOT"},121		{1_783_500, "1.7835 GNOT"},122		{978_743_800, "978.7438 GNOT"},123		{-2_100, "-0.0021 GNOT"},124		{1_000_001, "1.000001 GNOT"},125	}126	for _, tt := range tests {127		uassert.Equal(t, tt.want, FormatGNOT(tt.amount))128	}129}130131func TestEstimateBytes(t *testing.T) {132	// Measured: a 1,024-byte payload occupied 1,898 bytes of realm state.133	uassert.Equal(t, int64(1894), EstimateBytes(1024))134	uassert.Equal(t, int64(0), EstimateBytes(0))135	uassert.Equal(t, int64(0), EstimateBytes(-5))136	// Monotonic, which is all a bounty estimate really needs.137	uassert.True(t, EstimateBytes(2048) > EstimateBytes(1024))138}139140// TestFormatGNOTIsTotal pins what v0 could not do. v0 negated in int64, so at141// math.MinInt64 both halves kept a sign and it returned142// "--9223372036854.-775808 GNOT". Delegating to kit/num is the fix; this143// asserts the contract rather than the delegation.144func TestFormatGNOTIsTotal(t *testing.T) {145	const minInt64 = -9223372036854775808146	uassert.Equal(t, "-9223372036854.775808 GNOT", FormatGNOT(minInt64))147	uassert.Equal(t, "-1.5 GNOT", FormatGNOT(-1500000))148	uassert.Equal(t, "-0.000001 GNOT", FormatGNOT(-1))149	uassert.Equal(t, "1.5 GNOT", FormatGNOT(1500000))150	uassert.Equal(t, "0 GNOT", FormatGNOT(0))151}152153func TestEstimateNodes(t *testing.T) {154	cases := []struct {155		name  string156		nodes int64157		want  int64158	}{159		{"none", 0, 0},160		{"negative is not an error", -5, 0},161		// The mainnet measurement this constant comes from: compacting a162		// drained 8-node board returned 6,848 bytes.163		{"the mainnet sample", 8, 6848},164		// And the local harness, which agreed to the byte.165		{"the local harness sample", 31, 26536},166	}167	for _, tc := range cases {168		uassert.Equal(t, tc.want, EstimateNodes(tc.nodes), tc.name)169	}170}171172// TestEstimateNodesBeatsEstimateBytesOnTheCaseThatBurnedUs pins the reason173// EstimateNodes exists, not just what it computes.174//175// A realm advertised a bounty by running the payload length of five small176// entries through EstimateBytes and got 481 bytes. Reaping and compacting them177// actually returned 11,972. The payload path cannot see either the per-entry178// floor or the container, and no existing test could catch that because they179// all fed EstimateBytes the 1,024-byte payloads its ratio was measured on.180func TestEstimateNodesBeatsEstimateBytesOnTheCaseThatBurnedUs(t *testing.T) {181	const payload = 8 + 231 + 7 + 5 + 9 // the five note bodies, 260 bytes182	const reallyFreed = 11972183184	guess := EstimateBytes(payload)185	uassert.True(t, guess*20 < reallyFreed,186		"EstimateBytes is still supposed to be the bad one here")187188	// The container half is the part that is countable, and counting it gets189	// most of the way there on its own: 8 nodes were the larger share.190	counted := EstimateNodes(8)191	uassert.True(t, counted > guess*10,192		"counting nodes should dominate guessing from payload")193	uassert.True(t, counted <= reallyFreed,194		"counting nodes must never over-advertise")195}196

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.