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.

state.gno

4.88 Kb · 175 lines
  1package bolo
  2
  3import (
  4	"gno.land/p/nt/avl/v0"
  5	"gno.land/p/nt/seqid/v0"
  6)
  7
  8// Params are the settings snapshotted into each campaign when it is created
  9// (API §2.2): its deposit and its timers never change afterwards (INV-5).
 10// Durations are in seconds.
 11type Params struct {
 12	CreationDeposit int64
 13	DormancyPeriod  int64
 14	ExitDelay       int64
 15	BondHold        int64
 16}
 17
 18// Custody modes, statuses and close reasons (API §2.1).
 19const (
 20	modeDirect = "direct"
 21	modeEscrow = "escrow"
 22
 23	statusOpen    = "open"
 24	statusClosed  = "closed"
 25	statusSettled = "settled"
 26
 27	reasonOrganizer = "organizer"
 28	reasonDeadline  = "deadline"
 29	reasonDormant   = "dormant"
 30)
 31
 32// campaign holds what never changes once a campaign is created (INV-10), and
 33// points to what does. Gno re-saves a changed object and every object that owns
 34// it, up to the first with two owners, so each donation re-saves this object with
 35// its hot state and its trees: it holds only small fields, and the organizer's
 36// text lives in its own object, written once (API §2.5).
 37type campaign struct {
 38	id          seqid.ID
 39	category    string
 40	organizer   address
 41	beneficiary address
 42	mode        string // modeDirect or modeEscrow
 43	goal        int64  // ugnot; 0: no goal
 44	deadline    int64  // Unix seconds; 0: none
 45	createdAt   int64
 46	params      Params
 47
 48	text  *campaignText  // written once; read by views and Render
 49	state *campaignState // counters, timers and flags
 50
 51	// One object each, keyed by donor address or by seqid.Binary(): a donation
 52	// writes O(log n) small nodes, not the campaign's history.
 53	contributions *avl.Tree // address → *contribution
 54	receipts      *avl.Tree // seq → *receipt
 55	withdrawals   *avl.Tree // seq → *withdrawal
 56	refunds       *avl.Tree // seq → *refund
 57	updates       *avl.Tree // seq → *update
 58}
 59
 60// campaignText is what the organizer wrote, which never changes (INV-10): written
 61// once, off the path every donation re-saves.
 62type campaignText struct {
 63	title       string
 64	description string
 65	imageCID    string
 66	imageAlt    string
 67}
 68
 69const recentSize = 20
 70
 71// campaignState is a campaign's hot object: small, rewritten on every donation.
 72type campaignState struct {
 73	status      string // as stored; a passed deadline counts as closed before it is recorded
 74	closeReason string
 75	closedAt    int64
 76	listed      bool
 77	notice      string
 78	imageHidden bool
 79
 80	raised    int64 // gross: every donation ever
 81	refunded  int64
 82	withdrawn int64 // tracked coins only; untracked ones are counted apart
 83
 84	donorCount    int
 85	donationCount int
 86	refundCount   int
 87	updateCount   int
 88
 89	bond         int64
 90	bondSlashed  bool
 91	bondReleased bool
 92
 93	lastDonationAt int64
 94	lastUpdateAt   int64
 95	everWithdrawn  bool // ends the open refund window for good
 96
 97	// The exit window's snapshot, frozen by the first exit claim (API §3.2).
 98	exitFrozen bool
 99	exitPool   int64
100	exitBase   int64
101
102	// The last donations' sequence numbers, a ring: numbers, not receipts.
103	recent     [recentSize]uint64
104	recentNext int
105
106	receiptSeq    seqid.ID
107	withdrawalSeq seqid.ID
108	refundSeq     seqid.ID
109	updateSeq     seqid.ID
110}
111
112// contribution is one donor's record in one campaign (API §3.2).
113type contribution struct {
114	amount      int64 // everything given
115	refunded    int64 // everything paid back
116	exitClaimed bool  // the one exit claim is used (INV-17)
117	public      bool  // at least one gift wasn't anonymous
118}
119
120// receipt is one donation.
121type receipt struct {
122	seq           uint64
123	donor         address
124	anonymous     bool
125	amount        int64
126	tip           int64
127	message       string
128	messageHidden bool
129	at            int64
130	raisedAfter   int64
131
132	refundedBefore int64 // what this donor was refunded on this campaign before this gift
133}
134
135// withdrawal is one payout to the beneficiary.
136type withdrawal struct {
137	seq       uint64
138	amount    int64 // tracked coins
139	untracked int64 // coins sent to the escrow outside Bolo
140	at        int64
141	to        address
142}
143
144// refund is one payout to a donor.
145type refund struct {
146	seq    uint64
147	amount int64
148	at     int64
149	donor  address
150	kind   string // "open" or "exit"
151}
152
153// update is one organizer update: append-only.
154type update struct {
155	seq  uint64
156	at   int64
157	body string
158}
159
160// Package state, all unexported (API C6).
161var (
162	nextID    seqid.ID // the last campaign ID given out
163	campaigns avl.Tree // seqid.Binary() → *campaign
164
165	// derived holds every escrow and bond address a campaign ever got: none of
166	// them may be a beneficiary (API §1).
167	derived avl.Tree // address → true
168
169	// The indexes (API §2.5): keys sort newest campaign last.
170	active           avl.Tree // seqid.Binary() → true: the open, listed campaigns
171	activeByCategory avl.Tree // category + "/" + seqid.Binary() → true: the same
172	byOrganizer      avl.Tree // organizer + "/" + seqid.Binary() → true
173	byBeneficiary    avl.Tree // beneficiary + "/" + seqid.Binary() → true
174	byDonor          avl.Tree // donor + "/" + seqid.Binary() → true: a gift that wasn't anonymous
175)