> ## Documentation Index
> Fetch the complete documentation index at: https://docs.metalntwx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Oracle reports

> Certified report fields, verifier configuration, and signature encoding

A certified oracle report contains observations and a signature from the
required number of validators. `OracleReports` verifies that signature against
its configured validator keys and returns the report's items. The consuming
contract defines which items it accepts and its limits for age, confidence,
flags, and repeated use. [Use oracle data](https://docs.metalntwx.com/build/data-and-signatures/use-oracle-data.md#validate-a-value)
describes the value acceptance checks.

## Deployment configuration

The network operator supplies the `OracleReports` deployment address and
configuration for each validator set. The constructor permanently fixes that
set and the network identity. A changed validator set requires a new
deployment and retirement of the old verifier.

| Constructor input | Encoding |
| - | - |
| `compressedKeys` | Validators' 48-byte compressed BLS12-381 G1 public keys in strictly ascending byte order |
| `uncompressedKeys` | The same keys in the same order, each a 128-byte EIP-2537 G1 point |
| `proofsOfPossession` | One 256-byte EIP-2537 G2 signature per key, signed over that key's compressed bytes |
| `reportNamespace` | `UTF8("metal-oracle-report-v1") ∥ uint256_be(chainId) ∥ genesisHash` |
| `retireHeight_` | `uint64`: last report height this validator set may certify, inclusive |
| `retirer_` | Address allowed to lower the retirement height; zero makes the deployment-time bound final |

A proof of possession demonstrates that the validator holds the private key
for its public key. Its signature uses the domain separation tag
`BLS_POP_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_`. The constructor checks the key
encodings and possession proofs.

A verifier accepts reports only through `retireHeight`. When the validator set
changes, retire the old verifier so its keys cannot certify later reports. The
configured `retirer` can call `retire(newRetireHeight)` to lower the bound. The
new height must be strictly lower; it can never be extended. A successful call
emits `RetireHeightLowered(uint64 retireHeight)`.

## Report numbering

`MetalOracle` at `0x00000000000000000000000000000000000000fd` exposes the read
function `reportBaseMs() → uint64`. It returns the starting Unix timestamp in
milliseconds for certified report numbering. Report sequence numbers count
one-second intervals from this timestamp. A return value of zero means certified
report publication is disabled.

## Report RPC

`metal_getOracleReport` returns the latest retained certified report when
called with an empty parameter array. A single JSON integer parameter selects
a report by its sequence number, named `height`. The result is `null` when no
matching report is retained. Each node retains up to 64 certified reports.

| Response field | Meaning |
| - | - |
| `height` | Report sequence number, equal to the encoded report's `round` |
| `report` | ABI-encoded report bytes |
| `digest` | `keccak256(report)` |
| `signers` | Validator indices in the configured key order |
| `signature` | Aggregate signature as a 96-byte compressed BLS12-381 G2 point |
| `certificate` | Certificate in the aggregation service's encoding |
| `items` | Decoded report items, also contained in `report` |

`verifyReport` takes a signer bitmap and an EIP-2537 signature. The RPC exposes
`signers` and `signature` separately for that conversion. The `certificate`
field contains the encoded certificate for clients that use its native format.

## Report format

The report bytes are ABI-encoded as `(uint64 round, ReportItem[] items)`.
`round` is the report sequence number returned as `height` by the RPC.
Each `ReportItem` has these fields in order:

| Field | Type | Meaning |
| - | - | - |
| `itemId` | `bytes32` | Catalog item identifier |
| `value` | `uint256` | Aggregated value at the catalog's decimal scale |
| `conf` | `uint256` | Confidence half-width at the same scale as `value` |
| `observedAtMs` | `uint64` | Observation time in Unix milliseconds |
| `nSigners` | `uint16` | Number of validators contributing observations for this item |
| `minNSources` | `uint16` | Smallest source count among the contributing observations |
| `flags` | `uint32` | Item status flags |

Item names, units, quote directions, and acceptance limits come from the feed
configuration and oracle catalog. Report items use the same status flag masks
as stored oracle observations:

| Flag | Mask | Meaning |
| - | - | - |
| Disputed | `1` | Validators did not agree on an identical value |
| Halted | `2` | New writes are stopped |
| Frozen | `4` | Consumers should stop acting while writes may continue |
| Market closed | `8` | Last value from closed venues |
| Ripcord | `16` | Source operator stopped normal use |

## Verifier interface

| Signature | Result |
| - | - |
| `retireHeight() → uint64` | Last accepted report height, inclusive |
| `retirer() → address` | Account allowed to lower the retirement height |
| `retire(uint64 newRetireHeight)` | Lowers the bound; callable only by the configured nonzero retirer |
| `memberCount() → uint256` | Number of configured validators |
| `quorum() → uint256` | Required signer count, `n - floor((n - 1) / 3)` for `n` validators |
| `committeeKey(uint256 index) → bytes` | Validator key at that index as a 128-byte EIP-2537 G1 point |
| `ackNamespace() → bytes` | Report namespace with the UTF-8 suffix `_AGG_ACK` |
| `ackPreimage(uint64 height, bytes32 digest) → bytes` | Exact bytes covered by the aggregate signature |
| `verifyReport(uint64 height, bytes report, bytes signersBitmap, bytes signature) → (bool ok, ReportItem[] items)` | Signature result and items decoded from `report` |

All functions except `retire` are reads. `verifyReport` checks the retirement
bound, report number, signer bitmap, quorum, and signature. It returns the decoded items even when `ok` is
`false`. A consuming contract must require `ok` before using them. Item
selection, age, confidence, flags, and replay checks belong to that contract.

| Condition | Behavior |
| - | - |
| Report height exceeds `retireHeight` | `HeightRetired()` |
| `retire` caller is not the configured nonzero retirer | `NotRetirer()` |
| New retirement height is greater than or equal to the current bound | `RetirementExtended()` |
| Report cannot be ABI-decoded | Revert |
| Encoded `round` differs from `height` | `WrongHeight()` |
| Bitmap has the wrong length or nonzero unused bits | `BadBitmap()` |
| Signer count is below the quorum | `QuorumNotMet()` |
| Signature verification fails, including invalid signature length or point encoding | Returns `ok = false` |
| `committeeKey` index is outside the configured set | Revert with `index out of range` |

## Signature encoding

The signer bitmap is exactly `ceil(memberCount / 8)` bytes. Validator index
`i` is bit `i % 8` of byte `floor(i / 8)`, counting from the least significant
bit. Unused bits in the last byte are zero.

The verifier's `signature` argument is a 256-byte EIP-2537 G2 point. Its four
coordinates are `x.c0 ∥ x.c1 ∥ y.c0 ∥ y.c1`, each encoded as a 64-byte unsigned
big-endian integer. The RPC uses the 96-byte compressed form of the same point.

The signed message is
`varint(len(ns)) ∥ ns ∥ varint(height) ∥ keccak256(report)`, where `ns` is
`ackNamespace()` and each `varint` is an unsigned LEB128 integer. The aggregate
signature uses the domain separation tag
`BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_`. In these encodings, `∥` means byte
concatenation.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.