Skip to main content

07-18 How an Index-Price Update Can Leave an Auditable Record

· 11 min read

Even if an oracle network produces a price and the request returns successfully, an index-price update may still be neither final nor auditable. An operator must still show which policy governed the decision, which evidence counted, who authorized it, what state preceded it, and why the new state became final.

To test that boundary, we built a runnable local system rather than only describing an architecture: a four-node Lyquor committee, programmable HTTP data sources, a deterministic decision core, a fault-injection runner, a shared-state Lyquid, and a conventional single-process coordinator using the same rules and scenario inputs.

Our core conclusion from this prototype was that the useful output of this workflow is not an oracle value or certificate alone, but one terminal receipt that binds the evidence, authority, policy snapshot, and resulting state transition.

Multiple observations bound into a terminal receipt before an ordered state update

What We Actually Built

This prototype tested one business scenario: updating a BTC/USD index price. We used locally programmable data sources and did not connect to live exchange APIs, a public network, or real assets. We also did not implement automatic scheduling or production credential management. This let us reproduce different inputs and faults consistently and focus the test on state transitions and authority boundaries rather than uncertainty in external services.

To separate business decisions, Lyquor execution, fault testing, and the baseline implementation, we built four parts that worked together:

  • Decision core. It applied policy to observations, decided whether to accept a price update, and generated the terminal receipt. It did not depend on Lyquor, so both implementations could reuse exactly the same rules.

  • Lyquor implementation. Each node collected an observation from its configured source. The committee aggregated and certified a decision, then wrote the policy, round, price, and receipt to shared state.

  • Automated test environment. Programmable sources simulated normal responses, timeouts, invalid data, and disconnections. The runner opened rounds, retried operations, stopped or restarted nodes, and compared their final states.

  • Single-process coordinator. One operator collected observations, applied the same decision rules, and finalized the result. We ran the same scenarios against it as a fair baseline, separating guarantees provided by the business logic from those added by multi-party certification and shared state.

The diagram below shows the execution path and state-ownership boundaries of the Lyquor prototype:

This design separated node-local information from state that had to remain consistent across the network. Source endpoints, access credentials, raw HTTP responses, and diagnostics remained local. Policy, round identity, previous price, latest price, and terminal receipts were written to shared network state and kept consistent across all nodes. The runner only configured scenarios, initiated operations, and checked results; it could not decide which result became final.

How One Price Update Became Final

A price update passed through four steps: collect data, form a result, obtain confirmation from multiple nodes, and write the result to shared state.

The system first started a new price update and recorded the applicable rules and the price before the update. Four nodes then collected data independently. Whether a request succeeded, a source was unavailable, or a response was malformed, each node recorded and signed what happened. Missing data could not quietly become zero or an unexplained cached value.

The result then had to pass two checks:

CheckQuestionRule
Enough evidenceIs there enough data to decide the price?At least 3 valid results from at least 2 distinct data sources
Enough confirmationMay this result update shared state?At least 3 of the 4 nodes confirm the same result

The system did not wait indefinitely for every node. Once the first signed set of data was sufficient to produce a clear result, confirmation began. To verify that arrival order did not change the outcome, we tested every possible choice of three nodes and different input orders.

Even after three nodes confirmed a result, it was not written immediately. The system checked that the update was still valid, the rules had not changed, the starting price still matched, and the update had not already ended. Only then could it update the latest price and append exactly one receipt. A successful call meant only that the request had been submitted; the runner still queried every node for the latest price and receipt to confirm that they all saw the same state.

What the Terminal Receipt Recorded

The shared record stored the decision context, normalized evidence, and two stages of authorization:

ReceiptRecord
├─ round and terminal outcome
│ ├─ Accepted | Rejected | Expired | Cancelled
│ └─ previous price, decided price, and terminal reason
├─ governing snapshot
│ └─ policy identity/version/hash and committee epoch
├─ observation evidence
│ ├─ accepted node/source/value/time/response-hash summaries
│ └─ excluded summaries with invalid, unavailable, stale, or outlier reason
└─ authorization evidence
├─ proposal signer node IDs
└─ certificate signer node IDs

The terminal states had different meanings:

Terminal stateMeaningPrice effectAuthorization evidence
AcceptedBusiness rules accepted the candidateUpdate latest priceProposal and certificate signers
RejectedSigned evidence proved the business policy could not accept the updateKeep previous priceProposal and certificate signers
ExpiredA certificate could not form within the runner's retry policyKeep previous priceAuthorized operator transaction; no oracle certificate
CancelledAn authorized operator action or policy change closed the roundKeep previous priceAuthorized operator transaction; no oracle certificate

This distinction prevented node unavailability from being reported as bad market data. It also prevented operator-triggered expiry or cancellation from being presented as a committee-certified oracle decision.

What We Put Through the Fault Matrix

We ran 17 scenarios in the four-node environment, then ran the same batch against the coordinator baseline.

Scenario groupWhat we injected or repeatedWhat the runner required
H1Normal values 100, 101, 101, and 102One Accepted receipt and decided price 101
F1-F6Outlier, unavailable source, stale source, unreachable quorum, missing nodes, and excessive price jumpCorrect accepted/rejected/expired branch and no unintended price change
F7-F9Duplicate certified call, old-round callback, and policy-update raceExisting terminal state and receipt remain unchanged
F10-F11Initial proposer failure and node restart after finalizationSurviving nodes finalize; restarted node catches up without duplication
F12 variantsInvalid JSON and integer overflowInvalid evidence is explicit and excluded without corrupting the round
L1All four nodes return the same but incorrect price, 120The system still accepts 120 and explicitly reports that node agreement cannot detect a shared error
C20Twenty consecutive normal rounds in one deploymentMonotonic round IDs, previous-price chain, ordered receipts, and convergence after every round

Every target scenario checked the expected terminal state and reason, the expected latest price, exactly one receipt for the target round, the expected signer evidence, and equal authoritative state hashes across all observed or surviving nodes. The batch passed those assertions.

Several failures clarified the design more than the happy path did. Enough signed Unavailable evidence could prove that the business quorum was unreachable and produce a certified Rejected result. By contrast, stopping two nodes produced too little evidence to form a certificate; the round stayed open until an authorized Expired transition. Replaying the same certified decision, delivering a decision from an old round, or running against an obsolete policy produced neither another price change nor another receipt. A restarted node converged on the accepted state without duplicating history.

What the Single-Process Coordinator Comparison Showed

We used a single-process coordinator as the baseline. It shared the same decision rules, 17 test scenarios, and result format as the Lyquor prototype, and it passed the same business checks: deciding price updates, rejecting stale or duplicate operations, recovering state after a restart, and producing receipts. These capabilities did not depend on multi-node certification. The main difference was that one operator controlled the coordinator's data collection, decision-making, and state updates, while Lyquor required confirmation from at least three nodes before writing a result. The two implementations also left different audit records.

ComparisonLyquor prototypeSingle-process coordinator
Decision rulesShared deterministic coreThe same deterministic core
Who makes the result finalAt least 3 of 4 nodes confirm before shared state is updatedOne trusted process writes local state
How duplicate writes are preventedChecked against shared stateChecked by the process against local state
Recovery after a failureProposer failover; restarted nodes catch up with shared stateProcess restart and local state reload
Audit recordReceipt plus proposal and certificate signer identitiesReceipt plus operator-controlled records
Components to operateLyquid adapter, four nodes, sequencing backend, and test environmentOne process and one JSON file

For an internal task already owned by one team, the single-process coordinator is usually the more direct design. Storage access control, signed logs, or an append-only audit service may be sufficient. Lyquor's multi-node confirmation and shared state become useful when several parties must jointly decide what may change, or when no operator should be able to rewrite an accepted result alone.

Multi-node confirmation does not prove that the price is correct. Nodes can still confirm a bad result if they share a faulty source, accept a forged source identity, or apply flawed rules. Trust is distributed across data sources, operators, rules, and evidence records rather than removed.

What This Prototype Does Not Prove

Under controlled local conditions, the prototype showed that Lyquor could handle different node-local observations, produce a certified decision and one terminal receipt, prevent replay, fail over to another proposer, and recover state across nodes. It did not validate the economic quality of the price policy.

We did not connect to live exchanges or production infrastructure because we wanted to remove distractions from external data volatility, network conditions, and operational configuration. This kept the validation focused on the core question: could multiple nodes reach one result for a price update, write exactly one receipt, and keep state consistent through failures and restarts? Real-world source quality, public-network operation, production security, and market adoption still require separate validation.

The defensible conclusion is therefore narrower:

Use a single-operator coordinator when one trusted writer is the intended authority.
Use a certified shared-state design when the writer itself must be constrained
and each terminal decision must carry multi-party evidence.

The next question is: which real market operations require joint confirmation and must prevent any one party from changing the result alone? Only by finding those use cases and participants can we judge whether this design deserves further investment.

References