Fix ledger accounting for pool funding and starting balances

Mark truncated hourly totals and cover real economy writes in a regression test.

Co-Authored-By: Codex <[email protected]>
This commit is contained in:
levzzzandCodex committed 2026-11-05 17:11:55 +05:00
1 parent ed1a281c9c
commit 72c0912c7b
2 files changed
+60 -2

No files matched your search

+5 -1
View File
@@ -514,6 +514,7 @@ impl Economy {
let entry = serde_json::json!({
"time": self.now, "kind": kind, "amount": amount,
"to_pool": pool, "pool_before": self.pool(pool), "reason": reason,
"flow": "minted",
});
self.audit.append(&entry)?;
self.pool_add(pool, amount);
@@ -595,7 +596,10 @@ impl Economy {
}
None => {
let start = self.config.starting_balance.clamp(0, MAX_AMOUNT);
let entry = self.entry("open", None, Some(uuid), start, "");
let mut entry = self.entry("open", None, Some(uuid), start, "");
if start > 0 {
entry["flow"] = "minted".into();
}
if self.audit.append(&entry).is_ok() {
self.accounts.accounts.insert(
key,
+55 -1
View File
@@ -52,7 +52,13 @@ pub fn command(
.filter_map(|l| serde_json::from_str::<Value>(l).ok());
let page = |w: Option<&&str>| w.and_then(|p| p.parse::<usize>().ok()).unwrap_or(1).max(1);
let (who, page) = match words[1..] {
["minted"] => return Some(minted(newest, money, now)),
["minted"] => {
let mut out = minted(newest, money, now);
if audit.metadata().is_ok_and(|m| m.len() > TAIL) {
out.insert(1, Out::Reply("Partial totals: only the newest 1 MiB of the ledger was read; older movements may be missing.".into()));
}
return Some(out);
}
[] => (None, 1),
[w] if w.parse::<usize>().is_ok() && find(w).is_none() => (None, page(Some(&w))),
[w, ..] => match find(w) {
@@ -287,6 +293,54 @@ mod tests {
let _ = std::fs::remove_dir_all(d);
}
#[test]
fn minted_includes_pool_funding_and_starting_balances() {
use super::super::smp_economy::{Config, Economy};
let d = dir();
let mut e = Economy::open(
&d,
Config {
starting_balance: 50,
..Config::default()
},
)
.unwrap();
e.now = 1_793_880_000_000;
e.seen(ALEX, "Alex");
e.mint_pool("casino_float", "casino", 100, "the casino's float")
.unwrap();
e.save().unwrap();
let run = || {
command(
&op(),
&d.join("audit.log"),
&find,
&name_of,
&money,
e.now,
"ledger minted",
)
.unwrap()
};
assert!(
run()
.iter()
.any(|o| matches!(o, Out::Reply(s) if s.contains("made 150 coins")))
);
use std::io::Write;
let mut file = std::fs::OpenOptions::new()
.append(true)
.open(d.join("audit.log"))
.unwrap();
file.write_all(&vec![b'\n'; TAIL as usize]).unwrap();
assert!(
run()
.iter()
.any(|o| matches!(o, Out::Reply(s) if s.starts_with("Partial totals:")))
);
let _ = std::fs::remove_dir_all(d);
}
#[test]
fn pools_and_pages_read_as_they_should() {
let d = dir();