Skip to content

Latest commit

 

History

History
117 lines (82 loc) · 5.87 KB

0.19.0-changes.md

File metadata and controls

117 lines (82 loc) · 5.87 KB

Changes in 0.19.0

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.

Rationale behind changes

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.

Details of changes and migration guidance

Consolidation of call options

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.

Relocation of Error struct and extended usage

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.

Response struct

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.

No more nil, nil

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.
...

BeaconBlockProposal renamed

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.

BlindedBeaconBlockProposal renamed

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.

BeaconCommitteesAtEpoch removed

The BeaconCommitteesAtEpoch function has been removed. This functionality can be obtained used BeaconCommittees with the required epoch specified in its call options.

BeaconBlockSubmitter deprecated

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.

BlindedBeaconBlockSubmitter deprecated

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.

ValidatorsByPubKey removed

The ValidatorsByPubKey function has been removed; use Validators with suitable options instead.