diff --git a/CHANGELOG.md b/CHANGELOG.md index 362376fc..253a3715 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +dev: + - standardise names of options + - add common options (currently just timeout) to options structs + 0.19.4: - revert SubmitProposal() to use v1 of the API diff --git a/api/aggregateattestationopts.go b/api/aggregateattestationopts.go index 72facdc3..f2f213a6 100644 --- a/api/aggregateattestationopts.go +++ b/api/aggregateattestationopts.go @@ -17,6 +17,8 @@ import "github.com/attestantio/go-eth2-client/spec/phase0" // AggregateAttestationOpts are the options for obtaining aggregate attestations. type AggregateAttestationOpts struct { + Common CommonOpts + // Slot is the slot for which the data is obtained. Slot phase0.Slot // AttestationDataRoot is the root for which the data is obtained. diff --git a/api/attestationdataopts.go b/api/attestationdataopts.go index 360773bf..032a34ea 100644 --- a/api/attestationdataopts.go +++ b/api/attestationdataopts.go @@ -17,6 +17,8 @@ import "github.com/attestantio/go-eth2-client/spec/phase0" // AttestationDataOpts are the options for obtaining attestation data. type AttestationDataOpts struct { + Common CommonOpts + // Slot is the slot for which the data is obtained. Slot phase0.Slot // CommitteeIndex is the committee index for which the data is obtained. diff --git a/api/attestationpoolopts.go b/api/attestationpoolopts.go index 89f17734..57349fd0 100644 --- a/api/attestationpoolopts.go +++ b/api/attestationpoolopts.go @@ -17,6 +17,8 @@ import "github.com/attestantio/go-eth2-client/spec/phase0" // AttestationPoolOpts are the options for obtaining the attestation pool. type AttestationPoolOpts struct { + Common CommonOpts + // Slot is the slot for which the data is obtained. Slot phase0.Slot } diff --git a/api/attesterdutiesopts.go b/api/attesterdutiesopts.go index 4f323027..858573ff 100644 --- a/api/attesterdutiesopts.go +++ b/api/attesterdutiesopts.go @@ -17,6 +17,8 @@ import "github.com/attestantio/go-eth2-client/spec/phase0" // AttesterDutiesOpts are the options for obtaining proposer duties. type AttesterDutiesOpts struct { + Common CommonOpts + // Epoch is the epoch for which the data is obtained. Epoch phase0.Epoch // Indices is a list of validators for which to obtain the duties. diff --git a/api/beaconblockheaderopts.go b/api/beaconblockheaderopts.go index fbec4b22..5ce33283 100644 --- a/api/beaconblockheaderopts.go +++ b/api/beaconblockheaderopts.go @@ -15,6 +15,8 @@ package api // BeaconBlockHeaderOpts are the options for obtaining beacon block headers. type BeaconBlockHeaderOpts struct { + Common CommonOpts + // Block is the ID of the block which the data is obtained. Block string } diff --git a/api/beaconblockrootopts.go b/api/beaconblockrootopts.go index 93cee364..9d94d02f 100644 --- a/api/beaconblockrootopts.go +++ b/api/beaconblockrootopts.go @@ -15,6 +15,8 @@ package api // BeaconBlockRootOpts are the options for obtaining the beacon block root. type BeaconBlockRootOpts struct { + Common CommonOpts + // Block is the ID of the block which the data is obtained. Block string } diff --git a/api/beaconcommitteesopts.go b/api/beaconcommitteesopts.go index aea68517..e513b3f5 100644 --- a/api/beaconcommitteesopts.go +++ b/api/beaconcommitteesopts.go @@ -17,6 +17,8 @@ import "github.com/attestantio/go-eth2-client/spec/phase0" // BeaconCommitteesOpts are the options for obtaining proposer duties. type BeaconCommitteesOpts struct { + Common CommonOpts + // State is the state at which the data is obtained. // It can be a slot number or state root, or one of the special values "genesis", "head", "justified" or "finalized". State string diff --git a/api/beaconstateopts.go b/api/beaconstateopts.go index c916ab45..6da3467f 100644 --- a/api/beaconstateopts.go +++ b/api/beaconstateopts.go @@ -15,6 +15,8 @@ package api // BeaconStateOpts are the options for obtaining the beacon state. type BeaconStateOpts struct { + Common CommonOpts + // State is the state at which the data is obtained. // It can be a slot number or state root, or one of the special values "genesis", "head", "justified" or "finalized". State string diff --git a/api/beaconstaterandaoopts.go b/api/beaconstaterandaoopts.go index e83f83dc..6fd564d5 100644 --- a/api/beaconstaterandaoopts.go +++ b/api/beaconstaterandaoopts.go @@ -15,6 +15,8 @@ package api // BeaconStateRandaoOpts are the options for obtaining the beacon state RANDAO. type BeaconStateRandaoOpts struct { + Common CommonOpts + // State is the state at which the data is obtained. // It can be a slot number or state root, or one of the special values "genesis", "head", "justified" or "finalized". State string diff --git a/api/beaconstaterootopts.go b/api/beaconstaterootopts.go index 467dd71a..6866c285 100644 --- a/api/beaconstaterootopts.go +++ b/api/beaconstaterootopts.go @@ -15,6 +15,8 @@ package api // BeaconStateRootOpts are the options for obtaining the beacon state root. type BeaconStateRootOpts struct { + Common CommonOpts + // State is the state at which the data is obtained. // It can be a slot number or state root, or one of the special values "genesis", "head", "justified" or "finalized". State string diff --git a/api/blindedproposalopts.go b/api/blindedproposalopts.go index 994c48bb..0ba2fe96 100644 --- a/api/blindedproposalopts.go +++ b/api/blindedproposalopts.go @@ -17,6 +17,8 @@ import "github.com/attestantio/go-eth2-client/spec/phase0" // BlindedProposalOpts are the options for obtaining blinded proposals. type BlindedProposalOpts struct { + Common CommonOpts + // Slot is the slot for which the proposal should be fetched. Slot phase0.Slot // RandaoReveal is the RANDAO reveal for the proposal. diff --git a/api/blobsidecarsopts.go b/api/blobsidecarsopts.go index ed0f206d..5fa8f5bb 100644 --- a/api/blobsidecarsopts.go +++ b/api/blobsidecarsopts.go @@ -15,6 +15,8 @@ package api // BlobSidecarsOpts are the options for obtaining blob sidecars. type BlobSidecarsOpts struct { + Common CommonOpts + // Block is the ID of the block for which the data is obtained. Block string } diff --git a/api/commonopts.go b/api/commonopts.go new file mode 100644 index 00000000..6343d690 --- /dev/null +++ b/api/commonopts.go @@ -0,0 +1,23 @@ +// Copyright © 2023 Attestant Limited. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package api + +import "time" + +// CommonOpts are options common for all calls. +type CommonOpts struct { + // Timeout is a specific timeout for this call. + // If 0 then the default timeout is used. + Timeout time.Duration +} diff --git a/api/depositcontractopts.go b/api/depositcontractopts.go new file mode 100644 index 00000000..5ac278b3 --- /dev/null +++ b/api/depositcontractopts.go @@ -0,0 +1,19 @@ +// Copyright © 2023 Attestant Limited. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package api + +// DepositContractOpts are the options for obtaining the deposit contract. +type DepositContractOpts struct { + Common CommonOpts +} diff --git a/api/finalityopts.go b/api/finalityopts.go index 994509ce..8eb80b00 100644 --- a/api/finalityopts.go +++ b/api/finalityopts.go @@ -15,6 +15,8 @@ package api // FinalityOpts are the options for obtaining finality checkpoints. type FinalityOpts struct { + Common CommonOpts + // State is the state at which the data is obtained. // It can be a slot number or state root, or one of the special values "genesis", "head", "justified" or "finalized". State string diff --git a/api/forkchoiceopts.go b/api/forkchoiceopts.go new file mode 100644 index 00000000..bcbd8e09 --- /dev/null +++ b/api/forkchoiceopts.go @@ -0,0 +1,19 @@ +// Copyright © 2023 Attestant Limited. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package api + +// ForkChoiceOpts are the options for obtaining the fork choice. +type ForkChoiceOpts struct { + Common CommonOpts +} diff --git a/api/forkopts.go b/api/forkopts.go index 6708927f..fdcbcfb1 100644 --- a/api/forkopts.go +++ b/api/forkopts.go @@ -15,6 +15,8 @@ package api // ForkOpts are the options for obtaining the fork. type ForkOpts struct { + Common CommonOpts + // State is the state at which the data is obtained. // It can be a slot number or state root, or one of the special values "genesis", "head", "justified" or "finalized". State string diff --git a/api/forkscheduleopts.go b/api/forkscheduleopts.go new file mode 100644 index 00000000..e2e13159 --- /dev/null +++ b/api/forkscheduleopts.go @@ -0,0 +1,19 @@ +// Copyright © 2023 Attestant Limited. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package api + +// ForkScheduleOpts are the options for obtaining the fork schedule. +type ForkScheduleOpts struct { + Common CommonOpts +} diff --git a/api/genesisopts.go b/api/genesisopts.go new file mode 100644 index 00000000..cbe630f8 --- /dev/null +++ b/api/genesisopts.go @@ -0,0 +1,19 @@ +// Copyright © 2023 Attestant Limited. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package api + +// GenesisOpts are the options for obtaining genesis information. +type GenesisOpts struct { + Common CommonOpts +} diff --git a/api/peeropts.go b/api/nodepeersopts.go similarity index 87% rename from api/peeropts.go rename to api/nodepeersopts.go index 65eec95a..95060ca6 100644 --- a/api/peeropts.go +++ b/api/nodepeersopts.go @@ -13,8 +13,10 @@ package api -// PeerOpts are the options for client side peer filtering. -type PeerOpts struct { +// NodePeersOpts are the options for client side peer filtering. +type NodePeersOpts struct { + Common CommonOpts + // State of the connection (disconnected, connecting, connected, disconnecting) State []string // Direction of the connection (inbound, outbound) diff --git a/api/nodesyncingopts.go b/api/nodesyncingopts.go new file mode 100644 index 00000000..75ae3444 --- /dev/null +++ b/api/nodesyncingopts.go @@ -0,0 +1,19 @@ +// Copyright © 2023 Attestant Limited. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package api + +// NodeSyncingOpts are the options for obtaining node sync information. +type NodeSyncingOpts struct { + Common CommonOpts +} diff --git a/api/nodeversionopts.go b/api/nodeversionopts.go new file mode 100644 index 00000000..fb05a8e5 --- /dev/null +++ b/api/nodeversionopts.go @@ -0,0 +1,19 @@ +// Copyright © 2023 Attestant Limited. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package api + +// NodeVersionOpts are the options for obtaining the node version. +type NodeVersionOpts struct { + Common CommonOpts +} diff --git a/api/proposalopts.go b/api/proposalopts.go index 8af5b23e..27809bce 100644 --- a/api/proposalopts.go +++ b/api/proposalopts.go @@ -17,6 +17,8 @@ import "github.com/attestantio/go-eth2-client/spec/phase0" // ProposalOpts are the options for obtaining proposals. type ProposalOpts struct { + Common CommonOpts + // Slot is the slot for which the proposal should be fetched. Slot phase0.Slot // RandaoReveal is the RANDAO reveal for the proposal. diff --git a/api/proposerdutiesopts.go b/api/proposerdutiesopts.go index e327aba2..c66c28fe 100644 --- a/api/proposerdutiesopts.go +++ b/api/proposerdutiesopts.go @@ -17,6 +17,8 @@ import "github.com/attestantio/go-eth2-client/spec/phase0" // ProposerDutiesOpts are the options for obtaining proposer duties. type ProposerDutiesOpts struct { + Common CommonOpts + // Epoch is the epoch for which the data is obtained. Epoch phase0.Epoch // Indices is a list of validators to restrict the returned values. If no indices are supplied then no filter will be applied. diff --git a/api/signedbeaconblockopts.go b/api/signedbeaconblockopts.go index f3c310e1..7d58d3ea 100644 --- a/api/signedbeaconblockopts.go +++ b/api/signedbeaconblockopts.go @@ -15,6 +15,8 @@ package api // SignedBeaconBlockOpts are the options for obtaining signed beacon blocks. type SignedBeaconBlockOpts struct { + Common CommonOpts + // Block is the ID of the block which the data is obtained. Block string } diff --git a/api/specopts.go b/api/specopts.go new file mode 100644 index 00000000..f7b30fcf --- /dev/null +++ b/api/specopts.go @@ -0,0 +1,19 @@ +// Copyright © 2023 Attestant Limited. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package api + +// SpecOpts are the options for obtaining the chain specification. +type SpecOpts struct { + Common CommonOpts +} diff --git a/api/synccommitteecontributionopts.go b/api/synccommitteecontributionopts.go index a05bea9b..7a43c2fc 100644 --- a/api/synccommitteecontributionopts.go +++ b/api/synccommitteecontributionopts.go @@ -17,6 +17,8 @@ import "github.com/attestantio/go-eth2-client/spec/phase0" // SyncCommitteeContributionOpts are the options for obtaining sync committee contributions. type SyncCommitteeContributionOpts struct { + Common CommonOpts + // Slot is the slot for which the data is obtained. Slot phase0.Slot // SubcommitteeIndex is the index of the sync subcommittee for which the data is obtained. diff --git a/api/synccommitteedutiesopts.go b/api/synccommitteedutiesopts.go index add60e31..263de403 100644 --- a/api/synccommitteedutiesopts.go +++ b/api/synccommitteedutiesopts.go @@ -17,6 +17,8 @@ import "github.com/attestantio/go-eth2-client/spec/phase0" // SyncCommitteeDutiesOpts are the options for obtaining sync committee duties. type SyncCommitteeDutiesOpts struct { + Common CommonOpts + // Epoch is the epoch for which the data is obtained. Epoch phase0.Epoch // Indices is a list of validators for which to obtain the duties. diff --git a/api/synccommitteeopts.go b/api/synccommitteeopts.go index 1af05d59..c27cb4c1 100644 --- a/api/synccommitteeopts.go +++ b/api/synccommitteeopts.go @@ -17,6 +17,8 @@ import "github.com/attestantio/go-eth2-client/spec/phase0" // SyncCommitteeOpts are the options for obtaining sync committees. type SyncCommitteeOpts struct { + Common CommonOpts + // State is the state at which the data is obtained. // It can be a slot number or state root, or one of the special values "genesis", "head", "justified" or "finalized". State string diff --git a/api/validatorbalancesopts.go b/api/validatorbalancesopts.go index 401fcae5..13fbe1f2 100644 --- a/api/validatorbalancesopts.go +++ b/api/validatorbalancesopts.go @@ -17,6 +17,8 @@ import "github.com/attestantio/go-eth2-client/spec/phase0" // ValidatorBalancesOpts are the options for obtaining validator balances. type ValidatorBalancesOpts struct { + Common CommonOpts + // State is the state at which the data is obtained. // It can be a slot number or state root, or one of the special values "genesis", "head", "justified" or "finalized". State string diff --git a/api/validatorsopts.go b/api/validatorsopts.go index a117bedf..f3cd8ff3 100644 --- a/api/validatorsopts.go +++ b/api/validatorsopts.go @@ -17,6 +17,8 @@ import "github.com/attestantio/go-eth2-client/spec/phase0" // ValidatorsOpts are the options for obtaining validators. type ValidatorsOpts struct { + Common CommonOpts + // State is the state at which the data is obtained. // It can be a slot number or state root, or one of the special values "genesis", "head", "justified" or "finalized". State string diff --git a/api/voluntaryexitpoolopts.go b/api/voluntaryexitpoolopts.go new file mode 100644 index 00000000..0586c0ef --- /dev/null +++ b/api/voluntaryexitpoolopts.go @@ -0,0 +1,19 @@ +// Copyright © 2023 Attestant Limited. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package api + +// VoluntaryExitPoolOpts are the options for obtaining the voluntary exit pool. +type VoluntaryExitPoolOpts struct { + Common CommonOpts +} diff --git a/auto/service_test.go b/auto/service_test.go index b8335a26..bf59bef7 100644 --- a/auto/service_test.go +++ b/auto/service_test.go @@ -20,6 +20,7 @@ import ( "time" eth2client "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/auto" "github.com/rs/zerolog" "github.com/stretchr/testify/require" @@ -64,7 +65,7 @@ func TestService(t *testing.T) { require.EqualError(t, err, test.err) } else { require.NoError(t, err) - version, err := service.(eth2client.NodeVersionProvider).NodeVersion(context.Background()) + version, err := service.(eth2client.NodeVersionProvider).NodeVersion(context.Background(), &api.NodeVersionOpts{}) require.NoError(t, err) require.Contains(t, version, test.version) } diff --git a/http/aggregateattestation.go b/http/aggregateattestation.go index a6c719c9..56727dd6 100644 --- a/http/aggregateattestation.go +++ b/http/aggregateattestation.go @@ -37,7 +37,8 @@ func (s *Service) AggregateAttestation(ctx context.Context, return nil, errors.New("no attestation data root specified") } - httpResponse, err := s.get2(ctx, fmt.Sprintf("/eth/v1/validator/aggregate_attestation?slot=%d&attestation_data_root=%#x", opts.Slot, opts.AttestationDataRoot)) + url := fmt.Sprintf("/eth/v1/validator/aggregate_attestation?slot=%d&attestation_data_root=%#x", opts.Slot, opts.AttestationDataRoot) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/aggregateattestation_test.go b/http/aggregateattestation_test.go index 08842bd0..441fcfdc 100644 --- a/http/aggregateattestation_test.go +++ b/http/aggregateattestation_test.go @@ -38,7 +38,7 @@ func TestAggregateAttestation(t *testing.T) { require.NoError(t, err) // Need to fetch current slot for attestation. - genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx) + genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) slotDuration, err := service.(client.SlotDurationProvider).SlotDuration(ctx) require.NoError(t, err) diff --git a/http/attestationdata.go b/http/attestationdata.go index 09cb341f..a561cd3b 100644 --- a/http/attestationdata.go +++ b/http/attestationdata.go @@ -34,7 +34,8 @@ func (s *Service) AttestationData(ctx context.Context, return nil, errors.New("no options specified") } - httpResponse, err := s.get2(ctx, fmt.Sprintf("/eth/v1/validator/attestation_data?slot=%d&committee_index=%d", opts.Slot, opts.CommitteeIndex)) + url := fmt.Sprintf("/eth/v1/validator/attestation_data?slot=%d&committee_index=%d", opts.Slot, opts.CommitteeIndex) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/attestationdata_test.go b/http/attestationdata_test.go index 0ad20579..dafdd5ab 100644 --- a/http/attestationdata_test.go +++ b/http/attestationdata_test.go @@ -38,7 +38,7 @@ func TestAttestationData(t *testing.T) { require.NoError(t, err) // Need to fetch current slot for attestation data. - genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx) + genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) slotDuration, err := service.(client.SlotDurationProvider).SlotDuration(ctx) require.NoError(t, err) diff --git a/http/attestationpool.go b/http/attestationpool.go index 07e46a0e..cdbd7605 100644 --- a/http/attestationpool.go +++ b/http/attestationpool.go @@ -34,7 +34,8 @@ func (s *Service) AttestationPool(ctx context.Context, return nil, errors.New("no options specified") } - httpResponse, err := s.get2(ctx, fmt.Sprintf("/eth/v1/beacon/pool/attestations?slot=%d", opts.Slot)) + url := fmt.Sprintf("/eth/v1/beacon/pool/attestations?slot=%d", opts.Slot) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/attestationpool_test.go b/http/attestationpool_test.go index 3a997816..e88d2c9b 100644 --- a/http/attestationpool_test.go +++ b/http/attestationpool_test.go @@ -38,7 +38,7 @@ func TestAttestationPool(t *testing.T) { require.NoError(t, err) // Need to fetch current slot for attestation pools. - genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx) + genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) slotDuration, err := service.(client.SlotDurationProvider).SlotDuration(ctx) require.NoError(t, err) diff --git a/http/attesterduties_test.go b/http/attesterduties_test.go index d4cc5819..c1341dea 100644 --- a/http/attesterduties_test.go +++ b/http/attesterduties_test.go @@ -39,7 +39,7 @@ func TestAttesterDuties(t *testing.T) { require.NoError(t, err) // Need to fetch current epoch for duties. - genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx) + genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) slotDuration, err := service.(client.SlotDurationProvider).SlotDuration(ctx) require.NoError(t, err) diff --git a/http/beaconblockheader.go b/http/beaconblockheader.go index 32553630..1c5237d8 100644 --- a/http/beaconblockheader.go +++ b/http/beaconblockheader.go @@ -34,7 +34,8 @@ func (s *Service) BeaconBlockHeader(ctx context.Context, return nil, errors.New("no options specified") } - httpResponse, err := s.get2(ctx, fmt.Sprintf("/eth/v1/beacon/headers/%s", opts.Block)) + url := fmt.Sprintf("/eth/v1/beacon/headers/%s", opts.Block) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/beaconblockroot.go b/http/beaconblockroot.go index 0debd1bd..e4b9b5f5 100644 --- a/http/beaconblockroot.go +++ b/http/beaconblockroot.go @@ -41,7 +41,8 @@ func (s *Service) BeaconBlockRoot(ctx context.Context, return nil, errors.New("no block specified") } - httpResponse, err := s.get2(ctx, fmt.Sprintf("/eth/v1/beacon/blocks/%s/root", opts.Block)) + url := fmt.Sprintf("/eth/v1/beacon/blocks/%s/root", opts.Block) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/beaconblockroot_test.go b/http/beaconblockroot_test.go index 52d08eb0..6aa3bbf2 100644 --- a/http/beaconblockroot_test.go +++ b/http/beaconblockroot_test.go @@ -17,6 +17,7 @@ import ( "context" "os" "testing" + "time" client "github.com/attestantio/go-eth2-client" "github.com/attestantio/go-eth2-client/api" @@ -87,3 +88,22 @@ func TestBeaconBlockRoot(t *testing.T) { }) } } + +func TestBeaconBlockRootTimeout(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + service, err := http.New(ctx, + http.WithTimeout(timeout), + http.WithAddress(os.Getenv("HTTP_ADDRESS")), + ) + require.NoError(t, err) + + _, err = service.(client.BeaconBlockRootProvider).BeaconBlockRoot(ctx, &api.BeaconBlockRootOpts{ + Common: api.CommonOpts{ + Timeout: time.Millisecond, + }, + Block: "0", + }) + require.True(t, errors.Is(err, context.DeadlineExceeded)) +} diff --git a/http/beaconcommittees.go b/http/beaconcommittees.go index 68be6d72..8cf7350b 100644 --- a/http/beaconcommittees.go +++ b/http/beaconcommittees.go @@ -42,7 +42,7 @@ func (s *Service) BeaconCommittees(ctx context.Context, url = fmt.Sprintf("%s?epoch=%d", url, *opts.Epoch) } - httpResponse, err := s.get2(ctx, url) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/beaconstate.go b/http/beaconstate.go index 536397a3..1cc123a5 100644 --- a/http/beaconstate.go +++ b/http/beaconstate.go @@ -42,7 +42,8 @@ func (s *Service) BeaconState(ctx context.Context, return nil, errors.New("no state specified") } - httpResponse, err := s.get2(ctx, fmt.Sprintf("/eth/v2/debug/beacon/states/%s", opts.State)) + url := fmt.Sprintf("/eth/v2/debug/beacon/states/%s", opts.State) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/beaconstaterandao.go b/http/beaconstaterandao.go index 6390f7db..4b9bdb9d 100644 --- a/http/beaconstaterandao.go +++ b/http/beaconstaterandao.go @@ -36,7 +36,8 @@ func (s *Service) BeaconStateRandao(ctx context.Context, opts *api.BeaconStateRa return nil, errors.New("no state specified") } - httpResponse, err := s.get2(ctx, fmt.Sprintf("/eth/v1/beacon/states/%s/randao", opts.State)) + url := fmt.Sprintf("/eth/v1/beacon/states/%s/randao", opts.State) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/beaconstateroot.go b/http/beaconstateroot.go index 90e0ebe1..2c77f438 100644 --- a/http/beaconstateroot.go +++ b/http/beaconstateroot.go @@ -36,7 +36,8 @@ func (s *Service) BeaconStateRoot(ctx context.Context, opts *api.BeaconStateRoot return nil, errors.New("no state specified") } - httpResponse, err := s.get2(ctx, fmt.Sprintf("/eth/v1/beacon/states/%s/root", opts.State)) + url := fmt.Sprintf("/eth/v1/beacon/states/%s/root", opts.State) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/blindedproposal.go b/http/blindedproposal.go index 618667a0..0fe765f5 100644 --- a/http/blindedproposal.go +++ b/http/blindedproposal.go @@ -53,7 +53,7 @@ func (s *Service) BlindedProposal(ctx context.Context, url = fmt.Sprintf("%s&skip_randao_verification", url) } - res, err := s.get2(ctx, url) + res, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, errors.Wrap(err, "failed to request blinded beacon block proposal") } diff --git a/http/blindedproposal_test.go b/http/blindedproposal_test.go index c9803316..64a5eb1b 100644 --- a/http/blindedproposal_test.go +++ b/http/blindedproposal_test.go @@ -38,7 +38,7 @@ func TestBlindedProposal(t *testing.T) { require.NoError(t, err) // Need to fetch current slot for proposal. - genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx) + genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) slotDuration, err := service.(client.SlotDurationProvider).SlotDuration(ctx) require.NoError(t, err) diff --git a/http/blobsidecars.go b/http/blobsidecars.go index 33cbfe50..08952bfe 100644 --- a/http/blobsidecars.go +++ b/http/blobsidecars.go @@ -37,7 +37,8 @@ func (s *Service) BlobSidecars(ctx context.Context, return nil, errors.New("no block specified") } - httpResponse, err := s.get2(ctx, fmt.Sprintf("/eth/v1/beacon/blob_sidecars/%s", opts.Block)) + url := fmt.Sprintf("/eth/v1/beacon/blob_sidecars/%s", opts.Block) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/depositcontract.go b/http/depositcontract.go index 9e275091..56b5f7a0 100644 --- a/http/depositcontract.go +++ b/http/depositcontract.go @@ -19,10 +19,20 @@ import ( "github.com/attestantio/go-eth2-client/api" apiv1 "github.com/attestantio/go-eth2-client/api/v1" + "github.com/pkg/errors" ) // DepositContract provides details of the execution deposit contract for the chain. -func (s *Service) DepositContract(ctx context.Context) (*api.Response[*apiv1.DepositContract], error) { +func (s *Service) DepositContract(ctx context.Context, + opts *api.DepositContractOpts, +) ( + *api.Response[*apiv1.DepositContract], + error, +) { + if opts == nil { + return nil, errors.New("no options specified") + } + s.depositContractMutex.RLock() if s.depositContract != nil { defer s.depositContractMutex.RUnlock() @@ -45,7 +55,8 @@ func (s *Service) DepositContract(ctx context.Context) (*api.Response[*apiv1.Dep } // Up to us to fetch the information. - httpResponse, err := s.get2(ctx, "/eth/v1/config/deposit_contract") + url := "/eth/v1/config/deposit_contract" + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/depositcontract_test.go b/http/depositcontract_test.go index bb2df792..526f307e 100644 --- a/http/depositcontract_test.go +++ b/http/depositcontract_test.go @@ -19,6 +19,7 @@ import ( "testing" client "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/http" "github.com/stretchr/testify/require" ) @@ -43,7 +44,7 @@ func TestDepositContract(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - response, err := service.(client.DepositContractProvider).DepositContract(ctx) + response, err := service.(client.DepositContractProvider).DepositContract(ctx, &api.DepositContractOpts{}) require.NoError(t, err) require.NotNil(t, response) require.NotNil(t, response.Data.ChainID) diff --git a/http/domain.go b/http/domain.go index 4af498d2..be86e33a 100644 --- a/http/domain.go +++ b/http/domain.go @@ -17,6 +17,7 @@ import ( "bytes" "context" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/spec/phase0" "github.com/pkg/errors" ) @@ -68,7 +69,7 @@ func (s *Service) domain(ctx context.Context, if !bytes.Equal(domainType[:], []byte{0x00, 0x00, 0x00, 0x01}) { // Use the chain's genesis validators root for non-application domain types. - response, err := s.Genesis(ctx) + response, err := s.Genesis(ctx, &api.GenesisOpts{}) if err != nil { return phase0.Domain{}, errors.Wrap(err, "failed to obtain genesis") } @@ -90,7 +91,7 @@ func (s *Service) domain(ctx context.Context, // forkAtEpoch works through the fork schedule to obtain the current fork. func (s *Service) forkAtEpoch(ctx context.Context, epoch phase0.Epoch) (*phase0.Fork, error) { - response, err := s.ForkSchedule(ctx) + response, err := s.ForkSchedule(ctx, &api.ForkScheduleOpts{}) if err != nil { return nil, errors.Wrap(err, "failed to obtain fork schedule") } @@ -112,7 +113,7 @@ func (s *Service) forkAtEpoch(ctx context.Context, epoch phase0.Epoch) (*phase0. // forkAtGenesis returns the genesis fork. func (s *Service) forkAtGenesis(ctx context.Context) (*phase0.Fork, error) { - response, err := s.ForkSchedule(ctx) + response, err := s.ForkSchedule(ctx, &api.ForkScheduleOpts{}) if err != nil { return nil, errors.Wrap(err, "failed to obtain fork schedule") } diff --git a/http/finality.go b/http/finality.go index 82460da3..92156bf4 100644 --- a/http/finality.go +++ b/http/finality.go @@ -34,7 +34,7 @@ func (s *Service) Finality(ctx context.Context, return nil, errors.New("no options specified") } - httpResponse, err := s.get2(ctx, fmt.Sprintf("/eth/v1/beacon/states/%s/finality_checkpoints", opts.State)) + httpResponse, err := s.get(ctx, fmt.Sprintf("/eth/v1/beacon/states/%s/finality_checkpoints", opts.State), &opts.Common) if err != nil { return nil, err } diff --git a/http/fork.go b/http/fork.go index ce6ca54b..342f7c58 100644 --- a/http/fork.go +++ b/http/fork.go @@ -37,12 +37,13 @@ func (s *Service) Fork(ctx context.Context, return nil, errors.New("no state specified") } - res, err := s.get2(ctx, fmt.Sprintf("/eth/v1/beacon/states/%s/fork", opts.State)) + url := fmt.Sprintf("/eth/v1/beacon/states/%s/fork", opts.State) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } - data, metadata, err := decodeJSONResponse(bytes.NewReader(res.body), phase0.Fork{}) + data, metadata, err := decodeJSONResponse(bytes.NewReader(httpResponse.body), phase0.Fork{}) if err != nil { return nil, err } diff --git a/http/forkchoice.go b/http/forkchoice.go index 5cab7b83..0906e822 100644 --- a/http/forkchoice.go +++ b/http/forkchoice.go @@ -24,8 +24,18 @@ import ( ) // ForkChoice fetches all current fork choice context. -func (s *Service) ForkChoice(ctx context.Context) (*api.Response[*apiv1.ForkChoice], error) { - httpResponse, err := s.get2(ctx, "/eth/v1/debug/fork_choice") +func (s *Service) ForkChoice(ctx context.Context, + opts *api.ForkChoiceOpts, +) ( + *api.Response[*apiv1.ForkChoice], + error, +) { + if opts == nil { + return nil, errors.New("no options specified") + } + + url := "/eth/v1/debug/fork_choice" + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/forkchoice_test.go b/http/forkchoice_test.go index 1d3509a5..26b38b25 100644 --- a/http/forkchoice_test.go +++ b/http/forkchoice_test.go @@ -19,6 +19,7 @@ import ( "testing" client "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/http" "github.com/stretchr/testify/require" ) @@ -43,7 +44,7 @@ func TestForkChoice(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - response, err := service.(client.ForkChoiceProvider).ForkChoice(ctx) + response, err := service.(client.ForkChoiceProvider).ForkChoice(ctx, &api.ForkChoiceOpts{}) require.NoError(t, err) require.NotNil(t, response) require.NotNil(t, response.Data) diff --git a/http/forkschedule.go b/http/forkschedule.go index 8c1bbf24..c78ac4e0 100644 --- a/http/forkschedule.go +++ b/http/forkschedule.go @@ -19,10 +19,20 @@ import ( "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/spec/phase0" + "github.com/pkg/errors" ) // ForkSchedule provides details of past and future changes in the chain's fork version. -func (s *Service) ForkSchedule(ctx context.Context) (*api.Response[[]*phase0.Fork], error) { +func (s *Service) ForkSchedule(ctx context.Context, + opts *api.ForkScheduleOpts, +) ( + *api.Response[[]*phase0.Fork], + error, +) { + if opts == nil { + return nil, errors.New("no options specified") + } + s.forkScheduleMutex.RLock() if s.forkSchedule != nil { defer s.forkScheduleMutex.RUnlock() @@ -45,7 +55,8 @@ func (s *Service) ForkSchedule(ctx context.Context) (*api.Response[[]*phase0.For } // Up to us to fetch the information. - httpResponse, err := s.get2(ctx, "/eth/v1/config/fork_schedule") + url := "/eth/v1/config/fork_schedule" + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/forkschedule_test.go b/http/forkschedule_test.go index 96fa9ba6..8f89ec71 100644 --- a/http/forkschedule_test.go +++ b/http/forkschedule_test.go @@ -19,6 +19,7 @@ import ( "testing" client "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/http" "github.com/stretchr/testify/require" ) @@ -43,7 +44,7 @@ func TestForkSchedule(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - response, err := service.(client.ForkScheduleProvider).ForkSchedule(ctx) + response, err := service.(client.ForkScheduleProvider).ForkSchedule(ctx, &api.ForkScheduleOpts{}) require.NoError(t, err) require.NotNil(t, response) require.NotEmpty(t, response.Data) diff --git a/http/genesis.go b/http/genesis.go index 1c48f99f..d0a63c52 100644 --- a/http/genesis.go +++ b/http/genesis.go @@ -14,6 +14,7 @@ package http import ( + "bytes" "context" "encoding/json" @@ -27,7 +28,16 @@ type genesisJSON struct { } // Genesis provides the genesis information of the chain. -func (s *Service) Genesis(ctx context.Context) (*api.Response[*apiv1.Genesis], error) { +func (s *Service) Genesis(ctx context.Context, + opts *api.GenesisOpts, +) ( + *api.Response[*apiv1.Genesis], + error, +) { + if opts == nil { + return nil, errors.New("no options specified") + } + s.genesisMutex.RLock() if s.genesis != nil { defer s.genesisMutex.RUnlock() @@ -50,16 +60,14 @@ func (s *Service) Genesis(ctx context.Context) (*api.Response[*apiv1.Genesis], e } // Up to us to fetch the information. - respBodyReader, err := s.get(ctx, "/eth/v1/beacon/genesis") + url := "/eth/v1/beacon/genesis" + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, errors.Wrap(err, "failed to request genesis") } - if respBodyReader == nil { - return nil, errors.New("failed to obtain genesis") - } var resp genesisJSON - if err := json.NewDecoder(respBodyReader).Decode(&resp); err != nil { + if err := json.NewDecoder(bytes.NewReader(httpResponse.body)).Decode(&resp); err != nil { return nil, errors.Wrap(err, "failed to parse genesis") } s.genesis = resp.Data diff --git a/http/genesis_test.go b/http/genesis_test.go index d69833b8..b77bcc73 100644 --- a/http/genesis_test.go +++ b/http/genesis_test.go @@ -19,6 +19,7 @@ import ( "testing" client "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/http" "github.com/stretchr/testify/require" ) @@ -43,7 +44,7 @@ func TestGenesis(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - response, err := service.(client.GenesisProvider).Genesis(ctx) + response, err := service.(client.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) require.NotNil(t, response) require.NotNil(t, response.Data) diff --git a/http/genesistime.go b/http/genesistime.go index a9b3af14..bfb49c80 100644 --- a/http/genesistime.go +++ b/http/genesistime.go @@ -17,12 +17,13 @@ import ( "context" "time" + "github.com/attestantio/go-eth2-client/api" "github.com/pkg/errors" ) // GenesisTime provides the genesis time of the chain. func (s *Service) GenesisTime(ctx context.Context) (time.Time, error) { - response, err := s.Genesis(ctx) + response, err := s.Genesis(ctx, &api.GenesisOpts{}) if err != nil { return time.Time{}, errors.Wrap(err, "failed to obtain genesis") } diff --git a/http/http.go b/http/http.go index c6bd8e5e..98616232 100644 --- a/http/http.go +++ b/http/http.go @@ -32,69 +32,6 @@ import ( "go.opentelemetry.io/otel/codes" ) -// get sends an HTTP get request and returns the body. -// If the response from the server is a 404 this will return nil for both the reader and the error. -func (s *Service) get(ctx context.Context, endpoint string) (io.Reader, error) { - // #nosec G404 - log := s.log.With().Str("id", fmt.Sprintf("%02x", rand.Int31())).Str("address", s.address).Str("endpoint", endpoint).Logger() - log.Trace().Msg("GET request") - - url, err := url.Parse(fmt.Sprintf("%s%s", strings.TrimSuffix(s.base.String(), "/"), endpoint)) - if err != nil { - return nil, errors.Wrap(err, "invalid endpoint") - } - - opCtx, cancel := context.WithTimeout(ctx, s.timeout) - req, err := http.NewRequestWithContext(opCtx, http.MethodGet, url.String(), nil) - if err != nil { - cancel() - - return nil, errors.Wrap(err, "failed to create GET request") - } - s.addExtraHeaders(req) - req.Header.Set("Accept", "application/json") - - resp, err := s.client.Do(req) - if err != nil { - cancel() - - return nil, errors.Wrap(err, "failed to call GET endpoint") - } - defer resp.Body.Close() - - if resp.StatusCode == http.StatusNotFound { - // Nothing found. This is not an error, so we return nil on both counts. - cancel() - - return nil, nil - } - - data, err := io.ReadAll(resp.Body) - if err != nil { - cancel() - - return nil, errors.Wrap(err, "failed to read GET response") - } - - statusFamily := resp.StatusCode / 100 - if statusFamily != 2 { - cancel() - log.Trace().Int("status_code", resp.StatusCode).Str("data", string(data)).Msg("GET failed") - - return nil, &api.Error{ - Method: http.MethodGet, - StatusCode: resp.StatusCode, - Endpoint: endpoint, - Data: data, - } - } - cancel() - - log.Trace().Str("response", string(data)).Msg("GET response") - - return bytes.NewReader(data), nil -} - // post sends an HTTP post request and returns the body. func (s *Service) post(ctx context.Context, endpoint string, body io.Reader) (io.Reader, error) { // #nosec G404 @@ -262,9 +199,9 @@ type httpResponse struct { body []byte } -// get2 sends an HTTP get request and returns the body. +// get sends an HTTP get request and returns the body. // If the response from the server is a 404 this will return nil for both the reader and the error. -func (s *Service) get2(ctx context.Context, endpoint string) (*httpResponse, error) { +func (s *Service) get(ctx context.Context, endpoint string, opts *api.CommonOpts) (*httpResponse, error) { ctx, span := otel.Tracer("attestantio.go-eth2-client.http").Start(ctx, "get2") defer span.End() @@ -277,7 +214,12 @@ func (s *Service) get2(ctx context.Context, endpoint string) (*httpResponse, err return nil, errors.Wrap(err, "invalid endpoint") } - opCtx, cancel := context.WithTimeout(ctx, s.timeout) + timeout := s.timeout + if opts.Timeout != 0 { + timeout = opts.Timeout + } + + opCtx, cancel := context.WithTimeout(ctx, timeout) defer cancel() req, err := http.NewRequestWithContext(opCtx, http.MethodGet, url.String(), nil) if err != nil { diff --git a/http/nodeclient.go b/http/nodeclient.go index f1fb335f..1c9e7b11 100644 --- a/http/nodeclient.go +++ b/http/nodeclient.go @@ -22,7 +22,7 @@ import ( // NodeClient provides the client for the node. func (s *Service) NodeClient(ctx context.Context) (*api.Response[string], error) { - response, err := s.NodeVersion(ctx) + response, err := s.NodeVersion(ctx, &api.NodeVersionOpts{}) if err != nil { return nil, err } diff --git a/http/nodepeers.go b/http/nodepeers.go index e4516d3e..8284fbc0 100644 --- a/http/nodepeers.go +++ b/http/nodepeers.go @@ -11,9 +11,9 @@ import ( ) // NodePeers obtains the peers of a node. -func (s *Service) NodePeers(ctx context.Context, opts *api.PeerOpts) (*api.Response[[]*apiv1.Peer], error) { +func (s *Service) NodePeers(ctx context.Context, opts *api.NodePeersOpts) (*api.Response[[]*apiv1.Peer], error) { // all options are considered optional - request := "/eth/v1/node/peers" + url := "/eth/v1/node/peers" additionalFields := make([]string, 0, len(opts.State)+len(opts.Direction)) for _, stateFilter := range opts.State { @@ -25,10 +25,10 @@ func (s *Service) NodePeers(ctx context.Context, opts *api.PeerOpts) (*api.Respo } if len(additionalFields) > 0 { - request = fmt.Sprintf("%s?%s", request, strings.Join(additionalFields, "&")) + url = fmt.Sprintf("%s?%s", url, strings.Join(additionalFields, "&")) } - httpResponse, err := s.get2(ctx, request) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/nodepeers_test.go b/http/nodepeers_test.go index b544a365..86ef5f6b 100644 --- a/http/nodepeers_test.go +++ b/http/nodepeers_test.go @@ -15,12 +15,13 @@ package http_test import ( "context" + "os" + "testing" + client "github.com/attestantio/go-eth2-client" "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/http" "github.com/stretchr/testify/require" - "os" - "testing" ) func TestNodePeers(t *testing.T) { @@ -29,23 +30,23 @@ func TestNodePeers(t *testing.T) { tests := []struct { name string - opts *api.PeerOpts + opts *api.NodePeersOpts }{ { name: "AllPeers", - opts: &api.PeerOpts{}, + opts: &api.NodePeersOpts{}, }, { name: "AllInboundPeers", - opts: &api.PeerOpts{Direction: []string{"inbound"}}, + opts: &api.NodePeersOpts{Direction: []string{"inbound"}}, }, { name: "AllConnectedPeers", - opts: &api.PeerOpts{State: []string{"connected"}}, + opts: &api.NodePeersOpts{State: []string{"connected"}}, }, { name: "AllConnectedOutboundPeers", - opts: &api.PeerOpts{ + opts: &api.NodePeersOpts{ State: []string{"connected"}, Direction: []string{"outbound"}, }, diff --git a/http/nodesyncing.go b/http/nodesyncing.go index edeee589..1b6679bf 100644 --- a/http/nodesyncing.go +++ b/http/nodesyncing.go @@ -19,11 +19,17 @@ import ( "github.com/attestantio/go-eth2-client/api" apiv1 "github.com/attestantio/go-eth2-client/api/v1" + "github.com/pkg/errors" ) // NodeSyncing provides the syncing information for the node. -func (s *Service) NodeSyncing(ctx context.Context) (*api.Response[*apiv1.SyncState], error) { - httpResponse, err := s.get2(ctx, "/eth/v1/node/syncing") +func (s *Service) NodeSyncing(ctx context.Context, opts *api.NodeSyncingOpts) (*api.Response[*apiv1.SyncState], error) { + if opts == nil { + return nil, errors.New("no options specified") + } + + url := "/eth/v1/node/syncing" + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/nodesyncing_test.go b/http/nodesyncing_test.go index 2751cd01..57d691ef 100644 --- a/http/nodesyncing_test.go +++ b/http/nodesyncing_test.go @@ -19,6 +19,7 @@ import ( "testing" client "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/http" "github.com/stretchr/testify/require" ) @@ -43,7 +44,7 @@ func TestNodeSyncing(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - response, err := service.(client.NodeSyncingProvider).NodeSyncing(ctx) + response, err := service.(client.NodeSyncingProvider).NodeSyncing(ctx, &api.NodeSyncingOpts{}) require.NoError(t, err) require.NotNil(t, response) require.NotNil(t, response.Data) diff --git a/http/nodeversion.go b/http/nodeversion.go index 025a7afe..0697c99d 100644 --- a/http/nodeversion.go +++ b/http/nodeversion.go @@ -18,6 +18,7 @@ import ( "context" "github.com/attestantio/go-eth2-client/api" + "github.com/pkg/errors" ) type nodeVersionJSON struct { @@ -25,7 +26,16 @@ type nodeVersionJSON struct { } // NodeVersion provides the version information of the node. -func (s *Service) NodeVersion(ctx context.Context) (*api.Response[string], error) { +func (s *Service) NodeVersion(ctx context.Context, + opts *api.NodeVersionOpts, +) ( + *api.Response[string], + error, +) { + if opts == nil { + return nil, errors.New("no options specified") + } + s.nodeVersionMutex.RLock() if s.nodeVersion != "" { defer s.nodeVersionMutex.RUnlock() @@ -48,7 +58,8 @@ func (s *Service) NodeVersion(ctx context.Context) (*api.Response[string], error } // Up to us to fetch the information. - httpResponse, err := s.get2(ctx, "/eth/v1/node/version") + url := "/eth/v1/node/version" + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/nodeversion_test.go b/http/nodeversion_test.go index 2e47b01f..de90308e 100644 --- a/http/nodeversion_test.go +++ b/http/nodeversion_test.go @@ -19,6 +19,7 @@ import ( "testing" client "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/http" "github.com/stretchr/testify/require" ) @@ -43,7 +44,7 @@ func TestNodeVersion(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - nodeVersion, err := service.(client.NodeVersionProvider).NodeVersion(ctx) + nodeVersion, err := service.(client.NodeVersionProvider).NodeVersion(ctx, &api.NodeVersionOpts{}) require.NoError(t, err) require.NotNil(t, nodeVersion) }) diff --git a/http/proposal.go b/http/proposal.go index d713d376..1f4c4b6f 100644 --- a/http/proposal.go +++ b/http/proposal.go @@ -55,19 +55,19 @@ func (s *Service) Proposal(ctx context.Context, url = fmt.Sprintf("%s&skip_randao_verification", url) } - res, err := s.get2(ctx, url) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, errors.Wrap(err, "failed to request beacon block proposal") } var response *api.Response[*api.VersionedProposal] - switch res.contentType { + switch httpResponse.contentType { case ContentTypeSSZ: - response, err = s.beaconBlockProposalFromSSZ(res) + response, err = s.beaconBlockProposalFromSSZ(httpResponse) case ContentTypeJSON: - response, err = s.beaconBlockProposalFromJSON(res) + response, err = s.beaconBlockProposalFromJSON(httpResponse) default: - return nil, fmt.Errorf("unhandled content type %v", res.contentType) + return nil, fmt.Errorf("unhandled content type %v", httpResponse.contentType) } if err != nil { return nil, err diff --git a/http/proposal_test.go b/http/proposal_test.go index 8b8f88f6..fc74ec24 100644 --- a/http/proposal_test.go +++ b/http/proposal_test.go @@ -38,7 +38,7 @@ func TestProposal(t *testing.T) { require.NoError(t, err) // Need to fetch current slot for proposal. - genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx) + genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) slotDuration, err := service.(client.SlotDurationProvider).SlotDuration(ctx) require.NoError(t, err) diff --git a/http/proposerduties.go b/http/proposerduties.go index f24a1c04..8b711486 100644 --- a/http/proposerduties.go +++ b/http/proposerduties.go @@ -35,7 +35,8 @@ func (s *Service) ProposerDuties(ctx context.Context, return nil, errors.New("no options specified") } - httpResponse, err := s.get2(ctx, fmt.Sprintf("/eth/v1/validator/duties/proposer/%d", opts.Epoch)) + url := fmt.Sprintf("/eth/v1/validator/duties/proposer/%d", opts.Epoch) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/proposerduties_test.go b/http/proposerduties_test.go index 2bc1a4f0..3fc8df05 100644 --- a/http/proposerduties_test.go +++ b/http/proposerduties_test.go @@ -39,7 +39,7 @@ func TestProposerDuties(t *testing.T) { require.NoError(t, err) // Needed to fetch current epoch. - genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx) + genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) slotDuration, err := service.(client.SlotDurationProvider).SlotDuration(ctx) require.NoError(t, err) diff --git a/http/service.go b/http/service.go index e8bfa417..f343671a 100644 --- a/http/service.go +++ b/http/service.go @@ -24,7 +24,8 @@ import ( "time" eth2client "github.com/attestantio/go-eth2-client" - api "github.com/attestantio/go-eth2-client/api/v1" + "github.com/attestantio/go-eth2-client/api" + apiv1 "github.com/attestantio/go-eth2-client/api/v1" "github.com/attestantio/go-eth2-client/spec/phase0" "github.com/pkg/errors" "github.com/rs/zerolog" @@ -43,11 +44,11 @@ type Service struct { // Various information from the node that does not change during the // lifetime of a beacon node. - genesis *api.Genesis + genesis *apiv1.Genesis genesisMutex sync.RWMutex spec map[string]interface{} specMutex sync.RWMutex - depositContract *api.DepositContract + depositContract *apiv1.DepositContract depositContractMutex sync.RWMutex forkSchedule []*phase0.Fork forkScheduleMutex sync.RWMutex @@ -142,19 +143,19 @@ func New(ctx context.Context, params ...Parameter) (eth2client.Service, error) { // fetchStaticValues fetches values that never change. // This caches the values, avoiding future API calls. func (s *Service) fetchStaticValues(ctx context.Context) error { - if _, err := s.Genesis(ctx); err != nil { + if _, err := s.Genesis(ctx, &api.GenesisOpts{}); err != nil { return errors.Wrap(err, "failed to fetch genesis") } - if _, err := s.Spec(ctx); err != nil { + if _, err := s.Spec(ctx, &api.SpecOpts{}); err != nil { return errors.Wrap(err, "failed to fetch spec") } - if _, err := s.DepositContract(ctx); err != nil { + if _, err := s.DepositContract(ctx, &api.DepositContractOpts{}); err != nil { return errors.Wrap(err, "failed to fetch deposit contract") } - if _, err := s.ForkSchedule(ctx); err != nil { + if _, err := s.ForkSchedule(ctx, &api.ForkScheduleOpts{}); err != nil { return errors.Wrap(err, "failed to fetch fork schedule") } - if _, err := s.NodeVersion(ctx); err != nil { + if _, err := s.NodeVersion(ctx, &api.NodeVersionOpts{}); err != nil { return errors.Wrap(err, "failed to fetch node version") } @@ -196,7 +197,7 @@ func (s *Service) periodicClearStaticValues(ctx context.Context) { // checkDVT checks if connected to DVT middleware and sets // internal flags appropriately. func (s *Service) checkDVT(ctx context.Context) error { - response, err := s.NodeVersion(ctx) + response, err := s.NodeVersion(ctx, &api.NodeVersionOpts{}) if err != nil { return errors.Wrap(err, "failed to obtain node version for DVT check") } diff --git a/http/signedbeaconblock.go b/http/signedbeaconblock.go index cfff0759..9de55055 100644 --- a/http/signedbeaconblock.go +++ b/http/signedbeaconblock.go @@ -39,7 +39,8 @@ func (s *Service) SignedBeaconBlock(ctx context.Context, return nil, errors.New("no options specified") } - httpResponse, err := s.get2(ctx, fmt.Sprintf("/eth/v2/beacon/blocks/%s", opts.Block)) + url := fmt.Sprintf("/eth/v2/beacon/blocks/%s", opts.Block) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/slotduration.go b/http/slotduration.go index 3457b601..e6a7907c 100644 --- a/http/slotduration.go +++ b/http/slotduration.go @@ -16,11 +16,13 @@ package http import ( "context" "time" + + "github.com/attestantio/go-eth2-client/api" ) // SlotDuration provides the duration of a slot for the chain. func (s *Service) SlotDuration(ctx context.Context) (time.Duration, error) { - response, err := s.Spec(ctx) + response, err := s.Spec(ctx, &api.SpecOpts{}) if err != nil { return 0, err } diff --git a/http/slotsperepoch.go b/http/slotsperepoch.go index a835375c..981c76f7 100644 --- a/http/slotsperepoch.go +++ b/http/slotsperepoch.go @@ -15,11 +15,13 @@ package http import ( "context" + + "github.com/attestantio/go-eth2-client/api" ) // SlotsPerEpoch provides the number of slots per epoch for the chain. func (s *Service) SlotsPerEpoch(ctx context.Context) (uint64, error) { - response, err := s.Spec(ctx) + response, err := s.Spec(ctx, &api.SpecOpts{}) if err != nil { return 0, err } diff --git a/http/spec.go b/http/spec.go index a7752d24..81c53c15 100644 --- a/http/spec.go +++ b/http/spec.go @@ -23,10 +23,20 @@ import ( "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/spec/phase0" + "github.com/pkg/errors" ) // Spec provides the spec information of the chain. -func (s *Service) Spec(ctx context.Context) (*api.Response[map[string]any], error) { +func (s *Service) Spec(ctx context.Context, + opts *api.SpecOpts, +) ( + *api.Response[map[string]any], + error, +) { + if opts == nil { + return nil, errors.New("no options specified") + } + s.specMutex.RLock() if s.spec != nil { defer s.specMutex.RUnlock() @@ -49,7 +59,8 @@ func (s *Service) Spec(ctx context.Context) (*api.Response[map[string]any], erro } // Up to us to fetch the information. - httpResponse, err := s.get2(ctx, "/eth/v1/config/spec") + url := "/eth/v1/config/spec" + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/spec_test.go b/http/spec_test.go index 916d59b1..7aaff032 100644 --- a/http/spec_test.go +++ b/http/spec_test.go @@ -19,6 +19,7 @@ import ( "testing" client "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/http" "github.com/attestantio/go-eth2-client/spec/phase0" "github.com/stretchr/testify/require" @@ -44,7 +45,7 @@ func TestSpec(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - response, err := service.(client.SpecProvider).Spec(ctx) + response, err := service.(client.SpecProvider).Spec(ctx, &api.SpecOpts{}) require.NoError(t, err) // Check an integer type. require.IsType(t, response.Data["BASE_REWARD_FACTOR"], uint64(0)) diff --git a/http/submitattestations_test.go b/http/submitattestations_test.go index fcecceb1..dbed1787 100644 --- a/http/submitattestations_test.go +++ b/http/submitattestations_test.go @@ -39,7 +39,7 @@ func TestSubmitAttestations(t *testing.T) { require.NoError(t, err) // Need to fetch current slot for attestation. - genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx) + genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) slotDuration, err := service.(client.SlotDurationProvider).SlotDuration(ctx) require.NoError(t, err) diff --git a/http/submitbeaconblock_test.go b/http/submitbeaconblock_test.go index 3bb8835f..58dab7c6 100644 --- a/http/submitbeaconblock_test.go +++ b/http/submitbeaconblock_test.go @@ -41,7 +41,7 @@ func TestSubmitBeaconBlock(t *testing.T) { require.NoError(t, err) // Need to fetch current slot for proposal. - genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx) + genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) slotDuration, err := service.(client.SlotDurationProvider).SlotDuration(ctx) require.NoError(t, err) diff --git a/http/submitproposal_test.go b/http/submitproposal_test.go index 2cc05151..9cd935fc 100644 --- a/http/submitproposal_test.go +++ b/http/submitproposal_test.go @@ -41,7 +41,7 @@ func TestSubmitProposal(t *testing.T) { require.NoError(t, err) // Need to fetch current slot for proposal. - genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx) + genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) slotDuration, err := service.(client.SlotDurationProvider).SlotDuration(ctx) require.NoError(t, err) diff --git a/http/submitproposalslashing.go b/http/submitproposalslashing.go index 26310c2c..93029876 100644 --- a/http/submitproposalslashing.go +++ b/http/submitproposalslashing.go @@ -23,7 +23,7 @@ import ( ) // SubmitProposalSlashing submits a proposal slashing. -func (s *Service) SubmitProposalSlashing(ctx context.Context, slashing phase0.ProposerSlashing) error { +func (s *Service) SubmitProposalSlashing(ctx context.Context, slashing *phase0.ProposerSlashing) error { specJSON, err := json.Marshal(slashing) if err != nil { return errors.Wrap(err, "failed to marshal JSON") diff --git a/http/synccommittee.go b/http/synccommittee.go index 7f12fdac..f3ca482c 100644 --- a/http/synccommittee.go +++ b/http/synccommittee.go @@ -42,7 +42,7 @@ func (s *Service) SyncCommittee(ctx context.Context, url = fmt.Sprintf("%s?epoch=%d", url, *opts.Epoch) } - httpResponse, err := s.get2(ctx, url) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/synccommitteecontribution.go b/http/synccommitteecontribution.go index 64718252..c00222ec 100644 --- a/http/synccommitteecontribution.go +++ b/http/synccommitteecontribution.go @@ -37,7 +37,8 @@ func (s *Service) SyncCommitteeContribution(ctx context.Context, return nil, errors.New("no beacon block root specified") } - httpResponse, err := s.get2(ctx, fmt.Sprintf("/eth/v1/validator/sync_committee_contribution?slot=%d&subcommittee_index=%d&beacon_block_root=%#x", opts.Slot, opts.SubcommitteeIndex, opts.BeaconBlockRoot)) + url := fmt.Sprintf("/eth/v1/validator/sync_committee_contribution?slot=%d&subcommittee_index=%d&beacon_block_root=%#x", opts.Slot, opts.SubcommitteeIndex, opts.BeaconBlockRoot) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } diff --git a/http/synccommitteecontribution_test.go b/http/synccommitteecontribution_test.go index b6c222b9..64f55919 100644 --- a/http/synccommitteecontribution_test.go +++ b/http/synccommitteecontribution_test.go @@ -38,7 +38,7 @@ func TestSyncCommitteeContribution(t *testing.T) { require.NoError(t, err) // Needed to fetch current epoch. - genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx) + genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) slotDuration, err := service.(client.SlotDurationProvider).SlotDuration(ctx) require.NoError(t, err) diff --git a/http/synccommitteeduties_test.go b/http/synccommitteeduties_test.go index 44c16759..a55bd430 100644 --- a/http/synccommitteeduties_test.go +++ b/http/synccommitteeduties_test.go @@ -37,7 +37,7 @@ func TestSyncCommitteeDuties(t *testing.T) { require.NoError(t, err) // Needed to fetch current epoch. - genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx) + genesisResponse, err := service.(client.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) slotDuration, err := service.(client.SlotDurationProvider).SlotDuration(ctx) require.NoError(t, err) diff --git a/http/targetaggregatorspercommittee.go b/http/targetaggregatorspercommittee.go index 6d3135a1..e6bd73d6 100644 --- a/http/targetaggregatorspercommittee.go +++ b/http/targetaggregatorspercommittee.go @@ -15,11 +15,13 @@ package http import ( "context" + + "github.com/attestantio/go-eth2-client/api" ) // TargetAggregatorsPerCommittee provides the target aggregators per committee of the chain. func (s *Service) TargetAggregatorsPerCommittee(ctx context.Context) (uint64, error) { - response, err := s.Spec(ctx) + response, err := s.Spec(ctx, &api.SpecOpts{}) if err != nil { return 0, err } diff --git a/http/validatorbalances.go b/http/validatorbalances.go index ac9f1620..881ff8bb 100644 --- a/http/validatorbalances.go +++ b/http/validatorbalances.go @@ -52,16 +52,16 @@ func (s *Service) ValidatorBalances(ctx context.Context, url = fmt.Sprintf("%s?id=%s", url, strings.Join(ids, ",")) } - response, err := s.get2(ctx, url) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, err } - switch response.contentType { + switch httpResponse.contentType { case ContentTypeJSON: - return s.validatorBalancesFromJSON(ctx, response) + return s.validatorBalancesFromJSON(ctx, httpResponse) default: - return nil, fmt.Errorf("unhandled content type %v", response.contentType) + return nil, fmt.Errorf("unhandled content type %v", httpResponse.contentType) } } diff --git a/http/validators.go b/http/validators.go index 45925183..0ec0402a 100644 --- a/http/validators.go +++ b/http/validators.go @@ -14,6 +14,7 @@ package http import ( + "bytes" "context" "fmt" "strings" @@ -152,12 +153,12 @@ func (s *Service) Validators(ctx context.Context, url = fmt.Sprintf("%s?id=%s", url, strings.Join(ids, ",")) } - respBodyReader, err := s.get(ctx, url) + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, errors.Wrap(err, "failed to request validators") } - data, metadata, err := decodeJSONResponse(respBodyReader, []*apiv1.Validator{}) + data, metadata, err := decodeJSONResponse(bytes.NewReader(httpResponse.body), []*apiv1.Validator{}) if err != nil { return nil, err } diff --git a/http/voluntaryexitpool.go b/http/voluntaryexitpool.go index 5ce9cbdf..f2dc4ebe 100644 --- a/http/voluntaryexitpool.go +++ b/http/voluntaryexitpool.go @@ -14,9 +14,11 @@ package http import ( + "bytes" "context" "encoding/json" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/spec/phase0" "github.com/pkg/errors" ) @@ -26,17 +28,24 @@ type voluntaryExitPoolJSON struct { } // VoluntaryExitPool obtains the voluntary exit pool. -func (s *Service) VoluntaryExitPool(ctx context.Context) ([]*phase0.SignedVoluntaryExit, error) { - respBodyReader, err := s.get(ctx, "/eth/v1/beacon/pool/voluntary_exits") +func (s *Service) VoluntaryExitPool(ctx context.Context, + opts *api.VoluntaryExitPoolOpts, +) ( + *api.Response[[]*phase0.SignedVoluntaryExit], + error, +) { + if opts == nil { + return nil, errors.New("no options specified") + } + + url := "/eth/v1/beacon/pool/voluntary_exits" + httpResponse, err := s.get(ctx, url, &opts.Common) if err != nil { return nil, errors.Wrap(err, "failed to request voluntary exit pool") } - if respBodyReader == nil { - return nil, errors.New("failed to obtain voluntary exit pool") - } var voluntaryExitPoolJSON voluntaryExitPoolJSON - if err := json.NewDecoder(respBodyReader).Decode(&voluntaryExitPoolJSON); err != nil { + if err := json.NewDecoder(bytes.NewReader(httpResponse.body)).Decode(&voluntaryExitPoolJSON); err != nil { return nil, errors.Wrap(err, "failed to parse voluntary exit pool") } @@ -45,5 +54,8 @@ func (s *Service) VoluntaryExitPool(ctx context.Context) ([]*phase0.SignedVolunt return nil, errors.New("voluntary exit pool not returned") } - return voluntaryExitPoolJSON.Data, nil + return &api.Response[[]*phase0.SignedVoluntaryExit]{ + Data: voluntaryExitPoolJSON.Data, + Metadata: make(map[string]any), + }, nil } diff --git a/http/voluntaryexitpool_test.go b/http/voluntaryexitpool_test.go index 3d292116..366ed12f 100644 --- a/http/voluntaryexitpool_test.go +++ b/http/voluntaryexitpool_test.go @@ -19,6 +19,7 @@ import ( "testing" client "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/http" "github.com/stretchr/testify/require" ) @@ -43,7 +44,7 @@ func TestVoluntaryExitPool(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - voluntaryExitPool, err := service.(client.VoluntaryExitPoolProvider).VoluntaryExitPool(ctx) + voluntaryExitPool, err := service.(client.VoluntaryExitPoolProvider).VoluntaryExitPool(ctx, &api.VoluntaryExitPoolOpts{}) require.NoError(t, err) require.NotNil(t, voluntaryExitPool) }) diff --git a/mock/depositcontract.go b/mock/depositcontract.go index fcc1e43d..dcb4746a 100644 --- a/mock/depositcontract.go +++ b/mock/depositcontract.go @@ -21,7 +21,7 @@ import ( ) // DepositContract provides details of the execution layer deposit contract for the chain. -func (s *Service) DepositContract(_ context.Context) (*api.Response[*apiv1.DepositContract], error) { +func (s *Service) DepositContract(_ context.Context, _ *api.DepositContractOpts) (*api.Response[*apiv1.DepositContract], error) { return &api.Response[*apiv1.DepositContract]{ Data: &apiv1.DepositContract{}, Metadata: make(map[string]any), diff --git a/mock/domain.go b/mock/domain.go index 9da532ef..3f96c94f 100644 --- a/mock/domain.go +++ b/mock/domain.go @@ -17,6 +17,7 @@ import ( "bytes" "context" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/spec/phase0" "github.com/pkg/errors" ) @@ -68,7 +69,7 @@ func (s *Service) domain(ctx context.Context, if !bytes.Equal(domainType[:], []byte{0x00, 0x00, 0x00, 0x01}) { // Use the chain's genesis validators root for non-application domain types. - genesisResponse, err := s.Genesis(ctx) + genesisResponse, err := s.Genesis(ctx, &api.GenesisOpts{}) if err != nil { return phase0.Domain{}, errors.Wrap(err, "failed to obtain genesis") } @@ -90,7 +91,7 @@ func (s *Service) domain(ctx context.Context, // forkAtEpoch works through the fork schedule to obtain the current fork. func (s *Service) forkAtEpoch(ctx context.Context, epoch phase0.Epoch) (*phase0.Fork, error) { - response, err := s.ForkSchedule(ctx) + response, err := s.ForkSchedule(ctx, &api.ForkScheduleOpts{}) if err != nil { return nil, errors.Wrap(err, "failed to obtain fork schedule") } @@ -112,7 +113,7 @@ func (s *Service) forkAtEpoch(ctx context.Context, epoch phase0.Epoch) (*phase0. // forkAtGenesis returns the genesis fork. func (s *Service) forkAtGenesis(ctx context.Context) (*phase0.Fork, error) { - response, err := s.ForkSchedule(ctx) + response, err := s.ForkSchedule(ctx, &api.ForkScheduleOpts{}) if err != nil { return nil, errors.Wrap(err, "failed to obtain fork schedule") } diff --git a/mock/forkschedule.go b/mock/forkschedule.go index f011dd22..32bef4bf 100644 --- a/mock/forkschedule.go +++ b/mock/forkschedule.go @@ -21,7 +21,7 @@ import ( ) // ForkSchedule provides details of past and future changes in the chain's fork version. -func (s *Service) ForkSchedule(_ context.Context) (*api.Response[[]*spec.Fork], error) { +func (s *Service) ForkSchedule(_ context.Context, _ *api.ForkScheduleOpts) (*api.Response[[]*spec.Fork], error) { data := []*spec.Fork{ { PreviousVersion: spec.Version{0x01, 0x02, 0x03, 0x04}, diff --git a/mock/genesis.go b/mock/genesis.go index 69ad8a6e..056ad303 100644 --- a/mock/genesis.go +++ b/mock/genesis.go @@ -22,7 +22,7 @@ import ( ) // Genesis provides the genesis information of the chain. -func (s *Service) Genesis(_ context.Context) (*api.Response[*apiv1.Genesis], error) { +func (s *Service) Genesis(_ context.Context, _ *api.GenesisOpts) (*api.Response[*apiv1.Genesis], error) { data := &apiv1.Genesis{ GenesisTime: s.genesisTime, GenesisValidatorsRoot: phase0.Root([32]byte{ diff --git a/mock/genesis_test.go b/mock/genesis_test.go index 5b7a3e5b..cfeababa 100644 --- a/mock/genesis_test.go +++ b/mock/genesis_test.go @@ -17,6 +17,7 @@ import ( "context" "testing" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/mock" "github.com/stretchr/testify/require" ) @@ -35,7 +36,7 @@ func TestGenesis(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - response, err := service.Genesis(context.Background()) + response, err := service.Genesis(context.Background(), &api.GenesisOpts{}) require.NoError(t, err) require.NotNil(t, response) require.NotNil(t, response.Data) diff --git a/mock/genesistime.go b/mock/genesistime.go index c9b06413..ac423bba 100644 --- a/mock/genesistime.go +++ b/mock/genesistime.go @@ -16,11 +16,13 @@ package mock import ( "context" "time" + + "github.com/attestantio/go-eth2-client/api" ) // GenesisTime provides the genesis time of the chain. func (s *Service) GenesisTime(ctx context.Context) (time.Time, error) { - genesisResponse, err := s.Genesis(ctx) + genesisResponse, err := s.Genesis(ctx, &api.GenesisOpts{}) if err != nil { return time.Time{}, err } diff --git a/mock/nodepeers.go b/mock/nodepeers.go index 801dfb21..42cf85b4 100644 --- a/mock/nodepeers.go +++ b/mock/nodepeers.go @@ -21,7 +21,7 @@ import ( ) // NodePeers provides the peers of the node. -func (s *Service) NodePeers(_ context.Context, _ *api.PeerOpts) (*api.Response[[]*apiv1.Peer], error) { +func (s *Service) NodePeers(_ context.Context, _ *api.NodePeersOpts) (*api.Response[[]*apiv1.Peer], error) { return &api.Response[[]*apiv1.Peer]{ Data: []*apiv1.Peer{{ PeerID: "MOCK16Uiu2HAm7ukVy4XugqVShYbLih4H2jBJjYevevznBZaHsmd1FM96", diff --git a/mock/nodesyncing.go b/mock/nodesyncing.go index 574582c7..8afc72da 100644 --- a/mock/nodesyncing.go +++ b/mock/nodesyncing.go @@ -21,7 +21,7 @@ import ( ) // NodeSyncing provides the state of the node's synchronization with the chain. -func (s *Service) NodeSyncing(_ context.Context) (*api.Response[*apiv1.SyncState], error) { +func (s *Service) NodeSyncing(_ context.Context, _ *api.NodeSyncingOpts) (*api.Response[*apiv1.SyncState], error) { return &api.Response[*apiv1.SyncState]{ Data: &apiv1.SyncState{ HeadSlot: s.HeadSlot, diff --git a/mock/nodeversion.go b/mock/nodeversion.go index 88b5a04a..180ee0c6 100644 --- a/mock/nodeversion.go +++ b/mock/nodeversion.go @@ -20,7 +20,7 @@ import ( ) // NodeVersion returns a free-text string with the node version. -func (s *Service) NodeVersion(_ context.Context) (*api.Response[string], error) { +func (s *Service) NodeVersion(_ context.Context, _ *api.NodeVersionOpts) (*api.Response[string], error) { return &api.Response[string]{ Data: s.nodeVersion, Metadata: make(map[string]any), diff --git a/mock/service.go b/mock/service.go index 05f96943..dfd16379 100644 --- a/mock/service.go +++ b/mock/service.go @@ -17,6 +17,7 @@ import ( "context" "time" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/spec/phase0" "github.com/pkg/errors" "github.com/rs/zerolog" @@ -87,7 +88,7 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) { // fetchStaticValues fetches values that never change. // This caches the values, avoiding future API calls. func (s *Service) fetchStaticValues(ctx context.Context) error { - if _, err := s.Genesis(ctx); err != nil { + if _, err := s.Genesis(ctx, &api.GenesisOpts{}); err != nil { return errors.Wrap(err, "failed to fetch genesis") } // if _, err := s.Spec(ctx); err != nil { diff --git a/mock/spec.go b/mock/spec.go index 5e953476..e776565a 100644 --- a/mock/spec.go +++ b/mock/spec.go @@ -22,7 +22,7 @@ import ( // Spec provides the spec information of the chain. // This returns various useful values. -func (s *Service) Spec(_ context.Context) (*api.Response[map[string]any], error) { +func (s *Service) Spec(_ context.Context, _ *api.SpecOpts) (*api.Response[map[string]any], error) { data := map[string]any{ "SECONDS_PER_SLOT": 12 * time.Second, "SLOTS_PER_EPOCH": uint64(32), diff --git a/mock/voluntaryexitpool.go b/mock/voluntaryexitpool.go index a4ffb48d..22c1a313 100644 --- a/mock/voluntaryexitpool.go +++ b/mock/voluntaryexitpool.go @@ -16,11 +16,12 @@ package mock import ( "context" + "github.com/attestantio/go-eth2-client/api" spec "github.com/attestantio/go-eth2-client/spec/phase0" ) // VoluntaryExitPool fetches the voluntary exit pool. -func (s *Service) VoluntaryExitPool(_ context.Context) ([]*spec.SignedVoluntaryExit, error) { +func (s *Service) VoluntaryExitPool(_ context.Context, _ *api.VoluntaryExitPoolOpts) (*api.Response[[]*spec.SignedVoluntaryExit], error) { res := make([]*spec.SignedVoluntaryExit, 5) for i := 0; i < 5; i++ { res[i] = &spec.SignedVoluntaryExit{ @@ -39,5 +40,8 @@ func (s *Service) VoluntaryExitPool(_ context.Context) ([]*spec.SignedVoluntaryE } } - return res, nil + return &api.Response[[]*spec.SignedVoluntaryExit]{ + Data: res, + Metadata: make(map[string]any), + }, nil } diff --git a/multi/client.go b/multi/client.go index 58b87360..a5f81d57 100644 --- a/multi/client.go +++ b/multi/client.go @@ -19,6 +19,7 @@ import ( "time" consensusclient "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/pkg/errors" "github.com/rs/zerolog" ) @@ -127,7 +128,7 @@ func ping(ctx context.Context, client consensusclient.Service) bool { return false } - response, err := provider.NodeSyncing(ctx) + response, err := provider.NodeSyncing(ctx, &api.NodeSyncingOpts{}) if err != nil { log.Warn().Err(err).Msg("Failed to obtain sync state from node") @@ -208,7 +209,7 @@ func (s *Service) providerInfo(ctx context.Context, provider consensusclient.Ser providerName := "" nodeVersionProvider, isNodeVersionProvider := provider.(consensusclient.NodeVersionProvider) if isNodeVersionProvider { - response, err := nodeVersionProvider.NodeVersion(ctx) + response, err := nodeVersionProvider.NodeVersion(ctx, &api.NodeVersionOpts{}) if err == nil { switch { case strings.Contains(strings.ToLower(response.Data), "lighthouse"): diff --git a/multi/client_internal_test.go b/multi/client_internal_test.go index 6b1427f2..55b7adec 100644 --- a/multi/client_internal_test.go +++ b/multi/client_internal_test.go @@ -19,6 +19,7 @@ import ( "testing" consensusclient "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/mock" "github.com/attestantio/go-eth2-client/testclients" "github.com/rs/zerolog" @@ -132,12 +133,12 @@ func TestRecheck(t *testing.T) { require.NoError(t, err) multi := s.(*Service) - _, err = s.(consensusclient.GenesisProvider).Genesis(ctx) + _, err = s.(consensusclient.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) multi.deactivateClient(ctx, consensusClient) - _, err = s.(consensusclient.GenesisProvider).Genesis(ctx) + _, err = s.(consensusclient.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) // Should re-activate in recheck so not return an error. require.NoError(t, err) } diff --git a/multi/client_test.go b/multi/client_test.go index db19c432..2719609a 100644 --- a/multi/client_test.go +++ b/multi/client_test.go @@ -18,6 +18,7 @@ import ( "testing" consensusclient "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/mock" "github.com/attestantio/go-eth2-client/multi" "github.com/attestantio/go-eth2-client/testclients" @@ -49,7 +50,7 @@ func TestClient(t *testing.T) { require.NoError(t, err) for i := 0; i < 1024; i++ { - _, err := s.(consensusclient.GenesisProvider).Genesis(ctx) + _, err := s.(consensusclient.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) } } diff --git a/multi/depositcontract.go b/multi/depositcontract.go index 8a8f3ba3..98999a0e 100644 --- a/multi/depositcontract.go +++ b/multi/depositcontract.go @@ -22,9 +22,14 @@ import ( ) // DepositContract provides details of the Ethereum 1 deposit contract for the chain. -func (s *Service) DepositContract(ctx context.Context) (*api.Response[*apiv1.DepositContract], error) { +func (s *Service) DepositContract(ctx context.Context, + opts *api.DepositContractOpts, +) ( + *api.Response[*apiv1.DepositContract], + error, +) { res, err := s.doCall(ctx, func(ctx context.Context, client consensusclient.Service) (interface{}, error) { - aggregate, err := client.(consensusclient.DepositContractProvider).DepositContract(ctx) + aggregate, err := client.(consensusclient.DepositContractProvider).DepositContract(ctx, opts) if err != nil { return nil, err } diff --git a/multi/depositcontract_test.go b/multi/depositcontract_test.go index 767430e6..f01d9222 100644 --- a/multi/depositcontract_test.go +++ b/multi/depositcontract_test.go @@ -18,6 +18,7 @@ import ( "testing" consensusclient "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/mock" "github.com/attestantio/go-eth2-client/multi" "github.com/attestantio/go-eth2-client/testclients" @@ -50,7 +51,7 @@ func TestDepositContract(t *testing.T) { require.NoError(t, err) for i := 0; i < 128; i++ { - res, err := multiClient.(consensusclient.DepositContractProvider).DepositContract(ctx) + res, err := multiClient.(consensusclient.DepositContractProvider).DepositContract(ctx, &api.DepositContractOpts{}) require.NoError(t, err) require.NotNil(t, res) } diff --git a/multi/events.go b/multi/events.go index 9c94dbe6..21b1fdd4 100644 --- a/multi/events.go +++ b/multi/events.go @@ -20,7 +20,8 @@ import ( "time" consensusclient "github.com/attestantio/go-eth2-client" - api "github.com/attestantio/go-eth2-client/api/v1" + "github.com/attestantio/go-eth2-client/api" + apiv1 "github.com/attestantio/go-eth2-client/api/v1" "github.com/rs/zerolog" ) @@ -73,7 +74,7 @@ func (s *Service) Events(ctx context.Context, return } - syncResponse, err := provider.NodeSyncing(ctx) + syncResponse, err := provider.NodeSyncing(ctx, &api.NodeSyncingOpts{}) if err != nil { ah.log.Error().Str("address", ah.address).Strs("topics", topics).Err(err).Msg("Failed to obtain sync state from node") @@ -103,7 +104,7 @@ type activeHandler struct { handler consensusclient.EventHandlerFunc } -func (h *activeHandler) handleEvent(event *api.Event) { +func (h *activeHandler) handleEvent(event *apiv1.Event) { h.log.Trace().Str("address", h.address).Str("topic", event.Topic).Msg("Event received") // We only forward events from the currently active provider. If we did not do this then we could end up with // inconsistent results, for example a client may receive a `head` event and a subsequent call to fetch the head diff --git a/multi/forkschedule.go b/multi/forkschedule.go index 1fc7112d..08b910bc 100644 --- a/multi/forkschedule.go +++ b/multi/forkschedule.go @@ -22,9 +22,14 @@ import ( ) // ForkSchedule provides details of past and future changes in the chain's fork version. -func (s *Service) ForkSchedule(ctx context.Context) (*api.Response[[]*phase0.Fork], error) { +func (s *Service) ForkSchedule(ctx context.Context, + opts *api.ForkScheduleOpts, +) ( + *api.Response[[]*phase0.Fork], + error, +) { res, err := s.doCall(ctx, func(ctx context.Context, client consensusclient.Service) (interface{}, error) { - forkSchedule, err := client.(consensusclient.ForkScheduleProvider).ForkSchedule(ctx) + forkSchedule, err := client.(consensusclient.ForkScheduleProvider).ForkSchedule(ctx, opts) if err != nil { return nil, err } diff --git a/multi/forkschedule_test.go b/multi/forkschedule_test.go index 30708234..98a1a6b0 100644 --- a/multi/forkschedule_test.go +++ b/multi/forkschedule_test.go @@ -18,6 +18,7 @@ import ( "testing" consensusclient "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/mock" "github.com/attestantio/go-eth2-client/multi" "github.com/attestantio/go-eth2-client/testclients" @@ -50,7 +51,7 @@ func TestForkSchedule(t *testing.T) { require.NoError(t, err) for i := 0; i < 128; i++ { - res, err := multiClient.(consensusclient.ForkScheduleProvider).ForkSchedule(ctx) + res, err := multiClient.(consensusclient.ForkScheduleProvider).ForkSchedule(ctx, &api.ForkScheduleOpts{}) require.NoError(t, err) require.NotNil(t, res) } diff --git a/multi/genesis.go b/multi/genesis.go index af881d4f..d6cf002e 100644 --- a/multi/genesis.go +++ b/multi/genesis.go @@ -22,9 +22,14 @@ import ( ) // Genesis provides the genesis for the chain. -func (s *Service) Genesis(ctx context.Context) (*api.Response[*apiv1.Genesis], error) { +func (s *Service) Genesis(ctx context.Context, + opts *api.GenesisOpts, +) ( + *api.Response[*apiv1.Genesis], + error, +) { res, err := s.doCall(ctx, func(ctx context.Context, client consensusclient.Service) (interface{}, error) { - genesis, err := client.(consensusclient.GenesisProvider).Genesis(ctx) + genesis, err := client.(consensusclient.GenesisProvider).Genesis(ctx, opts) if err != nil { return nil, err } diff --git a/multi/genesis_test.go b/multi/genesis_test.go index ad0f1080..73a7c1c9 100644 --- a/multi/genesis_test.go +++ b/multi/genesis_test.go @@ -18,6 +18,7 @@ import ( "testing" consensusclient "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/mock" "github.com/attestantio/go-eth2-client/multi" "github.com/attestantio/go-eth2-client/testclients" @@ -50,7 +51,7 @@ func TestGenesis(t *testing.T) { require.NoError(t, err) for i := 0; i < 128; i++ { - res, err := multiClient.(consensusclient.GenesisProvider).Genesis(ctx) + res, err := multiClient.(consensusclient.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) require.NotNil(t, res) } diff --git a/multi/genesistime.go b/multi/genesistime.go index 9a063c34..6a8c7a30 100644 --- a/multi/genesistime.go +++ b/multi/genesistime.go @@ -22,6 +22,8 @@ import ( ) // GenesisTime provides the genesis time of the chain. +// +// Deprecated: use Genesis(). func (s *Service) GenesisTime(ctx context.Context) (time.Time, error) { res, err := s.doCall(ctx, func(ctx context.Context, client consensusclient.Service) (interface{}, error) { genesisTime, err := client.(consensusclient.GenesisTimeProvider).GenesisTime(ctx) diff --git a/multi/nodepeers.go b/multi/nodepeers.go index 182fd9d7..085f22d0 100644 --- a/multi/nodepeers.go +++ b/multi/nodepeers.go @@ -22,7 +22,7 @@ import ( ) // NodePeers provides the peers of the node. -func (s *Service) NodePeers(ctx context.Context, opts *api.PeerOpts) (*api.Response[[]*apiv1.Peer], error) { +func (s *Service) NodePeers(ctx context.Context, opts *api.NodePeersOpts) (*api.Response[[]*apiv1.Peer], error) { res, err := s.doCall(ctx, func(ctx context.Context, client consensusclient.Service) (interface{}, error) { nodePeers, err := client.(consensusclient.NodePeersProvider).NodePeers(ctx, opts) if err != nil { diff --git a/multi/nodepeers_test.go b/multi/nodepeers_test.go index c8a5120f..0ed13658 100644 --- a/multi/nodepeers_test.go +++ b/multi/nodepeers_test.go @@ -52,7 +52,7 @@ func TestNodePeers(t *testing.T) { require.NoError(t, err) for i := 0; i < 128; i++ { - res, err := multiClient.(consensusclient.NodePeersProvider).NodePeers(ctx, &api.PeerOpts{}) + res, err := multiClient.(consensusclient.NodePeersProvider).NodePeers(ctx, &api.NodePeersOpts{}) require.NoError(t, err) require.NotNil(t, res) } diff --git a/multi/nodesyncing.go b/multi/nodesyncing.go index 3451fcd1..760827b2 100644 --- a/multi/nodesyncing.go +++ b/multi/nodesyncing.go @@ -22,9 +22,14 @@ import ( ) // NodeSyncing provides the syncing information for the node. -func (s *Service) NodeSyncing(ctx context.Context) (*api.Response[*apiv1.SyncState], error) { +func (s *Service) NodeSyncing(ctx context.Context, + opts *api.NodeSyncingOpts, +) ( + *api.Response[*apiv1.SyncState], + error, +) { res, err := s.doCall(ctx, func(ctx context.Context, client consensusclient.Service) (interface{}, error) { - nodeSyncing, err := client.(consensusclient.NodeSyncingProvider).NodeSyncing(ctx) + nodeSyncing, err := client.(consensusclient.NodeSyncingProvider).NodeSyncing(ctx, opts) if err != nil { return nil, err } diff --git a/multi/nodesyncing_test.go b/multi/nodesyncing_test.go index d3d8f491..3c0fcf93 100644 --- a/multi/nodesyncing_test.go +++ b/multi/nodesyncing_test.go @@ -18,6 +18,7 @@ import ( "testing" consensusclient "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/mock" "github.com/attestantio/go-eth2-client/multi" "github.com/attestantio/go-eth2-client/testclients" @@ -50,7 +51,7 @@ func TestNodeSyncing(t *testing.T) { require.NoError(t, err) for i := 0; i < 128; i++ { - res, err := multiClient.(consensusclient.NodeSyncingProvider).NodeSyncing(ctx) + res, err := multiClient.(consensusclient.NodeSyncingProvider).NodeSyncing(ctx, &api.NodeSyncingOpts{}) require.NoError(t, err) require.NotNil(t, res) } diff --git a/multi/nodeversion.go b/multi/nodeversion.go index cb5cf4cb..a5d21ef0 100644 --- a/multi/nodeversion.go +++ b/multi/nodeversion.go @@ -21,9 +21,9 @@ import ( ) // NodeVersion provides the version information of the node. -func (s *Service) NodeVersion(ctx context.Context) (*api.Response[string], error) { +func (s *Service) NodeVersion(ctx context.Context, opts *api.NodeVersionOpts) (*api.Response[string], error) { res, err := s.doCall(ctx, func(ctx context.Context, client consensusclient.Service) (interface{}, error) { - aggregate, err := client.(consensusclient.NodeVersionProvider).NodeVersion(ctx) + aggregate, err := client.(consensusclient.NodeVersionProvider).NodeVersion(ctx, opts) if err != nil { return nil, err } diff --git a/multi/nodeversion_test.go b/multi/nodeversion_test.go index e376ad52..a1865207 100644 --- a/multi/nodeversion_test.go +++ b/multi/nodeversion_test.go @@ -18,6 +18,7 @@ import ( "testing" consensusclient "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/mock" "github.com/attestantio/go-eth2-client/multi" "github.com/attestantio/go-eth2-client/testclients" @@ -50,7 +51,7 @@ func TestNodeVersion(t *testing.T) { require.NoError(t, err) for i := 0; i < 128; i++ { - res, err := multiClient.(consensusclient.NodeVersionProvider).NodeVersion(ctx) + res, err := multiClient.(consensusclient.NodeVersionProvider).NodeVersion(ctx, &api.NodeVersionOpts{}) require.NoError(t, err) require.NotNil(t, res) } diff --git a/multi/slotduration.go b/multi/slotduration.go index 9b6bc067..a559849c 100644 --- a/multi/slotduration.go +++ b/multi/slotduration.go @@ -22,6 +22,8 @@ import ( ) // SlotDuration provides the duration of a slot of the chain. +// +// Deprecated: use Spec(). func (s *Service) SlotDuration(ctx context.Context) (time.Duration, error) { res, err := s.doCall(ctx, func(ctx context.Context, client consensusclient.Service) (interface{}, error) { duration, err := client.(consensusclient.SlotDurationProvider).SlotDuration(ctx) diff --git a/multi/slotsperepoch.go b/multi/slotsperepoch.go index 20c0989d..b56f3cc1 100644 --- a/multi/slotsperepoch.go +++ b/multi/slotsperepoch.go @@ -21,6 +21,8 @@ import ( ) // SlotsPerEpoch provides the slots per epoch of the chain. +// +// Deprecated: use Spec(). func (s *Service) SlotsPerEpoch(ctx context.Context) (uint64, error) { res, err := s.doCall(ctx, func(ctx context.Context, client consensusclient.Service) (interface{}, error) { slotsPerEpoch, err := client.(consensusclient.SlotsPerEpochProvider).SlotsPerEpoch(ctx) diff --git a/multi/spec.go b/multi/spec.go index 22b6ba2a..2557d248 100644 --- a/multi/spec.go +++ b/multi/spec.go @@ -21,9 +21,14 @@ import ( ) // Spec provides the spec information of the chain. -func (s *Service) Spec(ctx context.Context) (*api.Response[map[string]any], error) { +func (s *Service) Spec(ctx context.Context, + opts *api.SpecOpts, +) ( + *api.Response[map[string]any], + error, +) { res, err := s.doCall(ctx, func(ctx context.Context, client consensusclient.Service) (interface{}, error) { - aggregate, err := client.(consensusclient.SpecProvider).Spec(ctx) + aggregate, err := client.(consensusclient.SpecProvider).Spec(ctx, opts) if err != nil { return nil, err } diff --git a/multi/spec_test.go b/multi/spec_test.go index 5b098446..f29eecd3 100644 --- a/multi/spec_test.go +++ b/multi/spec_test.go @@ -18,6 +18,7 @@ import ( "testing" consensusclient "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/mock" "github.com/attestantio/go-eth2-client/multi" "github.com/attestantio/go-eth2-client/testclients" @@ -50,7 +51,7 @@ func TestSpec(t *testing.T) { require.NoError(t, err) for i := 0; i < 128; i++ { - res, err := multiClient.(consensusclient.SpecProvider).Spec(ctx) + res, err := multiClient.(consensusclient.SpecProvider).Spec(ctx, &api.SpecOpts{}) require.NoError(t, err) require.NotNil(t, res) } diff --git a/multi/targetaggregatorspercommittee.go b/multi/targetaggregatorspercommittee.go index 05d21658..8e234f55 100644 --- a/multi/targetaggregatorspercommittee.go +++ b/multi/targetaggregatorspercommittee.go @@ -21,6 +21,8 @@ import ( ) // TargetAggregatorsPerCommittee provides the target number of aggregators for each attestation committee. +// +// Deprecated: Use Spec(). func (s *Service) TargetAggregatorsPerCommittee(ctx context.Context) (uint64, error) { res, err := s.doCall(ctx, func(ctx context.Context, client consensusclient.Service) (interface{}, error) { aggregators, err := client.(consensusclient.TargetAggregatorsPerCommitteeProvider).TargetAggregatorsPerCommittee(ctx) diff --git a/multi/voluntaryexitpool.go b/multi/voluntaryexitpool.go index b9d6acbc..24b6b151 100644 --- a/multi/voluntaryexitpool.go +++ b/multi/voluntaryexitpool.go @@ -17,13 +17,19 @@ import ( "context" consensusclient "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/spec/phase0" ) // VoluntaryExitPool obtains the voluntary exit pool. -func (s *Service) VoluntaryExitPool(ctx context.Context) ([]*phase0.SignedVoluntaryExit, error) { +func (s *Service) VoluntaryExitPool(ctx context.Context, + opts *api.VoluntaryExitPoolOpts, +) ( + *api.Response[[]*phase0.SignedVoluntaryExit], + error, +) { res, err := s.doCall(ctx, func(ctx context.Context, client consensusclient.Service) (interface{}, error) { - voluntaryExitPool, err := client.(consensusclient.VoluntaryExitPoolProvider).VoluntaryExitPool(ctx) + voluntaryExitPool, err := client.(consensusclient.VoluntaryExitPoolProvider).VoluntaryExitPool(ctx, opts) if err != nil { return nil, err } @@ -33,9 +39,6 @@ func (s *Service) VoluntaryExitPool(ctx context.Context) ([]*phase0.SignedVolunt if err != nil { return nil, err } - if res == nil { - return nil, nil - } - return res.([]*phase0.SignedVoluntaryExit), nil + return res.(*api.Response[[]*phase0.SignedVoluntaryExit]), nil } diff --git a/multi/voluntaryexitpool_test.go b/multi/voluntaryexitpool_test.go index e7510055..d49ef5a3 100644 --- a/multi/voluntaryexitpool_test.go +++ b/multi/voluntaryexitpool_test.go @@ -18,6 +18,7 @@ import ( "testing" consensusclient "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/mock" "github.com/attestantio/go-eth2-client/multi" "github.com/attestantio/go-eth2-client/testclients" @@ -50,7 +51,7 @@ func TestVoluntaryExitPool(t *testing.T) { require.NoError(t, err) for i := 0; i < 128; i++ { - res, err := multiClient.(consensusclient.VoluntaryExitPoolProvider).VoluntaryExitPool(ctx) + res, err := multiClient.(consensusclient.VoluntaryExitPoolProvider).VoluntaryExitPool(ctx, &api.VoluntaryExitPoolOpts{}) require.NoError(t, err) require.NotNil(t, res) } diff --git a/service.go b/service.go index ecb5c458..75cf3e8b 100644 --- a/service.go +++ b/service.go @@ -47,21 +47,19 @@ type SlotFromStateIDProvider interface { SlotFromStateID(ctx context.Context, stateID string) (phase0.Slot, error) } -// NodeVersionProvider is the interface for providing the node version. -type NodeVersionProvider interface { - // NodeVersion returns a free-text string with the node version. - NodeVersion(ctx context.Context) (*api.Response[string], error) -} - // SlotDurationProvider is the interface for providing the duration of each slot of a chain. type SlotDurationProvider interface { // SlotDuration provides the duration of a slot of the chain. + // + // Deprecated: use Spec() SlotDuration(ctx context.Context) (time.Duration, error) } // SlotsPerEpochProvider is the interface for providing the number of slots in each epoch of a chain. type SlotsPerEpochProvider interface { // SlotsPerEpoch provides the slots per epoch of the chain. + // + // Deprecated: use Spec() SlotsPerEpoch(ctx context.Context) (uint64, error) } @@ -71,16 +69,12 @@ type FarFutureEpochProvider interface { FarFutureEpoch(ctx context.Context) (phase0.Epoch, error) } -// GenesisValidatorsRootProvider is the interface for providing the genesis validators root of a chain. -type GenesisValidatorsRootProvider interface { - // GenesisValidatorsRoot provides the genesis validators root of the chain. - GenesisValidatorsRoot(ctx context.Context) ([]byte, error) -} - // TargetAggregatorsPerCommitteeProvider is the interface for providing the target number of // aggregators in each attestation committee. type TargetAggregatorsPerCommitteeProvider interface { // TargetAggregatorsPerCommittee provides the target number of aggregators for each attestation committee. + // + // Deprecated: use Spec() TargetAggregatorsPerCommittee(ctx context.Context) (uint64, error) } @@ -102,12 +96,6 @@ type ValidatorIDProvider interface { ValidatorPubKeyProvider } -// DepositContractProvider is the interface for providng details about the deposit contract. -type DepositContractProvider interface { - // DepositContract provides details of the execution deposit contract for the chain. - DepositContract(ctx context.Context) (*api.Response[*apiv1.DepositContract], error) -} - // SignedBeaconBlockProvider is the interface for providing beacon blocks. type SignedBeaconBlockProvider interface { // SignedBeaconBlock fetches a signed beacon block given a block ID. @@ -181,6 +169,12 @@ type AttesterDutiesProvider interface { AttesterDuties(ctx context.Context, opts *api.AttesterDutiesOpts) (*api.Response[[]*apiv1.AttesterDuty], error) } +// DepositContractProvider is the interface for providing details about the deposit contract. +type DepositContractProvider interface { + // DepositContract provides details of the execution deposit contract for the chain. + DepositContract(ctx context.Context, opts *api.DepositContractOpts) (*api.Response[*apiv1.DepositContract], error) +} + // SyncCommitteeDutiesProvider is the interface for providing sync committee duties. type SyncCommitteeDutiesProvider interface { // SyncCommitteeDuties obtains sync committee duties. @@ -320,7 +314,7 @@ type FinalityProvider interface { // ForkChoiceProvider is the interface for providing fork choice information. type ForkChoiceProvider interface { // Fork fetches all current fork choice context. - ForkChoice(ctx context.Context) (*api.Response[*apiv1.ForkChoice], error) + ForkChoice(ctx context.Context, opts *api.ForkChoiceOpts) (*api.Response[*apiv1.ForkChoice], error) } // ForkProvider is the interface for providing fork information. @@ -332,25 +326,31 @@ type ForkProvider interface { // ForkScheduleProvider is the interface for providing fork schedule data. type ForkScheduleProvider interface { // ForkSchedule provides details of past and future changes in the chain's fork version. - ForkSchedule(ctx context.Context) (*api.Response[[]*phase0.Fork], error) + ForkSchedule(ctx context.Context, opts *api.ForkScheduleOpts) (*api.Response[[]*phase0.Fork], error) } // GenesisProvider is the interface for providing genesis information. type GenesisProvider interface { // Genesis fetches genesis information for the chain. - Genesis(ctx context.Context) (*api.Response[*apiv1.Genesis], error) + Genesis(ctx context.Context, opts *api.GenesisOpts) (*api.Response[*apiv1.Genesis], error) +} + +// NodePeersProvider is the interface for providing peer information. +type NodePeersProvider interface { + // NodePeers provides the peers of the node. + NodePeers(ctx context.Context, opts *api.NodePeersOpts) (*api.Response[[]*apiv1.Peer], error) } // NodeSyncingProvider is the interface for providing synchronization state. type NodeSyncingProvider interface { // NodeSyncing provides the state of the node's synchronization with the chain. - NodeSyncing(ctx context.Context) (*api.Response[*apiv1.SyncState], error) + NodeSyncing(ctx context.Context, opts *api.NodeSyncingOpts) (*api.Response[*apiv1.SyncState], error) } -// NodePeersProvider is the interface for providing peer information. -type NodePeersProvider interface { - // NodePeers provides the peers of the node. - NodePeers(ctx context.Context, opts *api.PeerOpts) (*api.Response[[]*apiv1.Peer], error) +// NodeVersionProvider is the interface for providing the node version. +type NodeVersionProvider interface { + // NodeVersion returns a free-text string with the node version. + NodeVersion(ctx context.Context, opts *api.NodeVersionOpts) (*api.Response[string], error) } // ProposalPreparationsSubmitter is the interface for submitting proposal preparations. @@ -369,12 +369,14 @@ type ProposerDutiesProvider interface { // SpecProvider is the interface for providing spec data. type SpecProvider interface { // Spec provides the spec information of the chain. - Spec(ctx context.Context) (*api.Response[map[string]any], error) + Spec(ctx context.Context, opts *api.SpecOpts) (*api.Response[map[string]any], error) } // SyncStateProvider is the interface for providing synchronization state. type SyncStateProvider interface { // SyncState provides the state of the node's synchronization with the chain. + // + // Deprecated: use NodeSyncing() SyncState(ctx context.Context) (*apiv1.SyncState, error) } @@ -399,7 +401,7 @@ type VoluntaryExitSubmitter interface { // VoluntaryExitPoolProvider is the interface for providing voluntary exit pools. type VoluntaryExitPoolProvider interface { // VoluntaryExitPool fetches the voluntary exit pool. - VoluntaryExitPool(ctx context.Context) ([]*phase0.SignedVoluntaryExit, error) + VoluntaryExitPool(ctx context.Context, opts *api.VoluntaryExitPoolOpts) (*api.Response[[]*phase0.SignedVoluntaryExit], error) } // @@ -419,6 +421,8 @@ type DomainProvider interface { } // GenesisTimeProvider is the interface for providing the genesis time of a chain. +// +// Deprecated: use Genesis(). type GenesisTimeProvider interface { // GenesisTime provides the genesis time of the chain. GenesisTime(ctx context.Context) (time.Time, error) diff --git a/testclients/erroring.go b/testclients/erroring.go index b038d774..15edc8c3 100644 --- a/testclients/erroring.go +++ b/testclients/erroring.go @@ -108,7 +108,7 @@ func (s *Erroring) SlotFromStateID(ctx context.Context, stateID string) (phase0. } // NodeVersion returns a free-text string with the node version. -func (s *Erroring) NodeVersion(ctx context.Context) (*api.Response[string], error) { +func (s *Erroring) NodeVersion(ctx context.Context, opts *api.NodeVersionOpts) (*api.Response[string], error) { if err := s.maybeError(ctx); err != nil { return nil, err } @@ -117,10 +117,12 @@ func (s *Erroring) NodeVersion(ctx context.Context) (*api.Response[string], erro return nil, fmt.Errorf("%s@%s does not support this call", s.next.Name(), s.next.Address()) } - return next.NodeVersion(ctx) + return next.NodeVersion(ctx, opts) } // SlotDuration provides the duration of a slot of the chain. +// +// Deprecated: use Spec(). func (s *Erroring) SlotDuration(ctx context.Context) (time.Duration, error) { if err := s.maybeError(ctx); err != nil { return 0, err @@ -134,6 +136,8 @@ func (s *Erroring) SlotDuration(ctx context.Context) (time.Duration, error) { } // SlotsPerEpoch provides the slots per epoch of the chain. +// +// Deprecated: use Spec(). func (s *Erroring) SlotsPerEpoch(ctx context.Context) (uint64, error) { if err := s.maybeError(ctx); err != nil { return 0, err @@ -159,20 +163,9 @@ func (s *Erroring) FarFutureEpoch(ctx context.Context) (phase0.Epoch, error) { return next.FarFutureEpoch(ctx) } -// GenesisValidatorsRoot provides the genesis validators root of the chain. -func (s *Erroring) GenesisValidatorsRoot(ctx context.Context) ([]byte, error) { - if err := s.maybeError(ctx); err != nil { - return nil, err - } - next, isNext := s.next.(consensusclient.GenesisValidatorsRootProvider) - if !isNext { - return nil, fmt.Errorf("%s@%s does not support this call", s.next.Name(), s.next.Address()) - } - - return next.GenesisValidatorsRoot(ctx) -} - // TargetAggregatorsPerCommittee provides the target number of aggregators for each attestation committee. +// +// Deprecated: use Spec(). func (s *Erroring) TargetAggregatorsPerCommittee(ctx context.Context) (uint64, error) { if err := s.maybeError(ctx); err != nil { return 0, err @@ -522,7 +515,7 @@ func (s *Erroring) Fork(ctx context.Context, } // ForkSchedule provides details of past and future changes in the chain's fork version. -func (s *Erroring) ForkSchedule(ctx context.Context) (*api.Response[[]*phase0.Fork], error) { +func (s *Erroring) ForkSchedule(ctx context.Context, opts *api.ForkScheduleOpts) (*api.Response[[]*phase0.Fork], error) { if err := s.maybeError(ctx); err != nil { return nil, err } @@ -531,11 +524,11 @@ func (s *Erroring) ForkSchedule(ctx context.Context) (*api.Response[[]*phase0.Fo return nil, fmt.Errorf("%s@%s does not support this call", s.next.Name(), s.next.Address()) } - return next.ForkSchedule(ctx) + return next.ForkSchedule(ctx, opts) } // Genesis fetches genesis information for the chain. -func (s *Erroring) Genesis(ctx context.Context) (*api.Response[*apiv1.Genesis], error) { +func (s *Erroring) Genesis(ctx context.Context, opts *api.GenesisOpts) (*api.Response[*apiv1.Genesis], error) { if err := s.maybeError(ctx); err != nil { return nil, err } @@ -544,11 +537,11 @@ func (s *Erroring) Genesis(ctx context.Context) (*api.Response[*apiv1.Genesis], return nil, fmt.Errorf("%s@%s does not support this call", s.next.Name(), s.next.Address()) } - return next.Genesis(ctx) + return next.Genesis(ctx, opts) } // NodeSyncing provides the state of the node's synchronization with the chain. -func (s *Erroring) NodeSyncing(ctx context.Context) (*api.Response[*apiv1.SyncState], error) { +func (s *Erroring) NodeSyncing(ctx context.Context, opts *api.NodeSyncingOpts) (*api.Response[*apiv1.SyncState], error) { if err := s.maybeError(ctx); err != nil { return nil, err } @@ -557,11 +550,11 @@ func (s *Erroring) NodeSyncing(ctx context.Context) (*api.Response[*apiv1.SyncSt return nil, fmt.Errorf("%s@%s does not support this call", s.next.Name(), s.next.Address()) } - return next.NodeSyncing(ctx) + return next.NodeSyncing(ctx, opts) } // NodePeers provides the peers of the node. -func (s *Erroring) NodePeers(ctx context.Context, opts *api.PeerOpts) (*api.Response[[]*apiv1.Peer], error) { +func (s *Erroring) NodePeers(ctx context.Context, opts *api.NodePeersOpts) (*api.Response[[]*apiv1.Peer], error) { if err := s.maybeError(ctx); err != nil { return nil, err } @@ -632,7 +625,7 @@ func (s *Erroring) SyncCommitteeDuties(ctx context.Context, opts *api.SyncCommit } // Spec provides the spec information of the chain. -func (s *Erroring) Spec(ctx context.Context) (*api.Response[map[string]interface{}], error) { +func (s *Erroring) Spec(ctx context.Context, opts *api.SpecOpts) (*api.Response[map[string]interface{}], error) { if err := s.maybeError(ctx); err != nil { return nil, err } @@ -641,7 +634,7 @@ func (s *Erroring) Spec(ctx context.Context) (*api.Response[map[string]interface return nil, fmt.Errorf("%s@%s does not support this call", s.next.Name(), s.next.Address()) } - return next.Spec(ctx) + return next.Spec(ctx, opts) } // ValidatorBalances provides the validator balances for a given state. @@ -694,7 +687,7 @@ func (s *Erroring) SubmitVoluntaryExit(ctx context.Context, voluntaryExit *phase } // VoluntaryExitPool fetches the voluntary exit pool. -func (s *Erroring) VoluntaryExitPool(ctx context.Context) ([]*phase0.SignedVoluntaryExit, error) { +func (s *Erroring) VoluntaryExitPool(ctx context.Context, opts *api.VoluntaryExitPoolOpts) (*api.Response[[]*phase0.SignedVoluntaryExit], error) { if err := s.maybeError(ctx); err != nil { return nil, err } @@ -703,7 +696,7 @@ func (s *Erroring) VoluntaryExitPool(ctx context.Context) ([]*phase0.SignedVolun return nil, fmt.Errorf("%s@%s does not support this call", s.next.Name(), s.next.Address()) } - return next.VoluntaryExitPool(ctx) + return next.VoluntaryExitPool(ctx, opts) } // Domain provides a domain for a given domain type at a given epoch. @@ -733,6 +726,8 @@ func (s *Erroring) GenesisDomain(ctx context.Context, domainType phase0.DomainTy } // GenesisTime provides the genesis time of the chain. +// +// Deprecated: use Genesis(). func (s *Erroring) GenesisTime(ctx context.Context) (time.Time, error) { if err := s.maybeError(ctx); err != nil { return time.Time{}, err @@ -746,7 +741,7 @@ func (s *Erroring) GenesisTime(ctx context.Context) (time.Time, error) { } // DepositContract provides details of the Ethereum 1 deposit contract for the chain. -func (s *Erroring) DepositContract(ctx context.Context) (*api.Response[*apiv1.DepositContract], error) { +func (s *Erroring) DepositContract(ctx context.Context, opts *api.DepositContractOpts) (*api.Response[*apiv1.DepositContract], error) { if err := s.maybeError(ctx); err != nil { return nil, err } @@ -755,7 +750,7 @@ func (s *Erroring) DepositContract(ctx context.Context) (*api.Response[*apiv1.De return nil, fmt.Errorf("%s@%s does not support this call", s.next.Name(), s.next.Address()) } - return next.DepositContract(ctx) + return next.DepositContract(ctx, opts) } // SignedBeaconBlock fetches a signed beacon block given a block ID. @@ -803,7 +798,7 @@ func (s *Erroring) BeaconStateRoot(ctx context.Context, } // ForkChoice fetches the node's current fork choice context. -func (s *Erroring) ForkChoice(ctx context.Context) (*api.Response[*apiv1.ForkChoice], error) { +func (s *Erroring) ForkChoice(ctx context.Context, opts *api.ForkChoiceOpts) (*api.Response[*apiv1.ForkChoice], error) { if err := s.maybeError(ctx); err != nil { return nil, err } @@ -812,5 +807,5 @@ func (s *Erroring) ForkChoice(ctx context.Context) (*api.Response[*apiv1.ForkCho return nil, fmt.Errorf("%s@%s does not support this call", s.next.Name(), s.next.Address()) } - return next.ForkChoice(ctx) + return next.ForkChoice(ctx, opts) } diff --git a/testclients/erroring_test.go b/testclients/erroring_test.go index 4fb8ba6d..7b999376 100644 --- a/testclients/erroring_test.go +++ b/testclients/erroring_test.go @@ -18,6 +18,7 @@ import ( "testing" consensusclient "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/mock" "github.com/attestantio/go-eth2-client/testclients" "github.com/rs/zerolog" @@ -88,7 +89,7 @@ func TestMaybeError(t *testing.T) { errors := 0 for i := 0; i < 100000; i++ { - _, err := s.(consensusclient.GenesisProvider).Genesis(ctx) + _, err := s.(consensusclient.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) if err != nil { errors++ } diff --git a/testclients/sleepy.go b/testclients/sleepy.go index 0b8dd973..ffbdcf40 100644 --- a/testclients/sleepy.go +++ b/testclients/sleepy.go @@ -101,17 +101,19 @@ func (s *Sleepy) SlotFromStateID(ctx context.Context, stateID string) (phase0.Sl } // NodeVersion returns a free-text string with the node version. -func (s *Sleepy) NodeVersion(ctx context.Context) (*api.Response[string], error) { +func (s *Sleepy) NodeVersion(ctx context.Context, opts *api.NodeVersionOpts) (*api.Response[string], error) { s.sleep(ctx) next, isNext := s.next.(consensusclient.NodeVersionProvider) if !isNext { return nil, errors.New("next does not support this call") } - return next.NodeVersion(ctx) + return next.NodeVersion(ctx, opts) } // SlotDuration provides the duration of a slot of the chain. +// +// Deprecated: use Spec(). func (s *Sleepy) SlotDuration(ctx context.Context) (time.Duration, error) { s.sleep(ctx) next, isNext := s.next.(consensusclient.SlotDurationProvider) @@ -123,6 +125,8 @@ func (s *Sleepy) SlotDuration(ctx context.Context) (time.Duration, error) { } // SlotsPerEpoch provides the slots per epoch of the chain. +// +// Deprecated: use Spec(). func (s *Sleepy) SlotsPerEpoch(ctx context.Context) (uint64, error) { s.sleep(ctx) next, isNext := s.next.(consensusclient.SlotsPerEpochProvider) @@ -144,18 +148,9 @@ func (s *Sleepy) FarFutureEpoch(ctx context.Context) (phase0.Epoch, error) { return next.FarFutureEpoch(ctx) } -// GenesisValidatorsRoot provides the genesis validators root of the chain. -func (s *Sleepy) GenesisValidatorsRoot(ctx context.Context) ([]byte, error) { - s.sleep(ctx) - next, isNext := s.next.(consensusclient.GenesisValidatorsRootProvider) - if !isNext { - return nil, errors.New("next does not support this call") - } - - return next.GenesisValidatorsRoot(ctx) -} - // TargetAggregatorsPerCommittee provides the target number of aggregators for each attestation committee. +// +// Deprecated: use Spec(). func (s *Sleepy) TargetAggregatorsPerCommittee(ctx context.Context) (uint64, error) { s.sleep(ctx) next, isNext := s.next.(consensusclient.TargetAggregatorsPerCommitteeProvider) @@ -394,40 +389,40 @@ func (s *Sleepy) Fork(ctx context.Context, } // ForkSchedule provides details of past and future changes in the chain's fork version. -func (s *Sleepy) ForkSchedule(ctx context.Context) (*api.Response[[]*phase0.Fork], error) { +func (s *Sleepy) ForkSchedule(ctx context.Context, opts *api.ForkScheduleOpts) (*api.Response[[]*phase0.Fork], error) { s.sleep(ctx) next, isNext := s.next.(consensusclient.ForkScheduleProvider) if !isNext { return nil, errors.New("next does not support this call") } - return next.ForkSchedule(ctx) + return next.ForkSchedule(ctx, opts) } // Genesis fetches genesis information for the chain. -func (s *Sleepy) Genesis(ctx context.Context) (*api.Response[*apiv1.Genesis], error) { +func (s *Sleepy) Genesis(ctx context.Context, opts *api.GenesisOpts) (*api.Response[*apiv1.Genesis], error) { s.sleep(ctx) next, isNext := s.next.(consensusclient.GenesisProvider) if !isNext { return nil, errors.New("next does not support this call") } - return next.Genesis(ctx) + return next.Genesis(ctx, opts) } // NodeSyncing provides the state of the node's synchronization with the chain. -func (s *Sleepy) NodeSyncing(ctx context.Context) (*api.Response[*apiv1.SyncState], error) { +func (s *Sleepy) NodeSyncing(ctx context.Context, opts *api.NodeSyncingOpts) (*api.Response[*apiv1.SyncState], error) { s.sleep(ctx) next, isNext := s.next.(consensusclient.NodeSyncingProvider) if !isNext { return nil, errors.New("next does not support this call") } - return next.NodeSyncing(ctx) + return next.NodeSyncing(ctx, opts) } // NodePeers provides the peers of the node. -func (s *Sleepy) NodePeers(ctx context.Context, opts *api.PeerOpts) (*api.Response[[]*apiv1.Peer], error) { +func (s *Sleepy) NodePeers(ctx context.Context, opts *api.NodePeersOpts) (*api.Response[[]*apiv1.Peer], error) { s.sleep(ctx) next, isNext := s.next.(consensusclient.NodePeersProvider) if !isNext { @@ -454,14 +449,14 @@ func (s *Sleepy) ProposerDuties(ctx context.Context, } // Spec provides the spec information of the chain. -func (s *Sleepy) Spec(ctx context.Context) (*api.Response[map[string]interface{}], error) { +func (s *Sleepy) Spec(ctx context.Context, opts *api.SpecOpts) (*api.Response[map[string]interface{}], error) { s.sleep(ctx) next, isNext := s.next.(consensusclient.SpecProvider) if !isNext { return nil, errors.New("next does not support this call") } - return next.Spec(ctx) + return next.Spec(ctx, opts) } // ValidatorBalances provides the validator balances for a given state. @@ -508,14 +503,14 @@ func (s *Sleepy) SubmitVoluntaryExit(ctx context.Context, voluntaryExit *phase0. } // VoluntaryExitPool fetches the voluntary exit pool. -func (s *Sleepy) VoluntaryExitPool(ctx context.Context) ([]*phase0.SignedVoluntaryExit, error) { +func (s *Sleepy) VoluntaryExitPool(ctx context.Context, opts *api.VoluntaryExitPoolOpts) (*api.Response[[]*phase0.SignedVoluntaryExit], error) { s.sleep(ctx) next, isNext := s.next.(consensusclient.VoluntaryExitPoolProvider) if !isNext { return nil, errors.New("next does not support this call") } - return next.VoluntaryExitPool(ctx) + return next.VoluntaryExitPool(ctx, opts) } // Domain provides a domain for a given domain type at a given epoch. @@ -541,6 +536,8 @@ func (s *Sleepy) GenesisDomain(ctx context.Context, domainType phase0.DomainType } // GenesisTime provides the genesis time of the chain. +// +// Deprecated: use Genesis(). func (s *Sleepy) GenesisTime(ctx context.Context) (time.Time, error) { s.sleep(ctx) next, isNext := s.next.(consensusclient.GenesisTimeProvider) @@ -552,14 +549,14 @@ func (s *Sleepy) GenesisTime(ctx context.Context) (time.Time, error) { } // ForkChoice fetches the node's current fork choice context. -func (s *Sleepy) ForkChoice(ctx context.Context) (*api.Response[*apiv1.ForkChoice], error) { +func (s *Sleepy) ForkChoice(ctx context.Context, opts *api.ForkChoiceOpts) (*api.Response[*apiv1.ForkChoice], error) { s.sleep(ctx) next, isNext := s.next.(consensusclient.ForkChoiceProvider) if !isNext { return nil, errors.New("next does not support this call") } - return next.ForkChoice(ctx) + return next.ForkChoice(ctx, opts) } // BlobSidecars fetches the blobs sidecars given options. diff --git a/testclients/sleepy_test.go b/testclients/sleepy_test.go index aa88c7fa..07f48c2c 100644 --- a/testclients/sleepy_test.go +++ b/testclients/sleepy_test.go @@ -19,6 +19,7 @@ import ( "time" consensusclient "github.com/attestantio/go-eth2-client" + "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/mock" "github.com/attestantio/go-eth2-client/testclients" "github.com/rs/zerolog" @@ -94,7 +95,7 @@ func TestSleep(t *testing.T) { for i := 0; i < 16; i++ { started := time.Now() - _, err := s.(consensusclient.GenesisProvider).Genesis(ctx) + _, err := s.(consensusclient.GenesisProvider).Genesis(ctx, &api.GenesisOpts{}) require.NoError(t, err) duration := time.Since(started) require.GreaterOrEqual(t, duration.Milliseconds(), minSleep.Milliseconds())