Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

emission_state.gno

5.20 Kb · 168 lines
  1package gns
  2
  3import (
  4	"chain/runtime"
  5	"time"
  6
  7	gnsmath "gno.land/p/gnoswap/gnsmath"
  8	ufmt "gno.land/p/nt/ufmt/v0"
  9)
 10
 11var emissionState *EmissionState
 12
 13func init() {
 14	emissionState = NewEmissionState(0, 0)
 15}
 16
 17// EmissionState manages emission state and halving data.
 18// Tracks emission timing, status, and halving year information for 12-year schedule.
 19type EmissionState struct {
 20	createdHeight  int64
 21	startTimestamp int64
 22	endTimestamp   int64
 23	halvingData    *HalvingData
 24}
 25
 26// isInitialized returns true if emission state has been initialized with valid height and timestamp.
 27func (e *EmissionState) isInitialized() bool {
 28	return e.createdHeight != 0 && e.startTimestamp != 0
 29}
 30
 31// isActive returns true if emission is currently active at the given timestamp.
 32// Returns false if not initialized or timestamp is outside emission period.
 33func (e *EmissionState) isActive(timestamp int64) bool {
 34	if !e.isInitialized() {
 35		return false
 36	}
 37
 38	if e.startTimestamp > timestamp {
 39		return false
 40	}
 41
 42	if e.endTimestamp < timestamp {
 43		return false
 44	}
 45
 46	return true
 47}
 48
 49// isEnded returns true if emission has ended at the given timestamp.
 50func (e *EmissionState) isEnded(timestamp int64) bool {
 51	return e.endTimestamp < timestamp
 52}
 53
 54// getCurrentYear returns the halving year (1-12) for the given timestamp, or 0 if outside emission period.
 55func (e *EmissionState) getCurrentYear(timestamp int64) int64 {
 56	if timestamp < e.startTimestamp {
 57		return 0
 58	}
 59
 60	if timestamp > e.endTimestamp {
 61		return 0
 62	}
 63
 64	year := (timestamp - e.startTimestamp) / SECONDS_IN_YEAR
 65	return year + 1
 66}
 67
 68// getCreatedHeight returns the blockchain height when emission started.
 69func (e *EmissionState) getCreatedHeight() int64 {
 70	return e.createdHeight
 71}
 72
 73// getStartTimestamp returns the timestamp when emission started.
 74func (e *EmissionState) getStartTimestamp() int64 {
 75	return e.startTimestamp
 76}
 77
 78// getEndTimestamp returns the timestamp when emission ends.
 79func (e *EmissionState) getEndTimestamp() int64 {
 80	return e.endTimestamp
 81}
 82
 83// getHalvingData returns the halving data containing emission schedule details.
 84func (e *EmissionState) getHalvingData() *HalvingData {
 85	return e.halvingData
 86}
 87
 88// getHalvingYearStartTimestamp returns the start timestamp for the specified halving year.
 89func (e *EmissionState) getHalvingYearStartTimestamp(year int64) int64 {
 90	return e.halvingData.getStartTimestamp(year)
 91}
 92
 93// getHalvingYearEndTimestamp returns the end timestamp for the specified halving year.
 94func (e *EmissionState) getHalvingYearEndTimestamp(year int64) int64 {
 95	return e.halvingData.getEndTimestamp(year)
 96}
 97
 98// getHalvingYearAmountPerSecond returns the emission rate per second for the specified halving year.
 99func (e *EmissionState) getHalvingYearAmountPerSecond(year int64) int64 {
100	return e.halvingData.getAmountPerSecond(year)
101}
102
103// getHalvingYearAccumulatedAmount returns the accumulated emission amount for the specified halving year.
104func (e *EmissionState) getHalvingYearAccumulatedAmount(year int64) int64 {
105	return e.halvingData.getAccumAmount(year)
106}
107
108// getHalvingYearLeftAmount returns the remaining emission amount for the specified halving year.
109func (e *EmissionState) getHalvingYearLeftAmount(year int64) int64 {
110	return e.halvingData.getLeftAmount(year)
111}
112
113// addHalvingYearAccumulatedAmount adds to the accumulated emission amount for the specified halving year.
114// Returns error if year is invalid (0 or outside 1-12 range).
115func (e *EmissionState) addHalvingYearAccumulatedAmount(year int64, amount int64) error {
116	if year == 0 {
117		return makeErrorWithDetails(errInvalidYear, ufmt.Sprintf("year: %d", year))
118	}
119
120	accumulatedAmount := e.halvingData.getAccumAmount(year)
121	accumulatedAmount = gnsmath.SafeAddInt64(accumulatedAmount, amount)
122
123	return e.halvingData.setAccumAmount(year, accumulatedAmount)
124}
125
126// subHalvingYearLeftAmount subtracts from the remaining emission amount for the specified halving year.
127// Returns error if year is invalid (0 or outside 1-12 range).
128func (e *EmissionState) subHalvingYearLeftAmount(year int64, amount int64) error {
129	if year == 0 {
130		return makeErrorWithDetails(errInvalidYear, ufmt.Sprintf("year: %d", year))
131	}
132
133	leftAmount := e.halvingData.getLeftAmount(year)
134	leftAmount = gnsmath.SafeSubInt64(leftAmount, amount)
135
136	return e.halvingData.setLeftAmount(year, leftAmount)
137}
138
139func (e *EmissionState) Clone() *EmissionState {
140	return &EmissionState{
141		createdHeight:  e.createdHeight,
142		startTimestamp: e.startTimestamp,
143		endTimestamp:   e.endTimestamp,
144		halvingData:    e.halvingData.Clone(),
145	}
146}
147
148// NewEmissionState creates a new EmissionState with specified start height and timestamp.
149// Calculates emission end time based on 12-year schedule and initializes halving data.
150func NewEmissionState(createdHeight int64, startTimestamp int64) *EmissionState {
151	emissionEndTime := gnsmath.SafeAddInt64(startTimestamp, SECONDS_IN_YEAR*HALVING_END_YEAR-1)
152
153	return &EmissionState{
154		createdHeight:  createdHeight,
155		startTimestamp: startTimestamp,
156		endTimestamp:   emissionEndTime,
157		halvingData:    NewHalvingData(startTimestamp),
158	}
159}
160
161// getEmissionState returns the singleton emission state instance.
162func getEmissionState() *EmissionState {
163	if emissionState == nil {
164		emissionState = NewEmissionState(runtime.ChainHeight(), time.Now().Unix())
165	}
166
167	return emissionState
168}