Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add block/state multiproof request/subscription feature (WIP) #267

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions apis/beacon/proof/block.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
get:
operationId: "getBlockProof"
summary: "Get partial Merkle proof for requested beacon block"
description: |
Returns [MultiProofResponse](../../../types/api.yaml#/MultiProofResponse) for block with given 'blockId' in the
specified [MultiProofRequest](../../../types/api.yaml#/MultiProofRequest) format. A response for the current head
is always guaranteed, for past blocks it is optional unless guaranteed by an active [subscription](./subscribe.yaml).
tags:
- Beacon
parameters:
- name: block_id
in: path
required: true
$ref: '../../../beacon-node-oapi.yaml#/components/parameters/BlockId'
- name: format
in: query
required: true
schema:
$ref: '../../../beacon-node-oapi.yaml#/components/schemas/MultiProofRequest'

responses:
"200":
description: Success
content:
application/octet-stream:
schema:
$ref: "../../../beacon-node-oapi.yaml#/components/schemas/MultiProofResponse"

"400":
description: "Invalid block ID"
content:
application/json:
schema:
$ref: "../../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage"
example:
code: 400
message: "Invalid block ID: current"
"404":
description: "Block not found"
content:
application/json:
schema:
$ref: "../../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage"
example:
code: 404
message: "Block not found"
"422":
description: "Requested tree node not available"
content:
application/json:
schema:
$ref: "../../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage"
example:
code: 400
message: "Requested tree node not available: #1234"
"500":
$ref: '../../../beacon-node-oapi.yaml#/components/responses/InternalError'

58 changes: 58 additions & 0 deletions apis/beacon/proof/state.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
get:
operationId: "getStateProof"
summary: "Get partial Merkle proof for requested beacon state"
description: |
Returns [MultiProofResponse](../../../types/api.yaml#/MultiProofResponse) for state with given 'stateId'
in the specified [MultiProofRequest](../../../types/api.yaml#/MultiProofRequest) format if available. A response for the current head
is always guaranteed, for past blocks it is optional unless guaranteed by an active [subscription](./subscribe.yaml).
tags:
- Beacon
parameters:
- name: state_id
in: path
required: true
$ref: '../../../beacon-node-oapi.yaml#/components/parameters/StateId'
- name: format
in: query
required: true
schema:
$ref: '../../../beacon-node-oapi.yaml#/components/schemas/MultiProofRequest'

responses:
"200":
description: Success
content:
application/octet-stream:
schema:
$ref: "../../../beacon-node-oapi.yaml#/components/schemas/MultiProofResponse"

"400":
description: "Invalid state ID"
content:
application/json:
schema:
$ref: "../../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage"
example:
code: 400
message: "Invalid state ID: current"
"404":
description: "State not found"
content:
application/json:
schema:
$ref: "../../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage"
example:
code: 404
message: "State not found"
"422":
description: "Requested tree node not available"
content:
application/json:
schema:
$ref: "../../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage"
example:
code: 400
message: "Requested tree node not available: #1234"
"500":
$ref: '../../../beacon-node-oapi.yaml#/components/responses/InternalError'

66 changes: 66 additions & 0 deletions apis/beacon/proof/subscribe.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
get:
operationId: "subscribeToProofs"
summary: "Subscribe to state or block proofs of future blocks"
description: |
Ensures that a [MultiProofResponse](../../../types/api.yaml#/MultiProofResponse) will be available for the states or blocks of
all *requested* future blocks in the specified [MultiProofRequest](../../../types/api.yaml#/MultiProofRequest) format. A block is
*requested* if `block.slot >= first+k*period > block.parent.slot` for any non-negative integer `k`. The default values of `first` and
`period` are both 0. A [MultiProofResponse](../../../types/api.yaml#/MultiProofResponse) is immediately returned for the last existing
canonical *requested* block if the state or block Merkle tree of that block is available. Otherwise a zero-length byte vector is
returned which means that the subscription has been successfully activated for future *requested* blocks. The generated proofs are
guaranteed to be available through `state` or `block` requests for 60 seconds. The subscription is guaranteed to stay active until its
*inactive timer* reaches 60 seconds. This timer is started whenever a new proof for a *requested* block is generated and it is stopped
and reset to zero whenever a [state](./state.yaml) or [block](./block.yaml) request is made to any response generated by the subscription.
tags:
- Beacon
parameters:
- name: blocks_or_states
in: path
required: true
type: string
enum: ["blocks", "states"]
- name: format
in: query
required: true
schema:
$ref: '../../../beacon-node-oapi.yaml#/components/schemas/MultiProofRequest'
- name: first
in: query
required: false
schema:
$ref: '../../../beacon-node-oapi.yaml#/components/schemas/Uint64'
- name: period
in: query
required: false
schema:
$ref: '../../../beacon-node-oapi.yaml#/components/schemas/Uint64'

responses:
"200":
description: Success
content:
application/octet-stream:
schema:
oneOf:
- $ref: "../../../beacon-node-oapi.yaml#/components/schemas/MultiProofResponse"
- description: "zero-length byte vector"
"422":
description: "Requested tree node not available"
content:
application/json:
schema:
$ref: "../../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage"
example:
code: 400
message: "Requested tree node not available: #1234"
"500":
$ref: '../../../beacon-node-oapi.yaml#/components/responses/InternalError'
"503":
description: "Too many subscriptions"
content:
application/json:
schema:
$ref: "../../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage"
example:
code: 503
message: "Too many subscriptions"
8 changes: 8 additions & 0 deletions beacon-node-oapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ paths:
$ref: "./apis/beacon/pool/voluntary_exists.yaml"
/eth/v1/beacon/pool/bls_to_execution_changes:
$ref: "./apis/beacon/pool/bls_to_execution_changes.yaml"
/eth/v0/beacon/proof/state:
$ref: "./apis/beacon/proof/state.yaml"
/eth/v0/beacon/proof/block:
$ref: "./apis/beacon/proof/block.yaml"
/eth/v0/beacon/proof/subscribe:
$ref: "./apis/beacon/proof/subscribe.yaml"

/eth/v2/debug/beacon/states/{state_id}:
$ref: './apis/debug/state.v2.yaml'
Expand Down Expand Up @@ -314,6 +320,8 @@ components:
$ref: './types/fork_choice.yaml#/Node'
ExtraData:
$ref: './types/fork_choice.yaml#/ExtraData'
MultiProofResponse:
$ref: './types/api.yaml#/MultiProofResponse'

parameters:
StateId:
Expand Down
20 changes: 20 additions & 0 deletions types/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,23 @@ Committee:
description: "List of validator indices assigned to this committee"
items:
$ref: './primitive.yaml#/Uint64'

MultiProofRequest:
description: |
The binary Merkle multi-proof request format, interpreted as an MSB-first bit list, recursively encodes the shape of the subtree
that the requested proof should cover. If the subtree is a single node whose Merkle proof is the tree node itself, it is encoded
as a single `1` bit. Otherwise the subtree encoding consists of a `0` bit, then the recursive encoding of the left child subtree,
then the right child subtree. This encoding always ends with a `1` bit and in total consists of `N` `1` bits and `N-1` `0` bits,
where `N` is the number of tree nodes stored in the resulting [MultiProofResponse](./api.yaml#/MultiProofResponse) in the same
order as the `1` bits representing the stored nodes in the format. After the last `1` bit the remaining least significant bits
of the last byte are filled with zeroes. The hex encoding should always have an even number of nibbles and leading zeroes should
not be discarded. For example, a proof that proves the generalized tree index 42 should be encoded as 0x25e0.
type: string
format: hex
example: "0x25e0"
pattern: "^0x[a-fA-F0-9]+$"

MultiProofResponse:
description: |
An `N*32` bytes long raw byte vector consisting of `N` Merkle tree nodes, each corresponding to a `1` bit in the
[MultiProofRequest](./api.yaml#/MultiProofRequest) format description, stored in the same order.