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.

storagecost_test.gno

4.29 Kb · 138 lines
  1package storagecost
  2
  3import (
  4	"testing"
  5
  6	"gno.land/p/nt/uassert/v0"
  7)
  8
  9func TestRefund(t *testing.T) {
 10	tests := []struct {
 11		name  string
 12		bytes int64
 13		price int64
 14		want  int64
 15	}{
 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}
 30
 31func TestBreakEvenBytes(t *testing.T) {
 32	tests := []struct {
 33		name string
 34		fee  int64
 35		want int64
 36	}{
 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}
 57
 58func 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}
 70
 71func 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}
 81
 82func 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}
 89
 90func 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}
 98
 99func 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())
104
105	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}
110
111func TestFormatGNOT(t *testing.T) {
112	tests := []struct {
113		amount int64
114		want   string
115	}{
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}
130
131func 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}