Totals
Ask AI
Totals are the book's total debits and credits.
Command
gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/inventory.Totals()"
Result
Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.
Package inventory is a per-owner inventory sub-ledger whose cost of goods sold is DERIVED from the lots on hand rather than asserted by a caller.
A general ledger takes a debit code, a credit code and an amount from whoever is posting. That is the right design for a ledger, and it means gno.land/r/.../books structurally CANNOT know that an entry was a shipment, or that the cost charged for that shipment is the cost the goods were actually bought at. Nothing stops a shipper from booking a flattering number, and nothing in the book can tell afterwards.
This realm closes that gap for one class of entry. It holds each item's cost lots as state, and when goods ship it computes the charge from those lots by the item's declared costing method. The amount is never a parameter: Ship takes a QUANTITY and returns the cost it derived.
The resulting claims are narrow and checkable by anyone, which is the point. Per item, from p/lots' own cross-foot:
1receivedCost == chargedCost + costOnHand
and, across a whole register, against the ledger the realm posted to:
1balance(1300) == sum of costOnHand over items
2balance(5000) == sum of chargedCost over items
3balance(3900) == sum of receivedCost over items
All four are exported — ItemCrossFoot, CrossFootInventory, CrossFootCOGS, CrossFootContributed — and all are FREE reads, deliberately; see "Why the invariants are free reads" below.
Note what the three ledger identities are NOT. Each compares a walk of the lots against an account balance, and the two are maintained by different code: the pool counts for itself inside p/lots, while this realm posts to the book. A disagreement is therefore a real signal and not a tautology. That is the same reason p/lots keeps counters beside its lots.
11300 Inventory (asset, debit-normal)
25000 Cost of goods sold (expense, debit-normal)
33900 Inventory contributed (equity, credit-normal)
A receipt is debit 1300 / credit 3900. A shipment is debit 5000 / credit 1300 for the DERIVED cost. There is no OpenAccount entrypoint and the underlying book is created with a hard cap of three accounts, so the chart cannot grow. The accounting equation offsets at 0 = 0 on an empty register and after every posting, because 1300 + 5000 == 3900 is the register-wide restatement of each pool's own cross-foot.
This is the design's one unavoidable assertion about the world, so it is stated here rather than buried.
gno.land/r/.../assets faced the same question about an asset's cost basis and answered by NOT BOOKING IT: the only honest credit legs were a liability ("2000 Acquisition payable") or an equity plug ("3000 Contributed capital"), both of which assert how the asset was funded, which that realm does not know. It kept the cost in register state as data instead.
That answer is not available here, and the difference is structural rather than a matter of taste. The product IS cost of goods sold. A shipment debits 5000 and credits 1300, so 1300 must carry a balance, so the receipt must reach the book — and a debit to 1300 needs a credit leg. The choice is therefore not "book it or not" but "which plug", and every candidate asserts something unobservable:
So 3900 was chosen because it needs no follow-up transaction to stay coherent, not because it is true. Read it as "goods arrived from somewhere this ledger does not model". A register whose goods were in fact purchased on credit is understating liabilities and overstating equity by exactly balance(3900), and no code path here can detect that. Pairing this sub-ledger with a real payables ledger is out of scope for v1 and is the honest fix.
An item is added by AddFIFO, AddLIFO or AddWAVG — three entrypoints rather than one taking a method code, following r/assets' Place / PlaceDeclining precedent, so a caller never has to know an enum's numbering.
p/lots fixes the method at pool construction and documents why: changing it mid-life would recost nothing already charged but would change what the next shipment costs, which is a restatement a sub-ledger must not be able to make silently. This realm inherits that and adds nothing: there is no entrypoint that changes an item's method. An owner who must switch opens a new SKU and discloses it.
The three methods differ observably, which is the point of having them: FIFO and LIFO charge different amounts whenever unit costs differ, and WAVG re-anchors every receipt into a single merged lot so it holds exactly one lot and can never hit the per-item lot cap.
That exemption is not a free win, and the trade is the other way round from how it reads. WAVG escapes the LOT cap and in exchange acquires a refusal FIFO and LIFO do not have: a merged lot must satisfy p/lots' per-lot overflow precondition `Cost <= maxInt64/Qty`, and two lots that each satisfy it separately can merge into one that does not. So under WAVG a receipt can be refused for the pool's ACCUMULATED HISTORY rather than for anything about the receipt — the same receipt a FIFO item would have taken. It is a far corner of the arithmetic and not a practical bound, but it is the reason LotCapacity is the wrong thing to watch for a WAVG item: its figure is a bound WAVG will never approach, so a caller sizing headroom from it is reading the one limit that does not apply. See p/lots' Pool.Receive.
p/journal rejects a posting of zero (ErrInvalidAmount) — correctly; a zero entry is not an event. But both of this realm's postings can legitimately be zero:
In both cases the pool is updated and NOTHING is posted. The identities above are preserved exactly, because a zero contribution to the ledger side is matched by a zero contribution to the walk side. The same choice r/assets makes for a degenerate declining schedule, for the same reason.
r/books exposes Rederive as an owner-only crossing function, to contain the cost of a full re-walk. This realm diverges, deliberately and for the same reason r/assets does: the derivation IS the product, and a claim only its owner can check is not a claim worth making. Rederive, ItemCrossFoot, the three register cross-foots and Render are all free reads, so any third party can verify a register from vm/qeval with no key.
MaxLotsPerItem is 64 against p/lots' own MaxLotsLimit of 1024, and the gap is not timidity. p/lots' audit left the cost of its O(live lots) walks explicitly UNPRICED and recorded that a realm rendering many pools must measure its own gas. This realm is that realm, so the figures are measured rather than reasoned about, under the pinned onyx toolchain.
There are TWO cost axes, not one, and this paragraph used to name only the first: MaxItemsPerRegister*MaxLotsPerItem live lots, and separately MaxEntriesPerRegister postings. It called 64 items of 64 live lots "the worst case this realm can hold", which is false — a register can sit at the lot cap and the entry cap AT ONCE. It was also claimed in review that the two are mutually exclusive by construction; that is wrong too. A one-unit FIFO shipment draws from the oldest lot, which holds 100 units, so 64 of them never exhaust it: 64 items x 64 receipts then 64 items x 64 one-unit shipments leaves 4096 live lots and exactly 8192 entries. The figures below were taken on a register asserted in-fixture to sit at all three caps simultaneously, so the combined shape is measured and not argued about.
Free reads, net of a trivial-read baseline on the same register:
1Rederive 506,486,523
2Render, register page 186,179,474
3CrossFoot 96,213,741
4Render, item page 6,467,621
5Render, index 192,716
The dearest is 16.9% of the 3,000,000,000 maxGasQuery. The two axes do not compose in any single read's price, because no single read walks both: Rederive walks postings and reads no lot, while CrossFoot and Render walk lots and read three accounts plus EntryCount. Measured rather than inferred — Rederive at the lot cap agrees with the same read on a lot-cheap register (506,495,345) to 0.002%, which is what proves the lot axis does not price it. So the ceiling is the MAX of the two axes and never their product.
A bound is not a price, and one item per call is what keeps the write side cheap: Receive and Ship each touch exactly one pool. Measured on the same toolchain, net of the same kind of baseline:
1Receive creating the 64th lot 930,676
2Ship of all OnHand, dropping all 64 lots 11,837,593
3Receive refused at the lot cap 304,454
The dearest write is 2.3% of the dearest read, so the read side is what the caps exist for. See DEPLOY_READINESS.md for the transcript, the per-header GAS pairing rule, and the two limits of these figures: they came from throwaway test files that were deleted rather than committed, so they are reproducible but NOT guarded by the suite; and gno test's GAS line covers a whole test function, so a figure is only a call's own price when the fixture that enables it lives in a separate test. Both halves bit: the refused receipt first measured at 53,123,019 — 174x its real price — because its 64-lot fixture shared its GAS line.
This realm imports p/journal and p/lots, so on any chain the order is p/journal, p/lots, then this realm. The order is stated and the deployment STATE of either import deliberately is not: a sentence about what is deployed is true at signing time at best, and addpkg freezes it — r/assets carries exactly that fossil. The import relation is the durable fact.
Totals are the book's total debits and credits.
gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/inventory.Totals()"