0.19.0 brings a number of breaking changes to the API. This document details these changes, and provides guidance for users migrating to this version.
The beacon API has changed significantly since it was first released. These changes generally fall into three categories:
- additional query parameters
- additional response metadata in JSON and/or headers
- introduction of new encoding systems, notably SSZ, for some endpoints
Due to these changes, it has become increasingly difficult to provide full functionality without changing function signatures. And, if function signatures are going to change, it makes sense to change them once in a more sustainable fashion rather than have a continual drip of function signature changes each time the beacon API changes. 0.19.0 brings these signature changes, and provides a strong base to move towards a version 1 release of the client.
Many endpoints in the beacon API have acquired additional parameters since the first release of the API specification. To allow for current options and to ease addition of future options all options have been moved to function-specific structs. For example, a call to fetch validators used to look something like this:
validatorsProvider.Validators(ctx, "head", nil)
Even with a relatively simple call like this it is not clear what these parameters represent, especially when one is nil
. With the consolidation of call options this now looks something like this:
validatorsProvider.Validators(ctx, &api.ValidatorsOpts{
State: "head",
})
Which makes it clearer that the "head"
parameter refers to the state, and hides the explicit nil
parameter for the specific validator indices. Additional parameters added to the API can then be added to the struct without further disrupting the function signature.
http.Error
has moved to api.Error
, to make it clearer that it is reporting an error found within the API rather than specifically an HTTP error.
Not all errors returned by the call will be api.Error
, only those that return an error relating to the server. So, for example, an attempt to call a function with a nil
options struct (see below for options structures) will return a simple error. But when an api.Error
is available it will provide additional information about why the API rejected a request.
Responses from endpoints are now wrapped in the api.Response
struct. The requested information can be found in the Data
element of this struct, and any metadata supplied in the response can be found in the Metadata
element of this struct. Metadata has been added to a number of endpoints to support situations where additional data may be useful to the user but is not part of the requested structure. For example:
response, _ := beaconBlockProvider.SignedBeaconBlock(ctx, &api.SignedBeaconBlockOpts{
Block: "123",
})
finalized, exists := response.Metadata[metadata.Finalized]
if exists {
fmt.Printf("Is block finalized? %b\n",finalized)
}
Note that different calls have different metadata; metadata keys are free-form text and information about which ones should be available for each call can be found in the beacon API documentation.
Some functions could return nil
for both result and error, which is bad practice. This resulted in the following style of code being required:
block, err := beaconBlockProvider.SignedBeaconBlock(ctx, "999999999999")
if err != nil {
panic(err)
}
if block == nil {
panic("no block for this slot")
}
...
Functions will now either return a response or an error, but always one and never both. Combined with use of api.Error
as mentioned above this allows for better control of both successful and failed calls, for example:
response, err := beaconBlockProvider.SignedBeaconBlock(ctx, &api.SignedBeaconBlockOpts{
Block: "999999999999",
})
if err != nil {
var apiErr *api.Error
if errors.As(err, &apiErr) {
switch apiErr.StatusCode {
case 404:
// No block found.
case 503:
// Node is syncing.
}
}
panic(err)
}
// At this point response will definitely not be nil.
...
The BeaconBlockProposal
function has been renamed to Proposal
. This better reflects that a proposal can contain more than just a block.
The BeaconBlockProposalProvider
interface has been similarly renamed to ProposalProvider
.
The BlindedBeaconBlockProposal
function has been renamed to BlindedProposal
. This better reflects that a blinded proposal can contain more than just a block.
The BlindedBeaconBlockProposalProvider
interface has been similarly renamed to BlindedProposalProvider
.
The BeaconCommitteesAtEpoch
function has been removed. This functionality can be obtained used BeaconCommittees
with the required epoch specified in its call options.
The BeaconBlockSubmitter
and associated SubmitBeaconBlock
function have been deprecated, and will not work at the Deneb hard fork. A new interface ProposalSubmitter
and associated SubmitProposal
function have been created to provide on-going support for submitting proposals.
The BlindedBeaconBlockSubmitter
and associated SubmitBlindedBeaconBlock
function have been deprecated, and will not work at the Deneb hard fork. A new interface BlindedProposalSubmitter
and associated SubmitBlindedProposal
function have been created to provide on-going support for submitting blinded proposals.
The ValidatorsByPubKey
function has been removed; use Validators
with suitable options instead.