Documentation
¶
Overview ¶
Package bal is the conservation primitive (@B): an append-only double-entry journal over bounded accounts, where conservation is an arithmetic identity — every transfer writes two signed entries (−a, +a) in one transaction, so the system total always equals the sum of its boundary accounts.
Identity (@B09a): the substrate-preferred two-identity split. The external account_id is a namespaced STRING at every boundary — no numeric width exists to truncate, so the /ts id-boundary bug class is structurally impossible here (@C04d the strong way). The internal account key is a dense uint32, engine-internal, fixed-width codec, never on any wire struct.
Numerics (@B04): amounts are int64 minor units through the account's scale. No float64 touches an amount anywhere, ever — ParseAmount is the only sanctioned string→amount crossing.
Index ¶
- func EncodeAccountKey(k AccountKey) [4]byte
- func FormatAmount(v int64, scale uint8) string
- func ParseAmount(s string, scale uint8) (int64, error)
- func ValidateAccountID(id string) error
- type AccountDef
- type AccountKey
- type AmountScaleError
- type BoundsError
- type ChainBreak
- type NotPostableError
- type Store
- func (s *Store) Balance(ctx context.Context, accountID string) (value int64, version int64, err error)
- func (s *Store) ChainOracle() chronicle.RebuildOracle
- func (s *Store) DefineAccount(ctx context.Context, def AccountDef) (AccountKey, error)
- func (s *Store) GlobalFoldOracle() chronicle.RebuildOracle
- func (s *Store) Init(ctx context.Context) error
- func (s *Store) Transfer(ctx context.Context, transferID, from, to string, amount int64, memo string, ...) error
- func (s *Store) VerifyChains(ctx context.Context) ([]ChainBreak, error)
- type UnknownAccountError
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func EncodeAccountKey ¶
func EncodeAccountKey(k AccountKey) [4]byte
EncodeAccountKey writes the key with an explicit fixed-width codec (4 bytes, big-endian) — the sanctioned byte crossing.
func FormatAmount ¶
FormatAmount renders minor units back to the canonical decimal string at the account's scale.
func ParseAmount ¶
ParseAmount converts a decimal string to int64 minor units under the account's scale — the ONLY string→amount crossing. It refuses anything that is not an exact integer of minor units at that scale (XOLU-BAL004 territory), and never passes through float64.
func ValidateAccountID ¶
ValidateAccountID enforces the external-id shape: non-empty, ≤256, no whitespace; '/' and ':' and '.' are the namespace vocabulary.
Types ¶
type AccountDef ¶
type AccountDef struct {
ID string // namespaced external id, e.g. "warehouse:A/widget" or "1.1.9.10"
Unit string // "EUR", "widget", "gram"
Scale uint8 // decimal places of the minor unit
Floor int64 // minimum balance (default 0)
Ceiling *int64 // optional maximum balance
Postable bool // only leaf (imputable) accounts accept entries (@B03a)
}
AccountDef defines an account (@B03, @B03a).
type AccountKey ¶
type AccountKey uint32
AccountKey is the engine-internal dense identity: uint32, the wave-1 per-primitive width. It never appears in JSON.
const MaxAccountKey AccountKey = 0xFFFFFFFF
MaxAccountKey is the codec ceiling; it fits uint32 exactly.
func DecodeAccountKey ¶
func DecodeAccountKey(b [4]byte) AccountKey
DecodeAccountKey reads the fixed-width codec back, losslessly across the full uint32 span.
type AmountScaleError ¶
type AmountScaleError struct{ Detail string }
func (*AmountScaleError) Error ¶
func (e *AmountScaleError) Error() string
type BoundsError ¶
func (*BoundsError) Error ¶
func (e *BoundsError) Error() string
type ChainBreak ¶
ChainBreak localises a violation of the per-account arithmetic chain.
type NotPostableError ¶
type NotPostableError struct{ AccountID string }
func (*NotPostableError) Error ¶
func (e *NotPostableError) Error() string
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is bal's SQL plane (@B05): the append-only journal and the balances table, maintained in the same transaction as each entry. The bounds guard's input commits-or-aborts with the entry it guards (@C04a); no rollup is ever consulted by a guard.
The db handle must carry the house SQLite contract: WAL + busy_timeout + _txlock=immediate. Immediate matters specifically for bal: Transfer reads account rows before its first UPDATE, and a deferred transaction upgrading read→write under WAL fails SQLITE_BUSY without consulting the busy handler (snapshot invalidation). Taking the write lock at BEGIN makes contending transfers queue under busy_timeout — the serialised-writer behaviour the admission guard's correctness argument assumes.
func (*Store) Balance ¶
func (s *Store) Balance(ctx context.Context, accountID string) (value int64, version int64, err error)
Balance returns the current balance and version for an account.
func (*Store) ChainOracle ¶
func (s *Store) ChainOracle() chronicle.RebuildOracle
ChainOracle wraps VerifyChains as a rebuild oracle for iolu db check.
func (*Store) DefineAccount ¶
func (s *Store) DefineAccount(ctx context.Context, def AccountDef) (AccountKey, error)
DefineAccount creates an account and its zero balance row. The internal key is allocated densely (MAX+1) inside the transaction.
func (*Store) GlobalFoldOracle ¶
func (s *Store) GlobalFoldOracle() chronicle.RebuildOracle
GlobalFoldOracle: SELECT SUM per account from the journal, compared row-for-row against balances — derive(journal) == current, exactly.
func (*Store) Init ¶
Init creates the bal tables. Idempotent. The journal's `state` column (default 'committed') leaves room for holds (@B10) without migration.
func (*Store) Transfer ¶
func (s *Store) Transfer(ctx context.Context, transferID, from, to string, amount int64, memo string, at time.Time) error
Transfer moves amount minor units from `from` to `to` as two signed journal entries (−a, +a) in ONE transaction (@B03). Admission is the house CAS discipline (@B06, T-34): the decision lives inside each UPDATE's predicate, rows-affected is the verdict — never read-decide-write. The chain triple is captured from the same guarded statement via RETURNING.
func (*Store) VerifyChains ¶
func (s *Store) VerifyChains(ctx context.Context) ([]ChainBreak, error)
VerifyChains is the local verifier (@B08): per account, every entry satisfies previous+amount=current, entryₙ.previous = entryₙ₋₁.current, and versions are contiguous. A lost, duplicated, or altered entry is not merely detected but LOCALISED to the exact break.
type UnknownAccountError ¶
type UnknownAccountError struct{ AccountID string }
func (*UnknownAccountError) Error ¶
func (e *UnknownAccountError) Error() string