# Header Oracle Application
prior work here: https://github.com/ethereum/portal-network-specs/issues/104
A web application that provides access to data from the historical header accumulator.
### The Problem:
The header chain is currently 13 million blocks long and takes 6GB of disk to store.
On a resource constrained device:
- We may not have 6GB available to store
- We may not be online consistently enough to track the chain
- We may not have the processing power or bandwidth to download and verify long portions of the chain
Under these constraints, we need a way to verify that a header is part of the canonical chain of headers (as opposed to an ommer).
## The Solution: Header Accumulator
The "accumulator" is a data structure borrowed from the Beacon chain which solves this problem, allowing for proofs that a given header was indeed canonical.
See here for specification on how this data structure works and is maintained: https://github.com/ethereum/portal-network-specs/blob/e910a1e23cbee4ebeb9b8c69f1620999b080b772/header-gossip-network.md#the-header-accumulator
Someone wishing to "prove" inclusion of a historical header would create a merkle proof for the epoch that the header was included in, as well as a merkle proof for the master accumulator's history which contains the merkle root of that epoch.
## The Oracle
The "Header Oracle" is a web application that is intended to be run by any individual or organization which wishes to help provide a mirror to retrieving data related to the header accumulator.
### Oracle Signing Key
Each instance of the oracle should be bound to a public/private keypair suitable for [EIP-712](https://eips.ethereum.org/EIPS/eip-712) signing of data payloads.
### Signed Responses
All API endpoints will include a data payload and an EIP-712 signature over that data. The signing of responses is meant to ensure that service providers can be caught if they provide incorrect data.
> TODO: Need a mechanism for registering the key so that a user can retrieve the expected signing key for an oracle service from some external registry.
> Problem Statement: Suppose Ethereum runs an oracle at `oracle.ethereum.org`. Suppose that for some set of IP addresses we use a different signing key so that the user cannot prove we lied. We need a system that allows the user to know ahead of time which key they should expect us to be signing with. ENS or DNS may be good tools for this.
### Maintaining the accumulator
The service needs a background process that maintains the accumulator data structure. This process would monitor the chain for new block headers, and then update it's local copy of the accumulator accordingly.
#### Data Retention
The application should be configurable on retention of historical epochs. Instead of discarding old epochs, they can be kept around to allow the service to generate proofs for old headers.
### API Endpoints
The service would need to expose the following API endpoints. The response data for each endpoint will need to be wrapped in an EIP-712 style signature.
#### GET `/v1/signing-key/`
Return the public key for the private key that this oracle uses to sign responses.
#### GET `/v1/accumulator/`
Returns the SSZ encoded full payload of the latest version of the accumulator.
#### GET `/v1/accumulator/<epoch-number>/`
Returns the epoch accumulator for the given epoch number or a 400 error if the data is not available.
#### GET `/v1/proof/<block-number>`
Return the merkle proof for the header at the given `block-number` against the latest version of the accumulator.
#### GET `/v1/proof/<block-number>/<accumulator-height>/`
Returns the merkle proof for the header at the given `block-number` against the accumulator as it would exist at the given `accumulator-height`
#### POST `/v1/proof/verify/`
Takes a proof and returns whether the proof is valid or returns a 400 if the proof is against an accumulator version that is not available due to data renttion policies.