Skip to content

HF14: Prediction Markets - #124

Open
On1x wants to merge 144 commits into
masterfrom
pm
Open

HF14: Prediction Markets#124
On1x wants to merge 144 commits into
masterfrom
pm

Conversation

@On1x

@On1x On1x commented Jul 2, 2026

Copy link
Copy Markdown
Member

Summary

Introduces Hardfork 14 (HF14): Prediction Markets — a full on-chain
prediction-market subsystem for the VIZ blockchain, plus the read-only APIs,
wallet bindings, snapshot support, tests and documentation around it.

The feature is hardfork-gated (CHAIN_HARDFORK_14) and preserves the zero-sum
token invariant: prediction markets never mint or burn tokens, current_supply
is untouched, and settlement conserves value across bets, LP and forfeit pools.

What's included

Consensus / chain

  • Core PM protocol operations, objects and evaluators (markets, oracles,
    bets, liquidity, resolution, disputes, leverage) gated behind HF14.
  • Oracle rebuttals on disputes (pm_dispute_oracle_respond), early ban lift
    (pm_unban) and automatic ban expiry (pm_ban_expired virtual op via the
    per-block cron).
  • On-chain resolution statements on markets (decision_url/decision_reason)
    and dispute oracle responses, readable without history scans.
  • v5 chain properties for PM tuning (witness-median), including insurance
    coverage floors for listing (2.5x) and betting (1.5x, advisory).

Plugin / wallet / snapshot

  • prediction_market_api plugin with extensive read APIs: market/oracle/
    dispute queries, category taxonomy + live counts, klines, one-call enriched
    market view, and non-consensus leverage previews (quote/close/convert) that
    reuse the in-node margin math.
  • Wallet remote_node_api bindings for the PM read APIs.
  • Snapshot import support for all HF14 PM objects.

Docs & tests

  • EN + ru + zh-CN documentation (chain properties, plugin API, specification,
    operations, virtual operations) and workflow/integration design docs.
  • Comprehensive test_pm_lifecycle consensus-sim suite covering the full
    market lifecycle, disputes, leverage, bans and settlement invariants.

Notes

  • Base branch: master. Feature branch: pm (16 commits).

On1x added 24 commits June 16, 2026 19:33
…ront-running protection

- Introduce two optional execution modes per bet: batch (mode 1) and commit-reveal (mode 2)
- Preserve instant per-bet execution (mode 0) as default for best UX
- Define global and per-market parameters for configuration and governance control
- Implement batch epochs with unified uniform-price settlement to prevent intra-batch front-running
- Add commit-reveal operations: bet commitment, reveal, penalty for no-reveal with transfer into winners' pool
- Design batch settlement math preserving liquidity provider invariant and fairness via canonical CPMM aggregation
- Add database schema changes for bets, commitments, and market flags supporting new modes and states
- Extend market logs to track batch-related actions: commit, reveal, batch settlement, and forfeits
- Specify layered defenses against front-running including epoch snapshot pricing and min_tokens enforcement
- Define phased rollout plan: batch mode first, then commit-reveal, followed by tiering and client policies
- Document open questions and future improvements like encrypted sealed bids (mode 3) and cancellation policy
…off strategy

- Add new chain_properties versions 4 (hf13) and 5 (hf14 PM) for governance params
- Introduce 40+ Prediction Market consensus parameters including fees, disputes, batch settings, cron budget, lazy pool, and leverage
- Define market fee structure and governance cap rules focusing on oracle fee cap
- Document versioning, median calculation, and validator publishing rules for new params
- Implement leverage fund as sub-allocation of lazy pool free balance with detailed accounting and protocol state transitions
- Present full mathematical leverage model: CPMM/LMSR calculations, cancel values, liquidation thresholds, safety margin, and leverage constraints
- Describe atomic liquidation mechanism ensuring pool protection before opposing bets execute, including cascade logic and cascade loop handling
- Analyze risk types and mitigation: price-movement risk elimination via atomic liquidation, safety margins, and dynamic caps; outcome risk remains inherent
- Provide detailed architecture overview, fund allocation parameters, frontend UI terminology (Boost vs Leverage), and risk analysis
- Outline protocol operations, API endpoints, database schema, pre-calculation and slider logic for leverage positions
- Address MEV considerations for liquidation rebalancing and sandwich attacks with mitigation plans for VIZ DLT implementation
…ion by role

- Add comprehensive README outlining canonical scenarios for normal and disputed resolves
- Document master ledger calculations for payout distributions and zero-sum properties
- Include role-specific subfolders with interaction diagrams and signed/virtual operations
- Provide detailed token flow tables for normal and disputed market outcomes
- Outline leverage mechanics including open, close, liquidation, and settlement steps
- Describe dispute scenarios: disputer wins, loses, and forced auto-close with penalties
- Verify all operations and virtual operations present in code with references
- Add instructions on how to observe states and events via API plugin methods
- Cover edge cases like time penalties, liquidations, and refund mechanics
- Provide an index of workflow document folders by participant role for easy navigation
- Updated fc submodule pointer from 99b5d133 to 5a9d84a1
- Ensured thirdparty dependencies are current and consistent
- Added mermaid package version 11.4.1
- Added vitepress-plugin-mermaid version 2.0.17 for Mermaid integration
- Added multiple new dependencies related to mermaid and diagram rendering
- Included types packages for d3 and related libraries for better type support
- Updated package-lock.json to reflect new dependencies and their versions
- Removed several optional and deprecated dependencies to clean up lock file
- Increase total number of hardforks from 13 to 14
- Introduce hardfork 14 with features for prediction markets (binary CPMM, multi LMSR)
- Add oracles, dispute mechanisms, batch/commit-reveal, and lazy liquidity pools
- Define placeholder activation times for mainnet and testnet
- Use version 4.0.0 for hardfork 14 release candidate
- Add chain_properties_pm median evaluator and integrate into median calculation
- Implement lazy-pool logic for DAO-committee voting weight in committee_processing
- Register PM evaluators for all PM operations in database initialization
- Add core indexes for PM-related objects for consensus and chain state tracking
- Implement PM liquidity settlement, market resolution, leverage liquidation, and recall mechanics
- Add HF14 hardfork initialization including lazy-liquidity pool singleton creation
- Update CMakeLists.txt to include PM source and header files with proper compiler flags
- Enhance database.cpp with PM processing hooks and vote weight adjustments for lazy pool stake
- Provide detailed internal helpers for PM operation including settle market, refund bets, and liquidity allocation
…ive APIs

- Implement prediction_market_api plugin with full lifecycle management
- Provide APIs to query markets, outcomes, bets, positions, and liquidity
- Support account leverage positions and creator ban status retrieval
- Offer oracle info and list oracles with reliability scoring
- Include dispute info and vote tallying with projected verdict calculation
- Record and prune metadata and kline time-series data on block application
- Add support for lazy pool and deposit queries along with chain properties
- Implement metadata parsing and filtered market listing by category and jurisdiction
- Integrate with chain plugin database and handle post-operation kline recording
- Configure plugin with pmm-ttl-days option for metadata retention days
- Setup CMake build configuration for prediction_market_api plugin library
- Introduce functions to import pm_oracle, pm_market, pm_outcome, and pm_dispute objects with
  shared_string member handling
- Add export and import logic for all HF14 PM related indices in snapshot processing
- Clear existing PM objects before importing new ones during database initialization
- Enhance snapshot deserialization to handle absent PM objects in pre-HF14 snapshots
- Log import counts for each PM object type during snapshot loading to aid diagnostics
- Include prediction_market_api plugin in wallet build dependencies
- Add remote_prediction_market_api binding with optional connection handling
- Implement pm_api() accessor for prediction_market_api proxy with assertion
- Introduce prediction market helper methods for oracle registration, update, market creation,
  bet placement, commitment hashing, bet commit/reveal/cancel, liquidity management, market resolution,
  dispute creation/voting/resolution, position transfer, lazy deposit/withdraw, and leverage operations
- Add read API passthrough methods for markets, oracles, bets, positions, liquidity, disputes, lazy pool,
  chain properties, market metadata, and market kline data
- Extend fc::api remote_node_api.hpp with prediction market API message signature class and FC_API definition
- Update wallet.hpp and wallet.cpp with full prediction market API support and method declarations
- Ensure wallet starts normally even if prediction_market_api plugin is unavailable on connected node
- Include prediction_market_api in CMakeLists.txt for vizd program
- Add prediction_market_api header inclusion in main.cpp
- Register prediction_market_api plugin in appbase application initialization code
…ests

- Add tests covering oracle registration after HF14 activation
- Implement full binary market lifecycle: creation, betting, resolution, payout
- Test committee dispute scenario with outcome overturning via voting
- Verify lazy-pool stake contributes to dispute voting weight and quorum
- Ensure external oracle rejection refunds seed liquidity exactly once
- Add bet cancellation scenario reversing CPMM reserves and bets sum
- Adjust consensus_sim harness to support new pm tests and sanitizer flags conditionally
- Expose direct database access in simulated_node for test assertions
- Fix simulated_node block witness field to validator for accuracy in tests
…operties support

- Introduce HF13 distribution epoch length and HF14 prediction markets features in governance docs
- Add detailed median-voted HF14 prediction-market parameters and kill-switch flags explanation
- Add new `prediction_market_api` plugin with extensive JSON-RPC read-only methods for markets, bets,
  oracles, disputes, lazy pool, and governance data access
- Include computed DTOs and charting support for prediction markets with offset-from-newest pagination
- Document prediction market concepts analysis comparing Onix protocol to theoretical models
- Update advanced hardfork and chain properties docs to cover new prediction market functionality
- Introduce readonly JSON-RPC plugin for HF14 prediction markets state access
- Document market-related API methods including markets, outcomes, bets, liquidity, and metadata
- Describe position, leverage, oracle, dispute, lazy pool, and governance methods
- Provide details on kline/time series for market weight history and pagination approach
- Explain computed DTOs representing bets, oracles, votes, and payout structures
- Include example usage and code snippets for API calls and data processing
- Link to relevant protocol operations and chain property documentation

docs(governance): update chain properties with HF13 and PM parameters

- Add chain_properties_hf13 with distribution_epoch_length parameter
- Introduce chain_properties_pm (v5) for ~30 prediction market parameters and kill-switch flags
- Detail all median-voted parameters for oracle, market, batch, dispute, time penalty, lazy pool, leverage, and fairness
- Clarify live kill-switch flags to disable commit-reveal, lazy pool, or leverage without hardfork

docs(advanced): extend hardfork management with HF13 and prediction markets

- Add entries for HF13 epoch length and HF14 prediction markets including CPMM/LMSR, oracles, disputes, commit-reveal, lazy-pool, and chain properties v5

docs(prediction-markets): add comprehensive analysis of conceptual mapping of Onix PM protocol

- Provide detailed table comparing 90 theoretical prediction market concepts against VIZ Onix on-chain implementation
- Categorize concepts as solved, inherent, not needed, partial/roadmap, client layer, or open risks
- Discuss information theory, mechanism design, liquidity and trading aspects in depth
- Highlight Onix innovations: risk-free LP, CPMM binary, LMSR multi, commit-reveal batch bets, optional leverage subsystem, lazy pool governance voting weight
- Explain architectural decisions omitting orderbooks, combinatorial markets, and peer prediction
- Updated chainbase submodule commit from 39ab2c2 to d429230
- Ensures third-party library is aligned with latest upstream changes
…cycle, coverage floors and thin-client APIs

Consensus (HF14 follow-up ops, appended so operation indices stay stable):
- pm_dispute_oracle_respond (op 22): the market oracle posts a public rebuttal
  onto an open dispute; stored on the dispute object (public-hearing model),
  allowed only while open and within oracle_response_deadline, re-post overwrites.
- pm_unban (op 23): the resolver that imposed an account-mode ban (banned_by)
  may lift it early; sets banned_until to epoch and clears banned_by.
- pm_ban_expired (virtual): the per-block cron sweeps temporary oracle/creator
  bans at banned_until, clears them and emits the lift for history/indexers.

On-chain state:
- pm_market gains decision_url/decision_reason — the oracle's resolution
  statement stored on-chain (set by pm_resolve_market / pm_no_contest reason),
  readable via get_market with no history scan.
- pm_resolve_market_operation gains decision_reason (reflected on the wire).
- pm_dispute gains oracle_response/oracle_response_time.
- pm_oracle and pm_creator_ban gain banned_by; pm_creator_ban gains a
  by_ban_expiry index so the cron sweeps expired bans oldest-first (cleared
  bans sort into the 0-bucket, permanent bans past now, both skipped).

Chain properties (witness-median tunables):
- pm_listing_min_coverage_percent (2.5x): hide under-insured markets from the
  default catalog (enforced by the API plugin, revealed via show_risky).
- pm_betting_min_coverage_percent (1.5x, advisory): client risk-confirm
  threshold; validated betting <= listing.

Thin-client read APIs (non-consensus, for the viz-js client):
- get_leverage_quote / get_leverage_close_preview / get_leverage_convert_preview
  reuse the frozen pm::leverage math to mirror the open/close/convert evaluators.
- get_market_categories (taxonomy + live counts), get_market_full (one-call
  enriched, account-scoped), get_lazy_allocations / get_market_lazy_allocation.
- Wallet remote_node_api bindings for all of the above.

Docs & tests:
- EN + ru + zh-CN docs updated (chain-properties, prediction-market-api,
  specification, operations overview/prediction-markets/validators,
  virtual-operations); library-integration spec + thin-client plan added.
- test_pm_lifecycle: cases #58-#63 cover oracle rebuttal + decision_reason,
  no-contest rationale, manual unban and its guards, and ban auto-expiry vop.
…throughs

The cli_wallet build failed because remote_prediction_market_api and the
wallet_api pm_get_*/pm_list_* methods returned the node's typed objects. Those
chainbase state objects (pm_market_object, pm_bet_object, ...) and the API DTOs
embedding them are not default-constructible (deleted default ctor / shared_string
members require a segment manager), so fc::api's client deserializer (T tmp;
var.as<T>()) could not instantiate them.

Return fc::variant instead: the node already emits fully-formed JSON and cli_wallet
prints the variant unchanged, so the read surface is identical.
…te_node_api

cli_wallet failed to compile because remote_node_api.hpp pulled in
<graphene/plugins/prediction_market_api/prediction_market_api.hpp> transitively,
but programs/cli_wallet has no include path to that plugin. After the read
pass-throughs switched to fc::variant, the header (and the pmapi alias) are no
longer referenced anywhere in the wallet, so remove them. graphene_wallet still
builds; the public wallet header no longer leaks a plugin-only dependency.
…LP fee

Add two HF14 median-voted consensus parameters and their enforcement:

- pm_oracle_accept_window_sec (default 1h): a pending market the named
  oracle never accepts nor rejects is voided by the per-block cron once
  now >= created_time + window. The creators seed liquidity is refunded
  (return_liquidity); the non-refundable creation fee stays with the DAO
  fund. Tracked via a new pm_market_object.accept_deadline field and a
  by_accept_deadline index; emits the new pm_market_expired virtual op
  (op-id 101, appended last in the operation variant to keep tags stable).

- pm_lazy_min_liquidity_fee_percent (default 2%): the lazy pool skips
  markets whose liquidity_fee_percent is below this reward floor, so it
  never subsidizes depth it is not paid enough to provide.

Wired into calc_median and chain_properties_pm::validate().
… fee

Cover the new pm_oracle_accept_window_sec / pm_market_expired lifecycle
and the pm_lazy_min_liquidity_fee_percent reward-floor gate across:

- EN docs (chain-properties, specification, operations, virtual-operations)
- RU and zh-CN localizations (@l10n) at full parity with the EN source
- library integration spec (delta section + property/vop tables, op-id 101)
  and thin-client plan
- Onix paper EN + RU (state machine, acceptance flow, lazy-pool gate);
  PDFs rebuilt via pandoc + xelatex (EN 30pp, RU 32pp, 0 missing glyphs).
- Added warning that the live protocol uses basis points (bp), not permille (‰)
- Explained the conversion from original PHP prototype’s permille to bp in on-chain code
- Specified that all fee fields (oracle_fee_percent, creator_fee_percent, liquidity_fee_percent, etc.) use bp (10000 = 100%)
- Highlighted the use of `fromBP` parser for fee fields and rejection of markets exceeding fee sum 10000
- Warned that using deprecated `fromPermille` leads to incorrect fee values, off by a factor of 10
…line

The ?: between time_point_sec() and (now + fc::seconds(...)) has no common
type — the latter yields fc::time_point, and each type converts to the other,
which GCC rejects as ambiguous. Wrap the second branch in an explicit
time_point_sec(), matching the copy-init conversion already used for the
reveal/dispute deadlines in this file.
…erations

The generic impacted-account visitor only collected signing authorities, so
prediction-market events were missing from the histories of accounts that did
not sign them:

- signed ops lost their counterparties (pm_create_market -> oracle,
  pm_transfer_position -> recipient, pm_unban -> target, oracle auto-accept
  whitelist);
- virtual ops carry no authority at all, so payouts, forfeits, liquidations,
  oracle penalties, market accept/expire and ban expiry were invisible to the
  affected users.

Add explicit get_impacted_account_visitor overloads for the PM user and
virtual operations, inserting every account field they carry. Market-only
virtual ops that reference a market by id but carry no account name
(pm_batch_settle / pm_dispute_finalize / pm_dispute_auto_close /
pm_lazy_recall) are intentionally left to the generic handler.
@On1x

On1x commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

Addressed the account-history review blocker in 3eebfd6: added explicit get_impacted_account_visitor overloads for the PM user and virtual operations (counterparties on signed ops + all account fields on virtual ops, which have no signing authority). Market-only virtual ops that carry no account name (pm_batch_settle / pm_dispute_finalize / pm_dispute_auto_close / pm_lazy_recall) are intentionally left to the generic handler.

…, per-node)

The free-form `metadata` JSON was stored in the consensus `pm_market_object`
(shared_string) permanently — never pruned — even though consensus never reads
it (it is written once and only parsed off-chain by the prediction_market_api
plugin). That let a market permanently bloat every node's chainbase/shared
memory with unbounded, unvalidated data.

Move it out of consensus entirely:

- pm_market_object: drop the `metadata` field (member, ctor, FC_REFLECT). The
  operation `pm_create_market_operation.metadata` is unchanged — clients still
  send it and it lives in the block log, exactly like custom_operation.json.
- pm_create_market_evaluator: stop persisting metadata into state.
- prediction_market_api: ingest metadata off-chain from the create operation
  (post_apply_operation) into the existing prunable pm_market_meta_object,
  instead of reading it back from the consensus object in on_block.
- snapshot: drop the metadata import/export for pm_market (auto-excluded from
  the reflected dump; import of legacy snapshots ignores the field).

Because it is now non-consensus, each node prunes it on its own schedule via
--pmm-ttl-days (default lowered 7 -> 5; 0 keeps it forever for archival nodes).
No consensus length/UTF-8 cap is needed — the blob no longer touches state.
@On1x

On1x commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

Addressed the unbounded on-chain metadata review blocker in 5479b9a (design agreed with maintainer): the free-form pm_create_market.metadata is no longer persisted in the consensus pm_market_object at all — consensus never reads it, so it moved off-chain into the prediction_market_api plugin, ingested from the create operation into the already-prunable pm_market_meta_object. Consequences: no permanent chainbase bloat, no consensus length/UTF-8 cap needed (the blob never touches state; it lives in the block log like custom_operation.json), and each node prunes it on its own schedule via --pmm-ttl-days (default lowered 7→5; 0 = keep forever for archival nodes). Note: plugin metadata index is now built from the operation stream, so enabling the plugin on an existing chain requires a replay to backfill (standard for plugin indexes). Not compiled locally (no build env here) — CI/build to confirm.

…xed retention

A resolved+settled market (status 3, payout_status 3) is immutable — no betting,
dispute, resolve or payout can touch it again; it only lingered in chainbase
"for history", growing shared-memory state without bound.

process_pm_markets() now GCs such markets and their whole object cluster
(outcomes, bets, liquidity, commits, dispute votes, leverage positions, the
dispute and lazy-allocation rows) once they have been closed for a FIXED protocol
constant PM_CLOSED_MARKET_RETENTION_SEC = 5 days (measured from
result_expiration + dispute grace). The retention is hardcoded and identical on
every node, so pruning is fully deterministic: every node deletes exactly the
same markets at the same block, keeping shared-memory state and snapshots in
lock-step network-wide (a node syncing from a snapshot ends up with the same
market set as everyone else). Work is bounded by the existing per-block cap.

Only status-3/payout-3 markets are collected; disputed (payout_status 2) and
never-settled markets are left untouched. Nothing holds an id-reference to a
settled market, so there are no dangling references after removal.
@On1x

On1x commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

Follow-up (31e8aab): resolved markets are now garbage-collected from consensus state. A settled market (status 3 / payout_status 3) is immutable, so process_pm_markets() reclaims it and its whole object cluster (outcomes/bets/liquidity/commits/dispute-votes/leverage/dispute/lazy-allocation) after a FIXED PM_CLOSED_MARKET_RETENTION_SEC = 5 days (from result_expiration + grace). Retention is a hardcoded protocol constant — identical on every node — so deletion is fully deterministic: all nodes prune the same markets at the same block and snapshots stay in lock-step (a node syncing from a snapshot gets the same market set as everyone else). Bounded by the existing per-block cap; only status-3/payout-3 markets are touched (disputed = payout_status 2 are excluded). Not compiled locally (no build env) — needs CI + ideally a consensus_sim case.

…ones

Extend the market garbage collector to reclaim ANY dead market a fixed 5 days
after it becomes terminal — not only resolved+paid ones. A market is dead once
nothing can act on it: resolved and paid out, void/no-contest, oracle-rejected,
or the oracle never accepted and the accept window expired.

To anchor the retention on the actual moment of death (rather than the declared
result_expiration), add a `finalized_time` field to pm_market_object, set to the
head-block time at every terminal transition:
  - oracle rejects the market (status -1)
  - accept window expires, market voided (pm_market_expired)
  - oracle misses resolution, refund (pm_oracle_missed_penalty)
  - dispute auto-close refund
  - settlement / auto-payout (covers resolved, no-contest, post-dispute)

A new by_finalized index (finalized_time, id) lets process_pm_markets() sweep
terminal markets in time order, skipping the finalized_time==0 live bucket, and
delete each cluster PM_CLOSED_MARKET_RETENTION_SEC (5 days) later. Retention is a
fixed protocol constant identical on every node, so pruning stays deterministic
and snapshots identical network-wide. Snapshot import reads finalized_time when
present. Work stays bounded by the per-block cap.
On1x added 2 commits August 10, 2026 12:28
test(pm): early-exit headroom-clamp conservation replay (PR #124 review round 4)
Every terminal path that can hold deferred claims already clears them:
settle_market consumes them, refund_all_bets purges them on void/no-contest/
missed-resolution, and accept-expired markets are pending (never had bets).
This drop is a defensive net so no overlooked or future finalize path can
leave a claim row dangling in shared memory / drift the snapshot. Mirrors
the other per-market drop_range calls (by_claim_market is composite
(market,id)).
…ims (PR #124)

Two CI-wired consensus_sim cases in test_pm_lifecycle.cpp, driven through the
REAL evaluators + database + settlement cron (not the standalone replay math):

- supply_conserved_binary_lifecycle: a full binary-market lifecycle (create,
  extra LP add, unequal two-sided bets, oracle resolve, parimutuel settle with
  a 6% fee schedule) and asserts current_supply grows by EXACTLY block inflation
  (CHAIN_DIGITAL_ASSET_ISSUED_PER_BLOCK x blocks). This is the PR's core safety
  claim ("PM never mints or burns; current_supply untouched") — the 51-case
  suite checks local balances and the pure compute_settlement struct, but never
  asserted global chain conservation end-to-end.

- early_exit_deferred_claim_paid_from_bucket: the F1/steemit#300 early-exit deferred-
  claim path had ZERO integration coverage (grep deferred/early_exit/claim_paid
  across tests/ = 0). Opens a leveraged position, a whale bets the same side to
  push it into profit, betting closes so the settlement force-close records the
  bettor residual as an outcome-contingent deferred claim (asserts it is DEFERRED,
  not refunded), then resolves the winning side and asserts the claim pays from
  the bounded early-exit bucket and every claim row is consumed at settlement.

Both verified GREEN against pm head (built the full chain locally): "Running 2
test cases... *** No errors detected".
@chiliec

chiliec commented Aug 10, 2026

Copy link
Copy Markdown
Member

Follow-up on the round-4 items: the two integration gaps are now covered in #143 (CI-wired consensus_sim cases, on top of the t15 replay merged in #142):

  • supply_conserved_binary_lifecycle — asserts current_supply moves by exactly block inflation across a full create→bet→resolve→settle lifecycle (the zero-sum backstop the suite lacked; supply_conserved() was a 0×-invoked stub).
  • early_exit_deferred_claim_paid_from_bucket — drives the F1/#300 path end-to-end (leverage open → same-side whale → profitable force-close records a deferred claim → winning-side settlement pays it from the bucket).

Both built against the full chain and run green (Running 2 test cases... *** No errors detected). The gc_market deferred-claim-index note and B8 timestamp item from the round-4 comment are still open.

On1x and others added 15 commits August 10, 2026 16:33
…erage

test(pm): consensus_sim zero-sum supply + early-exit deferred-claim coverage (PR #124)
…w.sh typo

- Remove .qoder/ (Qoder AI tool scratch: agents, plans, repowiki, research)
  from version control and ignore the whole dir. 168 tracked files, ~6.6MB
  of non-source content. Replaces the narrower .qoder/logs/* rule.
- Prune .gitignore rules for build targets that no longer exist:
  js_operation_serializer, vizd/test, delayed_node, size_checker,
  inflation_model, and tests/{app,chain_bench,chain,plugin,intense,performance}_test.
  Kept live-target rules (cli_wallet, vizd, cat-parts, get_dev_key).
- Rename build_mingv.sh -> build_mingw.sh. documentation/building.md already
  instructs users to copy and run 'build_mingw.sh', which did not exist due to
  the typo.
The repo carried two parallel doc trees: the old flat documentation/ (8
files) and the current VitePress docs/ tree (67 files, organized by topic,
EN/RU/ZH). PLAN.md already designates docs/ as the consolidated target and
lists documentation/* only as legacy source material.

Every topic in documentation/ is superseded by larger, current pages in docs/
(building, testing, snapshot, webserver, debug_node, plugin, api). Several old
pages were also stale — api_notes.md and plugin.md still referenced the
fictional hello_api / external_plugins / example_plugins layout that the tech
debt audit flagged as nonexistent.

Changes:
- Migrate the one piece of unique content — the testnet bootstrap details
  (CHAIN_INITIATOR_NAME/committee/test-user keys, snapshot.json mechanism) —
  from documentation/testnet.md into docs/node/docker.md under a new
  'Testnet bootstrap' subsection.
- Remove the 8-file documentation/ tree.
- Repoint inbound references: README.md (building + testnet links),
  install-deps-linux.sh (package-list hint).
- Update paths-ignore in docker-main, docker-pr-build, and windows-release
  workflows from 'documentation/**' to 'docs/**' + '@l10n/**' so doc-only
  changes still skip Docker/Windows builds (the docs tree has .mts/.js files
  that '**.md' alone wouldn't catch).
… comments

Three low-risk CMake cleanups; no source logic touched.

- Default CMAKE_BUILD_TYPE to Release when unset on single-config generators.
  Previously a bare `cmake ..` (or an IDE not passing -DCMAKE_BUILD_TYPE)
  configured with empty optimization flags -> an unoptimized node. Guarded on
  GENERATOR_IS_MULTI_CONFIG so MSVC / Ninja Multi-Config are untouched (they
  pick the config at build time). build-linux.sh/build-mac.sh always pass a
  type, so their behavior is unchanged.

- Build cat-parts only on MSVC/MinGW. The hardfork concatenator is invoked
  solely under if(MSVC OR MINGW) in libraries/chain/CMakeLists.txt; every other
  platform uses cat_parts.py. Linux/macOS builds were compiling and linking a
  tool they never run. The only $<TARGET_FILE:cat-parts> reference is inside
  the matching MSVC/MinGW guard, so non-Windows builds are unaffected.

- Translate five leftover Romanian comments (root CMakeLists.txt x2,
  libraries/chain/CMakeLists.txt x3) to English.
…Z_LIBRARY_TYPE

Every library and plugin CMakeLists carried the full source + header list twice:
once under add_library(<name> SHARED ...) and once under add_library(<name>
STATIC ...), inside an if(BUILD_SHARED_LIBRARIES)/else()/endif(). 26 files, with
the source list duplicated in each — a standing drift hazard.

Introduce a single VIZ_LIBRARY_TYPE variable at root scope (SHARED when
BUILD_SHARED_LIBRARIES is ON, STATIC otherwise) and replace each dual-branch
block with one add_library(<name> ${VIZ_LIBRARY_TYPE} ...). Net -220 lines.

The duplication had already drifted in libraries/chain: the SHARED branch listed
invite_evaluator.cpp twice and was missing include/graphene/chain/invite_objects.hpp,
while the STATIC branch was correct. Collapsing onto the STATIC list fixes both.

Verification:
- For all 26 targets the collapsed source/header set is byte-set-identical to the
  original STATIC branch (which is what the default build, Docker images, and CI
  all use via -DBUILD_SHARED_LIBRARIES=FALSE), so static-build behavior is
  unchanged.
- Configured a minimal reproduction with real cmake covering both the
  explicit-source pattern (chain/time) and the ${CURRENT_TARGET_SOURCES} plugin
  pattern: BUILD_SHARED_LIBRARIES=OFF yields STATIC_LIBRARY targets, ON yields
  SHARED_LIBRARY targets, matching the previous if/else semantics. graphene::
  ALIAS targets still resolve.

No source code touched; BUILD_SHARED_LIBRARIES option and its default (FALSE) are
unchanged. build-mac.sh (which defaults SHARED_LIBS=ON) keeps a working shared
path — now with the chain drift fixed.
Introduces target_precompile_headers for the three heaviest libraries, gated
behind a new ENABLE_PCH option (default OFF). CMake 3.16+ (already the minimum)
supports PCH natively; nothing used it before, so every translation unit
re-parsed the same large Boost.MultiIndex / FC reflection / std headers.

Each library gets a pch.hpp listing only *stable* third-party headers, chosen
from an include-frequency scan of that library's sources:
- chain    -> Boost.MultiIndex containers + FC serialization/reflection
- protocol -> FC reflection / static_variant + operation machinery
- wallet   -> Boost.MultiIndex, Boost string/range, FC api

Project headers are deliberately excluded: a churning header in the PCH would
force a full-library rebuild on every edit and defeat the purpose.

Default OFF so it cannot affect existing or CI builds until a maintainer opts
in and measures. ccache interaction is handled: when ENABLE_PCH is ON and
ccache is active but CCACHE_SLOPPINESS lacks pch_defines,time_macros, CMake
emits a warning (ccache otherwise disables its own cache for PCH TUs).

Validation (no Boost/submodules available in my env, so full tree build not run):
- Real cmake executes the ENABLE_PCH block correctly: OFF prints a silent
  status, ON prints status + the ccache warning only when sloppiness is unset.
- The target_precompile_headers wiring itself was proven on a standalone cmake
  project mimicking the same shape (24 TUs sharing a heavy header set): a
  single-threaded build went 16.84s -> 5.73s (2.9x) with a real .pch artifact
  produced. std headers stand in for Boost here; Boost.MultiIndex/FC parse
  costs are at least as high, so this is a conservative proxy.

Usage:
  cmake -S . -B build -DENABLE_PCH=ON
  # if using ccache:
  export CCACHE_SLOPPINESS=pch_defines,time_macros
The prior TECH_DEBT_AUDIT.md (2026-05-01, refreshed 2026-06-17) had gone stale
against the ~2 months of changes since. Concrete drift: it claimed 'zero tests /
no tests/ directory' (a consensus_sim harness now exists with 32 test cases),
referenced libraries/network/node.cpp (renamed to dlt_p2p_node.cpp in the DLT
redesign), located mongo_db in plugins/ (moved to examples-plugins/), and
audited the documentation/ tree (removed by an open PR). 23 of its 51 findings
referenced files that no longer exist or have moved.

Replace it with a from-scratch re-audit against master @ d4fe333, using fresh
D### numbering (old F### IDs not carried forward). Key changes vs the old audit:

- New top finding (D001): tests EXIST but are not enforced. consensus_sim is a
  real ASAN/UBSAN deterministic multi-node harness (32 BOOST_AUTO_TEST_CASE),
  but BUILD_CONSENSUS_TESTS defaults OFF and no CI workflow builds or runs it.
  This replaces the old (now false) 'zero tests' finding.
- God-file findings refreshed with current LOC and 6-month churn: database.cpp
  (7,991 / 130 commits), snapshot/plugin.cpp (4,657 / 125), dlt_p2p_node.cpp
  (4,380 / 125).
- New finding: using namespace std; in account_by_key_objects.hpp (a public
  header the old audit missed); 51 using-namespace-in-header total.
- Cross-references the six open cleanup/refactor PRs (#144-#149) against the
  findings they address (D010/D011/D012/D013/D002/D017/D018).
- Drops all findings that referenced deleted/renamed files.
- Verified counts: 32 test cases across 10 scenario files, 6 active usings in
  remote_node_api.hpp, 132 has_hardfork conditionals, 19 TODO markers.
…_mingw.sh typo

# Conflicts:
#	.qoder/docs/onix-protocol-paper-ru.md
#	.qoder/docs/onix-protocol-paper-ru.pdf
#	.qoder/docs/onix-protocol-paper.md
#	.qoder/docs/onix-protocol-paper.pdf
…RY_TYPE

# Conflicts:
#	libraries/chain/CMakeLists.txt
…cpp (pm, HF14-preserving)

Native re-implementation of #149 on the pm branch. #149 as authored is based on
master and its extracted database_hardfork.cpp does NOT contain pm's HF14 wiring
(init_hardforks registers CHAIN_HARDFORK_14 time/version; apply_hardfork's
CHAIN_HARDFORK_14 case instantiates the pm_lazy_pool_object singleton). Merging
#149 verbatim would have silently dropped that consensus code.

Instead this moves pm's OWN hardfork functions (init_hardforks,
reset_virtual_schedule_time, process_hardforks, has_hardfork, set_hardfork,
apply_hardfork) verbatim from database.cpp into database_hardfork.cpp. Verified
pure move: the 987 moved lines are byte-identical (diff clean). Added
pm_objects.hpp to the mirrored include set (HF14 apply case needs
pm_lazy_pool_object). Both TUs pass single-TU -fsyntax-only.
On1x added 2 commits August 11, 2026 14:36
Bump the HF14 code default for pm_leverage_funding_rate_ppm_per_day from 50 ppm
(~0.005%/day, ~1.8%/yr) to 100 ppm (~0.01%/day, ~3.65%/yr) so a fresh mainnet
enables leverage with a stronger lazy-pool funding compensation out of the box.
Kill-switch / other leverage params unchanged; median-voted on running chains.
Exposes the by_commit_account index so a client can look up its own commit-reveal
commitments (pm_commit_object) and their on-chain commit_id. pm_reveal_bet needs the
numeric commit_id, which no API previously returned — the Forecaster reveal step had to
ask the user to supply it by hand (a dead-end, no way to discover it). Default returns
only open (status==0, revealable) commits; open_only=false includes revealed/forfeited.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants