diff --git a/api/client/builder/bid.go b/api/client/builder/bid.go index df4b92fb31b7..50e3e21952f2 100644 --- a/api/client/builder/bid.go +++ b/api/client/builder/bid.go @@ -6,6 +6,7 @@ import ( consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types" "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" ) @@ -165,7 +166,7 @@ func WrappedBuilderBidCapella(p *ethpb.BuilderBidCapella) (Bid, error) { // Header returns the execution data interface. func (b builderBidCapella) Header() (interfaces.ExecutionData, error) { // We have to convert big endian to little endian because the value is coming from the execution layer. - return blocks.WrappedExecutionPayloadHeaderCapella(b.p.Header, blocks.PayloadValueToWei(b.p.Value)) + return blocks.WrappedExecutionPayloadHeaderCapella(b.p.Header, primitives.BigEndianBytesToWei(b.p.Value)) } // BlobKzgCommitments -- diff --git a/beacon-chain/core/electra/BUILD.bazel b/beacon-chain/core/electra/BUILD.bazel index 570655397f27..1ff209d88401 100644 --- a/beacon-chain/core/electra/BUILD.bazel +++ b/beacon-chain/core/electra/BUILD.bazel @@ -57,7 +57,6 @@ go_test( "//crypto/bls/blst:go_default_library", "//crypto/bls/common:go_default_library", "//encoding/bytesutil:go_default_library", - "//math:go_default_library", "//proto/engine/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//runtime/interop:go_default_library", diff --git a/beacon-chain/core/electra/balance_deposits.go b/beacon-chain/core/electra/balance_deposits.go index 75ef2a8ea949..6f1874e9a318 100644 --- a/beacon-chain/core/electra/balance_deposits.go +++ b/beacon-chain/core/electra/balance_deposits.go @@ -6,7 +6,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" - "github.com/prysmaticlabs/prysm/v5/math" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "go.opencensus.io/trace" ) @@ -32,7 +32,7 @@ import ( // state.deposit_balance_to_consume = Gwei(0) // else: // state.deposit_balance_to_consume = available_for_processing - processed_amount -func ProcessPendingBalanceDeposits(ctx context.Context, st state.BeaconState, activeBalance math.Gwei) error { +func ProcessPendingBalanceDeposits(ctx context.Context, st state.BeaconState, activeBalance primitives.Gwei) error { _, span := trace.StartSpan(ctx, "electra.ProcessPendingBalanceDeposits") defer span.End() @@ -54,13 +54,13 @@ func ProcessPendingBalanceDeposits(ctx context.Context, st state.BeaconState, ac } for _, deposit := range deposits { - if math.Gwei(deposit.Amount) > availableForProcessing { + if primitives.Gwei(deposit.Amount) > availableForProcessing { break } if err := helpers.IncreaseBalance(st, deposit.Index, deposit.Amount); err != nil { return err } - availableForProcessing -= math.Gwei(deposit.Amount) + availableForProcessing -= primitives.Gwei(deposit.Amount) nextDepositIndex++ } diff --git a/beacon-chain/core/electra/balance_deposits_test.go b/beacon-chain/core/electra/balance_deposits_test.go index 980785d86b46..552ef548c54b 100644 --- a/beacon-chain/core/electra/balance_deposits_test.go +++ b/beacon-chain/core/electra/balance_deposits_test.go @@ -9,7 +9,6 @@ import ( "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/testing/require" ) @@ -36,7 +35,7 @@ func TestProcessPendingBalanceDeposits(t *testing.T) { check: func(t *testing.T, st state.BeaconState) { res, err := st.DepositBalanceToConsume() require.NoError(t, err) - require.Equal(t, math.Gwei(0), res) + require.Equal(t, primitives.Gwei(0), res) }, }, { @@ -59,7 +58,7 @@ func TestProcessPendingBalanceDeposits(t *testing.T) { amountAvailForProcessing := helpers.ActivationExitChurnLimit(1_000 * 1e9) res, err := st.DepositBalanceToConsume() require.NoError(t, err) - require.Equal(t, math.Gwei(100), res) + require.Equal(t, primitives.Gwei(100), res) // Validators 0..9 should have their balance increased for i := primitives.ValidatorIndex(0); i < 10; i++ { b, err := st.BalanceAtIndex(i) @@ -93,7 +92,7 @@ func TestProcessPendingBalanceDeposits(t *testing.T) { amountAvailForProcessing := helpers.ActivationExitChurnLimit(1_000 * 1e9) res, err := st.DepositBalanceToConsume() require.NoError(t, err) - require.Equal(t, math.Gwei(0), res) + require.Equal(t, primitives.Gwei(0), res) // Validators 0..4 should have their balance increased for i := primitives.ValidatorIndex(0); i < 4; i++ { b, err := st.BalanceAtIndex(i) @@ -119,7 +118,7 @@ func TestProcessPendingBalanceDeposits(t *testing.T) { tab, err = helpers.TotalActiveBalance(tt.state) } require.NoError(t, err) - err = electra.ProcessPendingBalanceDeposits(context.TODO(), tt.state, math.Gwei(tab)) + err = electra.ProcessPendingBalanceDeposits(context.TODO(), tt.state, primitives.Gwei(tab)) require.Equal(t, tt.wantErr, err != nil, "wantErr=%v, got err=%s", tt.wantErr, err) if tt.check != nil { tt.check(t, tt.state) diff --git a/beacon-chain/core/electra/churn.go b/beacon-chain/core/electra/churn.go index bde3fe912516..8903ec54b531 100644 --- a/beacon-chain/core/electra/churn.go +++ b/beacon-chain/core/electra/churn.go @@ -37,7 +37,7 @@ import ( // state.earliest_consolidation_epoch = earliest_consolidation_epoch // // return state.earliest_consolidation_epoch -func ComputeConsolidationEpochAndUpdateChurn(ctx context.Context, s state.BeaconState, consolidationBalance math.Gwei) (primitives.Epoch, error) { +func ComputeConsolidationEpochAndUpdateChurn(ctx context.Context, s state.BeaconState, consolidationBalance primitives.Gwei) (primitives.Epoch, error) { earliestEpoch, err := s.EarliestConsolidationEpoch() if err != nil { return 0, err @@ -47,10 +47,10 @@ func ComputeConsolidationEpochAndUpdateChurn(ctx context.Context, s state.Beacon if err != nil { return 0, err } - perEpochConsolidationChurn := helpers.ConsolidationChurnLimit(math.Gwei(activeBal)) + perEpochConsolidationChurn := helpers.ConsolidationChurnLimit(primitives.Gwei(activeBal)) // New epoch for consolidations. - var consolidationBalanceToConsume math.Gwei + var consolidationBalanceToConsume primitives.Gwei if earliestEpoch < earliestConsolidationEpoch { consolidationBalanceToConsume = perEpochConsolidationChurn } else { @@ -70,7 +70,7 @@ func ComputeConsolidationEpochAndUpdateChurn(ctx context.Context, s state.Beacon } additionalEpochs++ earliestConsolidationEpoch += primitives.Epoch(additionalEpochs) - consolidationBalanceToConsume += math.Gwei(additionalEpochs) * perEpochConsolidationChurn + consolidationBalanceToConsume += primitives.Gwei(additionalEpochs) * perEpochConsolidationChurn } // Consume the balance and update state variables. diff --git a/beacon-chain/core/electra/churn_test.go b/beacon-chain/core/electra/churn_test.go index 3ce9d839c629..d1920229ca3b 100644 --- a/beacon-chain/core/electra/churn_test.go +++ b/beacon-chain/core/electra/churn_test.go @@ -9,14 +9,13 @@ import ( state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native" "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/time/slots" ) -func createValidatorsWithTotalActiveBalance(totalBal math.Gwei) []*eth.Validator { - num := totalBal / math.Gwei(params.BeaconConfig().MinActivationBalance) +func createValidatorsWithTotalActiveBalance(totalBal primitives.Gwei) []*eth.Validator { + num := totalBal / primitives.Gwei(params.BeaconConfig().MinActivationBalance) vals := make([]*eth.Validator, num) for i := range vals { vals[i] = ð.Validator{ @@ -25,7 +24,7 @@ func createValidatorsWithTotalActiveBalance(totalBal math.Gwei) []*eth.Validator EffectiveBalance: params.BeaconConfig().MinActivationBalance, } } - if totalBal%math.Gwei(params.BeaconConfig().MinActivationBalance) != 0 { + if totalBal%primitives.Gwei(params.BeaconConfig().MinActivationBalance) != 0 { vals = append(vals, ð.Validator{ ActivationEpoch: primitives.Epoch(0), ExitEpoch: params.BeaconConfig().FarFutureEpoch, @@ -41,9 +40,9 @@ func TestComputeConsolidationEpochAndUpdateChurn(t *testing.T) { tests := []struct { name string state state.BeaconState - consolidationBalance math.Gwei + consolidationBalance primitives.Gwei expectedEpoch primitives.Epoch - expectedConsolidationBalanceToConsume math.Gwei + expectedConsolidationBalanceToConsume primitives.Gwei }{ { name: "compute consolidation with no consolidation balance", diff --git a/beacon-chain/core/electra/consolidations.go b/beacon-chain/core/electra/consolidations.go index 603e40d893e0..37145c29a519 100644 --- a/beacon-chain/core/electra/consolidations.go +++ b/beacon-chain/core/electra/consolidations.go @@ -8,8 +8,8 @@ import ( "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/signing" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" "github.com/prysmaticlabs/prysm/v5/config/params" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/crypto/bls" - "github.com/prysmaticlabs/prysm/v5/math" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/time/slots" "go.opencensus.io/trace" @@ -166,7 +166,7 @@ func ProcessConsolidations(ctx context.Context, st state.BeaconState, cs []*ethp return err } - if helpers.ConsolidationChurnLimit(math.Gwei(totalBalance)) <= math.Gwei(params.BeaconConfig().MinActivationBalance) { + if helpers.ConsolidationChurnLimit(primitives.Gwei(totalBalance)) <= primitives.Gwei(params.BeaconConfig().MinActivationBalance) { return errors.New("too little available consolidation churn limit") } @@ -240,7 +240,7 @@ func ProcessConsolidations(ctx context.Context, st state.BeaconState, cs []*ethp return errors.New("consolidation signature verification failed") } - sEE, err := ComputeConsolidationEpochAndUpdateChurn(ctx, st, math.Gwei(source.EffectiveBalance)) + sEE, err := ComputeConsolidationEpochAndUpdateChurn(ctx, st, primitives.Gwei(source.EffectiveBalance)) if err != nil { return err } diff --git a/beacon-chain/core/electra/upgrade.go b/beacon-chain/core/electra/upgrade.go index 3ef96449c40f..cfb625cfeec9 100644 --- a/beacon-chain/core/electra/upgrade.go +++ b/beacon-chain/core/electra/upgrade.go @@ -11,7 +11,6 @@ import ( "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" - "github.com/prysmaticlabs/prysm/v5/math" enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/time/slots" @@ -271,9 +270,9 @@ func UpgradeToElectra(beaconState state.BeaconState) (state.BeaconState, error) DepositReceiptsStartIndex: params.BeaconConfig().UnsetDepositReceiptsStartIndex, DepositBalanceToConsume: 0, - ExitBalanceToConsume: helpers.ActivationExitChurnLimit(math.Gwei(tab)), + ExitBalanceToConsume: helpers.ActivationExitChurnLimit(primitives.Gwei(tab)), EarliestExitEpoch: earliestExitEpoch, - ConsolidationBalanceToConsume: helpers.ConsolidationChurnLimit(math.Gwei(tab)), + ConsolidationBalanceToConsume: helpers.ConsolidationChurnLimit(primitives.Gwei(tab)), EarliestConsolidationEpoch: helpers.ActivationExitEpoch(slots.ToEpoch(beaconState.Slot())), PendingBalanceDeposits: make([]*ethpb.PendingBalanceDeposit, 0), PendingPartialWithdrawals: make([]*ethpb.PendingPartialWithdrawal, 0), diff --git a/beacon-chain/core/electra/upgrade_test.go b/beacon-chain/core/electra/upgrade_test.go index ee180189e10a..4193b6b9ce7a 100644 --- a/beacon-chain/core/electra/upgrade_test.go +++ b/beacon-chain/core/electra/upgrade_test.go @@ -9,7 +9,6 @@ import ( "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" - "github.com/prysmaticlabs/prysm/v5/math" enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/testing/require" @@ -152,14 +151,14 @@ func TestUpgradeToElectra(t *testing.T) { balance, err := mSt.DepositBalanceToConsume() require.NoError(t, err) - require.Equal(t, math.Gwei(0), balance) + require.Equal(t, primitives.Gwei(0), balance) tab, err := helpers.TotalActiveBalance(mSt) require.NoError(t, err) ebtc, err := mSt.ExitBalanceToConsume() require.NoError(t, err) - require.Equal(t, helpers.ActivationExitChurnLimit(math.Gwei(tab)), ebtc) + require.Equal(t, helpers.ActivationExitChurnLimit(primitives.Gwei(tab)), ebtc) eee, err := mSt.EarliestExitEpoch() require.NoError(t, err) @@ -167,7 +166,7 @@ func TestUpgradeToElectra(t *testing.T) { cbtc, err := mSt.ConsolidationBalanceToConsume() require.NoError(t, err) - require.Equal(t, helpers.ConsolidationChurnLimit(math.Gwei(tab)), cbtc) + require.Equal(t, helpers.ConsolidationChurnLimit(primitives.Gwei(tab)), cbtc) earliestConsolidationEpoch, err := mSt.EarliestConsolidationEpoch() require.NoError(t, err) diff --git a/beacon-chain/core/helpers/BUILD.bazel b/beacon-chain/core/helpers/BUILD.bazel index 1b5709add134..1912d6c2998c 100644 --- a/beacon-chain/core/helpers/BUILD.bazel +++ b/beacon-chain/core/helpers/BUILD.bazel @@ -78,7 +78,6 @@ go_test( "//container/slice:go_default_library", "//crypto/hash:go_default_library", "//encoding/bytesutil:go_default_library", - "//math:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//testing/assert:go_default_library", "//testing/require:go_default_library", diff --git a/beacon-chain/core/helpers/validator_churn.go b/beacon-chain/core/helpers/validator_churn.go index 04409f08112a..a038e32b7db8 100644 --- a/beacon-chain/core/helpers/validator_churn.go +++ b/beacon-chain/core/helpers/validator_churn.go @@ -2,7 +2,7 @@ package helpers import ( "github.com/prysmaticlabs/prysm/v5/config/params" - "github.com/prysmaticlabs/prysm/v5/math" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" ) // BalanceChurnLimit for the current active balance, in gwei. @@ -19,12 +19,12 @@ import ( // get_total_active_balance(state) // CHURN_LIMIT_QUOTIENT // ) // return churn - churn % EFFECTIVE_BALANCE_INCREMENT -func BalanceChurnLimit(activeBalance math.Gwei) math.Gwei { +func BalanceChurnLimit(activeBalance primitives.Gwei) primitives.Gwei { churn := max( params.BeaconConfig().MinPerEpochChurnLimitElectra, (uint64(activeBalance) / params.BeaconConfig().ChurnLimitQuotient), ) - return math.Gwei(churn - churn%params.BeaconConfig().EffectiveBalanceIncrement) + return primitives.Gwei(churn - churn%params.BeaconConfig().EffectiveBalanceIncrement) } // ActivationExitChurnLimit for the current active balance, in gwei. @@ -37,8 +37,8 @@ func BalanceChurnLimit(activeBalance math.Gwei) math.Gwei { // Return the churn limit for the current epoch dedicated to activations and exits. // """ // return min(MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT, get_balance_churn_limit(state)) -func ActivationExitChurnLimit(activeBalance math.Gwei) math.Gwei { - return min(math.Gwei(params.BeaconConfig().MaxPerEpochActivationExitChurnLimit), BalanceChurnLimit(activeBalance)) +func ActivationExitChurnLimit(activeBalance primitives.Gwei) primitives.Gwei { + return min(primitives.Gwei(params.BeaconConfig().MaxPerEpochActivationExitChurnLimit), BalanceChurnLimit(activeBalance)) } // ConsolidationChurnLimit for the current active balance, in gwei. @@ -48,6 +48,6 @@ func ActivationExitChurnLimit(activeBalance math.Gwei) math.Gwei { // // def get_consolidation_churn_limit(state: BeaconState) -> Gwei: // return get_balance_churn_limit(state) - get_activation_exit_churn_limit(state) -func ConsolidationChurnLimit(activeBalance math.Gwei) math.Gwei { +func ConsolidationChurnLimit(activeBalance primitives.Gwei) primitives.Gwei { return BalanceChurnLimit(activeBalance) - ActivationExitChurnLimit(activeBalance) } diff --git a/beacon-chain/core/helpers/validator_churn_test.go b/beacon-chain/core/helpers/validator_churn_test.go index 6a83b4f0168c..9b5fac3d6cee 100644 --- a/beacon-chain/core/helpers/validator_churn_test.go +++ b/beacon-chain/core/helpers/validator_churn_test.go @@ -5,30 +5,30 @@ import ( "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/v5/config/params" - "github.com/prysmaticlabs/prysm/v5/math" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/testing/assert" ) func TestBalanceChurnLimit(t *testing.T) { tests := []struct { name string - activeBalance math.Gwei - expected math.Gwei + activeBalance primitives.Gwei + expected primitives.Gwei }{ { name: "less than MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA", activeBalance: 111, - expected: math.Gwei(params.BeaconConfig().MinPerEpochChurnLimitElectra), + expected: primitives.Gwei(params.BeaconConfig().MinPerEpochChurnLimitElectra), }, { name: "modulo EFFECTIVE_BALANCE_INCREMENT", - activeBalance: math.Gwei(111 + params.BeaconConfig().MinPerEpochChurnLimitElectra*params.BeaconConfig().ChurnLimitQuotient), - expected: math.Gwei(params.BeaconConfig().MinPerEpochChurnLimitElectra), + activeBalance: primitives.Gwei(111 + params.BeaconConfig().MinPerEpochChurnLimitElectra*params.BeaconConfig().ChurnLimitQuotient), + expected: primitives.Gwei(params.BeaconConfig().MinPerEpochChurnLimitElectra), }, { name: "more than MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA", - activeBalance: math.Gwei(2000 * params.BeaconConfig().EffectiveBalanceIncrement * params.BeaconConfig().ChurnLimitQuotient), - expected: math.Gwei(2000 * params.BeaconConfig().EffectiveBalanceIncrement), + activeBalance: primitives.Gwei(2000 * params.BeaconConfig().EffectiveBalanceIncrement * params.BeaconConfig().ChurnLimitQuotient), + expected: primitives.Gwei(2000 * params.BeaconConfig().EffectiveBalanceIncrement), }, } @@ -42,18 +42,18 @@ func TestBalanceChurnLimit(t *testing.T) { func TestActivationExitChurnLimit(t *testing.T) { tests := []struct { name string - activeBalance math.Gwei - expected math.Gwei + activeBalance primitives.Gwei + expected primitives.Gwei }{ { name: "less than MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT", activeBalance: 1, - expected: math.Gwei(params.BeaconConfig().MinPerEpochChurnLimitElectra), + expected: primitives.Gwei(params.BeaconConfig().MinPerEpochChurnLimitElectra), }, { name: "more than MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT", - activeBalance: math.Gwei(2000 * params.BeaconConfig().EffectiveBalanceIncrement * params.BeaconConfig().ChurnLimitQuotient), - expected: math.Gwei(params.BeaconConfig().MaxPerEpochActivationExitChurnLimit), + activeBalance: primitives.Gwei(2000 * params.BeaconConfig().EffectiveBalanceIncrement * params.BeaconConfig().ChurnLimitQuotient), + expected: primitives.Gwei(params.BeaconConfig().MaxPerEpochActivationExitChurnLimit), }, } @@ -67,6 +67,6 @@ func TestActivationExitChurnLimit(t *testing.T) { // FuzzConsolidationChurnLimit exercises BalanceChurnLimit and ActivationExitChurnLimit func FuzzConsolidationChurnLimit(f *testing.F) { f.Fuzz(func(t *testing.T, activeBalance uint64) { - helpers.ConsolidationChurnLimit(math.Gwei(activeBalance)) + helpers.ConsolidationChurnLimit(primitives.Gwei(activeBalance)) }) } diff --git a/beacon-chain/core/validators/BUILD.bazel b/beacon-chain/core/validators/BUILD.bazel index 6096f2aea509..8c341f4c791d 100644 --- a/beacon-chain/core/validators/BUILD.bazel +++ b/beacon-chain/core/validators/BUILD.bazel @@ -40,7 +40,6 @@ go_test( "//beacon-chain/state/state-native:go_default_library", "//config/params:go_default_library", "//consensus-types/primitives:go_default_library", - "//math:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//runtime/version:go_default_library", "//testing/assert:go_default_library", diff --git a/beacon-chain/core/validators/validator.go b/beacon-chain/core/validators/validator.go index c7a2f61015c1..33f4c57b1ed3 100644 --- a/beacon-chain/core/validators/validator.go +++ b/beacon-chain/core/validators/validator.go @@ -103,7 +103,7 @@ func InitiateValidatorExit(ctx context.Context, s state.BeaconState, idx primiti // [Modified in Electra:EIP7251] // exit_queue_epoch = compute_exit_epoch_and_update_churn(state, validator.effective_balance) var err error - exitQueueEpoch, err = s.ExitEpochAndUpdateChurn(math.Gwei(validator.EffectiveBalance)) + exitQueueEpoch, err = s.ExitEpochAndUpdateChurn(primitives.Gwei(validator.EffectiveBalance)) if err != nil { return nil, 0, err } diff --git a/beacon-chain/core/validators/validator_test.go b/beacon-chain/core/validators/validator_test.go index e4220f7128a9..f68634541255 100644 --- a/beacon-chain/core/validators/validator_test.go +++ b/beacon-chain/core/validators/validator_test.go @@ -10,7 +10,6 @@ import ( state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native" "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" "github.com/prysmaticlabs/prysm/v5/testing/assert" @@ -146,7 +145,7 @@ func TestInitiateValidatorExit_ProperExit_Electra(t *testing.T) { // Pre-check: Exit balance to consume should be zero. ebtc, err := state.ExitBalanceToConsume() require.NoError(t, err) - require.Equal(t, math.Gwei(0), ebtc) + require.Equal(t, primitives.Gwei(0), ebtc) newState, epoch, err := validators.InitiateValidatorExit(context.Background(), state, idx, 0, 0) // exitQueueEpoch and churn are not used in electra require.NoError(t, err) @@ -161,7 +160,7 @@ func TestInitiateValidatorExit_ProperExit_Electra(t *testing.T) { // Check that the exit balance to consume has been updated on the state. ebtc, err = state.ExitBalanceToConsume() require.NoError(t, err) - require.NotEqual(t, math.Gwei(0), ebtc, "Exit balance to consume was not updated") + require.NotEqual(t, primitives.Gwei(0), ebtc, "Exit balance to consume was not updated") } func TestSlashValidator_OK(t *testing.T) { diff --git a/beacon-chain/execution/BUILD.bazel b/beacon-chain/execution/BUILD.bazel index 2ff3ec037916..2d0edffd8744 100644 --- a/beacon-chain/execution/BUILD.bazel +++ b/beacon-chain/execution/BUILD.bazel @@ -12,6 +12,7 @@ go_library( "log_processing.go", "metrics.go", "options.go", + "payload_body.go", "prometheus.go", "rpc_connection.go", "service.go", @@ -86,6 +87,8 @@ go_test( "execution_chain_test.go", "init_test.go", "log_processing_test.go", + "mock_test.go", + "payload_body_test.go", "prometheus_test.go", "service_test.go", ], diff --git a/beacon-chain/execution/engine_client.go b/beacon-chain/execution/engine_client.go index c72b3ea33b30..8ed049bce9fc 100644 --- a/beacon-chain/execution/engine_client.go +++ b/beacon-chain/execution/engine_client.go @@ -1,7 +1,6 @@ package execution import ( - "bytes" "context" "fmt" "math/big" @@ -34,12 +33,19 @@ var ( supportedEngineEndpoints = []string{ NewPayloadMethod, NewPayloadMethodV2, + NewPayloadMethodV3, + NewPayloadMethodV4, ForkchoiceUpdatedMethod, ForkchoiceUpdatedMethodV2, + ForkchoiceUpdatedMethodV3, GetPayloadMethod, GetPayloadMethodV2, + GetPayloadMethodV3, + GetPayloadMethodV4, GetPayloadBodiesByHashV1, GetPayloadBodiesByRangeV1, + GetPayloadBodiesByHashV2, + GetPayloadBodiesByRangeV2, } ) @@ -69,16 +75,22 @@ const ( BlockByHashMethod = "eth_getBlockByHash" // BlockByNumberMethod request string for JSON-RPC. BlockByNumberMethod = "eth_getBlockByNumber" - // GetPayloadBodiesByHashV1 v1 request string for JSON-RPC. + // GetPayloadBodiesByHashV1 is the engine_getPayloadBodiesByHashX JSON-RPC method for pre-Electra payloads. GetPayloadBodiesByHashV1 = "engine_getPayloadBodiesByHashV1" - // GetPayloadBodiesByRangeV1 v1 request string for JSON-RPC. + // GetPayloadBodiesByHashV2 is the engine_getPayloadBodiesByHashX JSON-RPC method introduced by Electra. + GetPayloadBodiesByHashV2 = "engine_getPayloadBodiesByHashV2" + // GetPayloadBodiesByRangeV1 is the engine_getPayloadBodiesByRangeX JSON-RPC method for pre-Electra payloads. GetPayloadBodiesByRangeV1 = "engine_getPayloadBodiesByRangeV1" + // GetPayloadBodiesByRangeV2 is the engine_getPayloadBodiesByRangeX JSON-RPC method introduced by Electra. + GetPayloadBodiesByRangeV2 = "engine_getPayloadBodiesByRangeV2" // ExchangeCapabilities request string for JSON-RPC. ExchangeCapabilities = "engine_exchangeCapabilities" // Defines the seconds before timing out engine endpoints with non-block execution semantics. defaultEngineTimeout = time.Second ) +var errInvalidPayloadBodyResponse = errors.New("engine api payload body response is invalid") + // ForkchoiceUpdatedResponse is the response kind received by the // engine_forkchoiceUpdatedV1 endpoint. type ForkchoiceUpdatedResponse struct { @@ -509,93 +521,19 @@ func (s *Service) HeaderByNumber(ctx context.Context, number *big.Int) (*types.H return hdr, err } -// GetPayloadBodiesByHash returns the relevant payload bodies for the provided block hash. -func (s *Service) GetPayloadBodiesByHash(ctx context.Context, executionBlockHashes []common.Hash) ([]*pb.ExecutionPayloadBodyV1, error) { - ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.GetPayloadBodiesByHashV1") - defer span.End() - - result := make([]*pb.ExecutionPayloadBodyV1, 0) - // Exit early if there are no execution hashes. - if len(executionBlockHashes) == 0 { - return result, nil - } - err := s.rpcClient.CallContext(ctx, &result, GetPayloadBodiesByHashV1, executionBlockHashes) - if err != nil { - return nil, handleRPCError(err) - } - if len(result) != len(executionBlockHashes) { - return nil, fmt.Errorf("mismatch of payloads retrieved from the execution client: %d vs %d", len(result), len(executionBlockHashes)) - } - for i, item := range result { - if item == nil { - result[i] = &pb.ExecutionPayloadBodyV1{ - Transactions: make([][]byte, 0), - Withdrawals: make([]*pb.Withdrawal, 0), - } - } - } - return result, nil -} - -// GetPayloadBodiesByRange returns the relevant payload bodies for the provided range. -func (s *Service) GetPayloadBodiesByRange(ctx context.Context, start, count uint64) ([]*pb.ExecutionPayloadBodyV1, error) { - ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.GetPayloadBodiesByRangeV1") - defer span.End() - - result := make([]*pb.ExecutionPayloadBodyV1, 0) - err := s.rpcClient.CallContext(ctx, &result, GetPayloadBodiesByRangeV1, start, count) - - for i, item := range result { - if item == nil { - result[i] = &pb.ExecutionPayloadBodyV1{ - Transactions: make([][]byte, 0), - Withdrawals: make([]*pb.Withdrawal, 0), - } - } - } - return result, handleRPCError(err) -} - // ReconstructFullBlock takes in a blinded beacon block and reconstructs // a beacon block with a full execution payload via the engine API. func (s *Service) ReconstructFullBlock( ctx context.Context, blindedBlock interfaces.ReadOnlySignedBeaconBlock, ) (interfaces.SignedBeaconBlock, error) { - if err := blocks.BeaconBlockIsNil(blindedBlock); err != nil { - return nil, errors.Wrap(err, "cannot reconstruct bellatrix block from nil data") - } - if !blindedBlock.Block().IsBlinded() { - return nil, errors.New("can only reconstruct block from blinded block format") - } - header, err := blindedBlock.Block().Body().Execution() + reconstructed, err := s.ReconstructFullBellatrixBlockBatch(ctx, []interfaces.ReadOnlySignedBeaconBlock{blindedBlock}) if err != nil { return nil, err } - if header.IsNil() { - return nil, errors.New("execution payload header in blinded block was nil") + if len(reconstructed) != 1 { + return nil, errors.Errorf("could not retrieve the correct number of payload bodies: wanted 1 but got %d", len(reconstructed)) } - - // If the payload header has a block hash of 0x0, it means we are pre-merge and should - // simply return the block with an empty execution payload. - if bytes.Equal(header.BlockHash(), params.BeaconConfig().ZeroHash[:]) { - payload, err := buildEmptyExecutionPayload(blindedBlock.Version()) - if err != nil { - return nil, err - } - return blocks.BuildSignedBeaconBlockFromExecutionPayload(blindedBlock, payload) - } - - executionBlockHash := common.BytesToHash(header.BlockHash()) - payload, err := s.retrievePayloadFromExecutionHash(ctx, executionBlockHash, header, blindedBlock.Version()) - if err != nil { - return nil, err - } - fullBlock, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(blindedBlock, payload.Proto()) - if err != nil { - return nil, err - } - reconstructedExecutionPayloadCount.Add(1) - return fullBlock, nil + return reconstructed[0], nil } // ReconstructFullBellatrixBlockBatch takes in a batch of blinded beacon blocks and reconstructs @@ -603,114 +541,16 @@ func (s *Service) ReconstructFullBlock( func (s *Service) ReconstructFullBellatrixBlockBatch( ctx context.Context, blindedBlocks []interfaces.ReadOnlySignedBeaconBlock, ) ([]interfaces.SignedBeaconBlock, error) { - if len(blindedBlocks) == 0 { - return []interfaces.SignedBeaconBlock{}, nil - } - var executionHashes []common.Hash - var validExecPayloads []int - var zeroExecPayloads []int - for i, b := range blindedBlocks { - if err := blocks.BeaconBlockIsNil(b); err != nil { - return nil, errors.Wrap(err, "cannot reconstruct bellatrix block from nil data") - } - if !b.Block().IsBlinded() { - return nil, errors.New("can only reconstruct block from blinded block format") - } - header, err := b.Block().Body().Execution() - if err != nil { - return nil, err - } - if header.IsNil() { - return nil, errors.New("execution payload header in blinded block was nil") - } - // Determine if the block is pre-merge or post-merge. Depending on the result, - // we will ask the execution engine for the full payload. - if bytes.Equal(header.BlockHash(), params.BeaconConfig().ZeroHash[:]) { - zeroExecPayloads = append(zeroExecPayloads, i) - } else { - executionBlockHash := common.BytesToHash(header.BlockHash()) - validExecPayloads = append(validExecPayloads, i) - executionHashes = append(executionHashes, executionBlockHash) - } - } - fullBlocks, err := s.retrievePayloadsFromExecutionHashes(ctx, executionHashes, validExecPayloads, blindedBlocks) + unb, err := reconstructBlindedBlockBatch(ctx, s.rpcClient, blindedBlocks) if err != nil { return nil, err } - // For blocks that are pre-merge we simply reconstruct them via an empty - // execution payload. - for _, realIdx := range zeroExecPayloads { - bblock := blindedBlocks[realIdx] - payload, err := buildEmptyExecutionPayload(bblock.Version()) - if err != nil { - return nil, err - } - fullBlock, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(blindedBlocks[realIdx], payload) - if err != nil { - return nil, err - } - fullBlocks[realIdx] = fullBlock - } - reconstructedExecutionPayloadCount.Add(float64(len(blindedBlocks))) - return fullBlocks, nil -} - -func (s *Service) retrievePayloadFromExecutionHash(ctx context.Context, executionBlockHash common.Hash, header interfaces.ExecutionData, version int) (interfaces.ExecutionData, error) { - pBodies, err := s.GetPayloadBodiesByHash(ctx, []common.Hash{executionBlockHash}) - if err != nil { - return nil, fmt.Errorf("could not get payload body by hash %#x: %v", executionBlockHash, err) - } - if len(pBodies) != 1 { - return nil, errors.Errorf("could not retrieve the correct number of payload bodies: wanted 1 but got %d", len(pBodies)) - } - bdy := pBodies[0] - return fullPayloadFromPayloadBody(header, bdy, version) -} - -// This method assumes that the provided execution hashes are all valid and part of the -// canonical chain. -func (s *Service) retrievePayloadsFromExecutionHashes( - ctx context.Context, - executionHashes []common.Hash, - validExecPayloads []int, - blindedBlocks []interfaces.ReadOnlySignedBeaconBlock) ([]interfaces.SignedBeaconBlock, error) { - fullBlocks := make([]interfaces.SignedBeaconBlock, len(blindedBlocks)) - var payloadBodies []*pb.ExecutionPayloadBodyV1 - var err error - - payloadBodies, err = s.GetPayloadBodiesByHash(ctx, executionHashes) - if err != nil { - return nil, fmt.Errorf("could not fetch payload bodies by hash %#x: %v", executionHashes, err) - } - - // For each valid payload, we reconstruct the full block from it with the - // blinded block. - for sliceIdx, realIdx := range validExecPayloads { - var payload interfaces.ExecutionData - bblock := blindedBlocks[realIdx] - b := payloadBodies[sliceIdx] - if b == nil { - return nil, fmt.Errorf("received nil payload body for request by hash %#x", executionHashes[sliceIdx]) - } - header, err := bblock.Block().Body().Execution() - if err != nil { - return nil, err - } - payload, err = fullPayloadFromPayloadBody(header, b, bblock.Version()) - if err != nil { - return nil, err - } - fullBlock, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(bblock, payload.Proto()) - if err != nil { - return nil, err - } - fullBlocks[realIdx] = fullBlock - } - return fullBlocks, nil + reconstructedExecutionPayloadCount.Add(float64(len(unb))) + return unb, nil } func fullPayloadFromPayloadBody( - header interfaces.ExecutionData, body *pb.ExecutionPayloadBodyV1, bVersion int, + header interfaces.ExecutionData, body *pb.ExecutionPayloadBody, bVersion int, ) (interfaces.ExecutionData, error) { if header.IsNil() || body == nil { return nil, errors.New("execution block and header cannot be nil") @@ -732,7 +572,7 @@ func fullPayloadFromPayloadBody( ExtraData: header.ExtraData(), BaseFeePerGas: header.BaseFeePerGas(), BlockHash: header.BlockHash(), - Transactions: body.Transactions, + Transactions: pb.RecastHexutilByteSlice(body.Transactions), }) case version.Capella: return blocks.WrappedExecutionPayloadCapella(&pb.ExecutionPayloadCapella{ @@ -749,7 +589,7 @@ func fullPayloadFromPayloadBody( ExtraData: header.ExtraData(), BaseFeePerGas: header.BaseFeePerGas(), BlockHash: header.BlockHash(), - Transactions: body.Transactions, + Transactions: pb.RecastHexutilByteSlice(body.Transactions), Withdrawals: body.Withdrawals, }, big.NewInt(0)) // We can't get the block value and don't care about the block value for this instance case version.Deneb: @@ -776,7 +616,7 @@ func fullPayloadFromPayloadBody( ExtraData: header.ExtraData(), BaseFeePerGas: header.BaseFeePerGas(), BlockHash: header.BlockHash(), - Transactions: body.Transactions, + Transactions: pb.RecastHexutilByteSlice(body.Transactions), Withdrawals: body.Withdrawals, ExcessBlobGas: ebg, BlobGasUsed: bgu, @@ -790,25 +630,35 @@ func fullPayloadFromPayloadBody( if err != nil { return nil, errors.Wrap(err, "unable to extract BlobGasUsed attribute from execution payload header") } + wr, err := pb.JsonWithdrawalRequestsToProto(body.WithdrawalRequests) + if err != nil { + return nil, err + } + dr, err := pb.JsonDepositRequestsToProto(body.DepositRequests) + if err != nil { + return nil, err + } return blocks.WrappedExecutionPayloadElectra( &pb.ExecutionPayloadElectra{ - ParentHash: header.ParentHash(), - FeeRecipient: header.FeeRecipient(), - StateRoot: header.StateRoot(), - ReceiptsRoot: header.ReceiptsRoot(), - LogsBloom: header.LogsBloom(), - PrevRandao: header.PrevRandao(), - BlockNumber: header.BlockNumber(), - GasLimit: header.GasLimit(), - GasUsed: header.GasUsed(), - Timestamp: header.Timestamp(), - ExtraData: header.ExtraData(), - BaseFeePerGas: header.BaseFeePerGas(), - BlockHash: header.BlockHash(), - Transactions: body.Transactions, - Withdrawals: body.Withdrawals, - ExcessBlobGas: ebg, - BlobGasUsed: bgu, + ParentHash: header.ParentHash(), + FeeRecipient: header.FeeRecipient(), + StateRoot: header.StateRoot(), + ReceiptsRoot: header.ReceiptsRoot(), + LogsBloom: header.LogsBloom(), + PrevRandao: header.PrevRandao(), + BlockNumber: header.BlockNumber(), + GasLimit: header.GasLimit(), + GasUsed: header.GasUsed(), + Timestamp: header.Timestamp(), + ExtraData: header.ExtraData(), + BaseFeePerGas: header.BaseFeePerGas(), + BlockHash: header.BlockHash(), + Transactions: pb.RecastHexutilByteSlice(body.Transactions), + Withdrawals: body.Withdrawals, + ExcessBlobGas: ebg, + BlobGasUsed: bgu, + DepositReceipts: dr, + WithdrawalRequests: wr, }, big.NewInt(0)) // We can't get the block value and don't care about the block value for this instance default: return nil, fmt.Errorf("unknown execution block version for payload %d", bVersion) @@ -943,6 +793,22 @@ func buildEmptyExecutionPayload(v int) (proto.Message, error) { Transactions: make([][]byte, 0), Withdrawals: make([]*pb.Withdrawal, 0), }, nil + case version.Electra: + return &pb.ExecutionPayloadElectra{ + ParentHash: make([]byte, fieldparams.RootLength), + FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), + StateRoot: make([]byte, fieldparams.RootLength), + ReceiptsRoot: make([]byte, fieldparams.RootLength), + LogsBloom: make([]byte, fieldparams.LogsBloomLength), + PrevRandao: make([]byte, fieldparams.RootLength), + ExtraData: make([]byte, 0), + BaseFeePerGas: make([]byte, fieldparams.RootLength), + BlockHash: make([]byte, fieldparams.RootLength), + Transactions: make([][]byte, 0), + Withdrawals: make([]*pb.Withdrawal, 0), + WithdrawalRequests: make([]*pb.ExecutionLayerWithdrawalRequest, 0), + DepositReceipts: make([]*pb.DepositReceipt, 0), + }, nil default: return nil, errors.Wrapf(ErrUnsupportedVersion, "version=%s", version.String(v)) } diff --git a/beacon-chain/execution/engine_client_test.go b/beacon-chain/execution/engine_client_test.go index e42165d16651..2ac1f8d3c896 100644 --- a/beacon-chain/execution/engine_client_test.go +++ b/beacon-chain/execution/engine_client_test.go @@ -31,6 +31,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/testing/assert" "github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/testing/util" + "github.com/prysmaticlabs/prysm/v5/time/slots" logTest "github.com/sirupsen/logrus/hooks/test" ) @@ -993,7 +994,7 @@ func TestReconstructFullBellatrixBlockBatch(t *testing.T) { respJSON := map[string]interface{}{ "jsonrpc": "2.0", "id": 1, - "result": []map[string]interface{}{jsonPayload, jsonPayload}, + "result": []map[string]interface{}{jsonPayload}, } require.NoError(t, json.NewEncoder(w).Encode(respJSON)) @@ -1011,10 +1012,8 @@ func TestReconstructFullBellatrixBlockBatch(t *testing.T) { blindedBlock.Block.Body.ExecutionPayloadHeader = header wrapped, err := blocks.NewSignedBeaconBlock(blindedBlock) require.NoError(t, err) - copiedWrapped, err := wrapped.Copy() - require.NoError(t, err) - reconstructed, err := service.ReconstructFullBellatrixBlockBatch(ctx, []interfaces.ReadOnlySignedBeaconBlock{wrappedEmpty, wrapped, copiedWrapped}) + reconstructed, err := service.ReconstructFullBellatrixBlockBatch(ctx, []interfaces.ReadOnlySignedBeaconBlock{wrappedEmpty, wrapped}) require.NoError(t, err) // Make sure empty blocks are handled correctly @@ -1024,10 +1023,6 @@ func TestReconstructFullBellatrixBlockBatch(t *testing.T) { got, err := reconstructed[1].Block().Body().Execution() require.NoError(t, err) require.DeepEqual(t, payload, got.Proto()) - - got, err = reconstructed[2].Block().Body().Execution() - require.NoError(t, err) - require.DeepEqual(t, payload, got.Proto()) }) t.Run("handles invalid response from EL", func(t *testing.T) { fix := fixtures() @@ -1094,7 +1089,7 @@ func TestReconstructFullBellatrixBlockBatch(t *testing.T) { require.NoError(t, err) _, err = service.ReconstructFullBellatrixBlockBatch(ctx, []interfaces.ReadOnlySignedBeaconBlock{wrappedEmpty, wrapped, copiedWrapped}) - require.ErrorContains(t, "mismatch of payloads retrieved from the execution client", err) + require.ErrorIs(t, err, errInvalidPayloadBodyResponse) }) } @@ -1405,6 +1400,31 @@ func newTestIPCServer(t *testing.T) *rpc.Server { } func fixtures() map[string]interface{} { + s := fixturesStruct() + return map[string]interface{}{ + "ExecutionBlock": s.ExecutionBlock, + "ExecutionPayloadBody": s.ExecutionPayloadBody, + "ExecutionPayload": s.ExecutionPayload, + "ExecutionPayloadCapella": s.ExecutionPayloadCapella, + "ExecutionPayloadDeneb": s.ExecutionPayloadDeneb, + "ExecutionPayloadElectra": s.ExecutionPayloadElectra, + "ExecutionPayloadCapellaWithValue": s.ExecutionPayloadWithValueCapella, + "ExecutionPayloadDenebWithValue": s.ExecutionPayloadWithValueDeneb, + "ExecutionPayloadElectraWithValue": s.ExecutionPayloadWithValueElectra, + "ValidPayloadStatus": s.ValidPayloadStatus, + "InvalidBlockHashStatus": s.InvalidBlockHashStatus, + "AcceptedStatus": s.AcceptedStatus, + "SyncingStatus": s.SyncingStatus, + "InvalidStatus": s.InvalidStatus, + "UnknownStatus": s.UnknownStatus, + "ForkchoiceUpdatedResponse": s.ForkchoiceUpdatedResponse, + "ForkchoiceUpdatedSyncingResponse": s.ForkchoiceUpdatedSyncingResponse, + "ForkchoiceUpdatedAcceptedResponse": s.ForkchoiceUpdatedAcceptedResponse, + "ForkchoiceUpdatedInvalidResponse": s.ForkchoiceUpdatedInvalidResponse, + } +} + +func fixturesStruct() *payloadFixtures { foo := bytesutil.ToBytes32([]byte("foo")) bar := bytesutil.PadTo([]byte("bar"), 20) baz := bytesutil.PadTo([]byte("baz"), 256) @@ -1425,8 +1445,8 @@ func fixtures() map[string]interface{} { BlockHash: foo[:], Transactions: [][]byte{foo[:]}, } - executionPayloadBodyFixture := &pb.ExecutionPayloadBodyV1{ - Transactions: [][]byte{foo[:]}, + executionPayloadBodyFixture := &pb.ExecutionPayloadBody{ + Transactions: []hexutil.Bytes{foo[:]}, Withdrawals: []*pb.Withdrawal{}, } executionPayloadFixtureCapella := &pb.ExecutionPayloadCapella{ @@ -1446,7 +1466,7 @@ func fixtures() map[string]interface{} { Transactions: [][]byte{foo[:]}, Withdrawals: []*pb.Withdrawal{}, } - executionPayloadFixtureDeneb := &pb.ExecutionPayloadDeneb{ + emptyExecutionPayloadDeneb := &pb.ExecutionPayloadDeneb{ ParentHash: foo[:], FeeRecipient: bar, StateRoot: foo[:], @@ -1460,11 +1480,29 @@ func fixtures() map[string]interface{} { ExtraData: foo[:], BaseFeePerGas: bytesutil.PadTo(baseFeePerGas.Bytes(), fieldparams.RootLength), BlockHash: foo[:], - Transactions: [][]byte{foo[:]}, - Withdrawals: []*pb.Withdrawal{}, BlobGasUsed: 2, ExcessBlobGas: 3, } + executionPayloadFixtureDeneb := &pb.ExecutionPayloadDeneb{ + ParentHash: emptyExecutionPayloadDeneb.ParentHash, + FeeRecipient: emptyExecutionPayloadDeneb.FeeRecipient, + StateRoot: emptyExecutionPayloadDeneb.StateRoot, + ReceiptsRoot: emptyExecutionPayloadDeneb.ReceiptsRoot, + LogsBloom: emptyExecutionPayloadDeneb.LogsBloom, + PrevRandao: emptyExecutionPayloadDeneb.PrevRandao, + BlockNumber: emptyExecutionPayloadDeneb.BlockNumber, + GasLimit: emptyExecutionPayloadDeneb.GasLimit, + GasUsed: emptyExecutionPayloadDeneb.GasUsed, + Timestamp: emptyExecutionPayloadDeneb.Timestamp, + ExtraData: emptyExecutionPayloadDeneb.ExtraData, + BaseFeePerGas: emptyExecutionPayloadDeneb.BaseFeePerGas, + BlockHash: emptyExecutionPayloadDeneb.BlockHash, + BlobGasUsed: emptyExecutionPayloadDeneb.BlobGasUsed, + ExcessBlobGas: emptyExecutionPayloadDeneb.ExcessBlobGas, + // added on top of the empty payload + Transactions: [][]byte{foo[:]}, + Withdrawals: []*pb.Withdrawal{}, + } withdrawalRequests := make([]pb.WithdrawalRequestV1, 3) for i := range withdrawalRequests { amount := hexutil.Uint64(i) @@ -1496,9 +1534,13 @@ func fixtures() map[string]interface{} { Index: &idx, } } - outer := &pb.ExecutionPayloadElectraJSON{ - WithdrawalRequests: withdrawalRequests, - DepositRequests: depositRequests, + dr, err := pb.JsonDepositRequestsToProto(depositRequests) + if err != nil { + panic(err) + } + wr, err := pb.JsonWithdrawalRequestsToProto(withdrawalRequests) + if err != nil { + panic(err) } executionPayloadFixtureElectra := &pb.ExecutionPayloadElectra{ ParentHash: foo[:], @@ -1518,8 +1560,8 @@ func fixtures() map[string]interface{} { Withdrawals: []*pb.Withdrawal{}, BlobGasUsed: 2, ExcessBlobGas: 3, - DepositReceipts: outer.ElectraDepositReceipts(), - WithdrawalRequests: outer.ElectraExecutionLayerWithdrawalRequests(), + DepositReceipts: dr, + WithdrawalRequests: wr, } hexUint := hexutil.Uint64(1) executionPayloadWithValueFixtureCapella := &pb.GetPayloadV2ResponseJson{ @@ -1573,22 +1615,24 @@ func fixtures() map[string]interface{} { executionPayloadWithValueFixtureElectra := &pb.GetPayloadV4ResponseJson{ ShouldOverrideBuilder: true, ExecutionPayload: &pb.ExecutionPayloadElectraJSON{ - ParentHash: &common.Hash{'a'}, - FeeRecipient: &common.Address{'b'}, - StateRoot: &common.Hash{'c'}, - ReceiptsRoot: &common.Hash{'d'}, - LogsBloom: &hexutil.Bytes{'e'}, - PrevRandao: &common.Hash{'f'}, - BaseFeePerGas: "0x123", - BlockHash: &common.Hash{'g'}, - Transactions: []hexutil.Bytes{{'h'}}, - Withdrawals: []*pb.Withdrawal{}, - BlockNumber: &hexUint, - GasLimit: &hexUint, - GasUsed: &hexUint, - Timestamp: &hexUint, - BlobGasUsed: &bgu, - ExcessBlobGas: &ebg, + ParentHash: &common.Hash{'a'}, + FeeRecipient: &common.Address{'b'}, + StateRoot: &common.Hash{'c'}, + ReceiptsRoot: &common.Hash{'d'}, + LogsBloom: &hexutil.Bytes{'e'}, + PrevRandao: &common.Hash{'f'}, + BaseFeePerGas: "0x123", + BlockHash: &common.Hash{'g'}, + Transactions: []hexutil.Bytes{{'h'}}, + Withdrawals: []*pb.Withdrawal{}, + BlockNumber: &hexUint, + GasLimit: &hexUint, + GasUsed: &hexUint, + Timestamp: &hexUint, + BlobGasUsed: &bgu, + ExcessBlobGas: &ebg, + DepositRequests: depositRequests, + WithdrawalRequests: withdrawalRequests, }, BlockValue: "0x11fffffffff", BlobsBundle: &pb.BlobBundleJSON{ @@ -1681,27 +1725,52 @@ func fixtures() map[string]interface{} { Status: pb.PayloadStatus_UNKNOWN, LatestValidHash: foo[:], } - return map[string]interface{}{ - "ExecutionBlock": executionBlock, - "ExecutionPayloadBody": executionPayloadBodyFixture, - "ExecutionPayload": executionPayloadFixture, - "ExecutionPayloadCapella": executionPayloadFixtureCapella, - "ExecutionPayloadDeneb": executionPayloadFixtureDeneb, - "ExecutionPayloadElectra": executionPayloadFixtureElectra, - "ExecutionPayloadCapellaWithValue": executionPayloadWithValueFixtureCapella, - "ExecutionPayloadDenebWithValue": executionPayloadWithValueFixtureDeneb, - "ExecutionPayloadElectraWithValue": executionPayloadWithValueFixtureElectra, - "ValidPayloadStatus": validStatus, - "InvalidBlockHashStatus": inValidBlockHashStatus, - "AcceptedStatus": acceptedStatus, - "SyncingStatus": syncingStatus, - "InvalidStatus": invalidStatus, - "UnknownStatus": unknownStatus, - "ForkchoiceUpdatedResponse": forkChoiceResp, - "ForkchoiceUpdatedSyncingResponse": forkChoiceSyncingResp, - "ForkchoiceUpdatedAcceptedResponse": forkChoiceAcceptedResp, - "ForkchoiceUpdatedInvalidResponse": forkChoiceInvalidResp, + return &payloadFixtures{ + ExecutionBlock: executionBlock, + ExecutionPayloadBody: executionPayloadBodyFixture, + ExecutionPayload: executionPayloadFixture, + ExecutionPayloadCapella: executionPayloadFixtureCapella, + ExecutionPayloadDeneb: executionPayloadFixtureDeneb, + EmptyExecutionPayloadDeneb: emptyExecutionPayloadDeneb, + ExecutionPayloadElectra: executionPayloadFixtureElectra, + ExecutionPayloadWithValueCapella: executionPayloadWithValueFixtureCapella, + ExecutionPayloadWithValueDeneb: executionPayloadWithValueFixtureDeneb, + ExecutionPayloadWithValueElectra: executionPayloadWithValueFixtureElectra, + ValidPayloadStatus: validStatus, + InvalidBlockHashStatus: inValidBlockHashStatus, + AcceptedStatus: acceptedStatus, + SyncingStatus: syncingStatus, + InvalidStatus: invalidStatus, + UnknownStatus: unknownStatus, + ForkchoiceUpdatedResponse: forkChoiceResp, + ForkchoiceUpdatedSyncingResponse: forkChoiceSyncingResp, + ForkchoiceUpdatedAcceptedResponse: forkChoiceAcceptedResp, + ForkchoiceUpdatedInvalidResponse: forkChoiceInvalidResp, } + +} + +type payloadFixtures struct { + ExecutionBlock *pb.ExecutionBlock + ExecutionPayloadBody *pb.ExecutionPayloadBody + ExecutionPayload *pb.ExecutionPayload + ExecutionPayloadCapella *pb.ExecutionPayloadCapella + EmptyExecutionPayloadDeneb *pb.ExecutionPayloadDeneb + ExecutionPayloadDeneb *pb.ExecutionPayloadDeneb + ExecutionPayloadElectra *pb.ExecutionPayloadElectra + ExecutionPayloadWithValueCapella *pb.GetPayloadV2ResponseJson + ExecutionPayloadWithValueDeneb *pb.GetPayloadV3ResponseJson + ExecutionPayloadWithValueElectra *pb.GetPayloadV4ResponseJson + ValidPayloadStatus *pb.PayloadStatus + InvalidBlockHashStatus *pb.PayloadStatus + AcceptedStatus *pb.PayloadStatus + SyncingStatus *pb.PayloadStatus + InvalidStatus *pb.PayloadStatus + UnknownStatus *pb.PayloadStatus + ForkchoiceUpdatedResponse *ForkchoiceUpdatedResponse + ForkchoiceUpdatedSyncingResponse *ForkchoiceUpdatedResponse + ForkchoiceUpdatedAcceptedResponse *ForkchoiceUpdatedResponse + ForkchoiceUpdatedInvalidResponse *ForkchoiceUpdatedResponse } func TestHeaderByHash_NotFound(t *testing.T) { @@ -2084,507 +2153,35 @@ func newPayloadV4Setup(t *testing.T, status *pb.PayloadStatus, payload *pb.Execu return service } -func TestCapella_PayloadBodiesByHash(t *testing.T) { +func TestReconstructBlindedBlockBatch(t *testing.T) { t.Run("empty response works", func(t *testing.T) { - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - defer func() { - require.NoError(t, r.Body.Close()) - }() - executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 0) - resp := map[string]interface{}{ - "jsonrpc": "2.0", - "id": 1, - "result": executionPayloadBodies, - } - err := json.NewEncoder(w).Encode(resp) - require.NoError(t, err) - })) - ctx := context.Background() - - rpcClient, err := rpc.DialHTTP(srv.URL) - require.NoError(t, err) - - service := &Service{} - service.rpcClient = rpcClient - - results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{}) - require.NoError(t, err) - require.Equal(t, 0, len(results)) - - for _, item := range results { - require.NotNil(t, item) - } - }) - t.Run("single element response null works", func(t *testing.T) { - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - defer func() { - require.NoError(t, r.Body.Close()) - }() - executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 1) - executionPayloadBodies[0] = nil - - resp := map[string]interface{}{ - "jsonrpc": "2.0", - "id": 1, - "result": executionPayloadBodies, - } - err := json.NewEncoder(w).Encode(resp) - require.NoError(t, err) - })) - ctx := context.Background() - - rpcClient, err := rpc.DialHTTP(srv.URL) - require.NoError(t, err) - - service := &Service{} - service.rpcClient = rpcClient - - bRoot := [32]byte{} - copy(bRoot[:], "hash") - results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{bRoot}) - require.NoError(t, err) - require.Equal(t, 1, len(results)) - - for _, item := range results { - require.NotNil(t, item) - } - }) - t.Run("empty, null, full works", func(t *testing.T) { - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - defer func() { - require.NoError(t, r.Body.Close()) - }() - executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 3) - executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{ - Transactions: [][]byte{}, - Withdrawals: []*pb.Withdrawal{}, - } - executionPayloadBodies[1] = nil - executionPayloadBodies[2] = &pb.ExecutionPayloadBodyV1{ - Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")}, - Withdrawals: []*pb.Withdrawal{{ - Index: 1, - ValidatorIndex: 1, - Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"), - Amount: 1, - }}, - } - - resp := map[string]interface{}{ - "jsonrpc": "2.0", - "id": 1, - "result": executionPayloadBodies, - } - err := json.NewEncoder(w).Encode(resp) - require.NoError(t, err) - })) - ctx := context.Background() - - rpcClient, err := rpc.DialHTTP(srv.URL) - require.NoError(t, err) - - service := &Service{} - service.rpcClient = rpcClient - - bRoot := [32]byte{} - copy(bRoot[:], "hash") - results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{bRoot, bRoot, bRoot}) - require.NoError(t, err) - require.Equal(t, 3, len(results)) - - for _, item := range results { - require.NotNil(t, item) - } - }) - t.Run("full works, single item", func(t *testing.T) { - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - defer func() { - require.NoError(t, r.Body.Close()) - }() - executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 1) - executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{ - Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")}, - Withdrawals: []*pb.Withdrawal{{ - Index: 1, - ValidatorIndex: 1, - Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"), - Amount: 1, - }}, - } - - resp := map[string]interface{}{ - "jsonrpc": "2.0", - "id": 1, - "result": executionPayloadBodies, - } - err := json.NewEncoder(w).Encode(resp) - require.NoError(t, err) - })) - ctx := context.Background() - - rpcClient, err := rpc.DialHTTP(srv.URL) - require.NoError(t, err) - - service := &Service{} - service.rpcClient = rpcClient - - bRoot := [32]byte{} - copy(bRoot[:], "hash") - results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{bRoot}) - require.NoError(t, err) - require.Equal(t, 1, len(results)) - - for _, item := range results { - require.NotNil(t, item) - } - }) - t.Run("full works, multiple items", func(t *testing.T) { - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - defer func() { - require.NoError(t, r.Body.Close()) - }() - executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 2) - executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{ - Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")}, - Withdrawals: []*pb.Withdrawal{{ - Index: 1, - ValidatorIndex: 1, - Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"), - Amount: 1, - }}, - } - executionPayloadBodies[1] = &pb.ExecutionPayloadBodyV1{ - Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")}, - Withdrawals: []*pb.Withdrawal{{ - Index: 2, - ValidatorIndex: 1, - Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"), - Amount: 1, - }}, - } - - resp := map[string]interface{}{ - "jsonrpc": "2.0", - "id": 1, - "result": executionPayloadBodies, - } - err := json.NewEncoder(w).Encode(resp) - require.NoError(t, err) - })) ctx := context.Background() + cli, srv := newMockEngine(t) + srv.registerDefault(func(*jsonrpcMessage, http.ResponseWriter, *http.Request) { - rpcClient, err := rpc.DialHTTP(srv.URL) - require.NoError(t, err) - - service := &Service{} - service.rpcClient = rpcClient - - bRoot := [32]byte{} - copy(bRoot[:], "hash") - results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{bRoot, bRoot}) - require.NoError(t, err) - require.Equal(t, 2, len(results)) - - for _, item := range results { - require.NotNil(t, item) - } - }) - t.Run("returning empty, null, empty should work properly", func(t *testing.T) { - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - defer func() { - require.NoError(t, r.Body.Close()) - }() - // [A, B, C] but no B in the server means - // we get [Abody, null, Cbody]. - executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 3) - executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{ - Transactions: [][]byte{}, - Withdrawals: []*pb.Withdrawal{}, - } - executionPayloadBodies[1] = nil - executionPayloadBodies[2] = &pb.ExecutionPayloadBodyV1{ - Transactions: [][]byte{}, - Withdrawals: []*pb.Withdrawal{}, - } - - resp := map[string]interface{}{ - "jsonrpc": "2.0", - "id": 1, - "result": executionPayloadBodies, - } - err := json.NewEncoder(w).Encode(resp) - require.NoError(t, err) - })) - ctx := context.Background() - - rpcClient, err := rpc.DialHTTP(srv.URL) - require.NoError(t, err) - - service := &Service{} - service.rpcClient = rpcClient - - bRoot := [32]byte{} - copy(bRoot[:], "hash") - results, err := service.GetPayloadBodiesByHash(ctx, []common.Hash{bRoot, bRoot, bRoot}) - require.NoError(t, err) - require.Equal(t, 3, len(results)) - - for _, item := range results { - require.NotNil(t, item) - } - }) -} - -func TestCapella_PayloadBodiesByRange(t *testing.T) { - t.Run("empty response works", func(t *testing.T) { - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - defer func() { - require.NoError(t, r.Body.Close()) - }() - executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 0) - resp := map[string]interface{}{ - "jsonrpc": "2.0", - "id": 1, - "result": executionPayloadBodies, - } - err := json.NewEncoder(w).Encode(resp) - require.NoError(t, err) - })) - ctx := context.Background() - - rpcClient, err := rpc.DialHTTP(srv.URL) - require.NoError(t, err) - - service := &Service{} - service.rpcClient = rpcClient - - results, err := service.GetPayloadBodiesByRange(ctx, uint64(1), uint64(2)) + t.Fatal("http request should not be made") + }) + results, err := reconstructBlindedBlockBatch(ctx, cli, []interfaces.ReadOnlySignedBeaconBlock{}) require.NoError(t, err) require.Equal(t, 0, len(results)) - - for _, item := range results { - require.NotNil(t, item) - } }) - t.Run("single element response null works", func(t *testing.T) { - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - defer func() { - require.NoError(t, r.Body.Close()) - }() - executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 1) - executionPayloadBodies[0] = nil - - resp := map[string]interface{}{ - "jsonrpc": "2.0", - "id": 1, - "result": executionPayloadBodies, - } - err := json.NewEncoder(w).Encode(resp) - require.NoError(t, err) - })) + t.Run("expected error for nil response", func(t *testing.T) { ctx := context.Background() - - rpcClient, err := rpc.DialHTTP(srv.URL) - require.NoError(t, err) - - service := &Service{} - service.rpcClient = rpcClient - - results, err := service.GetPayloadBodiesByRange(ctx, uint64(1), uint64(2)) + slot, err := slots.EpochStart(params.BeaconConfig().DenebForkEpoch) require.NoError(t, err) - require.Equal(t, 1, len(results)) - - for _, item := range results { - require.NotNil(t, item) - } - }) - t.Run("empty, null, full works", func(t *testing.T) { - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - defer func() { - require.NoError(t, r.Body.Close()) - }() - executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 3) - executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{ - Transactions: [][]byte{}, - Withdrawals: []*pb.Withdrawal{}, - } - executionPayloadBodies[1] = nil - executionPayloadBodies[2] = &pb.ExecutionPayloadBodyV1{ - Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")}, - Withdrawals: []*pb.Withdrawal{{ - Index: 1, - ValidatorIndex: 1, - Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"), - Amount: 1, - }}, - } - - resp := map[string]interface{}{ - "jsonrpc": "2.0", - "id": 1, - "result": executionPayloadBodies, - } - err := json.NewEncoder(w).Encode(resp) - require.NoError(t, err) - })) - ctx := context.Background() - - rpcClient, err := rpc.DialHTTP(srv.URL) - require.NoError(t, err) - - service := &Service{} - service.rpcClient = rpcClient - - results, err := service.GetPayloadBodiesByRange(ctx, uint64(1), uint64(2)) - require.NoError(t, err) - require.Equal(t, 3, len(results)) - - for _, item := range results { - require.NotNil(t, item) - } - }) - t.Run("full works, single item", func(t *testing.T) { - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - defer func() { - require.NoError(t, r.Body.Close()) - }() - executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 1) - executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{ - Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")}, - Withdrawals: []*pb.Withdrawal{{ - Index: 1, - ValidatorIndex: 1, - Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"), - Amount: 1, - }}, - } - - resp := map[string]interface{}{ - "jsonrpc": "2.0", - "id": 1, - "result": executionPayloadBodies, - } - err := json.NewEncoder(w).Encode(resp) - require.NoError(t, err) - })) - ctx := context.Background() - - rpcClient, err := rpc.DialHTTP(srv.URL) - require.NoError(t, err) - - service := &Service{} - service.rpcClient = rpcClient - - results, err := service.GetPayloadBodiesByRange(ctx, uint64(1), uint64(2)) - require.NoError(t, err) - require.Equal(t, 1, len(results)) - - for _, item := range results { - require.NotNil(t, item) - } - }) - t.Run("full works, multiple items", func(t *testing.T) { - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - defer func() { - require.NoError(t, r.Body.Close()) - }() - executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 2) - executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{ - Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")}, - Withdrawals: []*pb.Withdrawal{{ - Index: 1, - ValidatorIndex: 1, - Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"), - Amount: 1, - }}, - } - executionPayloadBodies[1] = &pb.ExecutionPayloadBodyV1{ - Transactions: [][]byte{hexutil.MustDecode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86")}, - Withdrawals: []*pb.Withdrawal{{ - Index: 2, - ValidatorIndex: 1, - Address: hexutil.MustDecode("0xcf8e0d4e9587369b2301d0790347320302cc0943"), - Amount: 1, - }}, - } - - resp := map[string]interface{}{ - "jsonrpc": "2.0", - "id": 1, - "result": executionPayloadBodies, - } - err := json.NewEncoder(w).Encode(resp) - require.NoError(t, err) - })) - ctx := context.Background() - - rpcClient, err := rpc.DialHTTP(srv.URL) - require.NoError(t, err) - - service := &Service{} - service.rpcClient = rpcClient - - results, err := service.GetPayloadBodiesByRange(ctx, uint64(1), uint64(2)) - require.NoError(t, err) - require.Equal(t, 2, len(results)) - - for _, item := range results { - require.NotNil(t, item) - } - }) - t.Run("returning empty, null, empty should work properly", func(t *testing.T) { - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - defer func() { - require.NoError(t, r.Body.Close()) - }() - // [A, B, C] but no B in the server means - // we get [Abody, null, Cbody]. - executionPayloadBodies := make([]*pb.ExecutionPayloadBodyV1, 3) - executionPayloadBodies[0] = &pb.ExecutionPayloadBodyV1{ - Transactions: [][]byte{}, - Withdrawals: []*pb.Withdrawal{}, - } - executionPayloadBodies[1] = nil - executionPayloadBodies[2] = &pb.ExecutionPayloadBodyV1{ - Transactions: [][]byte{}, - Withdrawals: []*pb.Withdrawal{}, - } - - resp := map[string]interface{}{ - "jsonrpc": "2.0", - "id": 1, - "result": executionPayloadBodies, - } - err := json.NewEncoder(w).Encode(resp) - require.NoError(t, err) - })) - ctx := context.Background() + blk, _ := util.GenerateTestDenebBlockWithSidecar(t, [32]byte{}, slot, 0) + cli, srv := newMockEngine(t) + srv.registerDefault(func(msg *jsonrpcMessage, w http.ResponseWriter, req *http.Request) { + executionPayloadBodies := []*pb.ExecutionPayloadBody{nil} + mockWriteResult(t, w, msg, executionPayloadBodies) + }) - rpcClient, err := rpc.DialHTTP(srv.URL) + blinded, err := blk.ToBlinded() require.NoError(t, err) - service := &Service{} - service.rpcClient = rpcClient - - results, err := service.GetPayloadBodiesByRange(ctx, uint64(1), uint64(2)) - require.NoError(t, err) - require.Equal(t, 3, len(results)) - - for _, item := range results { - require.NotNil(t, item) - } + service.rpcClient = cli + _, err = service.ReconstructFullBlock(ctx, blinded) + require.ErrorIs(t, err, errNilPayloadBody) }) } diff --git a/beacon-chain/execution/mock_test.go b/beacon-chain/execution/mock_test.go new file mode 100644 index 000000000000..a77c83ecc446 --- /dev/null +++ b/beacon-chain/execution/mock_test.go @@ -0,0 +1,221 @@ +package execution + +import ( + "context" + "encoding/json" + "math" + "net/http" + "net/http/httptest" + "testing" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/rpc" + pb "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" + "github.com/prysmaticlabs/prysm/v5/testing/require" +) + +var mockHandlerDefaultName = "__default__" + +type jsonError struct { + Code int `json:"code"` + Message string `json:"message"` + Data interface{} `json:"data,omitempty"` +} + +type jsonrpcMessage struct { + Version string `json:"jsonrpc,omitempty"` + ID json.RawMessage `json:"id,omitempty"` + Method string `json:"method,omitempty"` + Params json.RawMessage `json:"params,omitempty"` + Error *jsonError `json:"error,omitempty"` + Result json.RawMessage `json:"result,omitempty"` +} + +type mockHandler func(*jsonrpcMessage, http.ResponseWriter, *http.Request) + +type mockEngine struct { + t *testing.T + handlers map[string]mockHandler + calls map[string][]*jsonrpcMessage +} + +func newMockEngine(t *testing.T) (*rpc.Client, *mockEngine) { + s := &mockEngine{t: t, handlers: make(map[string]mockHandler), calls: make(map[string][]*jsonrpcMessage)} + srv := httptest.NewServer(s) + c, err := rpc.DialHTTP(srv.URL) + require.NoError(t, err) + return c, s +} + +func (s *mockEngine) ServeHTTP(w http.ResponseWriter, r *http.Request) { + msg := &jsonrpcMessage{} + defer func() { + s.calls[msg.Method] = append(s.calls[msg.Method], msg) + }() + if err := json.NewDecoder(r.Body).Decode(msg); err != nil { + http.Error(w, "failed to decode request: "+err.Error(), http.StatusBadRequest) + return + } + w.Header().Set("Content-Type", "application/json") + defer func() { + require.NoError(s.t, r.Body.Close()) + }() + handler, ok := s.handlers[msg.Method] + if !ok { + // Fallback to default handler if it is registered. + handler, ok = s.handlers[mockHandlerDefaultName] + if !ok { + s.t.Fatalf("mockEngine called with unexpected method %s", msg.Method) + } + } + handler(msg, w, r) +} + +func (s *mockEngine) register(method string, handler mockHandler) { + s.handlers[method] = handler +} + +func (s *mockEngine) registerDefault(handler mockHandler) { + s.handlers[mockHandlerDefaultName] = handler +} + +func (s *mockEngine) callCount(method string) int { + return len(s.calls[method]) +} + +func mockParseUintList(t *testing.T, data json.RawMessage) []uint64 { + var list []uint64 + if err := json.Unmarshal(data, &list); err != nil { + t.Fatalf("failed to parse uint list: %v", err) + } + return list +} + +func mockParseHexByteList(t *testing.T, data json.RawMessage) []hexutil.Bytes { + var list [][]hexutil.Bytes + if err := json.Unmarshal(data, &list); err != nil { + t.Fatalf("failed to parse hex byte list: %v", err) + } + require.Equal(t, 1, len(list)) + return list[0] +} + +func strToHexBytes(t *testing.T, s string) hexutil.Bytes { + b := hexutil.Bytes{} + require.NoError(t, b.UnmarshalText([]byte(s))) + return b +} + +func mockWriteResult(t *testing.T, w http.ResponseWriter, req *jsonrpcMessage, result any) { + marshaled, err := json.Marshal(result) + require.NoError(t, err) + req.Result = marshaled + require.NoError(t, json.NewEncoder(w).Encode(req)) +} + +func TestParseRequest(t *testing.T) { + ctx := context.Background() + cases := []struct { + method string + uintArgs []uint64 + byteArgs []hexutil.Bytes + }{ + { + method: GetPayloadBodiesByHashV1, + byteArgs: []hexutil.Bytes{ + strToHexBytes(t, "0x656d707479000000000000000000000000000000000000000000000000000000"), + strToHexBytes(t, "0x66756c6c00000000000000000000000000000000000000000000000000000000"), + }, + }, + { + method: GetPayloadBodiesByHashV2, + byteArgs: []hexutil.Bytes{ + strToHexBytes(t, "0x656d707479000000000000000000000000000000000000000000000000000000"), + strToHexBytes(t, "0x66756c6c00000000000000000000000000000000000000000000000000000000"), + }, + }, + { + method: GetPayloadBodiesByRangeV1, + uintArgs: []uint64{0, 1}, + }, + { + method: GetPayloadBodiesByRangeV2, + uintArgs: []uint64{math.MaxUint64, 1}, + }, + } + for _, c := range cases { + t.Run(c.method, func(t *testing.T) { + cli, srv := newMockEngine(t) + srv.register(c.method, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) { + require.Equal(t, c.method, msg.Method) + nr := uint64(len(c.byteArgs)) + if len(c.byteArgs) > 0 { + require.DeepEqual(t, c.byteArgs, mockParseHexByteList(t, msg.Params)) + } + if len(c.uintArgs) > 0 { + rang := mockParseUintList(t, msg.Params) + require.DeepEqual(t, c.uintArgs, rang) + nr = rang[1] + } + mockWriteResult(t, w, msg, make([]*pb.ExecutionPayloadBody, nr)) + }) + + result := make([]*pb.ExecutionPayloadBody, 0) + var args []interface{} + if len(c.byteArgs) > 0 { + args = []interface{}{c.byteArgs} + } + if len(c.uintArgs) > 0 { + args = make([]interface{}, len(c.uintArgs)) + for i := range c.uintArgs { + args[i] = c.uintArgs[i] + } + } + require.NoError(t, cli.CallContext(ctx, &result, c.method, args...)) + if len(c.byteArgs) > 0 { + require.Equal(t, len(c.byteArgs), len(result)) + } + if len(c.uintArgs) > 0 { + require.Equal(t, int(c.uintArgs[1]), len(result)) + } + }) + } +} + +func TestCallCount(t *testing.T) { + methods := []string{ + GetPayloadBodiesByHashV1, + GetPayloadBodiesByHashV2, + GetPayloadBodiesByRangeV1, + GetPayloadBodiesByRangeV2, + } + cases := []struct { + method string + count int + }{ + {method: GetPayloadBodiesByHashV1, count: 1}, + {method: GetPayloadBodiesByHashV1, count: 2}, + {method: GetPayloadBodiesByHashV2, count: 1}, + {method: GetPayloadBodiesByRangeV1, count: 1}, + {method: GetPayloadBodiesByRangeV1, count: 2}, + {method: GetPayloadBodiesByRangeV2, count: 1}, + } + for _, c := range cases { + t.Run(c.method, func(t *testing.T) { + cli, srv := newMockEngine(t) + srv.register(c.method, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) { + mockWriteResult(t, w, msg, nil) + }) + for i := 0; i < c.count; i++ { + require.NoError(t, cli.CallContext(context.Background(), nil, c.method)) + } + for _, m := range methods { + if m == c.method { + require.Equal(t, c.count, srv.callCount(m)) + } else { + require.Equal(t, 0, srv.callCount(m)) + } + } + }) + } +} diff --git a/beacon-chain/execution/payload_body.go b/beacon-chain/execution/payload_body.go new file mode 100644 index 000000000000..71e8f7473978 --- /dev/null +++ b/beacon-chain/execution/payload_body.go @@ -0,0 +1,250 @@ +package execution + +import ( + "context" + "sort" + + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/v5/config/params" + "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" + "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" + "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" + pb "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" + "github.com/prysmaticlabs/prysm/v5/runtime/version" + "google.golang.org/protobuf/proto" +) + +var errNilPayloadBody = errors.New("nil payload body for block") + +type blockWithHeader struct { + block interfaces.ReadOnlySignedBeaconBlock + header interfaces.ExecutionData +} + +// reconstructionBatch is a map of block hashes to block numbers. +type reconstructionBatch map[[32]byte]uint64 + +type blindedBlockReconstructor struct { + orderedBlocks []*blockWithHeader + bodies map[[32]byte]*pb.ExecutionPayloadBody + batches map[string]reconstructionBatch +} + +func reconstructBlindedBlockBatch(ctx context.Context, client RPCClient, sbb []interfaces.ReadOnlySignedBeaconBlock) ([]interfaces.SignedBeaconBlock, error) { + r, err := newBlindedBlockReconstructor(sbb) + if err != nil { + return nil, err + } + if err := r.requestBodies(ctx, client); err != nil { + return nil, err + } + return r.unblinded() +} + +func newBlindedBlockReconstructor(sbb []interfaces.ReadOnlySignedBeaconBlock) (*blindedBlockReconstructor, error) { + r := &blindedBlockReconstructor{ + orderedBlocks: make([]*blockWithHeader, 0, len(sbb)), + bodies: make(map[[32]byte]*pb.ExecutionPayloadBody), + } + for i := range sbb { + if err := r.addToBatch(sbb[i]); err != nil { + return nil, err + } + } + return r, nil +} + +func (r *blindedBlockReconstructor) addToBatch(b interfaces.ReadOnlySignedBeaconBlock) error { + if err := blocks.BeaconBlockIsNil(b); err != nil { + return errors.Wrap(err, "cannot reconstruct bellatrix block from nil data") + } + if !b.Block().IsBlinded() { + return errors.New("can only reconstruct block from blinded block format") + } + header, err := b.Block().Body().Execution() + if err != nil { + return err + } + if header.IsNil() { + return errors.New("execution payload header in blinded block was nil") + } + r.orderedBlocks = append(r.orderedBlocks, &blockWithHeader{block: b, header: header}) + blockHash := bytesutil.ToBytes32(header.BlockHash()) + if blockHash == params.BeaconConfig().ZeroHash { + return nil + } + + method := payloadBodyMethodForBlock(b) + if r.batches == nil { + r.batches = make(map[string]reconstructionBatch) + } + if _, ok := r.batches[method]; !ok { + r.batches[method] = make(reconstructionBatch) + } + r.batches[method][bytesutil.ToBytes32(header.BlockHash())] = header.BlockNumber() + return nil +} + +func payloadBodyMethodForBlock(b interface{ Version() int }) string { + if b.Version() > version.Deneb { + return GetPayloadBodiesByHashV2 + } + return GetPayloadBodiesByHashV1 +} + +func (r *blindedBlockReconstructor) requestBodies(ctx context.Context, client RPCClient) error { + for method := range r.batches { + nilResults, err := r.requestBodiesByHash(ctx, client, method) + if err != nil { + return err + } + if err := r.handleNilResults(ctx, client, method, nilResults); err != nil { + return err + } + } + return nil +} + +type hashBlockNumber struct { + h [32]byte + n uint64 +} + +func (r *blindedBlockReconstructor) handleNilResults(ctx context.Context, client RPCClient, method string, nilResults [][32]byte) error { + if len(nilResults) == 0 { + return nil + } + hbns := make([]hashBlockNumber, len(nilResults)) + for i := range nilResults { + h := nilResults[i] + hbns[i] = hashBlockNumber{h: h, n: r.batches[method][h]} + } + reqs := computeRanges(hbns) + for i := range reqs { + if err := r.requestBodiesByRange(ctx, client, rangeMethodForHashMethod(method), reqs[i]); err != nil { + return err + } + } + return nil +} + +type byRangeReq struct { + start uint64 + count uint64 + hbns []hashBlockNumber +} + +func computeRanges(hbns []hashBlockNumber) []byRangeReq { + if len(hbns) == 0 { + return nil + } + sort.Slice(hbns, func(i, j int) bool { + return hbns[i].n < hbns[j].n + }) + ranges := make([]byRangeReq, 0) + start := hbns[0].n + count := uint64(0) + for i := 0; i < len(hbns); i++ { + if hbns[i].n == start+count { + count++ + continue + } + ranges = append(ranges, byRangeReq{start: start, count: count, hbns: hbns[uint64(i)-count : i]}) + start = hbns[i].n + count = 1 + } + ranges = append(ranges, byRangeReq{start: start, count: count, hbns: hbns[uint64(len(hbns))-count:]}) + return ranges +} + +func (r *blindedBlockReconstructor) requestBodiesByRange(ctx context.Context, client RPCClient, method string, req byRangeReq) error { + result := make([]*pb.ExecutionPayloadBody, 0) + if err := client.CallContext(ctx, &result, method, req.start, req.count); err != nil { + return err + } + if uint64(len(result)) != req.count { + return errors.Wrapf(errInvalidPayloadBodyResponse, "received %d payload bodies from %s with count=%d (start=%d)", len(result), method, req.count, req.start) + } + for i := range result { + if result[i] == nil { + return errors.Wrapf(errNilPayloadBody, "from %s, hash=%#x", method, req.hbns[i].h) + } + r.bodies[req.hbns[i].h] = result[i] + } + return nil +} + +func (r *blindedBlockReconstructor) requestBodiesByHash(ctx context.Context, client RPCClient, method string) ([][32]byte, error) { + batch := r.batches[method] + if len(batch) == 0 { + return nil, nil + } + hashes := make([]common.Hash, 0, len(batch)) + for h := range batch { + if h == params.BeaconConfig().ZeroHash { + continue + } + hashes = append(hashes, h) + } + result := make([]*pb.ExecutionPayloadBody, 0) + if err := client.CallContext(ctx, &result, method, hashes); err != nil { + return nil, err + } + if len(hashes) != len(result) { + return nil, errors.Wrapf(errInvalidPayloadBodyResponse, "received %d payload bodies for %d requested hashes", len(result), len(hashes)) + } + nilBodies := make([][32]byte, 0) + for i := range result { + if result[i] == nil { + nilBodies = append(nilBodies, hashes[i]) + continue + } + r.bodies[hashes[i]] = result[i] + } + return nilBodies, nil +} + +func (r *blindedBlockReconstructor) payloadForHeader(header interfaces.ExecutionData, v int) (proto.Message, error) { + bodyKey := bytesutil.ToBytes32(header.BlockHash()) + if bodyKey == params.BeaconConfig().ZeroHash { + payload, err := buildEmptyExecutionPayload(v) + if err != nil { + return nil, errors.Wrapf(err, "failed to reconstruct payload for body hash %#x", bodyKey) + } + return payload, nil + } + body, ok := r.bodies[bodyKey] + if !ok { + return nil, errors.Wrapf(errNilPayloadBody, "hash %#x", bodyKey) + } + ed, err := fullPayloadFromPayloadBody(header, body, v) + if err != nil { + return nil, errors.Wrapf(err, "failed to reconstruct payload for body hash %#x", bodyKey) + } + return ed.Proto(), nil +} + +func (r *blindedBlockReconstructor) unblinded() ([]interfaces.SignedBeaconBlock, error) { + unblinded := make([]interfaces.SignedBeaconBlock, len(r.orderedBlocks)) + for i := range r.orderedBlocks { + blk, header := r.orderedBlocks[i].block, r.orderedBlocks[i].header + payload, err := r.payloadForHeader(header, blk.Version()) + if err != nil { + return nil, err + } + full, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(blk, payload) + if err != nil { + return nil, errors.Wrapf(err, "failed to build full block from execution payload for block hash %#x", header.BlockHash()) + } + unblinded[i] = full + } + return unblinded, nil +} + +func rangeMethodForHashMethod(method string) string { + if method == GetPayloadBodiesByHashV2 { + return GetPayloadBodiesByRangeV2 + } + return GetPayloadBodiesByRangeV1 +} diff --git a/beacon-chain/execution/payload_body_test.go b/beacon-chain/execution/payload_body_test.go new file mode 100644 index 000000000000..b95edead67d8 --- /dev/null +++ b/beacon-chain/execution/payload_body_test.go @@ -0,0 +1,408 @@ +package execution + +import ( + "context" + "net/http" + "testing" + + "github.com/prysmaticlabs/prysm/v5/config/params" + "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" + "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" + "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" + pb "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" + "github.com/prysmaticlabs/prysm/v5/runtime/version" + "github.com/prysmaticlabs/prysm/v5/testing/require" + "github.com/prysmaticlabs/prysm/v5/testing/util" + "github.com/prysmaticlabs/prysm/v5/time/slots" +) + +type versioner struct { + version int +} + +func (v versioner) Version() int { + return v.version +} + +func TestPayloadBodyMethodForBlock(t *testing.T) { + cases := []struct { + versions []int + want string + }{ + { + versions: []int{version.Phase0, version.Altair, version.Bellatrix, version.Capella, version.Deneb}, + want: GetPayloadBodiesByHashV1, + }, + { + versions: []int{version.Electra}, + want: GetPayloadBodiesByHashV2, + }, + } + for _, c := range cases { + for _, v := range c.versions { + t.Run(version.String(v), func(t *testing.T) { + v := versioner{version: v} + require.Equal(t, c.want, payloadBodyMethodForBlock(v)) + }) + } + } + t.Run("post-electra", func(t *testing.T) { + require.Equal(t, GetPayloadBodiesByHashV2, payloadBodyMethodForBlock(versioner{version: version.Electra + 1})) + }) +} + +func payloadToBody(t *testing.T, ed interfaces.ExecutionData) *pb.ExecutionPayloadBody { + body := &pb.ExecutionPayloadBody{} + txs, err := ed.Transactions() + require.NoError(t, err) + wd, err := ed.Withdrawals() + // Bellatrix does not have withdrawals and will return an error. + if err == nil { + body.Withdrawals = wd + } + for i := range txs { + body.Transactions = append(body.Transactions, txs[i]) + } + eed, isElectra := ed.(interfaces.ExecutionDataElectra) + if isElectra { + body.DepositRequests = pb.ProtoDepositRequestsToJson(eed.DepositReceipts()) + body.WithdrawalRequests = pb.ProtoWithdrawalRequestsToJson(eed.WithdrawalRequests()) + } + return body +} + +type blindedBlockFixtures struct { + denebBlock *fullAndBlinded + emptyDenebBlock *fullAndBlinded + afterSkipDeneb *fullAndBlinded + electra *fullAndBlinded +} + +type fullAndBlinded struct { + full interfaces.ReadOnlySignedBeaconBlock + blinded *blockWithHeader +} + +func blindedBlockWithHeader(t *testing.T, b interfaces.ReadOnlySignedBeaconBlock) *fullAndBlinded { + header, err := b.Block().Body().Execution() + require.NoError(t, err) + blinded, err := b.ToBlinded() + require.NoError(t, err) + return &fullAndBlinded{ + full: b, + blinded: &blockWithHeader{ + block: blinded, + header: header, + }} +} + +func denebSlot(t *testing.T) primitives.Slot { + s, err := slots.EpochStart(params.BeaconConfig().DenebForkEpoch) + require.NoError(t, err) + return s +} + +func electraSlot(t *testing.T) primitives.Slot { + s, err := slots.EpochStart(params.BeaconConfig().ElectraForkEpoch) + require.NoError(t, err) + return s +} + +func testBlindedBlockFixtures(t *testing.T) *blindedBlockFixtures { + pfx := fixturesStruct() + fx := &blindedBlockFixtures{} + full := pfx.ExecutionPayloadDeneb + // this func overrides fixture blockhashes to ensure they are unique + full.BlockHash = bytesutil.PadTo([]byte("full"), 32) + denebBlock, _ := util.GenerateTestDenebBlockWithSidecar(t, [32]byte{}, denebSlot(t), 0, util.WithPayloadSetter(full)) + fx.denebBlock = blindedBlockWithHeader(t, denebBlock) + + empty := pfx.EmptyExecutionPayloadDeneb + empty.BlockHash = bytesutil.PadTo([]byte("empty"), 32) + empty.BlockNumber = 2 + emptyDenebBlock, _ := util.GenerateTestDenebBlockWithSidecar(t, [32]byte{}, denebSlot(t)+1, 0, util.WithPayloadSetter(empty)) + fx.emptyDenebBlock = blindedBlockWithHeader(t, emptyDenebBlock) + + afterSkip := fixturesStruct().ExecutionPayloadDeneb + // this func overrides fixture blockhashes to ensure they are unique + afterSkip.BlockHash = bytesutil.PadTo([]byte("afterSkip"), 32) + afterSkip.BlockNumber = 4 + afterSkipBlock, _ := util.GenerateTestDenebBlockWithSidecar(t, [32]byte{}, denebSlot(t)+3, 0, util.WithPayloadSetter(afterSkip)) + fx.afterSkipDeneb = blindedBlockWithHeader(t, afterSkipBlock) + + electra := fixturesStruct().ExecutionPayloadElectra + electra.BlockHash = bytesutil.PadTo([]byte("electra"), 32) + electra.BlockNumber = 5 + electraBlock, _ := util.GenerateTestElectraBlockWithSidecar(t, [32]byte{}, electraSlot(t), 0, util.WithElectraPayload(electra)) + fx.electra = blindedBlockWithHeader(t, electraBlock) + return fx +} + +func TestPayloadBodiesViaUnblinder(t *testing.T) { + defer util.HackElectraMaxuint(t)() + fx := testBlindedBlockFixtures(t) + t.Run("mix of non-empty and empty", func(t *testing.T) { + cli, srv := newMockEngine(t) + srv.register(GetPayloadBodiesByHashV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) { + executionPayloadBodies := []*pb.ExecutionPayloadBody{ + payloadToBody(t, fx.denebBlock.blinded.header), + payloadToBody(t, fx.emptyDenebBlock.blinded.header), + } + mockWriteResult(t, w, msg, executionPayloadBodies) + }) + ctx := context.Background() + + toUnblind := []interfaces.ReadOnlySignedBeaconBlock{ + fx.denebBlock.blinded.block, + fx.emptyDenebBlock.blinded.block, + } + bbr, err := newBlindedBlockReconstructor(toUnblind) + require.NoError(t, err) + require.NoError(t, bbr.requestBodies(ctx, cli)) + + payload, err := bbr.payloadForHeader(fx.denebBlock.blinded.header, fx.denebBlock.blinded.block.Version()) + require.NoError(t, err) + unblindFull, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(fx.denebBlock.blinded.block, payload) + require.NoError(t, err) + testAssertReconstructedEquivalent(t, fx.denebBlock.full, unblindFull) + + emptyPayload, err := bbr.payloadForHeader(fx.emptyDenebBlock.blinded.header, fx.emptyDenebBlock.blinded.block.Version()) + require.NoError(t, err) + unblindEmpty, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(fx.emptyDenebBlock.blinded.block, emptyPayload) + require.NoError(t, err) + testAssertReconstructedEquivalent(t, fx.emptyDenebBlock.full, unblindEmpty) + }) +} + +func TestFixtureEquivalence(t *testing.T) { + defer util.HackElectraMaxuint(t)() + fx := testBlindedBlockFixtures(t) + t.Run("full and blinded block equivalence", func(t *testing.T) { + testAssertReconstructedEquivalent(t, fx.denebBlock.blinded.block, fx.denebBlock.full) + testAssertReconstructedEquivalent(t, fx.emptyDenebBlock.blinded.block, fx.emptyDenebBlock.full) + }) +} + +func testAssertReconstructedEquivalent(t *testing.T, b, ogb interfaces.ReadOnlySignedBeaconBlock) { + bHtr, err := b.Block().HashTreeRoot() + require.NoError(t, err) + ogbHtr, err := ogb.Block().HashTreeRoot() + require.NoError(t, err) + require.Equal(t, bHtr, ogbHtr) +} + +func TestComputeRanges(t *testing.T) { + cases := []struct { + name string + hbns []hashBlockNumber + want []byRangeReq + }{ + { + name: "3 contiguous, 1 not", + hbns: []hashBlockNumber{ + {h: [32]byte{5}, n: 5}, + {h: [32]byte{3}, n: 3}, + {h: [32]byte{2}, n: 2}, + {h: [32]byte{1}, n: 1}, + }, + want: []byRangeReq{ + {start: 1, count: 3, hbns: []hashBlockNumber{{h: [32]byte{1}, n: 1}, {h: [32]byte{2}, n: 2}, {h: [32]byte{3}, n: 3}}}, + {start: 5, count: 1, hbns: []hashBlockNumber{{h: [32]byte{5}, n: 5}}}, + }, + }, + { + name: "1 element", + hbns: []hashBlockNumber{ + {h: [32]byte{1}, n: 1}, + }, + want: []byRangeReq{ + {start: 1, count: 1, hbns: []hashBlockNumber{{h: [32]byte{1}, n: 1}}}, + }, + }, + { + name: "2 contiguous", + hbns: []hashBlockNumber{ + {h: [32]byte{2}, n: 2}, + {h: [32]byte{1}, n: 1}, + }, + want: []byRangeReq{ + {start: 1, count: 2, hbns: []hashBlockNumber{{h: [32]byte{1}, n: 1}, {h: [32]byte{2}, n: 2}}}, + }, + }, + { + name: "2 non-contiguous", + hbns: []hashBlockNumber{ + {h: [32]byte{3}, n: 3}, + {h: [32]byte{1}, n: 1}, + }, + want: []byRangeReq{ + {start: 1, count: 1, hbns: []hashBlockNumber{{h: [32]byte{1}, n: 1}}}, + {start: 3, count: 1, hbns: []hashBlockNumber{{h: [32]byte{3}, n: 3}}}, + }, + }, + { + name: "3 contiguous", + hbns: []hashBlockNumber{ + {h: [32]byte{2}, n: 2}, + {h: [32]byte{1}, n: 1}, + {h: [32]byte{3}, n: 3}, + }, + want: []byRangeReq{ + {start: 1, count: 3, hbns: []hashBlockNumber{{h: [32]byte{1}, n: 1}, {h: [32]byte{2}, n: 2}, {h: [32]byte{3}, n: 3}}}, + }, + }, + { + name: "3 non-contiguous", + hbns: []hashBlockNumber{ + {h: [32]byte{5}, n: 5}, + {h: [32]byte{3}, n: 3}, + {h: [32]byte{1}, n: 1}, + }, + want: []byRangeReq{ + {start: 1, count: 1, hbns: []hashBlockNumber{{h: [32]byte{1}, n: 1}}}, + {start: 3, count: 1, hbns: []hashBlockNumber{{h: [32]byte{3}, n: 3}}}, + {start: 5, count: 1, hbns: []hashBlockNumber{{h: [32]byte{5}, n: 5}}}, + }, + }, + } + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + got := computeRanges(c.hbns) + for i := range got { + require.Equal(t, c.want[i].start, got[i].start) + require.Equal(t, c.want[i].count, got[i].count) + require.DeepEqual(t, c.want[i].hbns, got[i].hbns) + } + }) + } +} + +func TestReconstructBlindedBlockBatchFallbackToRange(t *testing.T) { + defer util.HackElectraMaxuint(t)() + ctx := context.Background() + t.Run("fallback fails", func(t *testing.T) { + cli, srv := newMockEngine(t) + fx := testBlindedBlockFixtures(t) + srv.register(GetPayloadBodiesByHashV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) { + executionPayloadBodies := []*pb.ExecutionPayloadBody{nil, nil} + mockWriteResult(t, w, msg, executionPayloadBodies) + }) + srv.register(GetPayloadBodiesByRangeV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) { + executionPayloadBodies := []*pb.ExecutionPayloadBody{nil, nil} + mockWriteResult(t, w, msg, executionPayloadBodies) + }) + toUnblind := []interfaces.ReadOnlySignedBeaconBlock{ + fx.denebBlock.blinded.block, + fx.emptyDenebBlock.blinded.block, + } + _, err := reconstructBlindedBlockBatch(ctx, cli, toUnblind) + require.ErrorIs(t, err, errNilPayloadBody) + require.Equal(t, 1, srv.callCount(GetPayloadBodiesByHashV1)) + require.Equal(t, 1, srv.callCount(GetPayloadBodiesByRangeV1)) + }) + t.Run("fallback succeeds", func(t *testing.T) { + cli, srv := newMockEngine(t) + fx := testBlindedBlockFixtures(t) + srv.register(GetPayloadBodiesByHashV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) { + executionPayloadBodies := []*pb.ExecutionPayloadBody{nil, nil} + mockWriteResult(t, w, msg, executionPayloadBodies) + }) + srv.register(GetPayloadBodiesByRangeV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) { + executionPayloadBodies := []*pb.ExecutionPayloadBody{ + payloadToBody(t, fx.denebBlock.blinded.header), + payloadToBody(t, fx.emptyDenebBlock.blinded.header), + } + mockWriteResult(t, w, msg, executionPayloadBodies) + }) + unblind := []interfaces.ReadOnlySignedBeaconBlock{ + fx.denebBlock.blinded.block, + fx.emptyDenebBlock.blinded.block, + } + _, err := reconstructBlindedBlockBatch(ctx, cli, unblind) + require.NoError(t, err) + }) + t.Run("separated by block number gap", func(t *testing.T) { + cli, srv := newMockEngine(t) + fx := testBlindedBlockFixtures(t) + srv.register(GetPayloadBodiesByHashV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) { + executionPayloadBodies := []*pb.ExecutionPayloadBody{nil, nil, nil} + mockWriteResult(t, w, msg, executionPayloadBodies) + }) + srv.register(GetPayloadBodiesByRangeV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) { + p := mockParseUintList(t, msg.Params) + require.Equal(t, 2, len(p)) + start, count := p[0], p[1] + // Return first 2 blocks by number, which are contiguous. + if start == fx.denebBlock.blinded.header.BlockNumber() { + require.Equal(t, uint64(2), count) + executionPayloadBodies := []*pb.ExecutionPayloadBody{ + payloadToBody(t, fx.denebBlock.blinded.header), + payloadToBody(t, fx.emptyDenebBlock.blinded.header), + } + mockWriteResult(t, w, msg, executionPayloadBodies) + return + } + // Assume it's the second request + require.Equal(t, fx.afterSkipDeneb.blinded.header.BlockNumber(), start) + require.Equal(t, uint64(1), count) + executionPayloadBodies := []*pb.ExecutionPayloadBody{ + payloadToBody(t, fx.afterSkipDeneb.blinded.header), + } + mockWriteResult(t, w, msg, executionPayloadBodies) + }) + // separate methods for the electra block + srv.register(GetPayloadBodiesByHashV2, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) { + executionPayloadBodies := []*pb.ExecutionPayloadBody{nil} + mockWriteResult(t, w, msg, executionPayloadBodies) + }) + srv.register(GetPayloadBodiesByRangeV2, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) { + p := mockParseUintList(t, msg.Params) + require.Equal(t, 2, len(p)) + start, count := p[0], p[1] + require.Equal(t, fx.electra.blinded.header.BlockNumber(), start) + require.Equal(t, uint64(1), count) + executionPayloadBodies := []*pb.ExecutionPayloadBody{ + payloadToBody(t, fx.electra.blinded.header), + } + mockWriteResult(t, w, msg, executionPayloadBodies) + }) + blind := []interfaces.ReadOnlySignedBeaconBlock{ + fx.denebBlock.blinded.block, + fx.emptyDenebBlock.blinded.block, + fx.afterSkipDeneb.blinded.block, + } + unblind, err := reconstructBlindedBlockBatch(ctx, cli, blind) + require.NoError(t, err) + for i := range unblind { + testAssertReconstructedEquivalent(t, blind[i], unblind[i]) + } + }) +} + +func TestReconstructBlindedBlockBatchDenebAndElectra(t *testing.T) { + defer util.HackElectraMaxuint(t)() + t.Run("deneb and electra", func(t *testing.T) { + cli, srv := newMockEngine(t) + fx := testBlindedBlockFixtures(t) + // The reconstructed should make separate calls for the deneb (v1) and electra (v2) blocks. + srv.register(GetPayloadBodiesByHashV1, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) { + executionPayloadBodies := []*pb.ExecutionPayloadBody{payloadToBody(t, fx.denebBlock.blinded.header)} + mockWriteResult(t, w, msg, executionPayloadBodies) + }) + srv.register(GetPayloadBodiesByHashV2, func(msg *jsonrpcMessage, w http.ResponseWriter, r *http.Request) { + executionPayloadBodies := []*pb.ExecutionPayloadBody{payloadToBody(t, fx.electra.blinded.header)} + mockWriteResult(t, w, msg, executionPayloadBodies) + }) + blinded := []interfaces.ReadOnlySignedBeaconBlock{ + fx.denebBlock.blinded.block, + fx.electra.blinded.block, + } + unblinded, err := reconstructBlindedBlockBatch(context.Background(), cli, blinded) + require.NoError(t, err) + require.Equal(t, len(blinded), len(unblinded)) + for i := range unblinded { + testAssertReconstructedEquivalent(t, blinded[i], unblinded[i]) + } + }) +} diff --git a/beacon-chain/p2p/encoder/BUILD.bazel b/beacon-chain/p2p/encoder/BUILD.bazel index 374e6d4f7e65..27c5f71bddc3 100644 --- a/beacon-chain/p2p/encoder/BUILD.bazel +++ b/beacon-chain/p2p/encoder/BUILD.bazel @@ -30,6 +30,7 @@ go_test( "ssz_test.go", "varint_test.go", ], + data = glob(["testdata/**"]), embed = [":go_default_library"], deps = [ "//config/params:go_default_library", @@ -39,6 +40,10 @@ go_test( "//testing/util:go_default_library", "@com_github_gogo_protobuf//proto:go_default_library", "@com_github_golang_snappy//:go_default_library", + "@com_github_google_go_cmp//cmp:go_default_library", + "@com_github_prysmaticlabs_fastssz//:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//testing/protocmp:go_default_library", ], ) diff --git a/beacon-chain/p2p/encoder/ssz_test.go b/beacon-chain/p2p/encoder/ssz_test.go index e51463f28f2a..9fa8a1cc4a10 100644 --- a/beacon-chain/p2p/encoder/ssz_test.go +++ b/beacon-chain/p2p/encoder/ssz_test.go @@ -9,6 +9,8 @@ import ( "testing" gogo "github.com/gogo/protobuf/proto" + "github.com/google/go-cmp/cmp" + fastssz "github.com/prysmaticlabs/fastssz" "github.com/prysmaticlabs/prysm/v5/beacon-chain/p2p/encoder" "github.com/prysmaticlabs/prysm/v5/config/params" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" @@ -16,8 +18,561 @@ import ( "github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/testing/util" "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/testing/protocmp" ) +// Define an interface that combines fastssz.Marshaler and proto.Message +type MarshalerProtoMessage interface { + fastssz.Marshaler + proto.Message + fastssz.Unmarshaler +} + +type MarshalerProtoCreator interface { + Create() MarshalerProtoMessage +} + +type AttestationCreator struct{} +type AttestationElectraCreator struct{} +type AggregateAttestationAndProofCreator struct{} +type AggregateAttestationAndProofElectraCreator struct{} +type SignedAggregateAttestationAndProofCreator struct{} +type SignedAggregateAttestationAndProofElectraCreator struct{} +type AttestationDataCreator struct{} +type CheckpointCreator struct{} +type BeaconBlockCreator struct{} +type SignedBeaconBlockCreator struct{} +type BeaconBlockAltairCreator struct{} +type SignedBeaconBlockAltairCreator struct{} +type BeaconBlockBodyCreator struct{} +type BeaconBlockBodyAltairCreator struct{} +type ProposerSlashingCreator struct{} +type AttesterSlashingCreator struct{} +type AttesterSlashingElectraCreator struct{} +type DepositCreator struct{} +type VoluntaryExitCreator struct{} +type SignedVoluntaryExitCreator struct{} +type Eth1DataCreator struct{} +type BeaconBlockHeaderCreator struct{} +type SignedBeaconBlockHeaderCreator struct{} +type IndexedAttestationCreator struct{} +type IndexedAttestationElectraCreator struct{} +type SyncAggregateCreator struct{} +type SignedBeaconBlockBellatrixCreator struct{} +type BeaconBlockBellatrixCreator struct{} +type BeaconBlockBodyBellatrixCreator struct{} +type SignedBlindedBeaconBlockBellatrixCreator struct{} +type BlindedBeaconBlockBellatrixCreator struct{} +type BlindedBeaconBlockBodyBellatrixCreator struct{} +type SignedBeaconBlockContentsDenebCreator struct{} +type BeaconBlockContentsDenebCreator struct{} +type SignedBeaconBlockDenebCreator struct{} +type BeaconBlockDenebCreator struct{} +type BeaconBlockBodyDenebCreator struct{} +type SignedBeaconBlockCapellaCreator struct{} +type BeaconBlockCapellaCreator struct{} +type BeaconBlockBodyCapellaCreator struct{} +type SignedBlindedBeaconBlockCapellaCreator struct{} +type BlindedBeaconBlockCapellaCreator struct{} +type BlindedBeaconBlockBodyCapellaCreator struct{} +type SignedBlindedBeaconBlockDenebCreator struct{} +type BlindedBeaconBlockDenebCreator struct{} +type BlindedBeaconBlockBodyDenebCreator struct{} +type SignedBeaconBlockElectraCreator struct{} +type BeaconBlockElectraCreator struct{} +type BeaconBlockBodyElectraCreator struct{} +type SignedBlindedBeaconBlockElectraCreator struct{} +type BlindedBeaconBlockElectraCreator struct{} +type BlindedBeaconBlockBodyElectraCreator struct{} +type ValidatorRegistrationV1Creator struct{} +type SignedValidatorRegistrationV1Creator struct{} +type BuilderBidCreator struct{} +type BuilderBidCapellaCreator struct{} +type BuilderBidDenebCreator struct{} +type BlobSidecarCreator struct{} +type BlobSidecarsCreator struct{} +type Deposit_DataCreator struct{} +type BeaconStateCreator struct{} +type BeaconStateAltairCreator struct{} +type ForkCreator struct{} +type PendingAttestationCreator struct{} +type HistoricalBatchCreator struct{} +type SigningDataCreator struct{} +type ForkDataCreator struct{} +type DepositMessageCreator struct{} +type SyncCommitteeCreator struct{} +type SyncAggregatorSelectionDataCreator struct{} +type BeaconStateBellatrixCreator struct{} +type BeaconStateCapellaCreator struct{} +type BeaconStateDenebCreator struct{} +type BeaconStateElectraCreator struct{} +type PowBlockCreator struct{} +type HistoricalSummaryCreator struct{} +type BlobIdentifierCreator struct{} +type PendingBalanceDepositCreator struct{} +type PendingPartialWithdrawalCreator struct{} +type ConsolidationCreator struct{} +type SignedConsolidationCreator struct{} +type PendingConsolidationCreator struct{} +type StatusCreator struct{} +type BeaconBlocksByRangeRequestCreator struct{} +type ENRForkIDCreator struct{} +type MetaDataV0Creator struct{} +type MetaDataV1Creator struct{} +type BlobSidecarsByRangeRequestCreator struct{} +type DepositSnapshotCreator struct{} +type SyncCommitteeMessageCreator struct{} +type SyncCommitteeContributionCreator struct{} +type ContributionAndProofCreator struct{} +type SignedContributionAndProofCreator struct{} +type ValidatorCreator struct{} +type BLSToExecutionChangeCreator struct{} +type SignedBLSToExecutionChangeCreator struct{} + +func (AttestationCreator) Create() MarshalerProtoMessage { return ðpb.Attestation{} } +func (AttestationElectraCreator) Create() MarshalerProtoMessage { return ðpb.AttestationElectra{} } +func (AggregateAttestationAndProofCreator) Create() MarshalerProtoMessage { + return ðpb.AggregateAttestationAndProof{} +} +func (AggregateAttestationAndProofElectraCreator) Create() MarshalerProtoMessage { + return ðpb.AggregateAttestationAndProofElectra{} +} +func (SignedAggregateAttestationAndProofCreator) Create() MarshalerProtoMessage { + return ðpb.SignedAggregateAttestationAndProof{} +} +func (SignedAggregateAttestationAndProofElectraCreator) Create() MarshalerProtoMessage { + return ðpb.SignedAggregateAttestationAndProofElectra{} +} +func (AttestationDataCreator) Create() MarshalerProtoMessage { return ðpb.AttestationData{} } +func (CheckpointCreator) Create() MarshalerProtoMessage { return ðpb.Checkpoint{} } +func (BeaconBlockCreator) Create() MarshalerProtoMessage { return ðpb.BeaconBlock{} } +func (SignedBeaconBlockCreator) Create() MarshalerProtoMessage { return ðpb.SignedBeaconBlock{} } +func (BeaconBlockAltairCreator) Create() MarshalerProtoMessage { return ðpb.BeaconBlockAltair{} } +func (SignedBeaconBlockAltairCreator) Create() MarshalerProtoMessage { + return ðpb.SignedBeaconBlockAltair{} +} +func (BeaconBlockBodyCreator) Create() MarshalerProtoMessage { return ðpb.BeaconBlockBody{} } +func (BeaconBlockBodyAltairCreator) Create() MarshalerProtoMessage { + return ðpb.BeaconBlockBodyAltair{} +} +func (ProposerSlashingCreator) Create() MarshalerProtoMessage { return ðpb.ProposerSlashing{} } +func (AttesterSlashingCreator) Create() MarshalerProtoMessage { return ðpb.AttesterSlashing{} } +func (AttesterSlashingElectraCreator) Create() MarshalerProtoMessage { + return ðpb.AttesterSlashingElectra{} +} +func (DepositCreator) Create() MarshalerProtoMessage { return ðpb.Deposit{} } +func (VoluntaryExitCreator) Create() MarshalerProtoMessage { return ðpb.VoluntaryExit{} } +func (SignedVoluntaryExitCreator) Create() MarshalerProtoMessage { + return ðpb.SignedVoluntaryExit{} +} +func (Eth1DataCreator) Create() MarshalerProtoMessage { return ðpb.Eth1Data{} } +func (BeaconBlockHeaderCreator) Create() MarshalerProtoMessage { return ðpb.BeaconBlockHeader{} } +func (SignedBeaconBlockHeaderCreator) Create() MarshalerProtoMessage { + return ðpb.SignedBeaconBlockHeader{} +} +func (IndexedAttestationCreator) Create() MarshalerProtoMessage { return ðpb.IndexedAttestation{} } +func (IndexedAttestationElectraCreator) Create() MarshalerProtoMessage { + return ðpb.IndexedAttestationElectra{} +} +func (SyncAggregateCreator) Create() MarshalerProtoMessage { return ðpb.SyncAggregate{} } +func (SignedBeaconBlockBellatrixCreator) Create() MarshalerProtoMessage { + return ðpb.SignedBeaconBlockBellatrix{} +} +func (BeaconBlockBellatrixCreator) Create() MarshalerProtoMessage { + return ðpb.BeaconBlockBellatrix{} +} +func (BeaconBlockBodyBellatrixCreator) Create() MarshalerProtoMessage { + return ðpb.BeaconBlockBodyBellatrix{} +} +func (SignedBlindedBeaconBlockBellatrixCreator) Create() MarshalerProtoMessage { + return ðpb.SignedBlindedBeaconBlockBellatrix{} +} +func (BlindedBeaconBlockBellatrixCreator) Create() MarshalerProtoMessage { + return ðpb.BlindedBeaconBlockBellatrix{} +} +func (BlindedBeaconBlockBodyBellatrixCreator) Create() MarshalerProtoMessage { + return ðpb.BlindedBeaconBlockBodyBellatrix{} +} +func (SignedBeaconBlockContentsDenebCreator) Create() MarshalerProtoMessage { + return ðpb.SignedBeaconBlockContentsDeneb{} +} +func (BeaconBlockContentsDenebCreator) Create() MarshalerProtoMessage { + return ðpb.BeaconBlockContentsDeneb{} +} +func (SignedBeaconBlockDenebCreator) Create() MarshalerProtoMessage { + return ðpb.SignedBeaconBlockDeneb{} +} +func (BeaconBlockDenebCreator) Create() MarshalerProtoMessage { return ðpb.BeaconBlockDeneb{} } +func (BeaconBlockBodyDenebCreator) Create() MarshalerProtoMessage { + return ðpb.BeaconBlockBodyDeneb{} +} +func (SignedBeaconBlockCapellaCreator) Create() MarshalerProtoMessage { + return ðpb.SignedBeaconBlockCapella{} +} +func (BeaconBlockCapellaCreator) Create() MarshalerProtoMessage { return ðpb.BeaconBlockCapella{} } +func (BeaconBlockBodyCapellaCreator) Create() MarshalerProtoMessage { + return ðpb.BeaconBlockBodyCapella{} +} +func (SignedBlindedBeaconBlockCapellaCreator) Create() MarshalerProtoMessage { + return ðpb.SignedBlindedBeaconBlockCapella{} +} +func (BlindedBeaconBlockCapellaCreator) Create() MarshalerProtoMessage { + return ðpb.BlindedBeaconBlockCapella{} +} +func (BlindedBeaconBlockBodyCapellaCreator) Create() MarshalerProtoMessage { + return ðpb.BlindedBeaconBlockBodyCapella{} +} +func (SignedBlindedBeaconBlockDenebCreator) Create() MarshalerProtoMessage { + return ðpb.SignedBlindedBeaconBlockDeneb{} +} +func (BlindedBeaconBlockDenebCreator) Create() MarshalerProtoMessage { + return ðpb.BlindedBeaconBlockDeneb{} +} +func (BlindedBeaconBlockBodyDenebCreator) Create() MarshalerProtoMessage { + return ðpb.BlindedBeaconBlockBodyDeneb{} +} +func (SignedBeaconBlockElectraCreator) Create() MarshalerProtoMessage { + return ðpb.SignedBeaconBlockElectra{} +} +func (BeaconBlockElectraCreator) Create() MarshalerProtoMessage { return ðpb.BeaconBlockElectra{} } +func (BeaconBlockBodyElectraCreator) Create() MarshalerProtoMessage { + return ðpb.BeaconBlockBodyElectra{} +} +func (SignedBlindedBeaconBlockElectraCreator) Create() MarshalerProtoMessage { + return ðpb.SignedBlindedBeaconBlockElectra{} +} +func (BlindedBeaconBlockElectraCreator) Create() MarshalerProtoMessage { + return ðpb.BlindedBeaconBlockElectra{} +} +func (BlindedBeaconBlockBodyElectraCreator) Create() MarshalerProtoMessage { + return ðpb.BlindedBeaconBlockBodyElectra{} +} +func (ValidatorRegistrationV1Creator) Create() MarshalerProtoMessage { + return ðpb.ValidatorRegistrationV1{} +} +func (SignedValidatorRegistrationV1Creator) Create() MarshalerProtoMessage { + return ðpb.SignedValidatorRegistrationV1{} +} +func (BuilderBidCreator) Create() MarshalerProtoMessage { return ðpb.BuilderBid{} } +func (BuilderBidCapellaCreator) Create() MarshalerProtoMessage { return ðpb.BuilderBidCapella{} } +func (BuilderBidDenebCreator) Create() MarshalerProtoMessage { return ðpb.BuilderBidDeneb{} } +func (BlobSidecarCreator) Create() MarshalerProtoMessage { return ðpb.BlobSidecar{} } +func (BlobSidecarsCreator) Create() MarshalerProtoMessage { return ðpb.BlobSidecars{} } +func (Deposit_DataCreator) Create() MarshalerProtoMessage { return ðpb.Deposit_Data{} } +func (BeaconStateCreator) Create() MarshalerProtoMessage { return ðpb.BeaconState{} } +func (BeaconStateAltairCreator) Create() MarshalerProtoMessage { return ðpb.BeaconStateAltair{} } +func (ForkCreator) Create() MarshalerProtoMessage { return ðpb.Fork{} } +func (PendingAttestationCreator) Create() MarshalerProtoMessage { return ðpb.PendingAttestation{} } +func (HistoricalBatchCreator) Create() MarshalerProtoMessage { return ðpb.HistoricalBatch{} } +func (SigningDataCreator) Create() MarshalerProtoMessage { return ðpb.SigningData{} } +func (ForkDataCreator) Create() MarshalerProtoMessage { return ðpb.ForkData{} } +func (DepositMessageCreator) Create() MarshalerProtoMessage { return ðpb.DepositMessage{} } +func (SyncCommitteeCreator) Create() MarshalerProtoMessage { return ðpb.SyncCommittee{} } +func (SyncAggregatorSelectionDataCreator) Create() MarshalerProtoMessage { + return ðpb.SyncAggregatorSelectionData{} +} +func (BeaconStateBellatrixCreator) Create() MarshalerProtoMessage { + return ðpb.BeaconStateBellatrix{} +} +func (BeaconStateCapellaCreator) Create() MarshalerProtoMessage { return ðpb.BeaconStateCapella{} } +func (BeaconStateDenebCreator) Create() MarshalerProtoMessage { return ðpb.BeaconStateDeneb{} } +func (BeaconStateElectraCreator) Create() MarshalerProtoMessage { return ðpb.BeaconStateElectra{} } +func (PowBlockCreator) Create() MarshalerProtoMessage { return ðpb.PowBlock{} } +func (HistoricalSummaryCreator) Create() MarshalerProtoMessage { return ðpb.HistoricalSummary{} } +func (BlobIdentifierCreator) Create() MarshalerProtoMessage { return ðpb.BlobIdentifier{} } +func (PendingBalanceDepositCreator) Create() MarshalerProtoMessage { + return ðpb.PendingBalanceDeposit{} +} +func (PendingPartialWithdrawalCreator) Create() MarshalerProtoMessage { + return ðpb.PendingPartialWithdrawal{} +} +func (ConsolidationCreator) Create() MarshalerProtoMessage { return ðpb.Consolidation{} } +func (SignedConsolidationCreator) Create() MarshalerProtoMessage { + return ðpb.SignedConsolidation{} +} +func (PendingConsolidationCreator) Create() MarshalerProtoMessage { + return ðpb.PendingConsolidation{} +} +func (StatusCreator) Create() MarshalerProtoMessage { return ðpb.Status{} } +func (BeaconBlocksByRangeRequestCreator) Create() MarshalerProtoMessage { + return ðpb.BeaconBlocksByRangeRequest{} +} +func (ENRForkIDCreator) Create() MarshalerProtoMessage { return ðpb.ENRForkID{} } +func (MetaDataV0Creator) Create() MarshalerProtoMessage { return ðpb.MetaDataV0{} } +func (MetaDataV1Creator) Create() MarshalerProtoMessage { return ðpb.MetaDataV1{} } +func (BlobSidecarsByRangeRequestCreator) Create() MarshalerProtoMessage { + return ðpb.BlobSidecarsByRangeRequest{} +} +func (DepositSnapshotCreator) Create() MarshalerProtoMessage { return ðpb.DepositSnapshot{} } +func (SyncCommitteeMessageCreator) Create() MarshalerProtoMessage { + return ðpb.SyncCommitteeMessage{} +} +func (SyncCommitteeContributionCreator) Create() MarshalerProtoMessage { + return ðpb.SyncCommitteeContribution{} +} +func (ContributionAndProofCreator) Create() MarshalerProtoMessage { + return ðpb.ContributionAndProof{} +} +func (SignedContributionAndProofCreator) Create() MarshalerProtoMessage { + return ðpb.SignedContributionAndProof{} +} +func (ValidatorCreator) Create() MarshalerProtoMessage { return ðpb.Validator{} } +func (BLSToExecutionChangeCreator) Create() MarshalerProtoMessage { + return ðpb.BLSToExecutionChange{} +} +func (SignedBLSToExecutionChangeCreator) Create() MarshalerProtoMessage { + return ðpb.SignedBLSToExecutionChange{} +} + +var creators = []MarshalerProtoCreator{ + AttestationCreator{}, + AttestationElectraCreator{}, + AggregateAttestationAndProofCreator{}, + AggregateAttestationAndProofElectraCreator{}, + SignedAggregateAttestationAndProofCreator{}, + SignedAggregateAttestationAndProofElectraCreator{}, + AttestationDataCreator{}, + CheckpointCreator{}, + BeaconBlockCreator{}, + SignedBeaconBlockCreator{}, + BeaconBlockAltairCreator{}, + SignedBeaconBlockAltairCreator{}, + BeaconBlockBodyCreator{}, + BeaconBlockBodyAltairCreator{}, + ProposerSlashingCreator{}, + AttesterSlashingCreator{}, + AttesterSlashingElectraCreator{}, + DepositCreator{}, + VoluntaryExitCreator{}, + SignedVoluntaryExitCreator{}, + Eth1DataCreator{}, + BeaconBlockHeaderCreator{}, + SignedBeaconBlockHeaderCreator{}, + IndexedAttestationCreator{}, + IndexedAttestationElectraCreator{}, + SyncAggregateCreator{}, + SignedBeaconBlockBellatrixCreator{}, + BeaconBlockBellatrixCreator{}, + BeaconBlockBodyBellatrixCreator{}, + SignedBlindedBeaconBlockBellatrixCreator{}, + BlindedBeaconBlockBellatrixCreator{}, + BlindedBeaconBlockBodyBellatrixCreator{}, + SignedBeaconBlockContentsDenebCreator{}, + BeaconBlockContentsDenebCreator{}, + SignedBeaconBlockDenebCreator{}, + BeaconBlockDenebCreator{}, + BeaconBlockBodyDenebCreator{}, + SignedBeaconBlockCapellaCreator{}, + BeaconBlockCapellaCreator{}, + BeaconBlockBodyCapellaCreator{}, + SignedBlindedBeaconBlockCapellaCreator{}, + BlindedBeaconBlockCapellaCreator{}, + BlindedBeaconBlockBodyCapellaCreator{}, + SignedBlindedBeaconBlockDenebCreator{}, + BlindedBeaconBlockDenebCreator{}, + BlindedBeaconBlockBodyDenebCreator{}, + SignedBeaconBlockElectraCreator{}, + BeaconBlockElectraCreator{}, + BeaconBlockBodyElectraCreator{}, + SignedBlindedBeaconBlockElectraCreator{}, + BlindedBeaconBlockElectraCreator{}, + BlindedBeaconBlockBodyElectraCreator{}, + ValidatorRegistrationV1Creator{}, + SignedValidatorRegistrationV1Creator{}, + BuilderBidCreator{}, + BuilderBidCapellaCreator{}, + BuilderBidDenebCreator{}, + BlobSidecarCreator{}, + BlobSidecarsCreator{}, + Deposit_DataCreator{}, + BeaconStateCreator{}, + BeaconStateAltairCreator{}, + ForkCreator{}, + PendingAttestationCreator{}, + HistoricalBatchCreator{}, + SigningDataCreator{}, + ForkDataCreator{}, + DepositMessageCreator{}, + SyncCommitteeCreator{}, + SyncAggregatorSelectionDataCreator{}, + BeaconStateBellatrixCreator{}, + BeaconStateCapellaCreator{}, + BeaconStateDenebCreator{}, + BeaconStateElectraCreator{}, + PowBlockCreator{}, + HistoricalSummaryCreator{}, + BlobIdentifierCreator{}, + PendingBalanceDepositCreator{}, + PendingPartialWithdrawalCreator{}, + ConsolidationCreator{}, + SignedConsolidationCreator{}, + PendingConsolidationCreator{}, + StatusCreator{}, + BeaconBlocksByRangeRequestCreator{}, + ENRForkIDCreator{}, + MetaDataV0Creator{}, + MetaDataV1Creator{}, + BlobSidecarsByRangeRequestCreator{}, + DepositSnapshotCreator{}, + SyncCommitteeMessageCreator{}, + SyncCommitteeContributionCreator{}, + ContributionAndProofCreator{}, + SignedContributionAndProofCreator{}, + ValidatorCreator{}, + BLSToExecutionChangeCreator{}, + SignedBLSToExecutionChangeCreator{}, +} + +func assertProtoMessagesEqual(t *testing.T, decoded, msg proto.Message) { + // Check if two proto messages are equal + if proto.Equal(decoded, msg) { + return + } + + // If they are not equal, check if their unknown values are equal + // Ignore unknown fields when comparing proto messages + a := decoded.ProtoReflect().GetUnknown() + b := msg.ProtoReflect().GetUnknown() + if !bytes.Equal(a, b) { + return + } + + // If unknown values are equal, check if any of the fields of the proto message are proto messages themselves + containsNestedProtoMessage := false + decoded.ProtoReflect().Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + // Check if the field is a message + if fd.Kind() == protoreflect.MessageKind { + containsNestedProtoMessage = true + + // Get the corresponding field from the other message + otherValue := msg.ProtoReflect().Get(fd) + + // If the field is not set in the other message, skip it + if !otherValue.IsValid() { + return true + } + + // Recursively compare the fields + assertProtoMessagesEqual(t, v.Message().Interface(), otherValue.Message().Interface()) + } + + return true + }) + + // If there are no proto messages contained inside, then throw an error + // The error is thrown iff the decoded message is not equal to the original message + // after ignoring unknown fields in (nested) proto message(s). + if !containsNestedProtoMessage { + t.Log(cmp.Diff(decoded, msg, protocmp.Transform())) + t.Fatal("Decoded message is not the same as original") + } +} + +// Refactor the unmarshal logic into a private function. +func unmarshalProtoMessage(data []byte, creator MarshalerProtoCreator) (MarshalerProtoMessage, error) { + msg := creator.Create() + if err := proto.Unmarshal(data, msg); err != nil { + return nil, err + } + return msg, nil +} + +func gossipRoundTripHelper(t *testing.T, msg MarshalerProtoMessage, creator MarshalerProtoCreator) { + e := &encoder.SszNetworkEncoder{} + buf := new(bytes.Buffer) + + // Example of calling a function that requires MarshalerProtoMessage + _, err := e.EncodeGossip(buf, msg) + if err != nil { + t.Logf("Failed to encode: %v", err) + return + } + + decoded := creator.Create() + + if err := e.DecodeGossip(buf.Bytes(), decoded); err != nil { + t.Fatalf("Failed to decode: %v", err) + } + assertProtoMessagesEqual(t, decoded, msg) +} + +func lengthRoundTripHelper(t *testing.T, msg MarshalerProtoMessage, creator MarshalerProtoCreator) { + e := &encoder.SszNetworkEncoder{} + buf := new(bytes.Buffer) + + // Example of calling a function that requires MarshalerProtoMessage + _, err := e.EncodeWithMaxLength(buf, msg) + if err != nil { + t.Logf("Failed to encode: %v", err) + return + } + + decoded := creator.Create() + + if err := e.DecodeWithMaxLength(buf, decoded); err != nil { + t.Fatalf("Failed to decode: %v", err) + } + + assertProtoMessagesEqual(t, decoded, msg) +} + +func FuzzRoundTripWithGossip(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte, index int) { + if index < 0 || index >= len(creators) { + t.Skip() + } + // Select a random creator from the list. + creator := creators[index] + msg, err := unmarshalProtoMessage(data, creator) + if err != nil { + t.Logf("Failed to unmarshal: %v", err) + return + } + gossipRoundTripHelper(t, msg, creator) + lengthRoundTripHelper(t, msg, creator) + }) +} + +func TestSszNetworkEncoder_RoundTrip_SignedVoluntaryExit(t *testing.T) { + e := &encoder.SszNetworkEncoder{} + buf := new(bytes.Buffer) + + data := []byte("\x12`000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n\n0000000000") + msg := ðpb.SignedVoluntaryExit{} + + if err := proto.Unmarshal(data, msg); err != nil { + t.Logf("Failed to unmarshal: %v", err) + return + } + + _, err := e.EncodeGossip(buf, msg) + require.NoError(t, err) + decoded := ðpb.SignedVoluntaryExit{} + require.NoError(t, e.DecodeGossip(buf.Bytes(), decoded)) + assertProtoMessagesEqual(t, decoded, msg) +} + +func TestSszNetworkEncoder_RoundTrip_Consolidation(t *testing.T) { + e := &encoder.SszNetworkEncoder{} + buf := new(bytes.Buffer) + + data := []byte("\xc800") + msg := ðpb.Consolidation{} + + if err := proto.Unmarshal(data, msg); err != nil { + t.Logf("Failed to unmarshal: %v", err) + return + } + + _, err := e.EncodeGossip(buf, msg) + require.NoError(t, err) + decoded := ðpb.Consolidation{} + require.NoError(t, e.DecodeGossip(buf.Bytes(), decoded)) + + assertProtoMessagesEqual(t, decoded, msg) +} + func TestSszNetworkEncoder_RoundTrip(t *testing.T) { e := &encoder.SszNetworkEncoder{} testRoundTripWithLength(t, e) diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block.go b/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block.go index 88e935e118f4..e90f3859dde6 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" - "github.com/prysmaticlabs/prysm/v5/math" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" @@ -44,7 +44,7 @@ func (vs *Server) constructGenericBeaconBlock(sBlk interfaces.SignedBeaconBlock, } // Helper functions for constructing blocks for each version -func (vs *Server) constructElectraBlock(blockProto proto.Message, isBlinded bool, payloadValue math.Wei, bundle *enginev1.BlobsBundle) *ethpb.GenericBeaconBlock { +func (vs *Server) constructElectraBlock(blockProto proto.Message, isBlinded bool, payloadValue primitives.Wei, bundle *enginev1.BlobsBundle) *ethpb.GenericBeaconBlock { if isBlinded { return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_BlindedElectra{BlindedElectra: blockProto.(*ethpb.BlindedBeaconBlockElectra)}, IsBlinded: true, PayloadValue: (*payloadValue).String()} } @@ -56,7 +56,7 @@ func (vs *Server) constructElectraBlock(blockProto proto.Message, isBlinded bool return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Electra{Electra: electraContents}, IsBlinded: false, PayloadValue: (*payloadValue).String()} } -func (vs *Server) constructDenebBlock(blockProto proto.Message, isBlinded bool, payloadValue math.Wei, bundle *enginev1.BlobsBundle) *ethpb.GenericBeaconBlock { +func (vs *Server) constructDenebBlock(blockProto proto.Message, isBlinded bool, payloadValue primitives.Wei, bundle *enginev1.BlobsBundle) *ethpb.GenericBeaconBlock { if isBlinded { return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_BlindedDeneb{BlindedDeneb: blockProto.(*ethpb.BlindedBeaconBlockDeneb)}, IsBlinded: true, PayloadValue: (*payloadValue).String()} } @@ -68,14 +68,14 @@ func (vs *Server) constructDenebBlock(blockProto proto.Message, isBlinded bool, return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Deneb{Deneb: denebContents}, IsBlinded: false, PayloadValue: (*payloadValue).String()} } -func (vs *Server) constructCapellaBlock(pb proto.Message, isBlinded bool, payloadValue math.Wei) *ethpb.GenericBeaconBlock { +func (vs *Server) constructCapellaBlock(pb proto.Message, isBlinded bool, payloadValue primitives.Wei) *ethpb.GenericBeaconBlock { if isBlinded { return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_BlindedCapella{BlindedCapella: pb.(*ethpb.BlindedBeaconBlockCapella)}, IsBlinded: true, PayloadValue: (*payloadValue).String()} } return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Capella{Capella: pb.(*ethpb.BeaconBlockCapella)}, IsBlinded: false, PayloadValue: (*payloadValue).String()} } -func (vs *Server) constructBellatrixBlock(pb proto.Message, isBlinded bool, payloadValue math.Wei) *ethpb.GenericBeaconBlock { +func (vs *Server) constructBellatrixBlock(pb proto.Message, isBlinded bool, payloadValue primitives.Wei) *ethpb.GenericBeaconBlock { if isBlinded { return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_BlindedBellatrix{BlindedBellatrix: pb.(*ethpb.BlindedBeaconBlockBellatrix)}, IsBlinded: true, PayloadValue: (*payloadValue).String()} } diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go index c7baa85b3fb8..907dbadf9132 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go @@ -18,7 +18,6 @@ import ( "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" "github.com/prysmaticlabs/prysm/v5/encoding/ssz" - "github.com/prysmaticlabs/prysm/v5/math" "github.com/prysmaticlabs/prysm/v5/monitoring/tracing" "github.com/prysmaticlabs/prysm/v5/network/forks" "github.com/prysmaticlabs/prysm/v5/runtime/version" @@ -243,7 +242,7 @@ func (vs *Server) getPayloadHeaderFromBuilder(ctx context.Context, slot primitiv } l := log.WithFields(logrus.Fields{ - "gweiValue": math.WeiToGwei(v), + "gweiValue": primitives.WeiToGwei(v), "builderPubKey": fmt.Sprintf("%#x", bid.Pubkey()), "blockHash": fmt.Sprintf("%#x", header.BlockHash()), "slot": slot, diff --git a/beacon-chain/state/BUILD.bazel b/beacon-chain/state/BUILD.bazel index 95af0712b819..fa1ee84cff41 100644 --- a/beacon-chain/state/BUILD.bazel +++ b/beacon-chain/state/BUILD.bazel @@ -13,7 +13,6 @@ go_library( "//config/fieldparams:go_default_library", "//consensus-types/interfaces:go_default_library", "//consensus-types/primitives:go_default_library", - "//math:go_default_library", "//proto/engine/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "@com_github_prometheus_client_golang//prometheus:go_default_library", diff --git a/beacon-chain/state/interfaces.go b/beacon-chain/state/interfaces.go index 2b32602cad14..7a6a5e83d9af 100644 --- a/beacon-chain/state/interfaces.go +++ b/beacon-chain/state/interfaces.go @@ -11,7 +11,6 @@ import ( fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" ) @@ -182,7 +181,7 @@ type ReadOnlyEth1Data interface { // ReadOnlyExits defines a struct which only has read access to Exit related methods. type ReadOnlyExits interface { - ExitBalanceToConsume() (math.Gwei, error) + ExitBalanceToConsume() (primitives.Gwei, error) EarliestExitEpoch() (primitives.Epoch, error) } @@ -219,13 +218,13 @@ type ReadOnlySyncCommittee interface { } type ReadOnlyDeposits interface { - DepositBalanceToConsume() (math.Gwei, error) + DepositBalanceToConsume() (primitives.Gwei, error) DepositReceiptsStartIndex() (uint64, error) PendingBalanceDeposits() ([]*ethpb.PendingBalanceDeposit, error) } type ReadOnlyConsolidations interface { - ConsolidationBalanceToConsume() (math.Gwei, error) + ConsolidationBalanceToConsume() (primitives.Gwei, error) EarliestConsolidationEpoch() (primitives.Epoch, error) PendingConsolidations() ([]*ethpb.PendingConsolidation, error) NumPendingConsolidations() (uint64, error) @@ -249,7 +248,7 @@ type WriteOnlyEth1Data interface { SetEth1DataVotes(val []*ethpb.Eth1Data) error AppendEth1DataVotes(val *ethpb.Eth1Data) error SetEth1DepositIndex(val uint64) error - ExitEpochAndUpdateChurn(exitBalance math.Gwei) (primitives.Epoch, error) + ExitEpochAndUpdateChurn(exitBalance primitives.Gwei) (primitives.Epoch, error) } // WriteOnlyValidators defines a struct which only has write access to validators methods. @@ -321,7 +320,7 @@ type WriteOnlyWithdrawals interface { type WriteOnlyConsolidations interface { AppendPendingConsolidation(val *ethpb.PendingConsolidation) error - SetConsolidationBalanceToConsume(math.Gwei) error + SetConsolidationBalanceToConsume(primitives.Gwei) error SetEarliestConsolidationEpoch(epoch primitives.Epoch) error SetPendingConsolidations(val []*ethpb.PendingConsolidation) error } @@ -330,5 +329,5 @@ type WriteOnlyDeposits interface { AppendPendingBalanceDeposit(index primitives.ValidatorIndex, amount uint64) error SetDepositReceiptsStartIndex(index uint64) error SetPendingBalanceDeposits(val []*ethpb.PendingBalanceDeposit) error - SetDepositBalanceToConsume(math.Gwei) error + SetDepositBalanceToConsume(primitives.Gwei) error } diff --git a/beacon-chain/state/state-native/BUILD.bazel b/beacon-chain/state/state-native/BUILD.bazel index 3f8760c2a411..91dd62d471a0 100644 --- a/beacon-chain/state/state-native/BUILD.bazel +++ b/beacon-chain/state/state-native/BUILD.bazel @@ -143,7 +143,6 @@ go_test( "//container/trie:go_default_library", "//crypto/rand:go_default_library", "//encoding/bytesutil:go_default_library", - "//math:go_default_library", "//proto/engine/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//runtime/interop:go_default_library", diff --git a/beacon-chain/state/state-native/beacon_state_mainnet.go b/beacon-chain/state/state-native/beacon_state_mainnet.go index 4ceb16a65518..8cdcda554e6a 100644 --- a/beacon-chain/state/state-native/beacon_state_mainnet.go +++ b/beacon-chain/state/state-native/beacon_state_mainnet.go @@ -13,7 +13,6 @@ import ( "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stateutil" "github.com/prysmaticlabs/prysm/v5/config/features" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" ) @@ -64,10 +63,10 @@ type BeaconState struct { // Electra fields depositReceiptsStartIndex uint64 - depositBalanceToConsume math.Gwei - exitBalanceToConsume math.Gwei + depositBalanceToConsume primitives.Gwei + exitBalanceToConsume primitives.Gwei earliestExitEpoch primitives.Epoch - consolidationBalanceToConsume math.Gwei + consolidationBalanceToConsume primitives.Gwei earliestConsolidationEpoch primitives.Epoch pendingBalanceDeposits []*ethpb.PendingBalanceDeposit // pending_balance_deposits: List[PendingBalanceDeposit, PENDING_BALANCE_DEPOSITS_LIMIT] pendingPartialWithdrawals []*ethpb.PendingPartialWithdrawal // pending_partial_withdrawals: List[PartialWithdrawal, PENDING_PARTIAL_WITHDRAWALS_LIMIT] @@ -121,10 +120,10 @@ type beaconStateMarshalable struct { NextWithdrawalIndex uint64 `json:"next_withdrawal_index" yaml:"next_withdrawal_index"` NextWithdrawalValidatorIndex primitives.ValidatorIndex `json:"next_withdrawal_validator_index" yaml:"next_withdrawal_validator_index"` DepositReceiptsStartIndex uint64 `json:"deposit_receipts_start_index" yaml:"deposit_receipts_start_index"` - DepositBalanceToConsume math.Gwei `json:"deposit_balance_to_consume" yaml:"deposit_balance_to_consume"` - ExitBalanceToConsume math.Gwei `json:"exit_balance_to_consume" yaml:"exit_balance_to_consume"` + DepositBalanceToConsume primitives.Gwei `json:"deposit_balance_to_consume" yaml:"deposit_balance_to_consume"` + ExitBalanceToConsume primitives.Gwei `json:"exit_balance_to_consume" yaml:"exit_balance_to_consume"` EarliestExitEpoch primitives.Epoch `json:"earliest_exit_epoch" yaml:"earliest_exit_epoch"` - ConsolidationBalanceToConsume math.Gwei `json:"consolidation_balance_to_consume" yaml:"consolidation_balance_to_consume"` + ConsolidationBalanceToConsume primitives.Gwei `json:"consolidation_balance_to_consume" yaml:"consolidation_balance_to_consume"` EarliestConsolidationEpoch primitives.Epoch `json:"earliest_consolidation_epoch" yaml:"earliest_consolidation_epoch"` PendingBalanceDeposits []*ethpb.PendingBalanceDeposit `json:"pending_balance_deposits" yaml:"pending_balance_deposits"` PendingPartialWithdrawals []*ethpb.PendingPartialWithdrawal `json:"pending_partial_withdrawals" yaml:"pending_partial_withdrawals"` diff --git a/beacon-chain/state/state-native/beacon_state_minimal.go b/beacon-chain/state/state-native/beacon_state_minimal.go index 1a5631f9cc1f..886634a90832 100644 --- a/beacon-chain/state/state-native/beacon_state_minimal.go +++ b/beacon-chain/state/state-native/beacon_state_minimal.go @@ -13,7 +13,6 @@ import ( "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stateutil" "github.com/prysmaticlabs/prysm/v5/config/features" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" ) @@ -64,10 +63,10 @@ type BeaconState struct { // Electra fields depositReceiptsStartIndex uint64 - depositBalanceToConsume math.Gwei - exitBalanceToConsume math.Gwei + depositBalanceToConsume primitives.Gwei + exitBalanceToConsume primitives.Gwei earliestExitEpoch primitives.Epoch - consolidationBalanceToConsume math.Gwei + consolidationBalanceToConsume primitives.Gwei earliestConsolidationEpoch primitives.Epoch pendingBalanceDeposits []*ethpb.PendingBalanceDeposit // pending_balance_deposits: List[PendingBalanceDeposit, PENDING_BALANCE_DEPOSITS_LIMIT] pendingPartialWithdrawals []*ethpb.PendingPartialWithdrawal // pending_partial_withdrawals: List[PartialWithdrawal, PENDING_PARTIAL_WITHDRAWALS_LIMIT] @@ -121,10 +120,10 @@ type beaconStateMarshalable struct { NextWithdrawalIndex uint64 `json:"next_withdrawal_index" yaml:"next_withdrawal_index"` NextWithdrawalValidatorIndex primitives.ValidatorIndex `json:"next_withdrawal_validator_index" yaml:"next_withdrawal_validator_index"` DepositReceiptsStartIndex uint64 `json:"deposit_receipts_start_index" yaml:"deposit_receipts_start_index"` - DepositBalanceToConsume math.Gwei `json:"deposit_balance_to_consume" yaml:"deposit_balance_to_consume"` - ExitBalanceToConsume math.Gwei `json:"exit_balance_to_consume" yaml:"exit_balance_to_consume"` + DepositBalanceToConsume primitives.Gwei `json:"deposit_balance_to_consume" yaml:"deposit_balance_to_consume"` + ExitBalanceToConsume primitives.Gwei `json:"exit_balance_to_consume" yaml:"exit_balance_to_consume"` EarliestExitEpoch primitives.Epoch `json:"earliest_exit_epoch" yaml:"earliest_exit_epoch"` - ConsolidationBalanceToConsume math.Gwei `json:"consolidation_balance_to_consume" yaml:"consolidation_balance_to_consume"` + ConsolidationBalanceToConsume primitives.Gwei `json:"consolidation_balance_to_consume" yaml:"consolidation_balance_to_consume"` EarliestConsolidationEpoch primitives.Epoch `json:"earliest_consolidation_epoch" yaml:"earliest_consolidation_epoch"` PendingBalanceDeposits []*ethpb.PendingBalanceDeposit `json:"pending_balance_deposits" yaml:"pending_balance_deposits"` PendingPartialWithdrawals []*ethpb.PendingPartialWithdrawal `json:"pending_partial_withdrawals" yaml:"pending_partial_withdrawals"` diff --git a/beacon-chain/state/state-native/getters_balance_deposits.go b/beacon-chain/state/state-native/getters_balance_deposits.go index 900a5ece2101..e7257dd0c270 100644 --- a/beacon-chain/state/state-native/getters_balance_deposits.go +++ b/beacon-chain/state/state-native/getters_balance_deposits.go @@ -1,7 +1,7 @@ package state_native import ( - "github.com/prysmaticlabs/prysm/v5/math" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" ) @@ -9,7 +9,7 @@ import ( // DepositBalanceToConsume is a non-mutating call to the beacon state which returns the value of the // deposit balance to consume field. This method requires access to the RLock on the state and only // applies in electra or later. -func (b *BeaconState) DepositBalanceToConsume() (math.Gwei, error) { +func (b *BeaconState) DepositBalanceToConsume() (primitives.Gwei, error) { if b.version < version.Electra { return 0, errNotSupported("DepositBalanceToConsume", b.version) } diff --git a/beacon-chain/state/state-native/getters_balance_deposits_test.go b/beacon-chain/state/state-native/getters_balance_deposits_test.go index 358681e52bad..ab1738e0b754 100644 --- a/beacon-chain/state/state-native/getters_balance_deposits_test.go +++ b/beacon-chain/state/state-native/getters_balance_deposits_test.go @@ -5,7 +5,6 @@ import ( state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/testing/require" ) @@ -17,7 +16,7 @@ func TestDepositBalanceToConsume(t *testing.T) { require.NoError(t, err) dbtc, err := s.DepositBalanceToConsume() require.NoError(t, err) - require.Equal(t, math.Gwei(44), dbtc) + require.Equal(t, primitives.Gwei(44), dbtc) // Fails for older than electra state s, err = state_native.InitializeFromProtoDeneb(ð.BeaconStateDeneb{}) diff --git a/beacon-chain/state/state-native/getters_consolidation.go b/beacon-chain/state/state-native/getters_consolidation.go index 017dde5112a4..0ec07328f5a0 100644 --- a/beacon-chain/state/state-native/getters_consolidation.go +++ b/beacon-chain/state/state-native/getters_consolidation.go @@ -2,7 +2,6 @@ package state_native import ( "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" ) @@ -22,7 +21,7 @@ func (b *BeaconState) EarliestConsolidationEpoch() (primitives.Epoch, error) { // ConsolidationBalanceToConsume is a non-mutating call to the beacon state which returns the value // of the consolidation balance to consume field. This method requires access to the RLock on the // state and only applies in electra or later. -func (b *BeaconState) ConsolidationBalanceToConsume() (math.Gwei, error) { +func (b *BeaconState) ConsolidationBalanceToConsume() (primitives.Gwei, error) { if b.version < version.Electra { return 0, errNotSupported("ConsolidationBalanceToConsume", b.version) } diff --git a/beacon-chain/state/state-native/getters_consolidation_test.go b/beacon-chain/state/state-native/getters_consolidation_test.go index 6a4ec384a24b..a2e768642278 100644 --- a/beacon-chain/state/state-native/getters_consolidation_test.go +++ b/beacon-chain/state/state-native/getters_consolidation_test.go @@ -5,7 +5,6 @@ import ( state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/testing/require" ) @@ -32,7 +31,7 @@ func TestEarliestConsolidationEpoch(t *testing.T) { func TestConsolidationBalanceToConsume(t *testing.T) { t.Run("electra returns expected value", func(t *testing.T) { - want := math.Gwei(10) + want := primitives.Gwei(10) st, err := state_native.InitializeFromProtoElectra(ðpb.BeaconStateElectra{ ConsolidationBalanceToConsume: want, }) diff --git a/beacon-chain/state/state-native/getters_exit.go b/beacon-chain/state/state-native/getters_exit.go index 12be6844e05c..c43ba8756b33 100644 --- a/beacon-chain/state/state-native/getters_exit.go +++ b/beacon-chain/state/state-native/getters_exit.go @@ -2,12 +2,11 @@ package state_native import ( "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" "github.com/prysmaticlabs/prysm/v5/runtime/version" ) // ExitBalanceToConsume is used for returning the ExitBalanceToConsume as part of eip 7251 -func (b *BeaconState) ExitBalanceToConsume() (math.Gwei, error) { +func (b *BeaconState) ExitBalanceToConsume() (primitives.Gwei, error) { if b.version < version.Electra { return 0, errNotSupported("ExitBalanceToConsume", b.version) } diff --git a/beacon-chain/state/state-native/getters_exit_test.go b/beacon-chain/state/state-native/getters_exit_test.go index 1e3287cd191d..cc3a0e479dcb 100644 --- a/beacon-chain/state/state-native/getters_exit_test.go +++ b/beacon-chain/state/state-native/getters_exit_test.go @@ -5,7 +5,6 @@ import ( state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/testing/util" @@ -18,7 +17,7 @@ func TestExitBalanceToConsume(t *testing.T) { require.ErrorContains(t, "is not supported", err) }) t.Run("electra returns expected value", func(t *testing.T) { - want := math.Gwei(2) + want := primitives.Gwei(2) dState, err := state_native.InitializeFromProtoElectra(ðpb.BeaconStateElectra{ExitBalanceToConsume: want}) require.NoError(t, err) got, err := dState.ExitBalanceToConsume() diff --git a/beacon-chain/state/state-native/setters_balance_deposits.go b/beacon-chain/state/state-native/setters_balance_deposits.go index 9bb398b13e15..1be44219bc5a 100644 --- a/beacon-chain/state/state-native/setters_balance_deposits.go +++ b/beacon-chain/state/state-native/setters_balance_deposits.go @@ -4,7 +4,6 @@ import ( "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native/types" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stateutil" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" ) @@ -52,7 +51,7 @@ func (b *BeaconState) SetPendingBalanceDeposits(val []*ethpb.PendingBalanceDepos // SetDepositBalanceToConsume is a mutating call to the beacon state which sets the deposit balance // to consume value to the given value. This method requires access to the Lock on the state and // only applies in electra or later. -func (b *BeaconState) SetDepositBalanceToConsume(dbtc math.Gwei) error { +func (b *BeaconState) SetDepositBalanceToConsume(dbtc primitives.Gwei) error { if b.version < version.Electra { return errNotSupported("SetDepositBalanceToConsume", b.version) } diff --git a/beacon-chain/state/state-native/setters_balance_deposits_test.go b/beacon-chain/state/state-native/setters_balance_deposits_test.go index 7c2b201230a3..594943b712a9 100644 --- a/beacon-chain/state/state-native/setters_balance_deposits_test.go +++ b/beacon-chain/state/state-native/setters_balance_deposits_test.go @@ -5,7 +5,6 @@ import ( state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/testing/require" ) @@ -52,7 +51,7 @@ func TestSetDepositBalanceToConsume(t *testing.T) { require.NoError(t, s.SetDepositBalanceToConsume(10)) dbtc, err := s.DepositBalanceToConsume() require.NoError(t, err) - require.Equal(t, math.Gwei(10), dbtc) + require.Equal(t, primitives.Gwei(10), dbtc) // Fails for versions older than electra s, err = state_native.InitializeFromProtoDeneb(ð.BeaconStateDeneb{}) diff --git a/beacon-chain/state/state-native/setters_churn.go b/beacon-chain/state/state-native/setters_churn.go index bf7e67602a01..fdcf547fdcd1 100644 --- a/beacon-chain/state/state-native/setters_churn.go +++ b/beacon-chain/state/state-native/setters_churn.go @@ -4,7 +4,6 @@ import ( "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native/types" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" "github.com/prysmaticlabs/prysm/v5/runtime/version" "github.com/prysmaticlabs/prysm/v5/time/slots" ) @@ -34,7 +33,7 @@ import ( // state.earliest_exit_epoch = earliest_exit_epoch // // return state.earliest_exit_epoch -func (b *BeaconState) ExitEpochAndUpdateChurn(exitBalance math.Gwei) (primitives.Epoch, error) { +func (b *BeaconState) ExitEpochAndUpdateChurn(exitBalance primitives.Gwei) (primitives.Epoch, error) { if b.version < version.Electra { return 0, errNotSupported("ExitEpochAndUpdateChurn", b.version) } @@ -49,10 +48,10 @@ func (b *BeaconState) ExitEpochAndUpdateChurn(exitBalance math.Gwei) (primitives defer b.lock.Unlock() earliestExitEpoch := max(b.earliestExitEpoch, helpers.ActivationExitEpoch(slots.ToEpoch(b.slot))) - perEpochChurn := helpers.ActivationExitChurnLimit(math.Gwei(activeBal)) // Guaranteed to be non-zero. + perEpochChurn := helpers.ActivationExitChurnLimit(primitives.Gwei(activeBal)) // Guaranteed to be non-zero. // New epoch for exits - var exitBalanceToConsume math.Gwei + var exitBalanceToConsume primitives.Gwei if b.earliestExitEpoch < earliestExitEpoch { exitBalanceToConsume = perEpochChurn } else { @@ -64,7 +63,7 @@ func (b *BeaconState) ExitEpochAndUpdateChurn(exitBalance math.Gwei) (primitives balanceToProcess := exitBalance - exitBalanceToConsume additionalEpochs := primitives.Epoch((balanceToProcess-1)/perEpochChurn + 1) earliestExitEpoch += additionalEpochs - exitBalanceToConsume += math.Gwei(additionalEpochs) * perEpochChurn + exitBalanceToConsume += primitives.Gwei(additionalEpochs) * perEpochChurn } // Consume the balance and update state variables. diff --git a/beacon-chain/state/state-native/setters_churn_test.go b/beacon-chain/state/state-native/setters_churn_test.go index 2aa98382c473..397932023d3b 100644 --- a/beacon-chain/state/state-native/setters_churn_test.go +++ b/beacon-chain/state/state-native/setters_churn_test.go @@ -8,7 +8,6 @@ import ( state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native" "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/testing/util" @@ -30,7 +29,7 @@ func TestExitEpochAndUpdateChurn_SpectestCase(t *testing.T) { val, err := s.ValidatorAtIndex(0) require.NoError(t, err) - ee, err := s.ExitEpochAndUpdateChurn(math.Gwei(val.EffectiveBalance)) + ee, err := s.ExitEpochAndUpdateChurn(primitives.Gwei(val.EffectiveBalance)) require.NoError(t, err) require.Equal(t, primitives.Epoch(262), ee) @@ -39,7 +38,7 @@ func TestExitEpochAndUpdateChurn_SpectestCase(t *testing.T) { if !ok { t.Fatal("wrong proto") } - require.Equal(t, math.Gwei(127000000000), pb.ExitBalanceToConsume) + require.Equal(t, primitives.Gwei(127000000000), pb.ExitBalanceToConsume) require.Equal(t, primitives.Epoch(262), pb.EarliestExitEpoch) // Fails for versions older than electra @@ -62,15 +61,15 @@ func TestExitEpochAndUpdateChurn(t *testing.T) { }, Balances: []uint64{params.BeaconConfig().MaxEffectiveBalanceElectra}, EarliestExitEpoch: epoch - params.BeaconConfig().MaxSeedLookahead*2, // Old, relative to slot. - ExitBalanceToConsume: math.Gwei(20_000_000), + ExitBalanceToConsume: primitives.Gwei(20_000_000), }) require.NoError(t, err) activeBal, err := helpers.TotalActiveBalance(st) require.NoError(t, err) - exitBal := math.Gwei(10_000_000) + exitBal := primitives.Gwei(10_000_000) - wantExitBalToConsume := helpers.ActivationExitChurnLimit(math.Gwei(activeBal)) - exitBal + wantExitBalToConsume := helpers.ActivationExitChurnLimit(primitives.Gwei(activeBal)) - exitBal ee, err := st.ExitEpochAndUpdateChurn(exitBal) require.NoError(t, err) @@ -97,16 +96,16 @@ func TestExitEpochAndUpdateChurn(t *testing.T) { }, Balances: []uint64{params.BeaconConfig().MaxEffectiveBalanceElectra}, EarliestExitEpoch: epoch, - ExitBalanceToConsume: math.Gwei(20_000_000), + ExitBalanceToConsume: primitives.Gwei(20_000_000), }) require.NoError(t, err) activeBal, err := helpers.TotalActiveBalance(st) require.NoError(t, err) - activationExitChurnLimit := helpers.ActivationExitChurnLimit(math.Gwei(activeBal)) + activationExitChurnLimit := helpers.ActivationExitChurnLimit(primitives.Gwei(activeBal)) exitBal := activationExitChurnLimit * 2 - wantExitBalToConsume := math.Gwei(0) + wantExitBalToConsume := primitives.Gwei(0) ee, err := st.ExitEpochAndUpdateChurn(exitBal) require.NoError(t, err) @@ -133,13 +132,13 @@ func TestExitEpochAndUpdateChurn(t *testing.T) { }, Balances: []uint64{params.BeaconConfig().MaxEffectiveBalanceElectra}, EarliestExitEpoch: epoch + 10_000, - ExitBalanceToConsume: math.Gwei(20_000_000), + ExitBalanceToConsume: primitives.Gwei(20_000_000), }) require.NoError(t, err) - exitBal := math.Gwei(10_000_000) + exitBal := primitives.Gwei(10_000_000) - wantExitBalToConsume := math.Gwei(20_000_000) - exitBal + wantExitBalToConsume := primitives.Gwei(20_000_000) - exitBal ee, err := st.ExitEpochAndUpdateChurn(exitBal) require.NoError(t, err) @@ -166,14 +165,14 @@ func TestExitEpochAndUpdateChurn(t *testing.T) { }, Balances: []uint64{params.BeaconConfig().MaxEffectiveBalanceElectra}, EarliestExitEpoch: epoch + 10_000, - ExitBalanceToConsume: math.Gwei(20_000_000), + ExitBalanceToConsume: primitives.Gwei(20_000_000), }) require.NoError(t, err) - exitBal := math.Gwei(40_000_000) + exitBal := primitives.Gwei(40_000_000) activeBal, err := helpers.TotalActiveBalance(st) require.NoError(t, err) - activationExitChurnLimit := helpers.ActivationExitChurnLimit(math.Gwei(activeBal)) + activationExitChurnLimit := helpers.ActivationExitChurnLimit(primitives.Gwei(activeBal)) wantExitBalToConsume := activationExitChurnLimit - 20_000_000 ee, err := st.ExitEpochAndUpdateChurn(exitBal) diff --git a/beacon-chain/state/state-native/setters_consolidation.go b/beacon-chain/state/state-native/setters_consolidation.go index c76e1ae5c091..525230578f0a 100644 --- a/beacon-chain/state/state-native/setters_consolidation.go +++ b/beacon-chain/state/state-native/setters_consolidation.go @@ -4,7 +4,6 @@ import ( "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native/types" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stateutil" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" ) @@ -69,7 +68,7 @@ func (b *BeaconState) SetEarliestConsolidationEpoch(epoch primitives.Epoch) erro // SetConsolidationBalanceToConsume is a mutating call to the beacon state which sets the value of // the consolidation balance to consume to the provided value. This method requires access to the // Lock on the state and only applies in electra or later. -func (b *BeaconState) SetConsolidationBalanceToConsume(balance math.Gwei) error { +func (b *BeaconState) SetConsolidationBalanceToConsume(balance primitives.Gwei) error { if b.version < version.Electra { return errNotSupported("SetConsolidationBalanceToConsume", b.version) } diff --git a/beacon-chain/state/state-native/setters_consolidation_test.go b/beacon-chain/state/state-native/setters_consolidation_test.go index 1a2ee153cef4..af8ced0ea22b 100644 --- a/beacon-chain/state/state-native/setters_consolidation_test.go +++ b/beacon-chain/state/state-native/setters_consolidation_test.go @@ -5,7 +5,6 @@ import ( state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/testing/require" ) @@ -67,7 +66,7 @@ func TestSetConsolidationBalanceToConsume(t *testing.T) { require.NoError(t, s.SetConsolidationBalanceToConsume(10)) cbtc, err := s.ConsolidationBalanceToConsume() require.NoError(t, err) - require.Equal(t, math.Gwei(10), cbtc) + require.Equal(t, primitives.Gwei(10), cbtc) // Fails for versions older than electra s, err = state_native.InitializeFromProtoDeneb(ð.BeaconStateDeneb{}) diff --git a/consensus-types/blocks/BUILD.bazel b/consensus-types/blocks/BUILD.bazel index feda65d199ba..d56c464ac30e 100644 --- a/consensus-types/blocks/BUILD.bazel +++ b/consensus-types/blocks/BUILD.bazel @@ -24,7 +24,6 @@ go_library( "//container/trie:go_default_library", "//encoding/bytesutil:go_default_library", "//encoding/ssz:go_default_library", - "//math:go_default_library", "//proto/engine/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//proto/prysm/v1alpha1/validator-client:go_default_library", diff --git a/consensus-types/blocks/execution.go b/consensus-types/blocks/execution.go index 08cc5aeabf6d..13e3905e698b 100644 --- a/consensus-types/blocks/execution.go +++ b/consensus-types/blocks/execution.go @@ -9,9 +9,9 @@ import ( fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" "github.com/prysmaticlabs/prysm/v5/encoding/ssz" - "github.com/prysmaticlabs/prysm/v5/math" enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" "google.golang.org/protobuf/proto" ) @@ -24,7 +24,7 @@ type executionPayload struct { } // NewWrappedExecutionData creates an appropriate execution payload wrapper based on the incoming type. -func NewWrappedExecutionData(v proto.Message, weiValue math.Wei) (interfaces.ExecutionData, error) { +func NewWrappedExecutionData(v proto.Message, weiValue primitives.Wei) (interfaces.ExecutionData, error) { if weiValue == nil { weiValue = new(big.Int).SetInt64(0) } @@ -194,7 +194,7 @@ func (e executionPayload) ExcessBlobGas() (uint64, error) { } // ValueInWei -- -func (executionPayload) ValueInWei() (math.Wei, error) { +func (executionPayload) ValueInWei() (primitives.Wei, error) { return nil, consensus_types.ErrUnsupportedField } @@ -362,7 +362,7 @@ func (e executionPayloadHeader) ExcessBlobGas() (uint64, error) { } // ValueInWei -- -func (executionPayloadHeader) ValueInWei() (math.Wei, error) { +func (executionPayloadHeader) ValueInWei() (primitives.Wei, error) { return nil, consensus_types.ErrUnsupportedField } @@ -404,15 +404,15 @@ func PayloadToHeader(payload interfaces.ExecutionData) (*enginev1.ExecutionPaylo // blocks for future forks can also be applied across Prysm without issues. type executionPayloadCapella struct { p *enginev1.ExecutionPayloadCapella - weiValue math.Wei + weiValue primitives.Wei gweiValue uint64 } var _ interfaces.ExecutionData = &executionPayloadCapella{} // WrappedExecutionPayloadCapella is a constructor which wraps a protobuf execution payload into an interface. -func WrappedExecutionPayloadCapella(p *enginev1.ExecutionPayloadCapella, value math.Wei) (interfaces.ExecutionData, error) { - w := executionPayloadCapella{p: p, weiValue: value, gweiValue: uint64(math.WeiToGwei(value))} +func WrappedExecutionPayloadCapella(p *enginev1.ExecutionPayloadCapella, value primitives.Wei) (interfaces.ExecutionData, error) { + w := executionPayloadCapella{p: p, weiValue: value, gweiValue: uint64(primitives.WeiToGwei(value))} if w.IsNil() { return nil, consensus_types.ErrNilObjectWrapped } @@ -560,7 +560,7 @@ func (e executionPayloadCapella) ExcessBlobGas() (uint64, error) { } // ValueInWei -- -func (e executionPayloadCapella) ValueInWei() (math.Wei, error) { +func (e executionPayloadCapella) ValueInWei() (primitives.Wei, error) { return e.weiValue, nil } @@ -574,15 +574,15 @@ func (e executionPayloadCapella) ValueInGwei() (uint64, error) { // blocks for future forks can also be applied across Prysm without issues. type executionPayloadHeaderCapella struct { p *enginev1.ExecutionPayloadHeaderCapella - weiValue math.Wei + weiValue primitives.Wei gweiValue uint64 } var _ interfaces.ExecutionData = &executionPayloadHeaderCapella{} // WrappedExecutionPayloadHeaderCapella is a constructor which wraps a protobuf execution header into an interface. -func WrappedExecutionPayloadHeaderCapella(p *enginev1.ExecutionPayloadHeaderCapella, value math.Wei) (interfaces.ExecutionData, error) { - w := executionPayloadHeaderCapella{p: p, weiValue: value, gweiValue: uint64(math.WeiToGwei(value))} +func WrappedExecutionPayloadHeaderCapella(p *enginev1.ExecutionPayloadHeaderCapella, value primitives.Wei) (interfaces.ExecutionData, error) { + w := executionPayloadHeaderCapella{p: p, weiValue: value, gweiValue: uint64(primitives.WeiToGwei(value))} if w.IsNil() { return nil, consensus_types.ErrNilObjectWrapped } @@ -730,7 +730,7 @@ func (e executionPayloadHeaderCapella) ExcessBlobGas() (uint64, error) { } // ValueInWei -- -func (e executionPayloadHeaderCapella) ValueInWei() (math.Wei, error) { +func (e executionPayloadHeaderCapella) ValueInWei() (primitives.Wei, error) { return e.weiValue, nil } @@ -966,15 +966,15 @@ func IsEmptyExecutionData(data interfaces.ExecutionData) (bool, error) { // blocks for future forks can also be applied across Prysm without issues. type executionPayloadHeaderDeneb struct { p *enginev1.ExecutionPayloadHeaderDeneb - weiValue math.Wei + weiValue primitives.Wei gweiValue uint64 } var _ interfaces.ExecutionData = &executionPayloadHeaderDeneb{} // WrappedExecutionPayloadHeaderDeneb is a constructor which wraps a protobuf execution header into an interface. -func WrappedExecutionPayloadHeaderDeneb(p *enginev1.ExecutionPayloadHeaderDeneb, value math.Wei) (interfaces.ExecutionData, error) { - w := executionPayloadHeaderDeneb{p: p, weiValue: value, gweiValue: uint64(math.WeiToGwei(value))} +func WrappedExecutionPayloadHeaderDeneb(p *enginev1.ExecutionPayloadHeaderDeneb, value primitives.Wei) (interfaces.ExecutionData, error) { + w := executionPayloadHeaderDeneb{p: p, weiValue: value, gweiValue: uint64(primitives.WeiToGwei(value))} if w.IsNil() { return nil, consensus_types.ErrNilObjectWrapped } @@ -1117,7 +1117,7 @@ func (e executionPayloadHeaderDeneb) ExcessBlobGas() (uint64, error) { } // ValueInWei -- -func (e executionPayloadHeaderDeneb) ValueInWei() (math.Wei, error) { +func (e executionPayloadHeaderDeneb) ValueInWei() (primitives.Wei, error) { return e.weiValue, nil } @@ -1136,15 +1136,15 @@ func (e executionPayloadHeaderDeneb) IsBlinded() bool { // blocks for future forks can also be applied across Prysm without issues. type executionPayloadDeneb struct { p *enginev1.ExecutionPayloadDeneb - weiValue math.Wei + weiValue primitives.Wei gweiValue uint64 } var _ interfaces.ExecutionData = &executionPayloadDeneb{} // WrappedExecutionPayloadDeneb is a constructor which wraps a protobuf execution payload into an interface. -func WrappedExecutionPayloadDeneb(p *enginev1.ExecutionPayloadDeneb, value math.Wei) (interfaces.ExecutionData, error) { - w := executionPayloadDeneb{p: p, weiValue: value, gweiValue: uint64(math.WeiToGwei(value))} +func WrappedExecutionPayloadDeneb(p *enginev1.ExecutionPayloadDeneb, value primitives.Wei) (interfaces.ExecutionData, error) { + w := executionPayloadDeneb{p: p, weiValue: value, gweiValue: uint64(primitives.WeiToGwei(value))} if w.IsNil() { return nil, consensus_types.ErrNilObjectWrapped } @@ -1285,7 +1285,7 @@ func (e executionPayloadDeneb) ExcessBlobGas() (uint64, error) { } // ValueInWei -- -func (e executionPayloadDeneb) ValueInWei() (math.Wei, error) { +func (e executionPayloadDeneb) ValueInWei() (primitives.Wei, error) { return e.weiValue, nil } @@ -1304,7 +1304,7 @@ func (e executionPayloadDeneb) IsBlinded() bool { // blocks for future forks can also be applied across Prysm without issues. type executionPayloadHeaderElectra struct { p *enginev1.ExecutionPayloadHeaderElectra - weiValue math.Wei + weiValue primitives.Wei gweiValue uint64 } @@ -1312,8 +1312,8 @@ var _ interfaces.ExecutionData = &executionPayloadElectra{} var _ interfaces.ExecutionDataElectra = &executionPayloadElectra{} // WrappedExecutionPayloadHeaderElectra is a constructor which wraps a protobuf execution header into an interface. -func WrappedExecutionPayloadHeaderElectra(p *enginev1.ExecutionPayloadHeaderElectra, value math.Wei) (interfaces.ExecutionData, error) { - w := executionPayloadHeaderElectra{p: p, weiValue: value, gweiValue: uint64(math.WeiToGwei(value))} +func WrappedExecutionPayloadHeaderElectra(p *enginev1.ExecutionPayloadHeaderElectra, value primitives.Wei) (interfaces.ExecutionData, error) { + w := executionPayloadHeaderElectra{p: p, weiValue: value, gweiValue: uint64(primitives.WeiToGwei(value))} if w.IsNil() { return nil, consensus_types.ErrNilObjectWrapped } @@ -1456,7 +1456,7 @@ func (e executionPayloadHeaderElectra) ExcessBlobGas() (uint64, error) { } // ValueInWei -- -func (e executionPayloadHeaderElectra) ValueInWei() (math.Wei, error) { +func (e executionPayloadHeaderElectra) ValueInWei() (primitives.Wei, error) { return e.weiValue, nil } @@ -1485,13 +1485,13 @@ func (e executionPayloadHeaderElectra) IsBlinded() bool { // blocks for future forks can also be applied across Prysm without issues. type executionPayloadElectra struct { p *enginev1.ExecutionPayloadElectra - weiValue math.Wei + weiValue primitives.Wei gweiValue uint64 } // WrappedExecutionPayloadElectra is a constructor which wraps a protobuf execution payload into an interface. -func WrappedExecutionPayloadElectra(p *enginev1.ExecutionPayloadElectra, value math.Wei) (interfaces.ExecutionData, error) { - w := executionPayloadElectra{p: p, weiValue: value, gweiValue: uint64(math.WeiToGwei(value))} +func WrappedExecutionPayloadElectra(p *enginev1.ExecutionPayloadElectra, value primitives.Wei) (interfaces.ExecutionData, error) { + w := executionPayloadElectra{p: p, weiValue: value, gweiValue: uint64(primitives.WeiToGwei(value))} if w.IsNil() { return nil, consensus_types.ErrNilObjectWrapped } @@ -1635,7 +1635,7 @@ func (e executionPayloadElectra) ExcessBlobGas() (uint64, error) { } // ValueInWei -- -func (e executionPayloadElectra) ValueInWei() (math.Wei, error) { +func (e executionPayloadElectra) ValueInWei() (primitives.Wei, error) { return e.weiValue, nil } @@ -1660,14 +1660,14 @@ func (e executionPayloadElectra) IsBlinded() bool { } // PayloadValueToWei returns a Wei value given the payload's value -func PayloadValueToWei(value []byte) math.Wei { +func PayloadValueToWei(value []byte) primitives.Wei { // We have to convert big endian to little endian because the value is coming from the execution layer. return big.NewInt(0).SetBytes(bytesutil.ReverseByteOrder(value)) } // PayloadValueToGwei returns a Gwei value given the payload's value -func PayloadValueToGwei(value []byte) math.Gwei { +func PayloadValueToGwei(value []byte) primitives.Gwei { // We have to convert big endian to little endian because the value is coming from the execution layer. v := big.NewInt(0).SetBytes(bytesutil.ReverseByteOrder(value)) - return math.WeiToGwei(v) + return primitives.WeiToGwei(v) } diff --git a/consensus-types/blocks/getters.go b/consensus-types/blocks/getters.go index 369f972d42ab..1c42187bd727 100644 --- a/consensus-types/blocks/getters.go +++ b/consensus-types/blocks/getters.go @@ -10,7 +10,6 @@ import ( consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" validatorpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/validator-client" @@ -329,7 +328,7 @@ func (b *SignedBeaconBlock) IsBlinded() bool { } // ValueInWei metadata on the payload value returned by the builder. -func (b *SignedBeaconBlock) ValueInWei() math.Wei { +func (b *SignedBeaconBlock) ValueInWei() primitives.Wei { exec, err := b.block.body.Execution() if err != nil { if !errors.Is(err, consensus_types.ErrUnsupportedField) { diff --git a/consensus-types/interfaces/BUILD.bazel b/consensus-types/interfaces/BUILD.bazel index 84e8be9f0d4b..3a20551c7d68 100644 --- a/consensus-types/interfaces/BUILD.bazel +++ b/consensus-types/interfaces/BUILD.bazel @@ -14,7 +14,6 @@ go_library( deps = [ "//config/fieldparams:go_default_library", "//consensus-types/primitives:go_default_library", - "//math:go_default_library", "//proto/engine/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//proto/prysm/v1alpha1/validator-client:go_default_library", diff --git a/consensus-types/interfaces/beacon_block.go b/consensus-types/interfaces/beacon_block.go index 3eae02c6956f..a852c683e0b6 100644 --- a/consensus-types/interfaces/beacon_block.go +++ b/consensus-types/interfaces/beacon_block.go @@ -6,7 +6,6 @@ import ( "github.com/prysmaticlabs/go-bitfield" field_params "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" validatorpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/validator-client" @@ -29,7 +28,7 @@ type ReadOnlySignedBeaconBlock interface { ssz.Unmarshaler Version() int IsBlinded() bool - ValueInWei() math.Wei + ValueInWei() primitives.Wei ValueInGwei() uint64 Header() (*ethpb.SignedBeaconBlockHeader, error) } @@ -130,7 +129,7 @@ type ExecutionData interface { TransactionsRoot() ([]byte, error) Withdrawals() ([]*enginev1.Withdrawal, error) WithdrawalsRoot() ([]byte, error) - ValueInWei() (math.Wei, error) + ValueInWei() (primitives.Wei, error) ValueInGwei() (uint64, error) } diff --git a/consensus-types/mock/BUILD.bazel b/consensus-types/mock/BUILD.bazel index a76b14edad33..b37f4f30d51d 100644 --- a/consensus-types/mock/BUILD.bazel +++ b/consensus-types/mock/BUILD.bazel @@ -9,7 +9,6 @@ go_library( "//config/fieldparams:go_default_library", "//consensus-types/interfaces:go_default_library", "//consensus-types/primitives:go_default_library", - "//math:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//proto/prysm/v1alpha1/validator-client:go_default_library", "@com_github_prysmaticlabs_fastssz//:go_default_library", diff --git a/consensus-types/mock/block.go b/consensus-types/mock/block.go index 846eb42618bf..e13e09be20b2 100644 --- a/consensus-types/mock/block.go +++ b/consensus-types/mock/block.go @@ -5,7 +5,6 @@ import ( field_params "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" validatorpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/validator-client" "google.golang.org/protobuf/proto" @@ -75,7 +74,7 @@ func (SignedBeaconBlock) Header() (*eth.SignedBeaconBlockHeader, error) { panic("implement me") } -func (SignedBeaconBlock) ValueInWei() math.Wei { +func (SignedBeaconBlock) ValueInWei() primitives.Wei { panic("implement me") } diff --git a/consensus-types/primitives/BUILD.bazel b/consensus-types/primitives/BUILD.bazel index ff6752a194e9..10ddde9c7346 100644 --- a/consensus-types/primitives/BUILD.bazel +++ b/consensus-types/primitives/BUILD.bazel @@ -13,6 +13,7 @@ go_library( "sszbytes.go", "sszuint64.go", "validator.go", + "wei.go", ], importpath = "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives", visibility = ["//visibility:public"], @@ -32,6 +33,7 @@ go_test( "sszbytes_test.go", "sszuint64_test.go", "validator_test.go", + "wei_test.go", ], embed = [":go_default_library"], deps = [ diff --git a/consensus-types/primitives/wei.go b/consensus-types/primitives/wei.go new file mode 100644 index 000000000000..8bcee0130899 --- /dev/null +++ b/consensus-types/primitives/wei.go @@ -0,0 +1,93 @@ +package primitives + +import ( + "fmt" + "math/big" + "slices" + + fssz "github.com/prysmaticlabs/fastssz" +) + +// ZeroWei is a non-nil zero value for primitives.Wei +var ZeroWei Wei = big.NewInt(0) + +// Wei is the smallest unit of Ether, represented as a pointer to a bigInt. +type Wei *big.Int + +// Gwei is a denomination of 1e9 Wei represented as an uint64. +type Gwei uint64 + +var _ fssz.HashRoot = (Gwei)(0) +var _ fssz.Marshaler = (*Gwei)(nil) +var _ fssz.Unmarshaler = (*Gwei)(nil) + +// HashTreeRoot -- +func (g Gwei) HashTreeRoot() ([32]byte, error) { + return fssz.HashWithDefaultHasher(g) +} + +// HashTreeRootWith -- +func (g Gwei) HashTreeRootWith(hh *fssz.Hasher) error { + hh.PutUint64(uint64(g)) + return nil +} + +// UnmarshalSSZ -- +func (g *Gwei) UnmarshalSSZ(buf []byte) error { + if len(buf) != g.SizeSSZ() { + return fmt.Errorf("expected buffer of length %d received %d", g.SizeSSZ(), len(buf)) + } + *g = Gwei(fssz.UnmarshallUint64(buf)) + return nil +} + +// MarshalSSZTo -- +func (g *Gwei) MarshalSSZTo(dst []byte) ([]byte, error) { + marshalled, err := g.MarshalSSZ() + if err != nil { + return nil, err + } + return append(dst, marshalled...), nil +} + +// MarshalSSZ -- +func (g *Gwei) MarshalSSZ() ([]byte, error) { + marshalled := fssz.MarshalUint64([]byte{}, uint64(*g)) + return marshalled, nil +} + +// SizeSSZ -- +func (g *Gwei) SizeSSZ() int { + return 8 +} + +// WeiToBigInt is a convenience method to cast a wei back to a big int +func WeiToBigInt(w Wei) *big.Int { + return w +} + +// Uint64ToWei creates a new Wei (aka big.Int) representing the given uint64 value. +func Uint64ToWei(v uint64) Wei { + return big.NewInt(0).SetUint64(v) +} + +// BigEndianBytesToWei returns a Wei value given a big-endian binary representation (eg engine api payload bids). +func BigEndianBytesToWei(value []byte) Wei { + v := make([]byte, len(value)) + copy(v, value) + slices.Reverse(v) + // We have to convert big endian to little endian because the value is coming from the execution layer. + return big.NewInt(0).SetBytes(v) +} + +// WeiToGwei converts big int wei to uint64 gwei. +// The input `v` is copied before being modified. +func WeiToGwei(v Wei) Gwei { + if v == nil { + return 0 + } + gweiPerEth := big.NewInt(1e9) + copied := big.NewInt(0).Set(v) + copied.Div(copied, gweiPerEth) + return Gwei(copied.Uint64()) +} diff --git a/consensus-types/primitives/wei_test.go b/consensus-types/primitives/wei_test.go new file mode 100644 index 000000000000..dd9ff308aeaf --- /dev/null +++ b/consensus-types/primitives/wei_test.go @@ -0,0 +1,41 @@ +package primitives_test + +import ( + "math" + "math/big" + "testing" + + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" + "github.com/prysmaticlabs/prysm/v5/testing/require" +) + +func TestWeiStringer(t *testing.T) { + require.Equal(t, "0", primitives.WeiToBigInt(primitives.ZeroWei).String()) + require.Equal(t, "1234", primitives.WeiToBigInt(primitives.Uint64ToWei(1234)).String()) + require.Equal(t, "18446744073709551615", primitives.WeiToBigInt(primitives.Uint64ToWei(math.MaxUint64)).String()) +} + +func TestWeiToGwei(t *testing.T) { + tests := []struct { + v *big.Int + want primitives.Gwei + }{ + {big.NewInt(1e9 - 1), 0}, + {big.NewInt(1e9), 1}, + {big.NewInt(1e10), 10}, + {big.NewInt(239489233849348394), 239489233}, + } + for _, tt := range tests { + if got := primitives.WeiToGwei(tt.v); got != tt.want { + t.Errorf("WeiToGwei() = %v, want %v", got, tt.want) + } + } +} + +func TestWeiToGwei_CopyOk(t *testing.T) { + v := big.NewInt(1e9) + got := primitives.WeiToGwei(v) + + require.Equal(t, primitives.Gwei(1), got) + require.Equal(t, big.NewInt(1e9).Uint64(), v.Uint64()) +} diff --git a/encoding/ssz/equality/BUILD.bazel b/encoding/ssz/equality/BUILD.bazel index 0e023a0463ed..4c67be0035a1 100644 --- a/encoding/ssz/equality/BUILD.bazel +++ b/encoding/ssz/equality/BUILD.bazel @@ -7,7 +7,6 @@ go_library( visibility = ["//visibility:public"], deps = [ "//consensus-types/primitives:go_default_library", - "//math:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", ], ) diff --git a/encoding/ssz/equality/deep_equal.go b/encoding/ssz/equality/deep_equal.go index 9c52d8475a8f..e0216a11c54e 100644 --- a/encoding/ssz/equality/deep_equal.go +++ b/encoding/ssz/equality/deep_equal.go @@ -5,7 +5,6 @@ import ( "unsafe" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/math" "google.golang.org/protobuf/proto" ) @@ -232,7 +231,7 @@ func deepValueBaseTypeEqual(v1, v2 reflect.Value) bool { case "CommitteeIndex": return v1.Interface().(primitives.CommitteeIndex) == v2.Interface().(primitives.CommitteeIndex) case "Gwei": - return v1.Interface().(math.Gwei) == v2.Interface().(math.Gwei) + return v1.Interface().(primitives.Gwei) == v2.Interface().(primitives.Gwei) } return v1.Interface().(uint64) == v2.Interface().(uint64) case reflect.Uint32: diff --git a/hack/beacon-node-api/README.md b/hack/beacon-node-api/README.md deleted file mode 100644 index 4cff2464e0e9..000000000000 --- a/hack/beacon-node-api/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Beacon Node API - -https://ethereum.github.io/beacon-APIs/ - -## Postman - -You can use Postman to test the API. https://www.postman.com/ - -### Postman collection - -In this package you will find the Postman collection for the Beacon Node API. -You can import this collection in your own Postman instance to test the API. - -#### Updating the collection - -The collection will need to be exported and overwritten to update the collection. A PR should be created once the file -is updated. diff --git a/hack/beacon-node-api/beacon-node-api.postman-collection.json b/hack/beacon-node-api/beacon-node-api.postman-collection.json deleted file mode 100644 index 824adf4efc79..000000000000 --- a/hack/beacon-node-api/beacon-node-api.postman-collection.json +++ /dev/null @@ -1,1795 +0,0 @@ -{ - "info": { - "_postman_id": "398a2b9f-13cb-480b-af67-6c6f9d6ba0aa", - "name": "API", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "/beacon/genesis", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"data:\": [\n {\n \"message\": {\n \"aggregator_index\": \"1\",\n \"selection_proof\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\",\n \"contribution\": {\n \"slot\": \"1\",\n \"beacon_block_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"subcommittee_index\": \"1\",\n \"aggregation_bits\": \"0x01000000000000000000000000000000\",\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\"\n }\n },\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\"\n }\n ]\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/genesis", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "genesis" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/states/{state_id}/root", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/states/{state_id}/root", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "states", - "{state_id}", - "root" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/states/{state_id}/fork", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/states/{state_id}/fork", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "states", - "{state_id}", - "fork" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/states/{state_id}/finality_checkpoints", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/states/{state_id}/finality_checkpoints", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "states", - "{state_id}", - "finality_checkpoints" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/states/{state_id}/validators", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/states/{state_id}/validators", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "states", - "{state_id}", - "validators" - ], - "query": [ - { - "key": "id", - "value": null, - "disabled": true - }, - { - "key": "status", - "value": null, - "disabled": true - } - ] - } - }, - "response": [] - }, - { - "name": "/beacon/states/{state_id}/validators/{validator_id}", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/states/{state_id}/validators/{validator_id}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "states", - "{state_id}", - "validators", - "{validator_id}" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/states/{state_id}/validator_balances", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/states/{state_id}/validator_balances", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "states", - "{state_id}", - "validator_balances" - ], - "query": [ - { - "key": "id", - "value": null, - "disabled": true - } - ] - } - }, - "response": [] - }, - { - "name": "/beacon/states/{state_id}/committees", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/states/{state_id}/committees", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "states", - "{state_id}", - "committees" - ], - "query": [ - { - "key": "epoch", - "value": null, - "disabled": true - }, - { - "key": "index", - "value": null, - "disabled": true - }, - { - "key": "slot", - "value": null, - "disabled": true - } - ] - } - }, - "response": [] - }, - { - "name": "/beacon/states/{state_id}/sync_committees", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/states/{state_id}/sync_committees", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "states", - "{state_id}", - "sync_committees" - ], - "query": [ - { - "key": "epoch", - "value": null, - "disabled": true - } - ] - } - }, - "response": [] - }, - { - "name": "/beacon/headers", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/headers", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "headers" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/headers/{block_id}", - "protocolProfileBehavior": { - "disableBodyPruning": true - }, - "request": { - "method": "GET", - "header": [], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/headers/{block_id}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "headers", - "{block_id}" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/blocks (Phase 0)", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"message\": {\n \"slot\": \"1\",\n \"proposer_index\": \"1\",\n \"parent_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"state_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"body\": {\n \"randao_reveal\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\",\n \"eth1_data\": {\n \"deposit_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"deposit_count\": \"1\",\n \"block_hash\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n },\n \"graffiti\": \"string\",\n \"proposer_slashings\": [\n {\n \"signed_header_1\": {\n \"message\": {\n \"slot\": \"1\",\n \"proposer_index\": \"1\",\n \"parent_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"state_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"body_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n },\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\"\n },\n \"signed_header_2\": {\n \"message\": {\n \"slot\": \"1\",\n \"proposer_index\": \"1\",\n \"parent_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"state_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"body_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n },\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\"\n }\n }\n ],\n \"attester_slashings\": [\n {\n \"attestation_1\": {\n \"attesting_indices\": [\n \"1\"\n ],\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\",\n \"data\": {\n \"slot\": \"1\",\n \"index\": \"1\",\n \"beacon_block_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"source\": {\n \"epoch\": \"1\",\n \"root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n },\n \"target\": {\n \"epoch\": \"1\",\n \"root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n }\n }\n },\n \"attestation_2\": {\n \"attesting_indices\": [\n \"1\"\n ],\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\",\n \"data\": {\n \"slot\": \"1\",\n \"index\": \"1\",\n \"beacon_block_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"source\": {\n \"epoch\": \"1\",\n \"root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n },\n \"target\": {\n \"epoch\": \"1\",\n \"root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n }\n }\n }\n }\n ],\n \"attestations\": [\n {\n \"aggregation_bits\": \"0x01\",\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\",\n \"data\": {\n \"slot\": \"1\",\n \"index\": \"1\",\n \"beacon_block_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"source\": {\n \"epoch\": \"1\",\n \"root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n },\n \"target\": {\n \"epoch\": \"1\",\n \"root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n }\n }\n }\n ],\n \"deposits\": [\n {\n \"proof\": [\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n ],\n \"data\": {\n \"pubkey\": \"0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a\",\n \"withdrawal_credentials\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"amount\": \"1\",\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\"\n }\n }\n ],\n \"voluntary_exits\": [\n {\n \"message\": {\n \"epoch\": \"1\",\n \"validator_index\": \"1\"\n },\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\"\n }\n ]\n }\n },\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/blocks", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "blocks" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/blocks (Altair)", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"message\": {\n \"slot\": \"2234176\",\n \"proposer_index\": \"44367\",\n \"parent_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"state_root\": \"0x3aebd5aa1e6a309c61b93bf75c6ec3a2dda2d9ffaa60f5e68db804c66aa2e533\",\n \"body\": {\n \"randao_reveal\": \"0x93487efef796a5d0ec276a7fb3ff3a389ca6a292ba2fb07fd06c54f051864b5fe423eca4eb9be8983a71a09184f75d91106082026ea87c9c67a22a1e2eefdd2a280ac25a4f7c6f2f7c5261f6614ba1d4f28b5ae8378149c1f730e7e1fcdcd94e\",\n \"eth1_data\": {\n \"deposit_root\": \"0x79f12e9aa03710400fc0c2a43392dc7904c6dc868767ca2f2947be51b7328915\",\n \"deposit_count\": \"129299\",\n \"block_hash\": \"0xa9d5bbb8b129562e92d323ed8aee915aa1d590e8e42be0bfda6fc5c88c87696a\"\n },\n \"graffiti\": \"0x677261666669746977616c6c3a34343a32343a23303066666666000000000000\",\n \"proposer_slashings\": [],\n \"attester_slashings\": [],\n \"attestations\": [\n {\n \"aggregation_bits\": \"0x7bfeff7ffbffffdfffdffffefb7fffde03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"3\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa44042aa4af92d9836dfd5829787bb7999e5771e8f00c1e65fc5e53aa8ce13be3c64eae0c857fd2849749d0b2a68d4a3042e727d68653e9ee70e302feff6d52877916e9de5ac2965acbb5d4b9ad65cd1040b8c69c063f7e2e4f833bec31106c3\"\n },\n {\n \"aggregation_bits\": \"0xff9fbdffdfeff7ff7dbbff77fccfb1fb03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"23\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xaf931b01212c174e364d7e2ebbcf27dc1fee77e946c7d77dc1574c51bde5775dba478000daf62e2d435600f0c9e666b50e603d3aaaa61b0ce8a50e7ec3f15e6f386fe8ceae82328cc3616126f8b13cc3657f6d00ef7620534ceeec847d3da016\"\n },\n {\n \"aggregation_bits\": \"0xffefeffffefdf7ffffffffbfef7d2ffd03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"27\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xb9b1a191b41e3db7feded9e9e8e448d07e7b7a4d2c2594ec480e654a5b0b57dc898491446489e8d51e87f362a606e0fc0d92e5cc1ec9bb9efb642c17baf2857b1e0dd6bd4eac42536f168289a4aece2f00364021ce8241e7cca729b662cfa8e2\"\n },\n {\n \"aggregation_bits\": \"0xfffbfffdffefdf7ffffafffffbf5efaf03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"8\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa03b0f34a325ae54edcdd33ec4389a4e468d534e2561369954fa00d6945c47b602c12f2ea3d2438b8e78df0bdbb3dfbe1586449edd3ac833e3c0939d2ffb97cbf772683cab6fa8ba09f13bd0d0f5204eaddcc4648e8c122edbd47e336d29df0c\"\n },\n {\n \"aggregation_bits\": \"0xff7fcffffedffffe7dfffffd6fffffd903\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"10\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x978c98d46f9eb89558db1d94d00a4ac86156cbfd53d9597f1062ea306b34a4efb08c9cd657efc35514f305434cc298bb187e24a2574cfce6196c0c3c16cee78f7a0ded8166a604208a99ffc9a66645c6d2928ce27b540465b6d9beb4ee5b5cfe\"\n },\n {\n \"aggregation_bits\": \"0xfffe77ffeeff7fe7ffb7fdfffb5fffff03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"4\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x99086ab2d7b08e0744a00f013b56f73c78c930e5759a399d2db6f1b746c6a92e648d06c406aeccbbb4aa40f1d3ae193a161d1be20c5664b352f3dd0d702cf3f3eae3352b70e78dc5f5eab10daa820be5baa1fac833d8a94881e2b367e1ca29bf\"\n },\n {\n \"aggregation_bits\": \"0xffefbfbffffefbfffff6ff7ebfbfffad03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"13\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa9c204d653d3532ef1cf5f70ccc48bababb6ec87a59afdb882707d5a48e64eea77abbc14ca397b5729e3891661b085a90d1e59a592cbf9df169f56d3519b17b5177c39dc95177d95311a79db5c72066094d64e0e2f563ece3d0b77c5530a86af\"\n },\n {\n \"aggregation_bits\": \"0x7ffbfebffffbffbeffffffbffef56bff03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"20\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xb3e0f49f8c7eb6ec9ebc30179ac4e0f8407db126797a356fd64868070c9425ce5e2c582fa39b92dfebdeac21dae9ebab0c53822303d2f2caff8c1b4bab53203e1796bb9bca4135bf4b14ab7337251244270e2de4d33df63fb3d865375cef3862\"\n },\n {\n \"aggregation_bits\": \"0xffdfdfefeffff7fffffdddbb77ffbe5f03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"12\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xb793d9bf48899fc0c976da9b1013317341c3fd33da1c61fdfcae8878920e6bfb26711942c5cff562b3dbe8e4d96f8657091bac679de3da0e6868887aeaeade13cd05829848fec7eedcc12de0d0813aa8862c392de08e5d7daab1e4570f9695e3\"\n },\n {\n \"aggregation_bits\": \"0xf3db7efff7fffefffffffef5befeffb702\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"26\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xaea6edb4cd5bce3ba9a428ffe13a21bee8dfffde9cf7686b41dad39848c86c785fc23aca4bc27b0f29d07b783b6b4efe012a2440d8ca2c7e3949ca0181e34d5775f9d84ab405130dd77ad5f8bf5f0e2f44179fb4d146b1573983319adf8af61d\"\n },\n {\n \"aggregation_bits\": \"0xbf6f3f7ffbffffff3dffffecdeffeeef03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"9\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa766696b3904f0ebe6593f461ced7456739ab73e89c0ddbab75a545b8d81eb09e7823f42a9231902a31618239413cbe111acd1e4e30391dc8066ce669610b4754b8a9f2af169a9ba1e53d6bea637d873ae4df8c50ea7d66f589ba41d906b9549\"\n },\n {\n \"aggregation_bits\": \"0xf7ffff1fcf3fff7dffdfffe7bfcd7fff03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"16\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xb6dafab655cef28f04f9f673453ecb1a8c480b5988fd37641a82753a337fdae893b14ba2a710c56e16e7ded689cbd23f0c3f336cc56c70c07dcd32d003f0eea9637aea419e23b6ea8b24a7fa2bb892e51df80c0da14b05feb20e81ca7a166383\"\n },\n {\n \"aggregation_bits\": \"0xb7fdbf77dfff67fdbff7df77ff7fefff03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"0\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x8e9b25b690f10a6bb6a21c85137f83304a12ac55c18bf7a0484022e9918023cbc6869960686eafe6668053965dd54305167dbf13fb5c5da78cfc873a102d5fd9d340dd00b5084bfd59aa3a9f6dca7c0f32aeff9179933ec5cb6e1673b348a1f0\"\n },\n {\n \"aggregation_bits\": \"0xdf7fefef7ffdbf7fffeebfbff7ffbbcf02\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"25\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x8b9279c11adf8530d0d4ce9c07099c2574e5841c915c34a402803832c61af44bcdbb613e43631b62bccde0dc55f9f9d61134fed1579b2dc3e4d1fb9183b2020f0022a5219de8b446e2cc1844655f4bf6bc415d488a767856131818ad1b123f8b\"\n },\n {\n \"aggregation_bits\": \"0xf1ff3ff7deffeff7efbdfffdff7fef7d03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"19\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x809ea2dc9ef6a5f57285f1b7c35dee8bcb6796e1f8720b6ca589b5fa8b387d7ee3ac6ffbe558d191b4b367c74dddf6dd0a8f0ffdf2abb67067ecbb3c73ce7bd01ad1a421ea0473908206cebb314b4fc23d25db96a9a87e3fae5468d6cc183cd2\"\n },\n {\n \"aggregation_bits\": \"0x7bffefffffbfefefb99bfdf5efffbefd03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"21\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x99b0bc6d72b0e0e9c82dc6c43c542b2de2b0b3907dc3c7e17bc6f007db4728701c6778026c58c708a82a9445e9a49d6716262a56534d36342b272c1fc5b59ff2485f9fa46ef127733564e486ca2614ba55c0ba3fa76674b9a6add76b48a4c876\"\n },\n {\n \"aggregation_bits\": \"0xf7ff7ff37dfffff1ffcdefbfffdf77af03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"18\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xac92cf2f15bd9374e3356f0eb930a725b27b63898af7ea177516527feab6f6dc1077117bc7f0c60c148eea4d1ab5684a1317319b29ebf126a3db5f2daa84de2f8f3b1f3908254cc32d8938e322033d9e00cf489cb1b3d042f7459e362ea54755\"\n },\n {\n \"aggregation_bits\": \"0xff58bbefffcbffbffdf7fffdfff6effd03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"2\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x8f6fbd4882a9f2f662e95080817852f04a5c017974409a50dc27c7e75958378139c57cc92129354681f4ba1ecbff20a40220fd3d66a11b0e385636a1c55cba16897673705719b3f1ed224a3218789ddb80cf0051fca9482e6f81242d25459eef\"\n },\n {\n \"aggregation_bits\": \"0xfff77fff799e767f7ff9ffbfffef6fff03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"28\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x94c5f322be8b860b73a11124e0be46a913bfae9ab266a8270d9549102df67b0c56161145f73aa4e0c6a65458f8a736aa050d8455ba4b3fa0bd55d4518042ccc1750955b82d2066a7ef7bd13707f1dc708755db490a53031b00c330dc15d03445\"\n },\n {\n \"aggregation_bits\": \"0xff7ffec75fbfbfffffd9efdffbfb3ebf03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"14\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa4cc56b14fd554512996895f185980e73cdf9ac9c1146996e29b2b1a0966e369c1232887e0324db84dcdeb34f679d7640545543bd2d50732b80be0d99d785bcbced28b2a97602cd738105bb90b0d88946972053a5c7f1f51213c75c783d459c3\"\n },\n {\n \"aggregation_bits\": \"0xfffebbfb7fa6bdf3ffffcb3ffffffddf03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"15\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x88b595627ce163a3b8d1dfc52dd3f805e502be6f4fa0ff5fd5707ebf2e6aaf3e05e539eb391219ec803b825221a7e7550d4a47f32dada5937c1f7544d51c79c075f7b9575fbd201497523045b82017f3bd615cb78343ded17a655f0dfe736e9e\"\n },\n {\n \"aggregation_bits\": \"0x7ee7f17fdeffffbf2ff6bffffe7fdfff03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"17\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x965088b03ad44a871be5cd881a88b9e580547f4db00e411c16bf3009ee8a4a50080afc2867d2eb921d0e10b50c3e6a910779d1e1d6d0ebd7ff914f0cb3a85d28fad68ddae1db6efb1811587d680453e015e626902bdc7eda4227d44635b7635b\"\n },\n {\n \"aggregation_bits\": \"0xfdffeffdfdf77e7fc75ffff5ffdfbddd03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"1\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x87b6ccc862bfe1d0c398f3dce7f50abc81bc9f68bae7dba4115c3082729dd58d60c872453337255fac4ffc752e8226b1076169e105ec094113414de8b49b5337e3ee6e5c27cbdbb6af5303049fafa1f2fed361435a1571c1b5efc1161b48ecee\"\n },\n {\n \"aggregation_bits\": \"0x5effefffef7f7ffef5fd6dfff7e6ffb603\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"7\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa1d7a8930c5eda36bd9084c523ab5d1133dd5d8684ad6a33704368b18d1b7463dddd082603535ec3f5773fe82d30a28101f75a0bcdf771a8c9408d22736f83e4fc0b8d5058cd9789eca4c844c7b9f24fd949231817187c10b92a332df1875b32\"\n },\n {\n \"aggregation_bits\": \"0x7fffff59fffb4f7fff3e79b3fffffeef02\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"5\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa5138829c94acc66e65f308d1379a1357785a2cabfabb36937f8c333c76af31bd4211c22e90ee3c3cddc50d6d998ac290c8758c1cfa558e0b21b32339df7405a77f42b730e394696501eab3563da5833d3e0d6a3885edc01f9888a540c56fae7\"\n },\n {\n \"aggregation_bits\": \"0xfff4d1fe5ffeff7ceffff7ff74dfffdd03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"24\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x8940827222f77edc46a334f19d9f771b2b5666e48454f32de5b9f2671f19225aa087bb04511f6df2d8bfa6043cbfbab602e2657e0446db136a2705efd7752c5cc89529546e7918b6cad2f546bb6e53651afe9b50c4f487c9a6d7ba785f51e829\"\n },\n {\n \"aggregation_bits\": \"0x3ff5dffb7ffb6dff7fbff7fffb9d2f3f03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"11\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x819d0442765245f7a7823baa7c2e8eb59ce23cb72f3912df9ba3b1a71d0c851d057cfbb7ccdf8af4acdd1bb234ef394d0aa91b54ba83f31f9f1f90238a0b87fa439b70b58e93e22830df90ea82347bf3388ef3cffbbd1a61402aaacbbae80de9\"\n },\n {\n \"aggregation_bits\": \"0xf537ff7ff97ffffb7d7fff7fffaf3aea03\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"22\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xac2660de0f2b0c63d2f7f3f9ce92134341e618d79303c6c67792ab8f05a1f0ce662575080567356a13c5830e0198c2d205d8fb3eeab14d3e337f0da11b818e7c31387da1d3b79b241ce7fb05b616eeb68120ef7ab430c86ae7c59fc35fcb0b78\"\n },\n {\n \"aggregation_bits\": \"0xdfdf7bfbffdeed5ff7dfffdf5d7ff3fa02\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"6\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x8be7a6be0d27e65461ddf335c397481075159b840c2a078edfeca186128d65792d80767597219a476c300fd2ce9b09a110eba93ddf2dceb8bd366a2542025e215a954dac49ca0db91735b66fc0c877e64be64a7a15a7f524b7b790c22b92998f\"\n },\n {\n \"aggregation_bits\": \"0xa3938fecedf7fbeef4bddc8a26ad2e4f02\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"12\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa6e97f50a436fe596c0e4fc41340188996b42808b65504f9c7e24c620b11c20551f70b7ecf2080f4d21b99ea74e0a41a17ea380f99c93435371ad70812646a181bd35f957d85a6fd030580af398a47b9dfe5935b9a34672291e2aab77a696b10\"\n },\n {\n \"aggregation_bits\": \"0x41020041c0002803800280510300101402\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"22\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xab39dbf89e169ab4b9b89be76a8f0829407a7af3f2080a104e1ca6fca8d841988a5d5111ba9fb4d2e6a9c6814c466b081967856c26d700845d9ac69851f96c93c812de1524b6ef36d2382d266cefcf32c472ee57ff78f1ba8bbc484e9a37e44e\"\n },\n {\n \"aggregation_bits\": \"0x4100000040400802800080010200100402\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"22\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x96cca9f882d04a3cfcba9a01a966036fcfab679a05f6a4a6342e73220a62f9537c4d1a965cca891ef9500d6793cd6ff205940d6d3b7e9211f5bb6b42f30d6ec21918a6f0395f10cc2caf82ede37ea6102e19f485a1e343d437c6fd3e1fccf323\"\n },\n {\n \"aggregation_bits\": \"0x2010000810000000000008800040000402\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"4\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa56463c667a08e3c6ff0190555fdee82158941d5e2b0c02821183b2ff2d4896494f8792e0dad8d20308a4821ad66df42003fba0be42b3b8f4047b61b8608e0d8c9aaf93ee92a88ae20b512d6af9286893fe97ae204bb327c0677dbab53fe6944\"\n },\n {\n \"aggregation_bits\": \"0x0800000001001008000000000020000102\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"11\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x982e41ae3573667b21332ebeeabf0ddd5111c8268daf20678d7971950dc56fb3dce054eae40dc23e6989bc25ce2a911e17114d12428bcac5e9b6f0ce8d0010d4b0da7ad99dbc7b238bc298d5bac47bccd6abf2fb06d1cef68b870af7ddb52f92\"\n },\n {\n \"aggregation_bits\": \"0x0000000022000004000000100000080002\",\n \"data\": {\n \"slot\": \"2234175\",\n \"index\": \"23\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x904e267663ddb6a660e5d8cc5d9620fee2353ee8a99a39b48a3fcf61405b2c3ea5c3f3ad3818b15cb56e23552881e31606d817ae5ffcef53ecd5a8af7176d8d57ef031a73a693e258d1ffce97eba6bafb093d9a5ea5913077a4c221d269125f5\"\n },\n {\n \"aggregation_bits\": \"0xffefefbfdffff67bffffffeff3fffffd03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"10\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa9a3596270858af12ae13089a2e93999baf18d4392b8acc926a8813e936b1e0fa0c6a6c37c1fc3ed98291c8a5b15d3ea02c1de3e1a14993b2fe7547f7ba18bb247bf099d92b41192389c70ab3fd65a95004687a2ac897af25b6fd3d566383711\"\n },\n {\n \"aggregation_bits\": \"0x7ff3bfdfeffbbdf7967cb5fb3ffbff9f03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"11\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa3d18879c4415affe2c45f8fb4e96412a8dcc085c107ca10f87a2a8e8a58777b688d54d1be265f450e1b0dc35936447c17b41305d9de5625e48777728713427447133dec05a07482ce0d27cd40a3250d3c0396c20e5966be43f628cc704c2d02\"\n },\n {\n \"aggregation_bits\": \"0xff76ffffeffdfffbbff5ffffddfeefdf03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"1\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xb99d28c29bd2be96fc931c21895123549c90a916cb11fde2db46654cc039bedabd3bfac46ad3137938059ef5098b8094190a461affd5ff77d0106d8243747dcc0d527585178320ea02cd62ff0340105d337846393ee7980f0445af04cf4d5615\"\n },\n {\n \"aggregation_bits\": \"0x7fedff7fffffbfaffefdffffedfffef603\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"15\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa34ffcde8175ca966d1aab3ff3917bedc99c13d1d245daf3ccc50921afd6d5d90e407d51eb6ee5db8004605c7571f15219dd67812a82dbeac78da9159021c6a1945ccc53cd0a6261fa29dec7b16bd72b321d59b3cdf97c5276aa3f193540b51e\"\n },\n {\n \"aggregation_bits\": \"0x7efffffffffeffffebeffffa7d7fff9b03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"18\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa3b6834d6483815aa79dabe3407f1e89bcf234b80785f2bbcdac7057cf391f2d38bed46cdf3b15f2c821eeeafef05260038b547c6e08de40e97f18fe7141ec9d9517d6d6af16c949e8990592b2fef4e1df0d65097e56c1a83412d2cd8116d56e\"\n },\n {\n \"aggregation_bits\": \"0xdeffeff5efff77ff7ffefeffffffb6fe03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"5\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x947af8d4392fc1dbcb4b3deab829b9cb072001d7eaa97f5c7ea244b7eb7d74a9fbcacb7e536e0888618620e076af3cc10d09f5b10fb4a88a549276b02634a9746136ab303f99982bd2595150b78b7e8de2c534ed01ef5f088072b6ae837b35b1\"\n },\n {\n \"aggregation_bits\": \"0xfdaffffa7fff7fbdfffffefefef7deff03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"14\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x92c9592a54ad50686fc65638deba628dd7c9612fca1276181562248a6c61dfce5f239e088252b585a2b5ef379738e3550cceb61bbbb9a7c569a16fd04d31c5285ee13a4982c6e417f515a1b670c4ee4e07d53dc09d769f439be3c5dab8cf3149\"\n },\n {\n \"aggregation_bits\": \"0xfdb74f77fffffeffff7ff7ff66ffbfff03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"16\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x88ff8c02f1725ba6b56e5891824f84dc7b2979597e745986241b3d936949994c9ed559d537e4a95d8389ffe2842cbb780ae58850f32ee161a36d0960e5e6bb0e790d50388e7768aa0ec3267fc38fb5e3b7c874fad672b2e7e484dfde465749a1\"\n },\n {\n \"aggregation_bits\": \"0xfbff7de7efffee7fffdfbd5dfbfffdff03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"26\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x82a17f682327b0e32466d9313922138ab16de2c9dc0be24803251adc6d9ccf54830d79c58eab34312f9c9a27c7d25754051bcc44a186e626768521a47a29deddab715fd377f4274b4b650fa16e01a78fe8221bfc8f16c57c0a2045abd807a1ed\"\n },\n {\n \"aggregation_bits\": \"0xbdfbffffbfffbe7fff76fadff3fedfff02\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"20\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x89de00fd95b37d1a0f091d9a974ca27a9542359eb93b8195e270e0dcf949a7db6acf1b6d115c86790aaef8be0ed5119e19500d37ad35f2b52e144764f02d36b30b84142c69c1379795ebff7ca51276cb53c608e02ec0c5e879bbcab28b36002c\"\n },\n {\n \"aggregation_bits\": \"0xdff7ff77fdffffe7fa67ed7ffffbbdff03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"4\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x84c060290fd05a8f33f03e9f62226fafc8c22883f6366b939f5918f83232d1bdf8d15451c4a2dede20556c5f06fcd88f081b6ff2eefd8da37ca6052246c69c2af7c2e70df318b9e3160edfc6603f650e178e200d015082590134e704573675f6\"\n },\n {\n \"aggregation_bits\": \"0xefefffbfffd7bdfffddfe7dcbeffafff03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"6\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xae6167ae809109be13693722b38d5a4478e128afa0f7468c0bc6b11936a46067950d08fb0d077eefbac21b9c3b3912c9108ab0dfb8a9069b8270fbb135639046902bd37d153d9f8d524be904d48acd5fb9702ea554354b870925dee77c0eaed8\"\n },\n {\n \"aggregation_bits\": \"0xbdf2ffff5d7ffffdcffbfbfefefffddf03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"3\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xaedfbd53294f007aea3987cb409334245e1d70b984ec8bf0160d80feedb9c97709031102b75e0c8a01f084ea0a62cdfa03b9a9b6c514c419b146a3458bedb3c8d9380a5b386baacda1949f23fb8029b4ee6e1df4100b104f57b90a6cb8542ad5\"\n },\n {\n \"aggregation_bits\": \"0xffb7bd2ff7ff7fef77e7ffffeeffffbf02\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"0\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x9725755ad371de5e0034a7c268cd0c4bfe8906a08aab1492df1c5e99447707c68bfbe1442b55aac5879ba08e449a84120a926b2b0e79d74541e98b0ee92082ad28663bf479717f4b8f5a9339823524470720517b0594576829b1a4d55a42030c\"\n },\n {\n \"aggregation_bits\": \"0xffd3bf3cfffbf77efff77ffffbd5ff7f03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"21\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa55586fe08d65916f3da6e443ab375bdfe35edc521f05995f40200c95105c494e77dac5e0ec96f6e3484595bcacf19f71302222100e913c6d70231fb86ec706d4feaf23bccdf7c17282ea3beeec9dd98bc96e5b76c1a489fe576e8784dfbaf3b\"\n },\n {\n \"aggregation_bits\": \"0xffefff7ffef89fffffcddbfffff7f55e03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"12\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x8b57dce1e842b001300a3d5a9688b8efb0b2775f9358f8e9169ede20e2b7bfe76a58a51a136a022ad1e113094a8322dd17f04a5bb34dd6e56bb97294e83ecf24325b208c9327d2fc25be121a12c6c4b333bfddc509b50e456d05b21d147c25c3\"\n },\n {\n \"aggregation_bits\": \"0xcfffff3ffff7dff7f797fddffff2edbf02\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"19\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa90639d61d328a2170cc2c7e3ac072da6bbefd95095256465227fc9690fc4f90a879f3c4ab3afca98ac00d7cc7bac84a0eec414a32f0df7b34c875cf54b2fe8e103c9846b364be20e55883cf72b59cde066ecf58d3ab0456297bf31acb1379c2\"\n },\n {\n \"aggregation_bits\": \"0xfcfeedfeb7fffff5df7efcfefeffbdef03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"17\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xb0724c415d91153a6a28834620822a6efc043ce75420ebae4e0d1f3987e771a351a3298d73af726056a75e18091f2a0001a1c5cc124ca680324e0841a77656a8545fad253e34d567e3d383be744e02f3e3c8628991f02e0b21ac412b204dbc2c\"\n },\n {\n \"aggregation_bits\": \"0xdffbfbedfbbefbefffbb3ffa7eedf6ff03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"7\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xad51bc8cdac71feef28340bd50240e72f7c1bb62b77ab242af3a0de34b67222356b52a4740d3ec4900ae403f409190f5025ff6931eb20f9d0f7bfc504a556c8f599e939c98e83b2522bf0f1ebbcc388d2a53b06fb6b40be8c8a1bd997907edf7\"\n },\n {\n \"aggregation_bits\": \"0xffcdeddb75fefffffbfffcfc7f3bfeff01\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"9\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x86cc3dfb6eec4e59c09bc43fb02e7d71fc70afd0e0872b419ec56fdf4833e1638a2c2236643a9a1ee3b4d32030364c9218a20c177618374dede15df58a9349903cf06ebbe6b270e4361432372418c12558a24b64a96818ed216a48ba21ffc36d\"\n },\n {\n \"aggregation_bits\": \"0xcbb3fffff797efd7ff4fff7fffcfebfe03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"2\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa11795d50d72b50dd88774b80e35c7b2114082ebb940e155f1b2719d85a54039b088cd361de0ec3ccaec327d01b4ec6b0dfd059834f018ad3eb6b696ffcba22a1d5b48ff0095844ef7125cf36d39243bb465b27fa0815a3aa25ab5fb5b045bfb\"\n },\n {\n \"aggregation_bits\": \"0xeeddbeff7fffffed3fa5e33fffffbfbf03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"8\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xad7066ec463c0991cf2f3b11e91de40d02cc878899532f07f0766a101ccb4abc54e75b939adbaf9fe6dfb6405990f3320b25f03af1fb3e0fb4cdb22180fe121113d1424484aad71a9230fe29293ac1ac1001016bb21289d0c5e9b782af8fd2b1\"\n },\n {\n \"aggregation_bits\": \"0x2fecfff7beefeffffbfbddbcfffef9fb02\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"24\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x83d04129691354ca553caac6c5ca6bcb1ad15aed523f878dd1bfc2d1c25257542b60619eb642aac4523691c59e82f6050b83ba51dba150cb5deb030fdc545fbf63cb0f9eba65f934f4bc5c7cd8df14bf0dde21c45521ed83b213c81a48ec2cf8\"\n },\n {\n \"aggregation_bits\": \"0xf9ffdffd7bebe7ff6ffd97fdbfeff9e703\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"13\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x8954a5fc4290abf328fcb113a7dbbb355a7cd6d85d5948d70ea11a6e8f2d3e26b7fe5d06078c4385b03a72fb6921fed4028538bde16fb75307405c6bdb99ab9e472e5b19965f108aae23fe1267094c67ffa4175685c1231d367ea935c570e599\"\n },\n {\n \"aggregation_bits\": \"0x7bf71d7fffddffff07af3ffbf7fdfbfe03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"23\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x90e10c0dcc12157299cabb25e4b552dd318ad48118576e4d1ac29b2298c93e5cad3c29fc390081510296c5a1c58052bc1232146a2fdd2ed85c5c90825d78ec6038aa73c6454c164f9f0aa5a9f93f711297a97cff91c21bcea990872da941b48c\"\n },\n {\n \"aggregation_bits\": \"0x4fbfd6bfbffeffff7bedbfdffd3dbdbd02\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"22\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x8815a0a80aec3cb7c9bb8feef66c9ae557ea2f1940e6ba2f6612a4055fc179ce8099b273c44d60ec8f9c3320a4c420a20f5f5b299d5ce6bfd3116e74e009e88ca12b1f63ccba8438fc1e18f57c44be3be118664209a5d5eb1b971e8d12423257\"\n },\n {\n \"aggregation_bits\": \"0xddea7bfdd5bb5fffee6ff7fffebff3f703\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"28\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x8b0fbc4645f83e75050c9cc1381c7f324e11c9c5118c2f549fef096a0aab5c9e0f807d751d9a768cc1b7c40e5f6e840e15e553a3edd4e4e93baf0901024c2cc0eb5affdcf164ad4944ff5e17d2adaef73a3f8d1fdaa1ca602b99adff6bc38004\"\n },\n {\n \"aggregation_bits\": \"0xfabdfff2fe8bf733ff76bffafffdf7ff03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"27\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x9375d76b2e1afc085af57030d3137e2b6f8a798961f98e19e58044eb0fe6496f74796513bcc49aa58f5c855e7876e01e14ed945ad2fe045e0e59b4b2ea9d1e388ccd03af3ef7a03ea980b0913b280d0e85be80de618392d8dbff781fdb64c45a\"\n },\n {\n \"aggregation_bits\": \"0xfc6f3af7ffff46fedbfdff5ffff779ad03\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"25\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x96db65f511117149f206719b3f68ea1e55b2a2730e09f99049eae1bffa789796a4f730e1507c3775998ab1c20126065c059311e43f5cbdf793038e4cf58b43f23c92d1a4032510758b621a37a6acd469fe4f8bc1a5ec84bf93c17c517d40ab16\"\n },\n {\n \"aggregation_bits\": \"0x100410b45d834b3241000045b889a4a402\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"28\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xb36a8952df24d70fef75d0174c54503f1d74624b97791cc8902d7ccf284e8b2ecdf144decdf6648f9ac7e9868a47bf8a116e4277c48764f83694f460493f9f826b7af04659526a4f45e7e0ce2a75ad03bcc4b0af27eea260fef0d10bd64945da\"\n },\n {\n \"aggregation_bits\": \"0x0080588408a0024087000da01004014002\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"24\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x9146464de6d0a0b9c725f39751bffdb7a83641d7c3c4a02e53ce77ab0bfeed8014ddc40dabbb373ff6caa838319013bd13317c16222a2ff72d7fbe7357d3d3752538214572014bfff78987f4b40705485737df4b501b3a089def2fd5ac64c615\"\n },\n {\n \"aggregation_bits\": \"0x0012000000000000000080000002090002\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"7\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xb0aae76ccc8db1db0a789dd9d527ee3728b47cfca02e5055e21cb46c58a1079cf0e7a01693c14b0eb7839419d1377118092f8768de7c27b46952346e55b5412c6c46c7eb8e0d607f072518925a1d1e6a1f3af8270d3ea4a7d6cd1446c9d1eb3c\"\n },\n {\n \"aggregation_bits\": \"0x0000100000000000000008110800000001\",\n \"data\": {\n \"slot\": \"2234174\",\n \"index\": \"9\",\n \"beacon_block_root\": \"0xc2a6b88ed0cb54dc0cc06da8d31e17a79cc6e5ca9a4b1feba5dbec043d35b45b\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xae71b8500d7a15e9ec8ae17b09ffc5fd2ea75e48eb56ea56a1011293f3f81117cff664b7b57b381e376a720396ab78240ede87febb7a9f6a9c0a13d12b0ad0aa1698ecddd6f4217c64a3a0375dcaa176d33b2d09d31291c01b550670ec455fea\"\n },\n {\n \"aggregation_bits\": \"0xff7ffbfbefbf7ede6df7b7f9ffbfffff01\",\n \"data\": {\n \"slot\": \"2234170\",\n \"index\": \"27\",\n \"beacon_block_root\": \"0x1dfd9b3e648dc5768dc004ced7e9b54f4b085a0e64882caec42c360a36a01312\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xb2a867f1e83642aa591f73a330c5d1a6c2518b1cb2f0e44df8bec63ad7bb24ea1342bd0accad582f6209e99866ceeb5303879bc8b882ba96a2ee34f99091cea17dada505163c86ad0d7248541325041b813a19e284ee8a0ee3ba4b5bf5386b3c\"\n },\n {\n \"aggregation_bits\": \"0xd7fffffff4fffdffffeff7fdfdfdffbd02\",\n \"data\": {\n \"slot\": \"2234170\",\n \"index\": \"20\",\n \"beacon_block_root\": \"0x1dfd9b3e648dc5768dc004ced7e9b54f4b085a0e64882caec42c360a36a01312\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa786c3f9227afa2fbaa4357a38174f8b373ecb013f448d913521e3a53a31e1bbea7f61f0077647b60713891328bcb91d04fbd51161043b347af16b009140db6ef4f39f4b89d81058b1cf7b72b19061d696db8580da88c80827028aab78f74f40\"\n },\n {\n \"aggregation_bits\": \"0xfff7f5f6ffffffd679fffeedfddffbff02\",\n \"data\": {\n \"slot\": \"2234170\",\n \"index\": \"25\",\n \"beacon_block_root\": \"0x1dfd9b3e648dc5768dc004ced7e9b54f4b085a0e64882caec42c360a36a01312\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x9251ef33249563f1f99dd7a3a1d0c7da1ea2e070e99ff3a3352cd39b7289df5727d12d707ca6937404e91a00cd7844300fa958edc526197fde12ecb5bad7984f056a51d306e5fb6a3e649d8e33f1a86abe74337034b92b9fdd6f1c17a060572d\"\n },\n {\n \"aggregation_bits\": \"0xfff7fbff7ffb37fdff5ffffdbefbfdff03\",\n \"data\": {\n \"slot\": \"2234169\",\n \"index\": \"23\",\n \"beacon_block_root\": \"0x1dfd9b3e648dc5768dc004ced7e9b54f4b085a0e64882caec42c360a36a01312\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x906b41676cfbceb32f97b2f0c86dbf948b8295f7bd29e22cff1c00958ec5864b5c863629da6ec00cc42d8d37eaa2cdeb03d290414222ccbc25fa2c4ef52e389a0a844757aea28e842de83a43ee1652f42f4d65b4bdd5080458d6ffc7f727545f\"\n },\n {\n \"aggregation_bits\": \"0xfff9ef7f3afdff3fffff7efffbddff3f02\",\n \"data\": {\n \"slot\": \"2234169\",\n \"index\": \"4\",\n \"beacon_block_root\": \"0x1dfd9b3e648dc5768dc004ced7e9b54f4b085a0e64882caec42c360a36a01312\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x86583e4d2a9c51f36e1976b7552095dc42ec9c318ef3ed0605264917b87830f1d2e53d8e5186868b89a94e069e93ed790424b782507245df39216ceba4c239d80101a31d68153425fa148d7c345dd278124ae84ef2c532442a792b16fc77ed18\"\n },\n {\n \"aggregation_bits\": \"0xfffffbfaf1f7fffe77fedfdbffda5bfd03\",\n \"data\": {\n \"slot\": \"2234169\",\n \"index\": \"19\",\n \"beacon_block_root\": \"0x1dfd9b3e648dc5768dc004ced7e9b54f4b085a0e64882caec42c360a36a01312\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x813e7cf5e7514929cf8cadcc83f2fc38853af70b221a0a88f286ed7e8c42dd2ad285b9f8e176ace15ca6a6d0746f2c0e15c44c92223888c5e5701e66a83c0ad9da486083f7f4f145f2ee049d53f6c97ab24b518d949c498bbd7e52b25d4b9ff8\"\n },\n {\n \"aggregation_bits\": \"0xffbfcfffff6be76fdfffffffffeef77f03\",\n \"data\": {\n \"slot\": \"2234169\",\n \"index\": \"25\",\n \"beacon_block_root\": \"0x1dfd9b3e648dc5768dc004ced7e9b54f4b085a0e64882caec42c360a36a01312\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x99e8025dc1f835cac1069dd292776ea733ea6e346e34e435b547c7a8c42ea16f1004ed86f1eb102f59ed11ce007a74d3008cb79f800e9fa364dd0d9d27190eca362ba09f314433c3b052130857258b7e0a51537d0b2628b983d72ed1735035ad\"\n },\n {\n \"aggregation_bits\": \"0xdffffdffdfafff73bfffdffffcbafffc03\",\n \"data\": {\n \"slot\": \"2234169\",\n \"index\": \"16\",\n \"beacon_block_root\": \"0x1dfd9b3e648dc5768dc004ced7e9b54f4b085a0e64882caec42c360a36a01312\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0x9449cdc69b48bc4bfde82c9d3b0a3b00d34cc6eef34aa9ddfec998b184f7e5511af6a4bfd3d1e1f4e3267a88616c55f111b36cb40a787f161e1fcbcf30ba3029bc3d49790bfadb8e92738ff04382f6ee4fc03f81ef9e4dc6b95e20a205d147ed\"\n },\n {\n \"aggregation_bits\": \"0xfdbffff5fdf7fefc2fffdfefdafefbfd02\",\n \"data\": {\n \"slot\": \"2234169\",\n \"index\": \"28\",\n \"beacon_block_root\": \"0x1dfd9b3e648dc5768dc004ced7e9b54f4b085a0e64882caec42c360a36a01312\",\n \"source\": {\n \"epoch\": \"69816\",\n \"root\": \"0xb9085fd60831fad7ea425dee4a04ebe1e89f547ebda92237801db041891530e1\"\n },\n \"target\": {\n \"epoch\": \"69817\",\n \"root\": \"0xeeaf0728bd92dd6b711aead39818c0b38dd70a45f22ecc189cedbcd156fd7ed7\"\n }\n },\n \"signature\": \"0xa968bc6bf1d6dc7b715f83ef2c4e157247b277aea4efc0705fab136f65ac40f30e60dcc53cbd32b33aacd5fd469bda1e01b4fd4d1caf0c31c9378b7ba778a858fa6e127903d6e672204205965d2b1c13b25433d10bc99da65fd80767a4a90602\"\n }\n ],\n \"deposits\": [],\n \"voluntary_exits\": [],\n \"sync_aggregate\": {\n \"sync_committee_bits\": \"0xbff7dbffedfffffdc5fffb56bbeeff9efd9feafb4ffbefff7fffffffefffff5efef9ffffe6fbff7ffdfaffff79f5effbfffbffffcff3ffcdfbfffefdffdfbdfb\",\n \"sync_committee_signature\": \"0xa1cdf7a4ba9d30ac0199a80ebeaade2b5312e324c5bbaa330709dd5f259a85598cd0ae534dcc3c96ac2c740b01c0dbc00f9b8fd0aeb8f3126671008b7dc4ab5eaaae1cf02c7b15ad73657b6f1273aae8a40953fe2031387ff1f285bce914604b\"\n }\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/blocks", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "blocks" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/blinded_blocks", - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "/beacon/blinded_blocks", - "path": [ - "beacon", - "blinded_blocks" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/blocks/{block_id}", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/blocks/{block_id}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "blocks", - "{block_id}" - ] - } - }, - "response": [] - }, - { - "name": "/v2/beacon/blocks/{block_id}", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v2/beacon/blocks/{block_id}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v2", - "beacon", - "blocks", - "{block_id}" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/blocks/{block_id} (SSZ)", - "protocolProfileBehavior": { - "disabledSystemHeaders": { - "accept": true - } - }, - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/octet-stream", - "type": "text" - } - ], - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/blocks/{block_id}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "blocks", - "{block_id}" - ] - } - }, - "response": [] - }, - { - "name": "/v2/beacon/blocks/{block_id} (SSZ)", - "protocolProfileBehavior": { - "disabledSystemHeaders": { - "accept": true - } - }, - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/octet-stream", - "type": "text" - } - ], - "url": { - "raw": "http://localhost:3500/eth/v2/beacon/blocks/{block_id}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v2", - "beacon", - "blocks", - "{block_id}" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/blocks/{block_id}/root", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/blocks/{block_id}/root", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "blocks", - "{block_id}", - "root" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/blocks/{block_id}/attestations", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/blocks/{block_id}/attestations", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "blocks", - "{block_id}", - "attestations" - ], - "query": [ - { - "key": "slot", - "value": null, - "disabled": true - }, - { - "key": "committee_index", - "value": null, - "disabled": true - } - ] - } - }, - "response": [] - }, - { - "name": "/beacon/pool/attestations", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/pool/attestations", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "pool", - "attestations" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/pool/attestations", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "[\n {\n \"aggregation_bits\": \"0x01\",\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\",\n \"data\": {\n \"slot\": \"1\",\n \"index\": \"1\",\n \"beacon_block_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"source\": {\n \"epoch\": \"1\",\n \"root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n },\n \"target\": {\n \"epoch\": \"1\",\n \"root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n }\n }\n }\n]", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/pool/attestations", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "pool", - "attestations" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/pool/attester_slashings", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/pool/attester_slashings", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "pool", - "attester_slashings" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/pool/attester_slashings", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"attestation_1\": {\n \"attesting_indices\": [\n \"1\"\n ],\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\",\n \"data\": {\n \"slot\": \"1\",\n \"index\": \"1\",\n \"beacon_block_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"source\": {\n \"epoch\": \"1\",\n \"root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n },\n \"target\": {\n \"epoch\": \"1\",\n \"root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n }\n }\n },\n \"attestation_2\": {\n \"attesting_indices\": [\n \"1\"\n ],\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\",\n \"data\": {\n \"slot\": \"1\",\n \"index\": \"1\",\n \"beacon_block_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"source\": {\n \"epoch\": \"1\",\n \"root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n },\n \"target\": {\n \"epoch\": \"1\",\n \"root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n }\n }\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/pool/attester_slashings", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "pool", - "attester_slashings" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/pool/proposer_slashings", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/pool/proposer_slashings", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "pool", - "proposer_slashings" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/pool/proposer_slashings", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"signed_header_1\": {\n \"message\": {\n \"slot\": \"1\",\n \"proposer_index\": \"1\",\n \"parent_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"state_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"body_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n },\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\"\n },\n \"signed_header_2\": {\n \"message\": {\n \"slot\": \"1\",\n \"proposer_index\": \"1\",\n \"parent_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"state_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"body_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n },\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\"\n }\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/pool/proposer_slashings", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "pool", - "proposer_slashings" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/pool/sync_committees", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "[\n {\n \"slot\": \"1\",\n \"beacon_block_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"validator_index\": \"1\",\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\"\n }\n]", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/pool/sync_committees", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "pool", - "sync_committees" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/pool/voluntary_exits", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/pool/voluntary_exits", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "pool", - "voluntary_exits" - ] - } - }, - "response": [] - }, - { - "name": "/beacon/pool/voluntary_exits", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"message\": {\n \"epoch\": \"1\",\n \"validator_index\": \"1\"\n },\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/beacon/pool/voluntary_exits", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "beacon", - "pool", - "voluntary_exits" - ] - } - }, - "response": [] - }, - { - "name": "/config/fork_schedule", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/config/fork_schedule", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "config", - "fork_schedule" - ] - } - }, - "response": [] - }, - { - "name": "/config/spec", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/config/spec", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "config", - "spec" - ] - } - }, - "response": [] - }, - { - "name": "/config/deposit_contract", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/config/deposit_contract", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "config", - "deposit_contract" - ] - } - }, - "response": [] - }, - { - "name": "/debug/beacon/states/{state_id}", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/debug/beacon/states/{state_id}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "debug", - "beacon", - "states", - "{state_id}" - ] - } - }, - "response": [] - }, - { - "name": "/debug/beacon/states/{state_id} (SSZ)", - "protocolProfileBehavior": { - "disabledSystemHeaders": { - "accept": true - } - }, - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/octet-stream", - "type": "text" - } - ], - "url": { - "raw": "http://localhost:3500/eth/v1/debug/beacon/states/{state_id}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "debug", - "beacon", - "states", - "{state_id}" - ] - } - }, - "response": [] - }, - { - "name": "/v2/debug/beacon/states/{state_id}", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v2/debug/beacon/states/{state_id}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v2", - "debug", - "beacon", - "states", - "{state_id}" - ] - } - }, - "response": [] - }, - { - "name": "/v2/debug/beacon/states/{state_id} (SSZ)", - "protocolProfileBehavior": { - "disabledSystemHeaders": { - "accept": true - } - }, - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/octet-stream", - "type": "text" - } - ], - "url": { - "raw": "http://localhost:3500/eth/v2/debug/beacon/states/{state_id}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v2", - "debug", - "beacon", - "states", - "{state_id}" - ] - } - }, - "response": [] - }, - { - "name": "/debug/beacon/heads", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/debug/beacon/heads", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "debug", - "beacon", - "heads" - ] - } - }, - "response": [] - }, - { - "name": "/v2/debug/beacon/heads", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v2/debug/beacon/heads", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v2", - "debug", - "beacon", - "heads" - ] - } - }, - "response": [] - }, - { - "name": "/node/identity", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/node/identity", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "node", - "identity" - ] - } - }, - "response": [] - }, - { - "name": "/node/peers", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/node/peers", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "node", - "peers" - ], - "query": [ - { - "key": "state", - "value": null, - "disabled": true - }, - { - "key": "direction", - "value": null, - "disabled": true - } - ] - } - }, - "response": [] - }, - { - "name": "/node/peers/{peer_id}", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/node/peers/{peer_id}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "node", - "peers", - "{peer_id}" - ] - } - }, - "response": [] - }, - { - "name": "/node/peer_count", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/node/peer_count", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "node", - "peer_count" - ] - } - }, - "response": [] - }, - { - "name": "/node/version", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/node/version", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "node", - "version" - ] - } - }, - "response": [] - }, - { - "name": "/node/syncing", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/node/syncing", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "node", - "syncing" - ] - } - }, - "response": [] - }, - { - "name": "/node/health", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/node/health", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "node", - "health" - ] - } - }, - "response": [] - }, - { - "name": "/validator/duties/attester/{epoch}", - "request": { - "method": "POST", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/validator/duties/attester/{epoch}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "validator", - "duties", - "attester", - "{epoch}" - ] - } - }, - "response": [] - }, - { - "name": "/validator/duties/proposer/{epoch}", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/validator/duties/proposer/{epoch}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "validator", - "duties", - "proposer", - "{epoch}" - ] - } - }, - "response": [] - }, - { - "name": "/validator/duties/sync/{epoch}", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "[\n \"97880\",\n \"122740\"\n]", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/validator/duties/sync/{epoch}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "validator", - "duties", - "sync", - "{epoch}" - ] - } - }, - "response": [] - }, - { - "name": "/validator/blocks/{slot}", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/validator/blocks/{slot}?randao_reveal=0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "validator", - "blocks", - "{slot}" - ], - "query": [ - { - "key": "randao_reveal", - "value": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" - }, - { - "key": "graffiti", - "value": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "disabled": true - } - ] - } - }, - "response": [] - }, - { - "name": "/v2/validator/blocks/{slot}", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v2/validator/blocks/{slot}?graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2=&randao_reveal=0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v2", - "validator", - "blocks", - "{slot}" - ], - "query": [ - { - "key": "graffiti", - "value": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2=" - }, - { - "key": "randao_reveal", - "value": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" - } - ] - } - }, - "response": [] - }, - { - "name": "validator/blinded_blocks/{slot}", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/validator/blinded_blocks/{slot}?graffiti=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2=&randao_reveal=0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "validator", - "blinded_blocks", - "{slot}" - ], - "query": [ - { - "key": "graffiti", - "value": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2=" - }, - { - "key": "randao_reveal", - "value": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" - } - ] - } - }, - "response": [] - }, - { - "name": "/validator/attestation_data", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/validator/attestation_data?slot=1820830&committee_index=1", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "validator", - "attestation_data" - ], - "query": [ - { - "key": "slot", - "value": "1820830" - }, - { - "key": "committee_index", - "value": "1" - } - ] - } - }, - "response": [] - }, - { - "name": "/validator/aggregate_attestation", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/validator/aggregate_attestation?attestation_data_root=MHhjZjhlMGQ0ZTk1ODczNjliMjMwMWQwNzkwMzQ3MzIwMzAyY2MwOTQzZDVhMTg4NDU2MDM2N2U4MjA4ZDkyMGYy", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "validator", - "aggregate_attestation" - ], - "query": [ - { - "key": "attestation_data_root", - "value": "MHhjZjhlMGQ0ZTk1ODczNjliMjMwMWQwNzkwMzQ3MzIwMzAyY2MwOTQzZDVhMTg4NDU2MDM2N2U4MjA4ZDkyMGYy" - }, - { - "key": "slot", - "value": "10000", - "disabled": true - } - ] - } - }, - "response": [] - }, - { - "name": "/validator/aggregate_and_proofs", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "[\n {\n \"message\": {\n \"aggregator_index\": \"1\",\n \"aggregate\": {\n \"aggregation_bits\": \"0x01\",\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\",\n \"data\": {\n \"slot\": \"1\",\n \"index\": \"1\",\n \"beacon_block_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"source\": {\n \"epoch\": \"1\",\n \"root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n },\n \"target\": {\n \"epoch\": \"1\",\n \"root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\"\n }\n }\n },\n \"selection_proof\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\"\n },\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\"\n }\n]", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/validator/aggregate_and_proofs", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "validator", - "aggregate_and_proofs" - ], - "query": [ - { - "key": "", - "value": "", - "disabled": true - }, - { - "key": "", - "value": "", - "disabled": true - } - ] - } - }, - "response": [] - }, - { - "name": "/validator/beacon_committee_subscriptions", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "[\n {\n \"validator_index\": \"10000\",\n \"committee_index\": \"1\",\n \"committees_at_slot\": \"1\",\n \"slot\": \"100000\",\n \"is_aggregator\": true\n }\n]", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/validator/beacon_committee_subscriptions", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "validator", - "beacon_committee_subscriptions" - ] - } - }, - "response": [] - }, - { - "name": "/validator/sync_committee_subscriptions", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "[\n {\n \"validator_index\": \"10000\",\n \"sync_committee_indices\": [\n \"1\"\n ],\n \"until_epoch\": \"64\"\n }\n]", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/validator/sync_committee_subscriptions", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "validator", - "sync_committee_subscriptions" - ] - } - }, - "response": [] - }, - { - "name": "/validator/sync_committee_contribution", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:3500/eth/v1/validator/sync_committee_contribution?slot=100000&subcommittee_index=1&beacon_block_root=0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "validator", - "sync_committee_contribution" - ], - "query": [ - { - "key": "slot", - "value": "100000" - }, - { - "key": "subcommittee_index", - "value": "1" - }, - { - "key": "beacon_block_root", - "value": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" - } - ] - } - }, - "response": [] - }, - { - "name": "/validator/contribution_and_proofs", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "[\n {\n \"message\": {\n \"aggregator_index\": \"1\",\n \"selection_proof\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\",\n \"contribution\": {\n \"slot\": \"1\",\n \"beacon_block_root\": \"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2\",\n \"subcommittee_index\": \"1\",\n \"aggregation_bits\": \"0x01000000000000000000000000000000\",\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\"\n }\n },\n \"signature\": \"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505\"\n }\n]", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "http://localhost:3500/eth/v1/validator/contribution_and_proofs", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "3500", - "path": [ - "eth", - "v1", - "validator", - "contribution_and_proofs" - ] - } - }, - "response": [] - }, - { - "name": "/validator/prepare_beacon_proposer", - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "[\n {\n \"validator_index\": \"1\",\n \"fee_recipient\": \"0xabcf8e0d4e9587369b2301d0790347320302cc09\"\n }\n]" - }, - "url": { - "raw": "/eth/v1/validator/prepare_beacon_proposer", - "path": [ - "eth", - "v1", - "validator", - "prepare_beacon_proposer" - ] - } - }, - "response": [] - } - ] -} \ No newline at end of file diff --git a/math/BUILD.bazel b/math/BUILD.bazel index 39964b0712c7..fac6ee3ab7a0 100644 --- a/math/BUILD.bazel +++ b/math/BUILD.bazel @@ -5,10 +5,7 @@ go_library( srcs = ["math_helper.go"], importpath = "github.com/prysmaticlabs/prysm/v5/math", visibility = ["//visibility:public"], - deps = [ - "@com_github_prysmaticlabs_fastssz//:go_default_library", - "@com_github_thomaso_mirodin_intmath//u64:go_default_library", - ], + deps = ["@com_github_thomaso_mirodin_intmath//u64:go_default_library"], ) go_test( @@ -17,6 +14,7 @@ go_test( srcs = ["math_helper_test.go"], deps = [ ":go_default_library", + "//consensus-types/primitives:go_default_library", "//testing/require:go_default_library", ], ) diff --git a/math/math_helper.go b/math/math_helper.go index d926a3db750e..e4a59e21d6f0 100644 --- a/math/math_helper.go +++ b/math/math_helper.go @@ -3,13 +3,11 @@ package math import ( "errors" - "fmt" stdmath "math" "math/big" "math/bits" "sync" - fssz "github.com/prysmaticlabs/fastssz" "github.com/thomaso-mirodin/intmath/u64" ) @@ -215,68 +213,6 @@ func AddInt(i ...int) (int, error) { return sum, nil } -// Wei is the smallest unit of Ether, represented as a pointer to a bigInt. -type Wei *big.Int - -var _ fssz.HashRoot = (Gwei)(0) -var _ fssz.Marshaler = (*Gwei)(nil) -var _ fssz.Unmarshaler = (*Gwei)(nil) - -// Gwei is a denomination of 1e9 Wei represented as an uint64. -type Gwei uint64 - -// HashTreeRoot -- -func (g Gwei) HashTreeRoot() ([32]byte, error) { - return fssz.HashWithDefaultHasher(g) -} - -// HashTreeRootWith -- -func (g Gwei) HashTreeRootWith(hh *fssz.Hasher) error { - hh.PutUint64(uint64(g)) - return nil -} - -// UnmarshalSSZ -- -func (g *Gwei) UnmarshalSSZ(buf []byte) error { - if len(buf) != g.SizeSSZ() { - return fmt.Errorf("expected buffer of length %d received %d", g.SizeSSZ(), len(buf)) - } - *g = Gwei(fssz.UnmarshallUint64(buf)) - return nil -} - -// MarshalSSZTo -- -func (g *Gwei) MarshalSSZTo(dst []byte) ([]byte, error) { - marshalled, err := g.MarshalSSZ() - if err != nil { - return nil, err - } - return append(dst, marshalled...), nil -} - -// MarshalSSZ -- -func (g *Gwei) MarshalSSZ() ([]byte, error) { - marshalled := fssz.MarshalUint64([]byte{}, uint64(*g)) - return marshalled, nil -} - -// SizeSSZ -- -func (g *Gwei) SizeSSZ() int { - return 8 -} - -// WeiToGwei converts big int wei to uint64 gwei. -// The input `v` is copied before being modified. -func WeiToGwei(v Wei) Gwei { - if v == nil { - return 0 - } - gweiPerEth := big.NewInt(1e9) - copied := big.NewInt(0).Set(v) - copied.Div(copied, gweiPerEth) - return Gwei(copied.Uint64()) -} - // IsValidUint256 given a bigint checks if the value is a valid Uint256 func IsValidUint256(bi *big.Int) bool { return bi.Cmp(big.NewInt(0)) >= 0 && bi.BitLen() <= 256 diff --git a/math/math_helper_test.go b/math/math_helper_test.go index 6419ff503e35..64243a694724 100644 --- a/math/math_helper_test.go +++ b/math/math_helper_test.go @@ -6,6 +6,7 @@ import ( "math/big" "testing" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/math" "github.com/prysmaticlabs/prysm/v5/testing/require" ) @@ -554,7 +555,7 @@ func TestAddInt(t *testing.T) { func TestWeiToGwei(t *testing.T) { tests := []struct { v *big.Int - want math.Gwei + want primitives.Gwei }{ {big.NewInt(1e9 - 1), 0}, {big.NewInt(1e9), 1}, @@ -562,7 +563,7 @@ func TestWeiToGwei(t *testing.T) { {big.NewInt(239489233849348394), 239489233}, } for _, tt := range tests { - if got := math.WeiToGwei(tt.v); got != tt.want { + if got := primitives.WeiToGwei(tt.v); got != tt.want { t.Errorf("WeiToGwei() = %v, want %v", got, tt.want) } } @@ -570,8 +571,8 @@ func TestWeiToGwei(t *testing.T) { func TestWeiToGwei_CopyOk(t *testing.T) { v := big.NewInt(1e9) - got := math.WeiToGwei(v) + got := primitives.WeiToGwei(v) - require.Equal(t, math.Gwei(1), got) + require.Equal(t, primitives.Gwei(1), got) require.Equal(t, big.NewInt(1e9).Uint64(), v.Uint64()) } diff --git a/proto/engine/v1/execution_engine.pb.go b/proto/engine/v1/execution_engine.pb.go index 2464d30de932..3bf7788d62e5 100755 --- a/proto/engine/v1/execution_engine.pb.go +++ b/proto/engine/v1/execution_engine.pb.go @@ -78,7 +78,7 @@ func (x PayloadStatus_Status) Number() protoreflect.EnumNumber { // Deprecated: Use PayloadStatus_Status.Descriptor instead. func (PayloadStatus_Status) EnumDescriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{15, 0} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{14, 0} } type ExecutionPayload struct { @@ -232,61 +232,6 @@ func (x *ExecutionPayload) GetTransactions() [][]byte { return nil } -type ExecutionPayloadBodyV1 struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Transactions [][]byte `protobuf:"bytes,1,rep,name=transactions,proto3" json:"transactions,omitempty"` - Withdrawals []*Withdrawal `protobuf:"bytes,2,rep,name=withdrawals,proto3" json:"withdrawals,omitempty"` -} - -func (x *ExecutionPayloadBodyV1) Reset() { - *x = ExecutionPayloadBodyV1{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExecutionPayloadBodyV1) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExecutionPayloadBodyV1) ProtoMessage() {} - -func (x *ExecutionPayloadBodyV1) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ExecutionPayloadBodyV1.ProtoReflect.Descriptor instead. -func (*ExecutionPayloadBodyV1) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{1} -} - -func (x *ExecutionPayloadBodyV1) GetTransactions() [][]byte { - if x != nil { - return x.Transactions - } - return nil -} - -func (x *ExecutionPayloadBodyV1) GetWithdrawals() []*Withdrawal { - if x != nil { - return x.Withdrawals - } - return nil -} - type ExecutionPayloadCapella struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -312,7 +257,7 @@ type ExecutionPayloadCapella struct { func (x *ExecutionPayloadCapella) Reset() { *x = ExecutionPayloadCapella{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[2] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -325,7 +270,7 @@ func (x *ExecutionPayloadCapella) String() string { func (*ExecutionPayloadCapella) ProtoMessage() {} func (x *ExecutionPayloadCapella) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[2] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -338,7 +283,7 @@ func (x *ExecutionPayloadCapella) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecutionPayloadCapella.ProtoReflect.Descriptor instead. func (*ExecutionPayloadCapella) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{2} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{1} } func (x *ExecutionPayloadCapella) GetParentHash() []byte { @@ -473,7 +418,7 @@ type ExecutionPayloadDeneb struct { func (x *ExecutionPayloadDeneb) Reset() { *x = ExecutionPayloadDeneb{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[3] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -486,7 +431,7 @@ func (x *ExecutionPayloadDeneb) String() string { func (*ExecutionPayloadDeneb) ProtoMessage() {} func (x *ExecutionPayloadDeneb) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[3] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -499,7 +444,7 @@ func (x *ExecutionPayloadDeneb) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecutionPayloadDeneb.ProtoReflect.Descriptor instead. func (*ExecutionPayloadDeneb) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{3} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{2} } func (x *ExecutionPayloadDeneb) GetParentHash() []byte { @@ -650,7 +595,7 @@ type ExecutionPayloadElectra struct { func (x *ExecutionPayloadElectra) Reset() { *x = ExecutionPayloadElectra{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[4] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -663,7 +608,7 @@ func (x *ExecutionPayloadElectra) String() string { func (*ExecutionPayloadElectra) ProtoMessage() {} func (x *ExecutionPayloadElectra) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[4] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -676,7 +621,7 @@ func (x *ExecutionPayloadElectra) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecutionPayloadElectra.ProtoReflect.Descriptor instead. func (*ExecutionPayloadElectra) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{4} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{3} } func (x *ExecutionPayloadElectra) GetParentHash() []byte { @@ -826,7 +771,7 @@ type ExecutionPayloadElectraWithValueAndBlobsBundle struct { func (x *ExecutionPayloadElectraWithValueAndBlobsBundle) Reset() { *x = ExecutionPayloadElectraWithValueAndBlobsBundle{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[5] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -839,7 +784,7 @@ func (x *ExecutionPayloadElectraWithValueAndBlobsBundle) String() string { func (*ExecutionPayloadElectraWithValueAndBlobsBundle) ProtoMessage() {} func (x *ExecutionPayloadElectraWithValueAndBlobsBundle) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[5] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -852,7 +797,7 @@ func (x *ExecutionPayloadElectraWithValueAndBlobsBundle) ProtoReflect() protoref // Deprecated: Use ExecutionPayloadElectraWithValueAndBlobsBundle.ProtoReflect.Descriptor instead. func (*ExecutionPayloadElectraWithValueAndBlobsBundle) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{5} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{4} } func (x *ExecutionPayloadElectraWithValueAndBlobsBundle) GetPayload() *ExecutionPayloadElectra { @@ -895,7 +840,7 @@ type ExecutionPayloadCapellaWithValue struct { func (x *ExecutionPayloadCapellaWithValue) Reset() { *x = ExecutionPayloadCapellaWithValue{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[6] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -908,7 +853,7 @@ func (x *ExecutionPayloadCapellaWithValue) String() string { func (*ExecutionPayloadCapellaWithValue) ProtoMessage() {} func (x *ExecutionPayloadCapellaWithValue) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[6] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -921,7 +866,7 @@ func (x *ExecutionPayloadCapellaWithValue) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecutionPayloadCapellaWithValue.ProtoReflect.Descriptor instead. func (*ExecutionPayloadCapellaWithValue) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{6} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{5} } func (x *ExecutionPayloadCapellaWithValue) GetPayload() *ExecutionPayloadCapella { @@ -952,7 +897,7 @@ type ExecutionPayloadDenebWithValueAndBlobsBundle struct { func (x *ExecutionPayloadDenebWithValueAndBlobsBundle) Reset() { *x = ExecutionPayloadDenebWithValueAndBlobsBundle{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[7] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -965,7 +910,7 @@ func (x *ExecutionPayloadDenebWithValueAndBlobsBundle) String() string { func (*ExecutionPayloadDenebWithValueAndBlobsBundle) ProtoMessage() {} func (x *ExecutionPayloadDenebWithValueAndBlobsBundle) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[7] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -978,7 +923,7 @@ func (x *ExecutionPayloadDenebWithValueAndBlobsBundle) ProtoReflect() protorefle // Deprecated: Use ExecutionPayloadDenebWithValueAndBlobsBundle.ProtoReflect.Descriptor instead. func (*ExecutionPayloadDenebWithValueAndBlobsBundle) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{7} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{6} } func (x *ExecutionPayloadDenebWithValueAndBlobsBundle) GetPayload() *ExecutionPayloadDeneb { @@ -1033,7 +978,7 @@ type ExecutionPayloadHeader struct { func (x *ExecutionPayloadHeader) Reset() { *x = ExecutionPayloadHeader{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[8] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1046,7 +991,7 @@ func (x *ExecutionPayloadHeader) String() string { func (*ExecutionPayloadHeader) ProtoMessage() {} func (x *ExecutionPayloadHeader) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[8] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1059,7 +1004,7 @@ func (x *ExecutionPayloadHeader) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecutionPayloadHeader.ProtoReflect.Descriptor instead. func (*ExecutionPayloadHeader) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{8} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{7} } func (x *ExecutionPayloadHeader) GetParentHash() []byte { @@ -1185,7 +1130,7 @@ type ExecutionPayloadHeaderCapella struct { func (x *ExecutionPayloadHeaderCapella) Reset() { *x = ExecutionPayloadHeaderCapella{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[9] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1198,7 +1143,7 @@ func (x *ExecutionPayloadHeaderCapella) String() string { func (*ExecutionPayloadHeaderCapella) ProtoMessage() {} func (x *ExecutionPayloadHeaderCapella) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[9] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1211,7 +1156,7 @@ func (x *ExecutionPayloadHeaderCapella) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecutionPayloadHeaderCapella.ProtoReflect.Descriptor instead. func (*ExecutionPayloadHeaderCapella) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{9} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{8} } func (x *ExecutionPayloadHeaderCapella) GetParentHash() []byte { @@ -1346,7 +1291,7 @@ type ExecutionPayloadHeaderDeneb struct { func (x *ExecutionPayloadHeaderDeneb) Reset() { *x = ExecutionPayloadHeaderDeneb{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[10] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1359,7 +1304,7 @@ func (x *ExecutionPayloadHeaderDeneb) String() string { func (*ExecutionPayloadHeaderDeneb) ProtoMessage() {} func (x *ExecutionPayloadHeaderDeneb) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[10] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1372,7 +1317,7 @@ func (x *ExecutionPayloadHeaderDeneb) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecutionPayloadHeaderDeneb.ProtoReflect.Descriptor instead. func (*ExecutionPayloadHeaderDeneb) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{10} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{9} } func (x *ExecutionPayloadHeaderDeneb) GetParentHash() []byte { @@ -1523,7 +1468,7 @@ type ExecutionPayloadHeaderElectra struct { func (x *ExecutionPayloadHeaderElectra) Reset() { *x = ExecutionPayloadHeaderElectra{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[11] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1536,7 +1481,7 @@ func (x *ExecutionPayloadHeaderElectra) String() string { func (*ExecutionPayloadHeaderElectra) ProtoMessage() {} func (x *ExecutionPayloadHeaderElectra) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[11] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1549,7 +1494,7 @@ func (x *ExecutionPayloadHeaderElectra) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecutionPayloadHeaderElectra.ProtoReflect.Descriptor instead. func (*ExecutionPayloadHeaderElectra) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{11} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{10} } func (x *ExecutionPayloadHeaderElectra) GetParentHash() []byte { @@ -1698,7 +1643,7 @@ type PayloadAttributes struct { func (x *PayloadAttributes) Reset() { *x = PayloadAttributes{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[12] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1711,7 +1656,7 @@ func (x *PayloadAttributes) String() string { func (*PayloadAttributes) ProtoMessage() {} func (x *PayloadAttributes) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[12] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1724,7 +1669,7 @@ func (x *PayloadAttributes) ProtoReflect() protoreflect.Message { // Deprecated: Use PayloadAttributes.ProtoReflect.Descriptor instead. func (*PayloadAttributes) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{12} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{11} } func (x *PayloadAttributes) GetTimestamp() uint64 { @@ -1762,7 +1707,7 @@ type PayloadAttributesV2 struct { func (x *PayloadAttributesV2) Reset() { *x = PayloadAttributesV2{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[13] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1775,7 +1720,7 @@ func (x *PayloadAttributesV2) String() string { func (*PayloadAttributesV2) ProtoMessage() {} func (x *PayloadAttributesV2) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[13] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1788,7 +1733,7 @@ func (x *PayloadAttributesV2) ProtoReflect() protoreflect.Message { // Deprecated: Use PayloadAttributesV2.ProtoReflect.Descriptor instead. func (*PayloadAttributesV2) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{13} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{12} } func (x *PayloadAttributesV2) GetTimestamp() uint64 { @@ -1834,7 +1779,7 @@ type PayloadAttributesV3 struct { func (x *PayloadAttributesV3) Reset() { *x = PayloadAttributesV3{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[14] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1847,7 +1792,7 @@ func (x *PayloadAttributesV3) String() string { func (*PayloadAttributesV3) ProtoMessage() {} func (x *PayloadAttributesV3) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[14] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1860,7 +1805,7 @@ func (x *PayloadAttributesV3) ProtoReflect() protoreflect.Message { // Deprecated: Use PayloadAttributesV3.ProtoReflect.Descriptor instead. func (*PayloadAttributesV3) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{14} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{13} } func (x *PayloadAttributesV3) GetTimestamp() uint64 { @@ -1911,7 +1856,7 @@ type PayloadStatus struct { func (x *PayloadStatus) Reset() { *x = PayloadStatus{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[15] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1924,7 +1869,7 @@ func (x *PayloadStatus) String() string { func (*PayloadStatus) ProtoMessage() {} func (x *PayloadStatus) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[15] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1937,7 +1882,7 @@ func (x *PayloadStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use PayloadStatus.ProtoReflect.Descriptor instead. func (*PayloadStatus) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{15} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{14} } func (x *PayloadStatus) GetStatus() PayloadStatus_Status { @@ -1974,7 +1919,7 @@ type ForkchoiceState struct { func (x *ForkchoiceState) Reset() { *x = ForkchoiceState{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1987,7 +1932,7 @@ func (x *ForkchoiceState) String() string { func (*ForkchoiceState) ProtoMessage() {} func (x *ForkchoiceState) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2000,7 +1945,7 @@ func (x *ForkchoiceState) ProtoReflect() protoreflect.Message { // Deprecated: Use ForkchoiceState.ProtoReflect.Descriptor instead. func (*ForkchoiceState) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{16} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{15} } func (x *ForkchoiceState) GetHeadBlockHash() []byte { @@ -2038,7 +1983,7 @@ type Withdrawal struct { func (x *Withdrawal) Reset() { *x = Withdrawal{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2051,7 +1996,7 @@ func (x *Withdrawal) String() string { func (*Withdrawal) ProtoMessage() {} func (x *Withdrawal) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2064,7 +2009,7 @@ func (x *Withdrawal) ProtoReflect() protoreflect.Message { // Deprecated: Use Withdrawal.ProtoReflect.Descriptor instead. func (*Withdrawal) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{17} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{16} } func (x *Withdrawal) GetIndex() uint64 { @@ -2108,7 +2053,7 @@ type BlobsBundle struct { func (x *BlobsBundle) Reset() { *x = BlobsBundle{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[18] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2121,7 +2066,7 @@ func (x *BlobsBundle) String() string { func (*BlobsBundle) ProtoMessage() {} func (x *BlobsBundle) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[18] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2134,7 +2079,7 @@ func (x *BlobsBundle) ProtoReflect() protoreflect.Message { // Deprecated: Use BlobsBundle.ProtoReflect.Descriptor instead. func (*BlobsBundle) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{18} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{17} } func (x *BlobsBundle) GetKzgCommitments() [][]byte { @@ -2169,7 +2114,7 @@ type Blob struct { func (x *Blob) Reset() { *x = Blob{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[19] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2182,7 +2127,7 @@ func (x *Blob) String() string { func (*Blob) ProtoMessage() {} func (x *Blob) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[19] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2195,7 +2140,7 @@ func (x *Blob) ProtoReflect() protoreflect.Message { // Deprecated: Use Blob.ProtoReflect.Descriptor instead. func (*Blob) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{19} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{18} } func (x *Blob) GetData() []byte { @@ -2216,7 +2161,7 @@ type ExchangeCapabilities struct { func (x *ExchangeCapabilities) Reset() { *x = ExchangeCapabilities{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[20] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2229,7 +2174,7 @@ func (x *ExchangeCapabilities) String() string { func (*ExchangeCapabilities) ProtoMessage() {} func (x *ExchangeCapabilities) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[20] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2242,7 +2187,7 @@ func (x *ExchangeCapabilities) ProtoReflect() protoreflect.Message { // Deprecated: Use ExchangeCapabilities.ProtoReflect.Descriptor instead. func (*ExchangeCapabilities) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{20} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{19} } func (x *ExchangeCapabilities) GetSupportedMethods() []string { @@ -2265,7 +2210,7 @@ type ExecutionLayerWithdrawalRequest struct { func (x *ExecutionLayerWithdrawalRequest) Reset() { *x = ExecutionLayerWithdrawalRequest{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[21] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2278,7 +2223,7 @@ func (x *ExecutionLayerWithdrawalRequest) String() string { func (*ExecutionLayerWithdrawalRequest) ProtoMessage() {} func (x *ExecutionLayerWithdrawalRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[21] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2291,7 +2236,7 @@ func (x *ExecutionLayerWithdrawalRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecutionLayerWithdrawalRequest.ProtoReflect.Descriptor instead. func (*ExecutionLayerWithdrawalRequest) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{21} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{20} } func (x *ExecutionLayerWithdrawalRequest) GetSourceAddress() []byte { @@ -2330,7 +2275,7 @@ type DepositReceipt struct { func (x *DepositReceipt) Reset() { *x = DepositReceipt{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[22] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2343,7 +2288,7 @@ func (x *DepositReceipt) String() string { func (*DepositReceipt) ProtoMessage() {} func (x *DepositReceipt) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[22] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2356,7 +2301,7 @@ func (x *DepositReceipt) ProtoReflect() protoreflect.Message { // Deprecated: Use DepositReceipt.ProtoReflect.Descriptor instead. func (*DepositReceipt) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{22} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{21} } func (x *DepositReceipt) GetPubkey() []byte { @@ -2439,15 +2384,7 @@ var file_proto_engine_v1_execution_engine_proto_rawDesc = []byte{ 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x1d, 0x8a, 0xb5, 0x18, 0x03, 0x3f, 0x2c, 0x3f, 0x92, 0xb5, 0x18, 0x12, 0x31, 0x30, 0x34, 0x38, 0x35, 0x37, 0x36, 0x2c, 0x31, 0x30, 0x37, 0x33, 0x37, 0x34, 0x31, 0x38, 0x32, 0x34, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x7e, 0x0a, 0x16, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, - 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x64, 0x79, 0x56, 0x31, 0x12, 0x22, - 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x40, 0x0a, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, - 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x74, - 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, - 0x77, 0x61, 0x6c, 0x73, 0x22, 0x99, 0x05, 0x0a, 0x17, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x99, 0x05, 0x0a, 0x17, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x61, 0x70, 0x65, 0x6c, 0x6c, 0x61, 0x12, 0x27, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0a, 0x70, @@ -2958,53 +2895,51 @@ func file_proto_engine_v1_execution_engine_proto_rawDescGZIP() []byte { } var file_proto_engine_v1_execution_engine_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_proto_engine_v1_execution_engine_proto_msgTypes = make([]protoimpl.MessageInfo, 23) +var file_proto_engine_v1_execution_engine_proto_msgTypes = make([]protoimpl.MessageInfo, 22) var file_proto_engine_v1_execution_engine_proto_goTypes = []interface{}{ (PayloadStatus_Status)(0), // 0: ethereum.engine.v1.PayloadStatus.Status (*ExecutionPayload)(nil), // 1: ethereum.engine.v1.ExecutionPayload - (*ExecutionPayloadBodyV1)(nil), // 2: ethereum.engine.v1.ExecutionPayloadBodyV1 - (*ExecutionPayloadCapella)(nil), // 3: ethereum.engine.v1.ExecutionPayloadCapella - (*ExecutionPayloadDeneb)(nil), // 4: ethereum.engine.v1.ExecutionPayloadDeneb - (*ExecutionPayloadElectra)(nil), // 5: ethereum.engine.v1.ExecutionPayloadElectra - (*ExecutionPayloadElectraWithValueAndBlobsBundle)(nil), // 6: ethereum.engine.v1.ExecutionPayloadElectraWithValueAndBlobsBundle - (*ExecutionPayloadCapellaWithValue)(nil), // 7: ethereum.engine.v1.ExecutionPayloadCapellaWithValue - (*ExecutionPayloadDenebWithValueAndBlobsBundle)(nil), // 8: ethereum.engine.v1.ExecutionPayloadDenebWithValueAndBlobsBundle - (*ExecutionPayloadHeader)(nil), // 9: ethereum.engine.v1.ExecutionPayloadHeader - (*ExecutionPayloadHeaderCapella)(nil), // 10: ethereum.engine.v1.ExecutionPayloadHeaderCapella - (*ExecutionPayloadHeaderDeneb)(nil), // 11: ethereum.engine.v1.ExecutionPayloadHeaderDeneb - (*ExecutionPayloadHeaderElectra)(nil), // 12: ethereum.engine.v1.ExecutionPayloadHeaderElectra - (*PayloadAttributes)(nil), // 13: ethereum.engine.v1.PayloadAttributes - (*PayloadAttributesV2)(nil), // 14: ethereum.engine.v1.PayloadAttributesV2 - (*PayloadAttributesV3)(nil), // 15: ethereum.engine.v1.PayloadAttributesV3 - (*PayloadStatus)(nil), // 16: ethereum.engine.v1.PayloadStatus - (*ForkchoiceState)(nil), // 17: ethereum.engine.v1.ForkchoiceState - (*Withdrawal)(nil), // 18: ethereum.engine.v1.Withdrawal - (*BlobsBundle)(nil), // 19: ethereum.engine.v1.BlobsBundle - (*Blob)(nil), // 20: ethereum.engine.v1.Blob - (*ExchangeCapabilities)(nil), // 21: ethereum.engine.v1.ExchangeCapabilities - (*ExecutionLayerWithdrawalRequest)(nil), // 22: ethereum.engine.v1.ExecutionLayerWithdrawalRequest - (*DepositReceipt)(nil), // 23: ethereum.engine.v1.DepositReceipt + (*ExecutionPayloadCapella)(nil), // 2: ethereum.engine.v1.ExecutionPayloadCapella + (*ExecutionPayloadDeneb)(nil), // 3: ethereum.engine.v1.ExecutionPayloadDeneb + (*ExecutionPayloadElectra)(nil), // 4: ethereum.engine.v1.ExecutionPayloadElectra + (*ExecutionPayloadElectraWithValueAndBlobsBundle)(nil), // 5: ethereum.engine.v1.ExecutionPayloadElectraWithValueAndBlobsBundle + (*ExecutionPayloadCapellaWithValue)(nil), // 6: ethereum.engine.v1.ExecutionPayloadCapellaWithValue + (*ExecutionPayloadDenebWithValueAndBlobsBundle)(nil), // 7: ethereum.engine.v1.ExecutionPayloadDenebWithValueAndBlobsBundle + (*ExecutionPayloadHeader)(nil), // 8: ethereum.engine.v1.ExecutionPayloadHeader + (*ExecutionPayloadHeaderCapella)(nil), // 9: ethereum.engine.v1.ExecutionPayloadHeaderCapella + (*ExecutionPayloadHeaderDeneb)(nil), // 10: ethereum.engine.v1.ExecutionPayloadHeaderDeneb + (*ExecutionPayloadHeaderElectra)(nil), // 11: ethereum.engine.v1.ExecutionPayloadHeaderElectra + (*PayloadAttributes)(nil), // 12: ethereum.engine.v1.PayloadAttributes + (*PayloadAttributesV2)(nil), // 13: ethereum.engine.v1.PayloadAttributesV2 + (*PayloadAttributesV3)(nil), // 14: ethereum.engine.v1.PayloadAttributesV3 + (*PayloadStatus)(nil), // 15: ethereum.engine.v1.PayloadStatus + (*ForkchoiceState)(nil), // 16: ethereum.engine.v1.ForkchoiceState + (*Withdrawal)(nil), // 17: ethereum.engine.v1.Withdrawal + (*BlobsBundle)(nil), // 18: ethereum.engine.v1.BlobsBundle + (*Blob)(nil), // 19: ethereum.engine.v1.Blob + (*ExchangeCapabilities)(nil), // 20: ethereum.engine.v1.ExchangeCapabilities + (*ExecutionLayerWithdrawalRequest)(nil), // 21: ethereum.engine.v1.ExecutionLayerWithdrawalRequest + (*DepositReceipt)(nil), // 22: ethereum.engine.v1.DepositReceipt } var file_proto_engine_v1_execution_engine_proto_depIdxs = []int32{ - 18, // 0: ethereum.engine.v1.ExecutionPayloadBodyV1.withdrawals:type_name -> ethereum.engine.v1.Withdrawal - 18, // 1: ethereum.engine.v1.ExecutionPayloadCapella.withdrawals:type_name -> ethereum.engine.v1.Withdrawal - 18, // 2: ethereum.engine.v1.ExecutionPayloadDeneb.withdrawals:type_name -> ethereum.engine.v1.Withdrawal - 18, // 3: ethereum.engine.v1.ExecutionPayloadElectra.withdrawals:type_name -> ethereum.engine.v1.Withdrawal - 23, // 4: ethereum.engine.v1.ExecutionPayloadElectra.deposit_receipts:type_name -> ethereum.engine.v1.DepositReceipt - 22, // 5: ethereum.engine.v1.ExecutionPayloadElectra.withdrawal_requests:type_name -> ethereum.engine.v1.ExecutionLayerWithdrawalRequest - 5, // 6: ethereum.engine.v1.ExecutionPayloadElectraWithValueAndBlobsBundle.payload:type_name -> ethereum.engine.v1.ExecutionPayloadElectra - 19, // 7: ethereum.engine.v1.ExecutionPayloadElectraWithValueAndBlobsBundle.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundle - 3, // 8: ethereum.engine.v1.ExecutionPayloadCapellaWithValue.payload:type_name -> ethereum.engine.v1.ExecutionPayloadCapella - 4, // 9: ethereum.engine.v1.ExecutionPayloadDenebWithValueAndBlobsBundle.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb - 19, // 10: ethereum.engine.v1.ExecutionPayloadDenebWithValueAndBlobsBundle.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundle - 18, // 11: ethereum.engine.v1.PayloadAttributesV2.withdrawals:type_name -> ethereum.engine.v1.Withdrawal - 18, // 12: ethereum.engine.v1.PayloadAttributesV3.withdrawals:type_name -> ethereum.engine.v1.Withdrawal - 0, // 13: ethereum.engine.v1.PayloadStatus.status:type_name -> ethereum.engine.v1.PayloadStatus.Status - 14, // [14:14] is the sub-list for method output_type - 14, // [14:14] is the sub-list for method input_type - 14, // [14:14] is the sub-list for extension type_name - 14, // [14:14] is the sub-list for extension extendee - 0, // [0:14] is the sub-list for field type_name + 17, // 0: ethereum.engine.v1.ExecutionPayloadCapella.withdrawals:type_name -> ethereum.engine.v1.Withdrawal + 17, // 1: ethereum.engine.v1.ExecutionPayloadDeneb.withdrawals:type_name -> ethereum.engine.v1.Withdrawal + 17, // 2: ethereum.engine.v1.ExecutionPayloadElectra.withdrawals:type_name -> ethereum.engine.v1.Withdrawal + 22, // 3: ethereum.engine.v1.ExecutionPayloadElectra.deposit_receipts:type_name -> ethereum.engine.v1.DepositReceipt + 21, // 4: ethereum.engine.v1.ExecutionPayloadElectra.withdrawal_requests:type_name -> ethereum.engine.v1.ExecutionLayerWithdrawalRequest + 4, // 5: ethereum.engine.v1.ExecutionPayloadElectraWithValueAndBlobsBundle.payload:type_name -> ethereum.engine.v1.ExecutionPayloadElectra + 18, // 6: ethereum.engine.v1.ExecutionPayloadElectraWithValueAndBlobsBundle.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundle + 2, // 7: ethereum.engine.v1.ExecutionPayloadCapellaWithValue.payload:type_name -> ethereum.engine.v1.ExecutionPayloadCapella + 3, // 8: ethereum.engine.v1.ExecutionPayloadDenebWithValueAndBlobsBundle.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb + 18, // 9: ethereum.engine.v1.ExecutionPayloadDenebWithValueAndBlobsBundle.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundle + 17, // 10: ethereum.engine.v1.PayloadAttributesV2.withdrawals:type_name -> ethereum.engine.v1.Withdrawal + 17, // 11: ethereum.engine.v1.PayloadAttributesV3.withdrawals:type_name -> ethereum.engine.v1.Withdrawal + 0, // 12: ethereum.engine.v1.PayloadStatus.status:type_name -> ethereum.engine.v1.PayloadStatus.Status + 13, // [13:13] is the sub-list for method output_type + 13, // [13:13] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name } func init() { file_proto_engine_v1_execution_engine_proto_init() } @@ -3026,18 +2961,6 @@ func file_proto_engine_v1_execution_engine_proto_init() { } } file_proto_engine_v1_execution_engine_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExecutionPayloadBodyV1); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_engine_v1_execution_engine_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExecutionPayloadCapella); i { case 0: return &v.state @@ -3049,7 +2972,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExecutionPayloadDeneb); i { case 0: return &v.state @@ -3061,7 +2984,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExecutionPayloadElectra); i { case 0: return &v.state @@ -3073,7 +2996,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExecutionPayloadElectraWithValueAndBlobsBundle); i { case 0: return &v.state @@ -3085,7 +3008,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExecutionPayloadCapellaWithValue); i { case 0: return &v.state @@ -3097,7 +3020,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExecutionPayloadDenebWithValueAndBlobsBundle); i { case 0: return &v.state @@ -3109,7 +3032,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExecutionPayloadHeader); i { case 0: return &v.state @@ -3121,7 +3044,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExecutionPayloadHeaderCapella); i { case 0: return &v.state @@ -3133,7 +3056,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExecutionPayloadHeaderDeneb); i { case 0: return &v.state @@ -3145,7 +3068,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExecutionPayloadHeaderElectra); i { case 0: return &v.state @@ -3157,7 +3080,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PayloadAttributes); i { case 0: return &v.state @@ -3169,7 +3092,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PayloadAttributesV2); i { case 0: return &v.state @@ -3181,7 +3104,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PayloadAttributesV3); i { case 0: return &v.state @@ -3193,7 +3116,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PayloadStatus); i { case 0: return &v.state @@ -3205,7 +3128,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ForkchoiceState); i { case 0: return &v.state @@ -3217,7 +3140,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Withdrawal); i { case 0: return &v.state @@ -3229,7 +3152,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BlobsBundle); i { case 0: return &v.state @@ -3241,7 +3164,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Blob); i { case 0: return &v.state @@ -3253,7 +3176,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExchangeCapabilities); i { case 0: return &v.state @@ -3265,7 +3188,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExecutionLayerWithdrawalRequest); i { case 0: return &v.state @@ -3277,7 +3200,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { return nil } } - file_proto_engine_v1_execution_engine_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + file_proto_engine_v1_execution_engine_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DepositReceipt); i { case 0: return &v.state @@ -3296,7 +3219,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_engine_v1_execution_engine_proto_rawDesc, NumEnums: 1, - NumMessages: 23, + NumMessages: 22, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/engine/v1/execution_engine.proto b/proto/engine/v1/execution_engine.proto index 6085c05c9b44..a6686a326495 100644 --- a/proto/engine/v1/execution_engine.proto +++ b/proto/engine/v1/execution_engine.proto @@ -41,11 +41,6 @@ message ExecutionPayload { repeated bytes transactions = 14 [(ethereum.eth.ext.ssz_size) = "?,?", (ethereum.eth.ext.ssz_max) = "1048576,1073741824"]; } -message ExecutionPayloadBodyV1 { - repeated bytes transactions = 1; - repeated Withdrawal withdrawals = 2; -} - message ExecutionPayloadCapella { bytes parent_hash = 1 [(ethereum.eth.ext.ssz_size) = "32"]; bytes fee_recipient = 2 [(ethereum.eth.ext.ssz_size) = "20"]; diff --git a/proto/engine/v1/generated.ssz.go b/proto/engine/v1/generated.ssz.go index 9022df00bdf5..05d41cc36251 100644 --- a/proto/engine/v1/generated.ssz.go +++ b/proto/engine/v1/generated.ssz.go @@ -1,5 +1,5 @@ // Code generated by fastssz. DO NOT EDIT. -// Hash: 88fdbdfda4571603e11174a57e65c25e06780ff2cbd795c8ae2a4709da24d9a9 +// Hash: 5e73dfd1d7df4fb984d773b9aa92658a1bc4db66b0e050f9b869a470e61416d3 package enginev1 import ( diff --git a/proto/engine/v1/json_marshal_unmarshal.go b/proto/engine/v1/json_marshal_unmarshal.go index f6c7d78d013b..cbaac71f2be6 100644 --- a/proto/engine/v1/json_marshal_unmarshal.go +++ b/proto/engine/v1/json_marshal_unmarshal.go @@ -21,6 +21,8 @@ const ( BlsSignLen = 96 ) +var errJsonNilField = errors.New("nil field in JSON value") + // BlsPubkey represents a 48 byte BLS public key. type BlsPubkey [BlsPubKeyLen]byte @@ -325,6 +327,14 @@ type ExecutionPayloadElectraJSON struct { DepositRequests []DepositRequestV1 `json:"depositRequests"` } +// ExecutionPayloadBody represents the engine API ExecutionPayloadV1 or ExecutionPayloadV2 type. +type ExecutionPayloadBody struct { + Transactions []hexutil.Bytes `json:"transactions"` + Withdrawals []*Withdrawal `json:"withdrawals"` + WithdrawalRequests []WithdrawalRequestV1 `json:"withdrawalRequests"` + DepositRequests []DepositRequestV1 `json:"depositRequests"` +} + // Validate returns an error if key fields in GetPayloadV4ResponseJson are nil or invalid. func (j *GetPayloadV4ResponseJson) Validate() error { if j.ExecutionPayload == nil { @@ -411,6 +421,19 @@ type WithdrawalRequestV1 struct { Amount *hexutil.Uint64 `json:"amount"` } +func (r WithdrawalRequestV1) Validate() error { + if r.SourceAddress == nil { + return errors.Wrap(errJsonNilField, "missing required field 'sourceAddress' for WithdrawalRequestV1") + } + if r.ValidatorPubkey == nil { + return errors.Wrap(errJsonNilField, "missing required field 'validatorPublicKey' for WithdrawalRequestV1") + } + if r.Amount == nil { + return errors.Wrap(errJsonNilField, "missing required field 'amount' for WithdrawalRequestV1") + } + return nil +} + // DepositRequestV1 represents an execution engine DepositRequestV1 value // https://github.com/ethereum/execution-apis/blob/main/src/engine/prague.md#depositrequestv1 type DepositRequestV1 struct { @@ -426,6 +449,25 @@ type DepositRequestV1 struct { Index *hexutil.Uint64 `json:"index"` } +func (r DepositRequestV1) Validate() error { + if r.PubKey == nil { + return errors.Wrap(errJsonNilField, "missing required field 'pubkey' for DepositRequestV1") + } + if r.WithdrawalCredentials == nil { + return errors.Wrap(errJsonNilField, "missing required field 'withdrawalCredentials' for DepositRequestV1") + } + if r.Amount == nil { + return errors.Wrap(errJsonNilField, "missing required field 'amount' for DepositRequestV1") + } + if r.Signature == nil { + return errors.Wrap(errJsonNilField, "missing required field 'signature' for DepositRequestV1") + } + if r.Index == nil { + return errors.Wrap(errJsonNilField, "missing required field 'index' for DepositRequestV1") + } + return nil +} + // MarshalJSON -- func (e *ExecutionPayload) MarshalJSON() ([]byte, error) { transactions := make([]hexutil.Bytes, len(e.Transactions)) @@ -941,17 +983,20 @@ func (e *ExecutionPayloadElectra) MarshalJSON() ([]byte, error) { Withdrawals: withdrawals, BlobGasUsed: &blobGasUsed, ExcessBlobGas: &excessBlobGas, - WithdrawalRequests: WithdrawalRequestProtoToJson(e.WithdrawalRequests), - DepositRequests: DepositRequestProtoToJson(e.DepositReceipts), + WithdrawalRequests: ProtoWithdrawalRequestsToJson(e.WithdrawalRequests), + DepositRequests: ProtoDepositRequestsToJson(e.DepositReceipts), }) } -func (j *ExecutionPayloadElectraJSON) ElectraDepositReceipts() []*DepositReceipt { - rcpt := make([]*DepositReceipt, len(j.DepositRequests)) +func JsonDepositRequestsToProto(j []DepositRequestV1) ([]*DepositReceipt, error) { + reqs := make([]*DepositReceipt, len(j)) - for i := range j.DepositRequests { - req := j.DepositRequests[i] - rcpt[i] = &DepositReceipt{ + for i := range j { + req := j[i] + if err := req.Validate(); err != nil { + return nil, err + } + reqs[i] = &DepositReceipt{ Pubkey: req.PubKey.Bytes(), WithdrawalCredentials: req.WithdrawalCredentials.Bytes(), Amount: uint64(*req.Amount), @@ -960,10 +1005,10 @@ func (j *ExecutionPayloadElectraJSON) ElectraDepositReceipts() []*DepositReceipt } } - return rcpt + return reqs, nil } -func DepositRequestProtoToJson(reqs []*DepositReceipt) []DepositRequestV1 { +func ProtoDepositRequestsToJson(reqs []*DepositReceipt) []DepositRequestV1 { j := make([]DepositRequestV1, len(reqs)) for i := range reqs { r := reqs[i] @@ -985,11 +1030,14 @@ func DepositRequestProtoToJson(reqs []*DepositReceipt) []DepositRequestV1 { return j } -func (j *ExecutionPayloadElectraJSON) ElectraExecutionLayerWithdrawalRequests() []*ExecutionLayerWithdrawalRequest { - reqs := make([]*ExecutionLayerWithdrawalRequest, len(j.WithdrawalRequests)) +func JsonWithdrawalRequestsToProto(j []WithdrawalRequestV1) ([]*ExecutionLayerWithdrawalRequest, error) { + reqs := make([]*ExecutionLayerWithdrawalRequest, len(j)) - for i := range j.WithdrawalRequests { - req := j.WithdrawalRequests[i] + for i := range j { + req := j[i] + if err := req.Validate(); err != nil { + return nil, err + } reqs[i] = &ExecutionLayerWithdrawalRequest{ SourceAddress: req.SourceAddress.Bytes(), ValidatorPubkey: req.ValidatorPubkey.Bytes(), @@ -997,10 +1045,10 @@ func (j *ExecutionPayloadElectraJSON) ElectraExecutionLayerWithdrawalRequests() } } - return reqs + return reqs, nil } -func WithdrawalRequestProtoToJson(reqs []*ExecutionLayerWithdrawalRequest) []WithdrawalRequestV1 { +func ProtoWithdrawalRequestsToJson(reqs []*ExecutionLayerWithdrawalRequest) []WithdrawalRequestV1 { j := make([]WithdrawalRequestV1, len(reqs)) for i := range reqs { r := reqs[i] @@ -1031,6 +1079,14 @@ func (j *ExecutionPayloadElectraJSON) ElectraPayload() (*ExecutionPayloadElectra if j.Withdrawals == nil { j.Withdrawals = make([]*Withdrawal, 0) } + dr, err := JsonDepositRequestsToProto(j.DepositRequests) + if err != nil { + return nil, err + } + wr, err := JsonWithdrawalRequestsToProto(j.WithdrawalRequests) + if err != nil { + return nil, err + } return &ExecutionPayloadElectra{ ParentHash: j.ParentHash.Bytes(), FeeRecipient: j.FeeRecipient.Bytes(), @@ -1049,8 +1105,8 @@ func (j *ExecutionPayloadElectraJSON) ElectraPayload() (*ExecutionPayloadElectra Withdrawals: j.Withdrawals, BlobGasUsed: uint64(*j.BlobGasUsed), ExcessBlobGas: uint64(*j.ExcessBlobGas), - DepositReceipts: j.ElectraDepositReceipts(), - WithdrawalRequests: j.ElectraExecutionLayerWithdrawalRequests(), + DepositReceipts: dr, + WithdrawalRequests: wr, }, nil } @@ -1232,42 +1288,11 @@ func (e *ExecutionPayloadDenebWithValueAndBlobsBundle) UnmarshalJSON(enc []byte) return nil } -type executionPayloadBodyV1JSON struct { - Transactions []hexutil.Bytes `json:"transactions"` - Withdrawals []*Withdrawal `json:"withdrawals"` -} - -func (b *ExecutionPayloadBodyV1) MarshalJSON() ([]byte, error) { - transactions := make([]hexutil.Bytes, len(b.Transactions)) - for i, tx := range b.Transactions { - transactions[i] = tx - } - if len(b.Withdrawals) == 0 { - b.Withdrawals = make([]*Withdrawal, 0) - } - return json.Marshal(executionPayloadBodyV1JSON{ - Transactions: transactions, - Withdrawals: b.Withdrawals, - }) -} - -func (b *ExecutionPayloadBodyV1) UnmarshalJSON(enc []byte) error { - var decoded *executionPayloadBodyV1JSON - err := json.Unmarshal(enc, &decoded) - if err != nil { - return err +// RecastHexutilByteSlice converts a []hexutil.Bytes to a [][]byte +func RecastHexutilByteSlice(h []hexutil.Bytes) [][]byte { + r := make([][]byte, len(h)) + for i := range h { + r[i] = h[i] } - if len(decoded.Transactions) == 0 { - b.Transactions = make([][]byte, 0) - } - if len(decoded.Withdrawals) == 0 { - b.Withdrawals = make([]*Withdrawal, 0) - } - transactions := make([][]byte, len(decoded.Transactions)) - for i, tx := range decoded.Transactions { - transactions[i] = tx - } - b.Transactions = transactions - b.Withdrawals = decoded.Withdrawals - return nil + return r } diff --git a/proto/engine/v1/json_marshal_unmarshal_test.go b/proto/engine/v1/json_marshal_unmarshal_test.go index b2dfbddc6a66..7aed00f1b7a9 100644 --- a/proto/engine/v1/json_marshal_unmarshal_test.go +++ b/proto/engine/v1/json_marshal_unmarshal_test.go @@ -360,8 +360,8 @@ func TestJsonMarshalUnmarshal(t *testing.T) { }}, BlobGasUsed: &bgu, ExcessBlobGas: &ebg, - WithdrawalRequests: enginev1.WithdrawalRequestProtoToJson(withdrawalReq), - DepositRequests: enginev1.DepositRequestProtoToJson(depositReq), + WithdrawalRequests: enginev1.ProtoWithdrawalRequestsToJson(withdrawalReq), + DepositRequests: enginev1.ProtoDepositRequestsToJson(depositReq), }, } enc, err := json.Marshal(resp) @@ -763,8 +763,8 @@ func TestPayloadIDBytes_MarshalUnmarshalJSON(t *testing.T) { } func TestExecutionPayloadBody_MarshalUnmarshalJSON(t *testing.T) { - pBody := &enginev1.ExecutionPayloadBodyV1{ - Transactions: [][]byte{[]byte("random1"), []byte("random2"), []byte("random3")}, + pBody := &enginev1.ExecutionPayloadBody{ + Transactions: []hexutil.Bytes{[]byte("random1"), []byte("random2"), []byte("random3")}, Withdrawals: []*enginev1.Withdrawal{ { Index: 200, @@ -782,8 +782,8 @@ func TestExecutionPayloadBody_MarshalUnmarshalJSON(t *testing.T) { } enc, err := json.Marshal(pBody) require.NoError(t, err) - res := &enginev1.ExecutionPayloadBodyV1{} - err = res.UnmarshalJSON(enc) + res := &enginev1.ExecutionPayloadBody{} + err = json.Unmarshal(enc, res) require.NoError(t, err) require.DeepEqual(t, pBody, res) } diff --git a/proto/eth/v1/generated.ssz.go b/proto/eth/v1/generated.ssz.go index d6f69e0a83a6..01daabe6c0ab 100644 --- a/proto/eth/v1/generated.ssz.go +++ b/proto/eth/v1/generated.ssz.go @@ -1,5 +1,5 @@ // Code generated by fastssz. DO NOT EDIT. -// Hash: 6fed60156f1e57926b40b972ee25b48a82b18726a9c64fb0e974e4f638784049 +// Hash: 2874e1dadeb47411763f48fe31e5daaa91ac663e796933d9a508c2e7be94fa5e package v1 import ( diff --git a/proto/eth/v2/generated.ssz.go b/proto/eth/v2/generated.ssz.go index 2674eea802fb..29dcf6d09da2 100644 --- a/proto/eth/v2/generated.ssz.go +++ b/proto/eth/v2/generated.ssz.go @@ -1,5 +1,5 @@ // Code generated by fastssz. DO NOT EDIT. -// Hash: 36d05ceafa355d5aa87123eb218143987a79f5095e2cafbad7760712ad0934a3 +// Hash: 2755944d1f9b0e6e8b7e58d3cbba1d6028bbbb740ec05f5de43137d5b5459411 package eth import ( diff --git a/proto/prysm/v1alpha1/beacon_state.pb.go b/proto/prysm/v1alpha1/beacon_state.pb.go index aac6093e1d11..8a01977e8ee7 100755 --- a/proto/prysm/v1alpha1/beacon_state.pb.go +++ b/proto/prysm/v1alpha1/beacon_state.pb.go @@ -12,7 +12,6 @@ import ( github_com_prysmaticlabs_go_bitfield "github.com/prysmaticlabs/go-bitfield" github_com_prysmaticlabs_prysm_v5_consensus_types_primitives "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - github_com_prysmaticlabs_prysm_v5_math "github.com/prysmaticlabs/prysm/v5/math" v1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" _ "github.com/prysmaticlabs/prysm/v5/proto/eth/ext" protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -1869,10 +1868,10 @@ type BeaconStateElectra struct { NextWithdrawalValidatorIndex github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.ValidatorIndex `protobuf:"varint,11002,opt,name=next_withdrawal_validator_index,json=nextWithdrawalValidatorIndex,proto3" json:"next_withdrawal_validator_index,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.ValidatorIndex"` HistoricalSummaries []*HistoricalSummary `protobuf:"bytes,11003,rep,name=historical_summaries,json=historicalSummaries,proto3" json:"historical_summaries,omitempty" ssz-max:"16777216"` DepositReceiptsStartIndex uint64 `protobuf:"varint,12001,opt,name=deposit_receipts_start_index,json=depositReceiptsStartIndex,proto3" json:"deposit_receipts_start_index,omitempty"` - DepositBalanceToConsume github_com_prysmaticlabs_prysm_v5_math.Gwei `protobuf:"varint,12002,opt,name=deposit_balance_to_consume,json=depositBalanceToConsume,proto3" json:"deposit_balance_to_consume,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/math.Gwei"` - ExitBalanceToConsume github_com_prysmaticlabs_prysm_v5_math.Gwei `protobuf:"varint,12003,opt,name=exit_balance_to_consume,json=exitBalanceToConsume,proto3" json:"exit_balance_to_consume,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/math.Gwei"` + DepositBalanceToConsume github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Gwei `protobuf:"varint,12002,opt,name=deposit_balance_to_consume,json=depositBalanceToConsume,proto3" json:"deposit_balance_to_consume,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Gwei"` + ExitBalanceToConsume github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Gwei `protobuf:"varint,12003,opt,name=exit_balance_to_consume,json=exitBalanceToConsume,proto3" json:"exit_balance_to_consume,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Gwei"` EarliestExitEpoch github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Epoch `protobuf:"varint,12004,opt,name=earliest_exit_epoch,json=earliestExitEpoch,proto3" json:"earliest_exit_epoch,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Epoch"` - ConsolidationBalanceToConsume github_com_prysmaticlabs_prysm_v5_math.Gwei `protobuf:"varint,12005,opt,name=consolidation_balance_to_consume,json=consolidationBalanceToConsume,proto3" json:"consolidation_balance_to_consume,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/math.Gwei"` + ConsolidationBalanceToConsume github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Gwei `protobuf:"varint,12005,opt,name=consolidation_balance_to_consume,json=consolidationBalanceToConsume,proto3" json:"consolidation_balance_to_consume,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Gwei"` EarliestConsolidationEpoch github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Epoch `protobuf:"varint,12006,opt,name=earliest_consolidation_epoch,json=earliestConsolidationEpoch,proto3" json:"earliest_consolidation_epoch,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Epoch"` PendingBalanceDeposits []*PendingBalanceDeposit `protobuf:"bytes,12007,rep,name=pending_balance_deposits,json=pendingBalanceDeposits,proto3" json:"pending_balance_deposits,omitempty" ssz-max:"134217728"` PendingPartialWithdrawals []*PendingPartialWithdrawal `protobuf:"bytes,12008,rep,name=pending_partial_withdrawals,json=pendingPartialWithdrawals,proto3" json:"pending_partial_withdrawals,omitempty" ssz-max:"134217728"` @@ -2114,18 +2113,18 @@ func (x *BeaconStateElectra) GetDepositReceiptsStartIndex() uint64 { return 0 } -func (x *BeaconStateElectra) GetDepositBalanceToConsume() github_com_prysmaticlabs_prysm_v5_math.Gwei { +func (x *BeaconStateElectra) GetDepositBalanceToConsume() github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Gwei { if x != nil { return x.DepositBalanceToConsume } - return github_com_prysmaticlabs_prysm_v5_math.Gwei(0) + return github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Gwei(0) } -func (x *BeaconStateElectra) GetExitBalanceToConsume() github_com_prysmaticlabs_prysm_v5_math.Gwei { +func (x *BeaconStateElectra) GetExitBalanceToConsume() github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Gwei { if x != nil { return x.ExitBalanceToConsume } - return github_com_prysmaticlabs_prysm_v5_math.Gwei(0) + return github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Gwei(0) } func (x *BeaconStateElectra) GetEarliestExitEpoch() github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Epoch { @@ -2135,11 +2134,11 @@ func (x *BeaconStateElectra) GetEarliestExitEpoch() github_com_prysmaticlabs_pry return github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Epoch(0) } -func (x *BeaconStateElectra) GetConsolidationBalanceToConsume() github_com_prysmaticlabs_prysm_v5_math.Gwei { +func (x *BeaconStateElectra) GetConsolidationBalanceToConsume() github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Gwei { if x != nil { return x.ConsolidationBalanceToConsume } - return github_com_prysmaticlabs_prysm_v5_math.Gwei(0) + return github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Gwei(0) } func (x *BeaconStateElectra) GetEarliestConsolidationEpoch() github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Epoch { @@ -3011,7 +3010,7 @@ var file_proto_prysm_v1alpha1_beacon_state_proto_rawDesc = []byte{ 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x42, 0x0c, 0x92, 0xb5, 0x18, 0x08, 0x31, 0x36, 0x37, 0x37, 0x37, 0x32, 0x31, 0x36, 0x52, 0x13, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x69, 0x65, 0x73, 0x22, 0x8d, 0x19, 0x0a, 0x12, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x53, + 0x72, 0x69, 0x65, 0x73, 0x22, 0xd1, 0x19, 0x0a, 0x12, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x12, 0x22, 0x0a, 0x0c, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0xe9, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x12, @@ -3152,94 +3151,98 @@ var file_proto_prysm_v1alpha1_beacon_state_proto_rawDesc = []byte{ 0x69, 0x70, 0x74, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0xe1, 0x5d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x19, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x53, 0x74, 0x61, 0x72, 0x74, 0x49, 0x6e, 0x64, - 0x65, 0x78, 0x12, 0x6d, 0x0a, 0x1a, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x62, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, - 0x18, 0xe2, 0x5d, 0x20, 0x01, 0x28, 0x04, 0x42, 0x2f, 0x82, 0xb5, 0x18, 0x2b, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, - 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x6d, - 0x61, 0x74, 0x68, 0x2e, 0x47, 0x77, 0x65, 0x69, 0x52, 0x17, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, - 0x65, 0x12, 0x67, 0x0a, 0x17, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x18, 0xe3, 0x5d, 0x20, - 0x01, 0x28, 0x04, 0x42, 0x2f, 0x82, 0xb5, 0x18, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, - 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, - 0x47, 0x77, 0x65, 0x69, 0x52, 0x14, 0x65, 0x78, 0x69, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x65, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x12, 0x77, 0x0a, 0x13, 0x65, 0x61, - 0x72, 0x6c, 0x69, 0x65, 0x73, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x65, 0x70, 0x6f, 0x63, - 0x68, 0x18, 0xe4, 0x5d, 0x20, 0x01, 0x28, 0x04, 0x42, 0x46, 0x82, 0xb5, 0x18, 0x42, 0x67, 0x69, + 0x65, 0x78, 0x12, 0x83, 0x01, 0x0a, 0x1a, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, + 0x65, 0x18, 0xe2, 0x5d, 0x20, 0x01, 0x28, 0x04, 0x42, 0x45, 0x82, 0xb5, 0x18, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, - 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x45, 0x70, 0x6f, 0x63, 0x68, - 0x52, 0x11, 0x65, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x73, 0x74, 0x45, 0x78, 0x69, 0x74, 0x45, 0x70, - 0x6f, 0x63, 0x68, 0x12, 0x79, 0x0a, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x6f, 0x5f, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x18, 0xe5, 0x5d, 0x20, 0x01, 0x28, 0x04, 0x42, 0x2f, - 0x82, 0xb5, 0x18, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, - 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, - 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x47, 0x77, 0x65, 0x69, 0x52, - 0x1d, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x12, 0x89, - 0x01, 0x0a, 0x1c, 0x65, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x73, - 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, - 0xe6, 0x5d, 0x20, 0x01, 0x28, 0x04, 0x42, 0x46, 0x82, 0xb5, 0x18, 0x42, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, - 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x63, 0x6f, - 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, - 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x1a, - 0x65, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x76, 0x0a, 0x18, 0x70, 0x65, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x64, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x18, 0xe7, 0x5d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, - 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x42, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x42, 0x0d, 0x92, 0xb5, 0x18, - 0x09, 0x31, 0x33, 0x34, 0x32, 0x31, 0x37, 0x37, 0x32, 0x38, 0x52, 0x16, 0x70, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x73, 0x12, 0x7f, 0x0a, 0x1b, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x61, - 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, - 0x73, 0x18, 0xe8, 0x5d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, + 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x47, 0x77, 0x65, 0x69, 0x52, + 0x17, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x54, + 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x12, 0x7d, 0x0a, 0x17, 0x65, 0x78, 0x69, 0x74, + 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6e, 0x73, + 0x75, 0x6d, 0x65, 0x18, 0xe3, 0x5d, 0x20, 0x01, 0x28, 0x04, 0x42, 0x45, 0x82, 0xb5, 0x18, 0x41, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, + 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, + 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x47, 0x77, 0x65, + 0x69, 0x52, 0x14, 0x65, 0x78, 0x69, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x6f, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x12, 0x77, 0x0a, 0x13, 0x65, 0x61, 0x72, 0x6c, 0x69, + 0x65, 0x73, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0xe4, + 0x5d, 0x20, 0x01, 0x28, 0x04, 0x42, 0x46, 0x82, 0xb5, 0x18, 0x42, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, + 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x63, 0x6f, 0x6e, + 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, + 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x11, 0x65, + 0x61, 0x72, 0x6c, 0x69, 0x65, 0x73, 0x74, 0x45, 0x78, 0x69, 0x74, 0x45, 0x70, 0x6f, 0x63, 0x68, + 0x12, 0x8f, 0x01, 0x0a, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x18, 0xe5, 0x5d, 0x20, 0x01, 0x28, 0x04, 0x42, 0x45, 0x82, 0xb5, + 0x18, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, + 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, + 0x2f, 0x76, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x47, + 0x77, 0x65, 0x69, 0x52, 0x1d, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, + 0x6d, 0x65, 0x12, 0x89, 0x01, 0x0a, 0x1c, 0x65, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x73, 0x74, 0x5f, + 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x70, + 0x6f, 0x63, 0x68, 0x18, 0xe6, 0x5d, 0x20, 0x01, 0x28, 0x04, 0x42, 0x46, 0x82, 0xb5, 0x18, 0x42, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, + 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, + 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x45, 0x70, 0x6f, + 0x63, 0x68, 0x52, 0x1a, 0x65, 0x61, 0x72, 0x6c, 0x69, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x73, + 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x76, + 0x0a, 0x18, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x18, 0xe7, 0x5d, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x42, + 0x0d, 0x92, 0xb5, 0x18, 0x09, 0x31, 0x33, 0x34, 0x32, 0x31, 0x37, 0x37, 0x32, 0x38, 0x52, 0x16, + 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x12, 0x7f, 0x0a, 0x1b, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, + 0x61, 0x77, 0x61, 0x6c, 0x73, 0x18, 0xe8, 0x5d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x65, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x72, 0x74, + 0x69, 0x61, 0x6c, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x42, 0x0d, 0x92, + 0xb5, 0x18, 0x09, 0x31, 0x33, 0x34, 0x32, 0x31, 0x37, 0x37, 0x32, 0x38, 0x52, 0x19, 0x70, 0x65, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x57, 0x69, 0x74, 0x68, + 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x73, 0x12, 0x6f, 0x0a, 0x16, 0x70, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0xe9, 0x5d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x57, - 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x42, 0x0d, 0x92, 0xb5, 0x18, 0x09, 0x31, - 0x33, 0x34, 0x32, 0x31, 0x37, 0x37, 0x32, 0x38, 0x52, 0x19, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, - 0x61, 0x6c, 0x73, 0x12, 0x6f, 0x0a, 0x16, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, - 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xe9, 0x5d, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, - 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x65, 0x6e, - 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x42, 0x0a, 0x92, 0xb5, 0x18, 0x06, 0x32, 0x36, 0x32, 0x31, 0x34, 0x34, 0x52, 0x15, 0x70, - 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x8d, 0x01, 0x0a, 0x08, 0x50, 0x6f, 0x77, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x12, 0x25, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x09, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x27, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, - 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, - 0x68, 0x12, 0x31, 0x0a, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x69, - 0x63, 0x75, 0x6c, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, - 0x02, 0x33, 0x32, 0x52, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x69, 0x66, 0x66, 0x69, 0x63, - 0x75, 0x6c, 0x74, 0x79, 0x22, 0x7f, 0x0a, 0x11, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, - 0x61, 0x6c, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x34, 0x0a, 0x12, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x10, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x6f, 0x6f, 0x74, 0x12, - 0x34, 0x0a, 0x12, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, - 0x02, 0x33, 0x32, 0x52, 0x10, 0x73, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, - 0x79, 0x52, 0x6f, 0x6f, 0x74, 0x42, 0x9b, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, - 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x42, 0x10, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, - 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, - 0x65, 0x74, 0x68, 0xaa, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, - 0x74, 0x68, 0x2e, 0x56, 0x31, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, - 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0a, 0x92, 0xb5, 0x18, 0x06, 0x32, 0x36, 0x32, 0x31, 0x34, + 0x34, 0x52, 0x15, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x8d, 0x01, 0x0a, 0x08, 0x50, 0x6f, 0x77, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x25, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, + 0x32, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x27, 0x0a, 0x0b, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x31, 0x0a, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, + 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, + 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x69, + 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x22, 0x7f, 0x0a, 0x11, 0x48, 0x69, 0x73, 0x74, + 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x34, 0x0a, + 0x12, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x72, + 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, + 0x32, 0x52, 0x10, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, + 0x6f, 0x6f, 0x74, 0x12, 0x34, 0x0a, 0x12, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, + 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x10, 0x73, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x6f, 0x6f, 0x74, 0x42, 0x9b, 0x01, 0x0a, 0x19, 0x6f, 0x72, + 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x10, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, + 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x56, 0x31, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, + 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/prysm/v1alpha1/beacon_state.proto b/proto/prysm/v1alpha1/beacon_state.proto index f4bc57e2ce1d..dd38eebd201a 100644 --- a/proto/prysm/v1alpha1/beacon_state.proto +++ b/proto/prysm/v1alpha1/beacon_state.proto @@ -397,10 +397,10 @@ message BeaconStateElectra { // Fields introduced in EIP-7251 fork [12001-13000] uint64 deposit_receipts_start_index = 12001; - uint64 deposit_balance_to_consume = 12002 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/math.Gwei"]; - uint64 exit_balance_to_consume = 12003 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/math.Gwei"]; + uint64 deposit_balance_to_consume = 12002 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Gwei"]; + uint64 exit_balance_to_consume = 12003 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Gwei"]; uint64 earliest_exit_epoch = 12004 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Epoch"]; - uint64 consolidation_balance_to_consume = 12005 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/math.Gwei"]; + uint64 consolidation_balance_to_consume = 12005 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Gwei"]; uint64 earliest_consolidation_epoch = 12006 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Epoch"]; repeated PendingBalanceDeposit pending_balance_deposits = 12007 [(ethereum.eth.ext.ssz_max) = "pending_balance_deposits_limit"]; repeated PendingPartialWithdrawal pending_partial_withdrawals = 12008 [(ethereum.eth.ext.ssz_max) = "pending_partial_withdrawals_limit"]; diff --git a/proto/prysm/v1alpha1/generated.ssz.go b/proto/prysm/v1alpha1/generated.ssz.go index d95f6eb989f2..50b0fb52dc8a 100644 --- a/proto/prysm/v1alpha1/generated.ssz.go +++ b/proto/prysm/v1alpha1/generated.ssz.go @@ -1,11 +1,10 @@ // Code generated by fastssz. DO NOT EDIT. -// Hash: 4e7c07afe12b97ee034415333c33967cab8cf624f3fd43f37562cd6307760ec3 +// Hash: 75d48d13b4efa7867468bae2df70b80e9606b9a44e621915d2093a4f20ae111f package eth import ( ssz "github.com/prysmaticlabs/fastssz" github_com_prysmaticlabs_prysm_v5_consensus_types_primitives "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - github_com_prysmaticlabs_prysm_v5_math "github.com/prysmaticlabs/prysm/v5/math" v1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" ) @@ -17980,16 +17979,16 @@ func (b *BeaconStateElectra) UnmarshalSSZ(buf []byte) error { b.DepositReceiptsStartIndex = ssz.UnmarshallUint64(buf[2736653:2736661]) // Field (29) 'DepositBalanceToConsume' - b.DepositBalanceToConsume = github_com_prysmaticlabs_prysm_v5_math.Gwei(ssz.UnmarshallUint64(buf[2736661:2736669])) + b.DepositBalanceToConsume = github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Gwei(ssz.UnmarshallUint64(buf[2736661:2736669])) // Field (30) 'ExitBalanceToConsume' - b.ExitBalanceToConsume = github_com_prysmaticlabs_prysm_v5_math.Gwei(ssz.UnmarshallUint64(buf[2736669:2736677])) + b.ExitBalanceToConsume = github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Gwei(ssz.UnmarshallUint64(buf[2736669:2736677])) // Field (31) 'EarliestExitEpoch' b.EarliestExitEpoch = github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Epoch(ssz.UnmarshallUint64(buf[2736677:2736685])) // Field (32) 'ConsolidationBalanceToConsume' - b.ConsolidationBalanceToConsume = github_com_prysmaticlabs_prysm_v5_math.Gwei(ssz.UnmarshallUint64(buf[2736685:2736693])) + b.ConsolidationBalanceToConsume = github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Gwei(ssz.UnmarshallUint64(buf[2736685:2736693])) // Field (33) 'EarliestConsolidationEpoch' b.EarliestConsolidationEpoch = github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Epoch(ssz.UnmarshallUint64(buf[2736693:2736701])) diff --git a/testing/spectest/shared/electra/epoch_processing/BUILD.bazel b/testing/spectest/shared/electra/epoch_processing/BUILD.bazel index d2876b2b3ef3..f651ce5c648e 100644 --- a/testing/spectest/shared/electra/epoch_processing/BUILD.bazel +++ b/testing/spectest/shared/electra/epoch_processing/BUILD.bazel @@ -27,7 +27,7 @@ go_library( "//beacon-chain/state:go_default_library", "//beacon-chain/state/state-native:go_default_library", "//config/params:go_default_library", - "//math:go_default_library", + "//consensus-types/primitives:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//testing/require:go_default_library", "//testing/spectest/utils:go_default_library", diff --git a/testing/spectest/shared/electra/epoch_processing/pending_balance_updates.go b/testing/spectest/shared/electra/epoch_processing/pending_balance_updates.go index fbd3714cde54..89a734373199 100644 --- a/testing/spectest/shared/electra/epoch_processing/pending_balance_updates.go +++ b/testing/spectest/shared/electra/epoch_processing/pending_balance_updates.go @@ -8,7 +8,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/electra" "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" - "github.com/prysmaticlabs/prysm/v5/math" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/testing/spectest/utils" ) @@ -31,5 +31,5 @@ func processPendingBalanceDeposits(t *testing.T, st state.BeaconState) (state.Be // balance from the given state. tab, err := helpers.TotalActiveBalance(st) require.NoError(t, err) - return st, electra.ProcessPendingBalanceDeposits(context.TODO(), st, math.Gwei(tab)) + return st, electra.ProcessPendingBalanceDeposits(context.TODO(), st, primitives.Gwei(tab)) } diff --git a/testing/util/BUILD.bazel b/testing/util/BUILD.bazel index 921d39161c9d..675ea1fb6c33 100644 --- a/testing/util/BUILD.bazel +++ b/testing/util/BUILD.bazel @@ -49,7 +49,6 @@ go_library( "//crypto/hash:go_default_library", "//crypto/rand:go_default_library", "//encoding/bytesutil:go_default_library", - "//math:go_default_library", "//network/forks:go_default_library", "//proto/engine/v1:go_default_library", "//proto/eth/v1:go_default_library", diff --git a/testing/util/deneb.go b/testing/util/deneb.go index a847fa502322..12a888bf9d11 100644 --- a/testing/util/deneb.go +++ b/testing/util/deneb.go @@ -31,6 +31,7 @@ type denebBlockGenerator struct { sk bls.SecretKey proposer primitives.ValidatorIndex valRoot []byte + payload *enginev1.ExecutionPayloadDeneb } func WithProposerSigning(idx primitives.ValidatorIndex, sk bls.SecretKey, valRoot []byte) DenebBlockGeneratorOption { @@ -42,6 +43,12 @@ func WithProposerSigning(idx primitives.ValidatorIndex, sk bls.SecretKey, valRoo } } +func WithPayloadSetter(p *enginev1.ExecutionPayloadDeneb) DenebBlockGeneratorOption { + return func(g *denebBlockGenerator) { + g.payload = p + } +} + func GenerateTestDenebBlockWithSidecar(t *testing.T, parent [32]byte, slot primitives.Slot, nblobs int, opts ...DenebBlockGeneratorOption) (blocks.ROBlock, []blocks.ROBlob) { g := &denebBlockGenerator{ parent: parent, @@ -51,47 +58,51 @@ func GenerateTestDenebBlockWithSidecar(t *testing.T, parent [32]byte, slot primi for _, o := range opts { o(g) } - stateRoot := bytesutil.PadTo([]byte("stateRoot"), fieldparams.RootLength) - receiptsRoot := bytesutil.PadTo([]byte("receiptsRoot"), fieldparams.RootLength) - logsBloom := bytesutil.PadTo([]byte("logs"), fieldparams.LogsBloomLength) - parentHash := bytesutil.PadTo([]byte("parentHash"), fieldparams.RootLength) - ads := common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87") - tx := gethTypes.NewTx(&gethTypes.LegacyTx{ - Nonce: 0, - To: &ads, - Value: big.NewInt(0), - Gas: 0, - GasPrice: big.NewInt(0), - Data: nil, - }) - - txs := []*gethTypes.Transaction{tx} - encodedBinaryTxs := make([][]byte, 1) - var err error - encodedBinaryTxs[0], err = txs[0].MarshalBinary() - require.NoError(t, err) - blockHash := bytesutil.ToBytes32([]byte("foo")) - payload := &enginev1.ExecutionPayloadDeneb{ - ParentHash: parentHash, - FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), - StateRoot: stateRoot, - ReceiptsRoot: receiptsRoot, - LogsBloom: logsBloom, - PrevRandao: blockHash[:], - BlockNumber: 0, - GasLimit: 0, - GasUsed: 0, - Timestamp: 0, - ExtraData: make([]byte, 0), - BaseFeePerGas: bytesutil.PadTo([]byte("baseFeePerGas"), fieldparams.RootLength), - BlockHash: blockHash[:], - Transactions: encodedBinaryTxs, - Withdrawals: make([]*enginev1.Withdrawal, 0), - BlobGasUsed: 0, - ExcessBlobGas: 0, + + if g.payload == nil { + stateRoot := bytesutil.PadTo([]byte("stateRoot"), fieldparams.RootLength) + ads := common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87") + tx := gethTypes.NewTx(&gethTypes.LegacyTx{ + Nonce: 0, + To: &ads, + Value: big.NewInt(0), + Gas: 0, + GasPrice: big.NewInt(0), + Data: nil, + }) + + txs := []*gethTypes.Transaction{tx} + encodedBinaryTxs := make([][]byte, 1) + var err error + encodedBinaryTxs[0], err = txs[0].MarshalBinary() + require.NoError(t, err) + blockHash := bytesutil.ToBytes32([]byte("foo")) + logsBloom := bytesutil.PadTo([]byte("logs"), fieldparams.LogsBloomLength) + receiptsRoot := bytesutil.PadTo([]byte("receiptsRoot"), fieldparams.RootLength) + parentHash := bytesutil.PadTo([]byte("parentHash"), fieldparams.RootLength) + g.payload = &enginev1.ExecutionPayloadDeneb{ + ParentHash: parentHash, + FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), + StateRoot: stateRoot, + ReceiptsRoot: receiptsRoot, + LogsBloom: logsBloom, + PrevRandao: blockHash[:], + BlockNumber: 0, + GasLimit: 0, + GasUsed: 0, + Timestamp: 0, + ExtraData: make([]byte, 0), + BaseFeePerGas: bytesutil.PadTo([]byte("baseFeePerGas"), fieldparams.RootLength), + BlockHash: blockHash[:], + Transactions: encodedBinaryTxs, + Withdrawals: make([]*enginev1.Withdrawal, 0), + BlobGasUsed: 0, + ExcessBlobGas: 0, + } } + block := NewBeaconBlockDeneb() - block.Block.Body.ExecutionPayload = payload + block.Block.Body.ExecutionPayload = g.payload block.Block.Slot = g.slot block.Block.ParentRoot = g.parent[:] block.Block.ProposerIndex = g.proposer diff --git a/testing/util/electra.go b/testing/util/electra.go index 81a127923760..09bcc8b7c70f 100644 --- a/testing/util/electra.go +++ b/testing/util/electra.go @@ -1,11 +1,24 @@ package util import ( + "encoding/binary" "math" + "math/big" "testing" + "github.com/ethereum/go-ethereum/common" + gethTypes "github.com/ethereum/go-ethereum/core/types" + "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/signing" + fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" + "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" + "github.com/prysmaticlabs/prysm/v5/crypto/bls" + "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" + "github.com/prysmaticlabs/prysm/v5/network/forks" + enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" "github.com/prysmaticlabs/prysm/v5/testing/require" + "github.com/prysmaticlabs/prysm/v5/time/slots" ) // HackElectraMaxuint is helpful for tests that need to set up cases where the electra fork has passed. @@ -23,3 +36,165 @@ func HackElectraMaxuint(t *testing.T) func() { require.NoError(t, undo()) } } + +type ElectraBlockGeneratorOption func(*electraBlockGenerator) + +type electraBlockGenerator struct { + parent [32]byte + slot primitives.Slot + nblobs int + sign bool + sk bls.SecretKey + proposer primitives.ValidatorIndex + valRoot []byte + payload *enginev1.ExecutionPayloadElectra +} + +func WithElectraProposerSigning(idx primitives.ValidatorIndex, sk bls.SecretKey, valRoot []byte) ElectraBlockGeneratorOption { + return func(g *electraBlockGenerator) { + g.sign = true + g.proposer = idx + g.sk = sk + g.valRoot = valRoot + } +} + +func WithElectraPayload(p *enginev1.ExecutionPayloadElectra) ElectraBlockGeneratorOption { + return func(g *electraBlockGenerator) { + g.payload = p + } +} + +func GenerateTestElectraBlockWithSidecar(t *testing.T, parent [32]byte, slot primitives.Slot, nblobs int, opts ...ElectraBlockGeneratorOption) (blocks.ROBlock, []blocks.ROBlob) { + g := &electraBlockGenerator{ + parent: parent, + slot: slot, + nblobs: nblobs, + } + for _, o := range opts { + o(g) + } + + if g.payload == nil { + stateRoot := bytesutil.PadTo([]byte("stateRoot"), fieldparams.RootLength) + ads := common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87") + tx := gethTypes.NewTx(&gethTypes.LegacyTx{ + Nonce: 0, + To: &ads, + Value: big.NewInt(0), + Gas: 0, + GasPrice: big.NewInt(0), + Data: nil, + }) + + txs := []*gethTypes.Transaction{tx} + encodedBinaryTxs := make([][]byte, 1) + var err error + encodedBinaryTxs[0], err = txs[0].MarshalBinary() + require.NoError(t, err) + blockHash := bytesutil.ToBytes32([]byte("foo")) + logsBloom := bytesutil.PadTo([]byte("logs"), fieldparams.LogsBloomLength) + receiptsRoot := bytesutil.PadTo([]byte("receiptsRoot"), fieldparams.RootLength) + parentHash := bytesutil.PadTo([]byte("parentHash"), fieldparams.RootLength) + g.payload = &enginev1.ExecutionPayloadElectra{ + ParentHash: parentHash, + FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), + StateRoot: stateRoot, + ReceiptsRoot: receiptsRoot, + LogsBloom: logsBloom, + PrevRandao: blockHash[:], + BlockNumber: 0, + GasLimit: 0, + GasUsed: 0, + Timestamp: 0, + ExtraData: make([]byte, 0), + BaseFeePerGas: bytesutil.PadTo([]byte("baseFeePerGas"), fieldparams.RootLength), + BlockHash: blockHash[:], + Transactions: encodedBinaryTxs, + Withdrawals: make([]*enginev1.Withdrawal, 0), + BlobGasUsed: 0, + ExcessBlobGas: 0, + DepositReceipts: generateTestDepositRequests(uint64(g.slot), 4), + WithdrawalRequests: generateTestWithdrawalRequests(uint64(g.slot), 4), + } + } + + block := NewBeaconBlockElectra() + block.Block.Body.ExecutionPayload = g.payload + block.Block.Slot = g.slot + block.Block.ParentRoot = g.parent[:] + block.Block.ProposerIndex = g.proposer + commitments := make([][48]byte, g.nblobs) + block.Block.Body.BlobKzgCommitments = make([][]byte, g.nblobs) + for i := range commitments { + binary.LittleEndian.PutUint16(commitments[i][0:16], uint16(i)) + binary.LittleEndian.PutUint16(commitments[i][16:32], uint16(g.slot)) + block.Block.Body.BlobKzgCommitments[i] = commitments[i][:] + } + + body, err := blocks.NewBeaconBlockBody(block.Block.Body) + require.NoError(t, err) + inclusion := make([][][]byte, len(commitments)) + for i := range commitments { + proof, err := blocks.MerkleProofKZGCommitment(body, i) + require.NoError(t, err) + inclusion[i] = proof + } + if g.sign { + epoch := slots.ToEpoch(block.Block.Slot) + schedule := forks.NewOrderedSchedule(params.BeaconConfig()) + version, err := schedule.VersionForEpoch(epoch) + require.NoError(t, err) + fork, err := schedule.ForkFromVersion(version) + require.NoError(t, err) + domain := params.BeaconConfig().DomainBeaconProposer + sig, err := signing.ComputeDomainAndSignWithoutState(fork, epoch, domain, g.valRoot, block.Block, g.sk) + require.NoError(t, err) + block.Signature = sig + } + + root, err := block.Block.HashTreeRoot() + require.NoError(t, err) + + sidecars := make([]blocks.ROBlob, len(commitments)) + sbb, err := blocks.NewSignedBeaconBlock(block) + require.NoError(t, err) + + sh, err := sbb.Header() + require.NoError(t, err) + for i, c := range block.Block.Body.BlobKzgCommitments { + sidecars[i] = GenerateTestDenebBlobSidecar(t, root, sh, i, c, inclusion[i]) + } + + rob, err := blocks.NewROBlock(sbb) + require.NoError(t, err) + return rob, sidecars +} + +func generateTestDepositRequests(offset, n uint64) []*enginev1.DepositReceipt { + r := make([]*enginev1.DepositReceipt, n) + var i uint64 + for i = 0; i < n; i++ { + r[i] = &enginev1.DepositReceipt{ + Pubkey: make([]byte, 48), + WithdrawalCredentials: make([]byte, 32), + Amount: offset + i, + Signature: make([]byte, 96), + Index: offset + i + 100, + } + } + return r +} + +func generateTestWithdrawalRequests(offset, n uint64) []*enginev1.ExecutionLayerWithdrawalRequest { + r := make([]*enginev1.ExecutionLayerWithdrawalRequest, n) + var i uint64 + for i = 0; i < n; i++ { + r[i] = &enginev1.ExecutionLayerWithdrawalRequest{ + SourceAddress: make([]byte, 20), + ValidatorPubkey: make([]byte, 48), + Amount: offset + i, + } + } + return r +} diff --git a/testing/util/electra_state.go b/testing/util/electra_state.go index 9af5a78e10d9..947b096f2f7f 100644 --- a/testing/util/electra_state.go +++ b/testing/util/electra_state.go @@ -11,8 +11,8 @@ import ( "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stateutil" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/crypto/bls" - "github.com/prysmaticlabs/prysm/v5/math" enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/time/slots" @@ -84,9 +84,9 @@ func emptyGenesisStateElectra() (state.BeaconState, error) { LatestExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderElectra{}, - DepositBalanceToConsume: math.Gwei(0), - ExitBalanceToConsume: math.Gwei(0), - ConsolidationBalanceToConsume: math.Gwei(0), + DepositBalanceToConsume: primitives.Gwei(0), + ExitBalanceToConsume: primitives.Gwei(0), + ConsolidationBalanceToConsume: primitives.Gwei(0), } return state_native.InitializeFromProtoElectra(st) } @@ -192,9 +192,9 @@ func buildGenesisBeaconStateElectra(genesisTime uint64, preState state.BeaconSta // Electra Data DepositReceiptsStartIndex: params.BeaconConfig().UnsetDepositReceiptsStartIndex, - ExitBalanceToConsume: helpers.ActivationExitChurnLimit(math.Gwei(tab)), + ExitBalanceToConsume: helpers.ActivationExitChurnLimit(primitives.Gwei(tab)), EarliestConsolidationEpoch: helpers.ActivationExitEpoch(slots.ToEpoch(preState.Slot())), - ConsolidationBalanceToConsume: helpers.ConsolidationChurnLimit(math.Gwei(tab)), + ConsolidationBalanceToConsume: helpers.ConsolidationChurnLimit(primitives.Gwei(tab)), PendingBalanceDeposits: make([]*ethpb.PendingBalanceDeposit, 0), PendingPartialWithdrawals: make([]*ethpb.PendingPartialWithdrawal, 0), PendingConsolidations: make([]*ethpb.PendingConsolidation, 0), diff --git a/testing/validator-mock/BUILD.bazel b/testing/validator-mock/BUILD.bazel index e7df6fed845f..08bb8fa69b31 100644 --- a/testing/validator-mock/BUILD.bazel +++ b/testing/validator-mock/BUILD.bazel @@ -5,9 +5,9 @@ package(default_testonly = True) go_library( name = "go_default_library", srcs = [ - "beacon_chain_client_mock.go", + "chain_client_mock.go", "node_client_mock.go", - "prysm_beacon_chain_client_mock.go", + "prysm_chain_client_mock.go", "validator_client_mock.go", ], importpath = "github.com/prysmaticlabs/prysm/v5/testing/validator-mock", diff --git a/testing/validator-mock/beacon_chain_client_mock.go b/testing/validator-mock/chain_client_mock.go similarity index 54% rename from testing/validator-mock/beacon_chain_client_mock.go rename to testing/validator-mock/chain_client_mock.go index 971547686796..0b10bcf7d810 100644 --- a/testing/validator-mock/beacon_chain_client_mock.go +++ b/testing/validator-mock/chain_client_mock.go @@ -18,31 +18,31 @@ import ( emptypb "google.golang.org/protobuf/types/known/emptypb" ) -// MockBeaconChainClient is a mock of BeaconChainClient interface. -type MockBeaconChainClient struct { +// MockChainClient is a mock of ChainClient interface. +type MockChainClient struct { ctrl *gomock.Controller - recorder *MockBeaconChainClientMockRecorder + recorder *MockChainClientMockRecorder } -// MockBeaconChainClientMockRecorder is the mock recorder for MockBeaconChainClient. -type MockBeaconChainClientMockRecorder struct { - mock *MockBeaconChainClient +// MockChainClientMockRecorder is the mock recorder for MockChainClient. +type MockChainClientMockRecorder struct { + mock *MockChainClient } -// NewMockBeaconChainClient creates a new mock instance. -func NewMockBeaconChainClient(ctrl *gomock.Controller) *MockBeaconChainClient { - mock := &MockBeaconChainClient{ctrl: ctrl} - mock.recorder = &MockBeaconChainClientMockRecorder{mock} +// NewMockChainClient creates a new mock instance. +func NewMockChainClient(ctrl *gomock.Controller) *MockChainClient { + mock := &MockChainClient{ctrl: ctrl} + mock.recorder = &MockChainClientMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockBeaconChainClient) EXPECT() *MockBeaconChainClientMockRecorder { +func (m *MockChainClient) EXPECT() *MockChainClientMockRecorder { return m.recorder } // GetChainHead mocks base method. -func (m *MockBeaconChainClient) GetChainHead(arg0 context.Context, arg1 *emptypb.Empty) (*eth.ChainHead, error) { +func (m *MockChainClient) GetChainHead(arg0 context.Context, arg1 *emptypb.Empty) (*eth.ChainHead, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetChainHead", arg0, arg1) ret0, _ := ret[0].(*eth.ChainHead) @@ -51,13 +51,13 @@ func (m *MockBeaconChainClient) GetChainHead(arg0 context.Context, arg1 *emptypb } // GetChainHead indicates an expected call of GetChainHead. -func (mr *MockBeaconChainClientMockRecorder) GetChainHead(arg0, arg1 any) *gomock.Call { +func (mr *MockChainClientMockRecorder) GetChainHead(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChainHead", reflect.TypeOf((*MockBeaconChainClient)(nil).GetChainHead), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChainHead", reflect.TypeOf((*MockChainClient)(nil).GetChainHead), arg0, arg1) } // GetValidatorParticipation mocks base method. -func (m *MockBeaconChainClient) GetValidatorParticipation(arg0 context.Context, arg1 *eth.GetValidatorParticipationRequest) (*eth.ValidatorParticipationResponse, error) { +func (m *MockChainClient) GetValidatorParticipation(arg0 context.Context, arg1 *eth.GetValidatorParticipationRequest) (*eth.ValidatorParticipationResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetValidatorParticipation", arg0, arg1) ret0, _ := ret[0].(*eth.ValidatorParticipationResponse) @@ -66,13 +66,13 @@ func (m *MockBeaconChainClient) GetValidatorParticipation(arg0 context.Context, } // GetValidatorParticipation indicates an expected call of GetValidatorParticipation. -func (mr *MockBeaconChainClientMockRecorder) GetValidatorParticipation(arg0, arg1 any) *gomock.Call { +func (mr *MockChainClientMockRecorder) GetValidatorParticipation(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorParticipation", reflect.TypeOf((*MockBeaconChainClient)(nil).GetValidatorParticipation), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorParticipation", reflect.TypeOf((*MockChainClient)(nil).GetValidatorParticipation), arg0, arg1) } // GetValidatorPerformance mocks base method. -func (m *MockBeaconChainClient) GetValidatorPerformance(arg0 context.Context, arg1 *eth.ValidatorPerformanceRequest) (*eth.ValidatorPerformanceResponse, error) { +func (m *MockChainClient) GetValidatorPerformance(arg0 context.Context, arg1 *eth.ValidatorPerformanceRequest) (*eth.ValidatorPerformanceResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetValidatorPerformance", arg0, arg1) ret0, _ := ret[0].(*eth.ValidatorPerformanceResponse) @@ -81,13 +81,13 @@ func (m *MockBeaconChainClient) GetValidatorPerformance(arg0 context.Context, ar } // GetValidatorPerformance indicates an expected call of GetValidatorPerformance. -func (mr *MockBeaconChainClientMockRecorder) GetValidatorPerformance(arg0, arg1 any) *gomock.Call { +func (mr *MockChainClientMockRecorder) GetValidatorPerformance(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorPerformance", reflect.TypeOf((*MockBeaconChainClient)(nil).GetValidatorPerformance), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorPerformance", reflect.TypeOf((*MockChainClient)(nil).GetValidatorPerformance), arg0, arg1) } // GetValidatorQueue mocks base method. -func (m *MockBeaconChainClient) GetValidatorQueue(arg0 context.Context, arg1 *emptypb.Empty) (*eth.ValidatorQueue, error) { +func (m *MockChainClient) GetValidatorQueue(arg0 context.Context, arg1 *emptypb.Empty) (*eth.ValidatorQueue, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetValidatorQueue", arg0, arg1) ret0, _ := ret[0].(*eth.ValidatorQueue) @@ -96,13 +96,13 @@ func (m *MockBeaconChainClient) GetValidatorQueue(arg0 context.Context, arg1 *em } // GetValidatorQueue indicates an expected call of GetValidatorQueue. -func (mr *MockBeaconChainClientMockRecorder) GetValidatorQueue(arg0, arg1 any) *gomock.Call { +func (mr *MockChainClientMockRecorder) GetValidatorQueue(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorQueue", reflect.TypeOf((*MockBeaconChainClient)(nil).GetValidatorQueue), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorQueue", reflect.TypeOf((*MockChainClient)(nil).GetValidatorQueue), arg0, arg1) } // ListValidatorBalances mocks base method. -func (m *MockBeaconChainClient) ListValidatorBalances(arg0 context.Context, arg1 *eth.ListValidatorBalancesRequest) (*eth.ValidatorBalances, error) { +func (m *MockChainClient) ListValidatorBalances(arg0 context.Context, arg1 *eth.ListValidatorBalancesRequest) (*eth.ValidatorBalances, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListValidatorBalances", arg0, arg1) ret0, _ := ret[0].(*eth.ValidatorBalances) @@ -111,13 +111,13 @@ func (m *MockBeaconChainClient) ListValidatorBalances(arg0 context.Context, arg1 } // ListValidatorBalances indicates an expected call of ListValidatorBalances. -func (mr *MockBeaconChainClientMockRecorder) ListValidatorBalances(arg0, arg1 any) *gomock.Call { +func (mr *MockChainClientMockRecorder) ListValidatorBalances(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListValidatorBalances", reflect.TypeOf((*MockBeaconChainClient)(nil).ListValidatorBalances), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListValidatorBalances", reflect.TypeOf((*MockChainClient)(nil).ListValidatorBalances), arg0, arg1) } // ListValidators mocks base method. -func (m *MockBeaconChainClient) ListValidators(arg0 context.Context, arg1 *eth.ListValidatorsRequest) (*eth.Validators, error) { +func (m *MockChainClient) ListValidators(arg0 context.Context, arg1 *eth.ListValidatorsRequest) (*eth.Validators, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListValidators", arg0, arg1) ret0, _ := ret[0].(*eth.Validators) @@ -126,7 +126,7 @@ func (m *MockBeaconChainClient) ListValidators(arg0 context.Context, arg1 *eth.L } // ListValidators indicates an expected call of ListValidators. -func (mr *MockBeaconChainClientMockRecorder) ListValidators(arg0, arg1 any) *gomock.Call { +func (mr *MockChainClientMockRecorder) ListValidators(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListValidators", reflect.TypeOf((*MockBeaconChainClient)(nil).ListValidators), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListValidators", reflect.TypeOf((*MockChainClient)(nil).ListValidators), arg0, arg1) } diff --git a/testing/validator-mock/prysm_beacon_chain_client_mock.go b/testing/validator-mock/prysm_beacon_chain_client_mock.go deleted file mode 100644 index 15d88735d78d..000000000000 --- a/testing/validator-mock/prysm_beacon_chain_client_mock.go +++ /dev/null @@ -1,57 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/prysmaticlabs/prysm/v5/validator/client/iface (interfaces: PrysmBeaconChainClient) -// -// Generated by this command: -// -// mockgen -package=validator_mock -destination=testing/validator-mock/prysm_beacon_chain_client_mock.go github.com/prysmaticlabs/prysm/v5/validator/client/iface PrysmBeaconChainClient -// - -// Package validator_mock is a generated GoMock package. -package validator_mock - -import ( - context "context" - reflect "reflect" - - validator "github.com/prysmaticlabs/prysm/v5/consensus-types/validator" - iface "github.com/prysmaticlabs/prysm/v5/validator/client/iface" - gomock "go.uber.org/mock/gomock" -) - -// MockPrysmBeaconChainClient is a mock of PrysmBeaconChainClient interface. -type MockPrysmBeaconChainClient struct { - ctrl *gomock.Controller - recorder *MockPrysmBeaconChainClientMockRecorder -} - -// MockPrysmBeaconChainClientMockRecorder is the mock recorder for MockPrysmBeaconChainClient. -type MockPrysmBeaconChainClientMockRecorder struct { - mock *MockPrysmBeaconChainClient -} - -// NewMockPrysmBeaconChainClient creates a new mock instance. -func NewMockPrysmBeaconChainClient(ctrl *gomock.Controller) *MockPrysmBeaconChainClient { - mock := &MockPrysmBeaconChainClient{ctrl: ctrl} - mock.recorder = &MockPrysmBeaconChainClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockPrysmBeaconChainClient) EXPECT() *MockPrysmBeaconChainClientMockRecorder { - return m.recorder -} - -// GetValidatorCount mocks base method. -func (m *MockPrysmBeaconChainClient) GetValidatorCount(arg0 context.Context, arg1 string, arg2 []validator.Status) ([]iface.ValidatorCount, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetValidatorCount", arg0, arg1, arg2) - ret0, _ := ret[0].([]iface.ValidatorCount) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetValidatorCount indicates an expected call of GetValidatorCount. -func (mr *MockPrysmBeaconChainClientMockRecorder) GetValidatorCount(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorCount", reflect.TypeOf((*MockPrysmBeaconChainClient)(nil).GetValidatorCount), arg0, arg1, arg2) -} diff --git a/testing/validator-mock/prysm_chain_client_mock.go b/testing/validator-mock/prysm_chain_client_mock.go new file mode 100644 index 000000000000..330af4c503ee --- /dev/null +++ b/testing/validator-mock/prysm_chain_client_mock.go @@ -0,0 +1,52 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/prysmaticlabs/prysm/v4/validator/client/iface (interfaces: PrysmChainClient) + +// Package validator_mock is a generated GoMock package. +package validator_mock + +import ( + context "context" + reflect "reflect" + + validator "github.com/prysmaticlabs/prysm/v5/consensus-types/validator" + iface "github.com/prysmaticlabs/prysm/v5/validator/client/iface" + gomock "go.uber.org/mock/gomock" +) + +// MockPrysmChainClient is a mock of PrysmChainClient interface. +type MockPrysmChainClient struct { + ctrl *gomock.Controller + recorder *MockPrysmChainClientMockRecorder +} + +// MockPrysmChainClientMockRecorder is the mock recorder for MockPrysmChainClient. +type MockPrysmChainClientMockRecorder struct { + mock *MockPrysmChainClient +} + +// NewMockPrysmChainClient creates a new mock instance. +func NewMockPrysmChainClient(ctrl *gomock.Controller) *MockPrysmChainClient { + mock := &MockPrysmChainClient{ctrl: ctrl} + mock.recorder = &MockPrysmChainClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockPrysmChainClient) EXPECT() *MockPrysmChainClientMockRecorder { + return m.recorder +} + +// GetValidatorCount mocks base method. +func (m *MockPrysmChainClient) GetValidatorCount(arg0 context.Context, arg1 string, arg2 []validator.Status) ([]iface.ValidatorCount, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetValidatorCount", arg0, arg1, arg2) + ret0, _ := ret[0].([]iface.ValidatorCount) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetValidatorCount indicates an expected call of GetValidatorCount. +func (mr *MockPrysmChainClientMockRecorder) GetValidatorCount(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorCount", reflect.TypeOf((*MockPrysmChainClient)(nil).GetValidatorCount), arg0, arg1, arg2) +} diff --git a/validator/client/aggregate.go b/validator/client/aggregate.go index ab4b532f7282..5cfd40fdf1b3 100644 --- a/validator/client/aggregate.go +++ b/validator/client/aggregate.go @@ -44,7 +44,7 @@ func (v *validator) SubmitAggregateAndProof(ctx context.Context, slot primitives } // Avoid sending beacon node duplicated aggregation requests. - k := validatorSubscribeKey(slot, duty.CommitteeIndex) + k := validatorSubnetSubscriptionKey(slot, duty.CommitteeIndex) v.aggregatedSlotCommitteeIDCacheLock.Lock() if v.aggregatedSlotCommitteeIDCache.Contains(k) { v.aggregatedSlotCommitteeIDCacheLock.Unlock() @@ -149,7 +149,7 @@ func (v *validator) signSlotWithSelectionProof(ctx context.Context, pubKey [fiel if err != nil { return nil, err } - sig, err = v.keyManager.Sign(ctx, &validatorpb.SignRequest{ + sig, err = v.km.Sign(ctx, &validatorpb.SignRequest{ PublicKey: pubKey[:], SigningRoot: root[:], SignatureDomain: domain.SignatureDomain, @@ -203,7 +203,7 @@ func (v *validator) aggregateAndProofSig(ctx context.Context, pubKey [fieldparam if err != nil { return nil, err } - sig, err = v.keyManager.Sign(ctx, &validatorpb.SignRequest{ + sig, err = v.km.Sign(ctx, &validatorpb.SignRequest{ PublicKey: pubKey[:], SigningRoot: root[:], SignatureDomain: d.SignatureDomain, diff --git a/validator/client/attest.go b/validator/client/attest.go index 8a501f8f3f66..42973c4b13b1 100644 --- a/validator/client/attest.go +++ b/validator/client/attest.go @@ -203,7 +203,7 @@ func (v *validator) signAtt(ctx context.Context, pubKey [fieldparams.BLSPubkeyLe if err != nil { return nil, [32]byte{}, err } - sig, err := v.keyManager.Sign(ctx, &validatorpb.SignRequest{ + sig, err := v.km.Sign(ctx, &validatorpb.SignRequest{ PublicKey: pubKey[:], SigningRoot: root[:], SignatureDomain: domain.SignatureDomain, diff --git a/validator/client/attest_test.go b/validator/client/attest_test.go index c9309a99601c..23308302f355 100644 --- a/validator/client/attest_test.go +++ b/validator/client/attest_test.go @@ -167,7 +167,7 @@ func TestAttestToBlockHead_AttestsCorrectly(t *testing.T) { root, err := signing.ComputeSigningRoot(expectedAttestation.Data, make([]byte, 32)) require.NoError(t, err) - sig, err := validator.keyManager.Sign(context.Background(), &validatorpb.SignRequest{ + sig, err := validator.km.Sign(context.Background(), &validatorpb.SignRequest{ PublicKey: validatorKey.PublicKey().Marshal(), SigningRoot: root[:], }) @@ -504,7 +504,7 @@ func TestSignAttestation(t *testing.T) { att.Data.BeaconBlockRoot = bytesutil.PadTo([]byte("blockRoot"), 32) pk := testKeyFromBytes(t, []byte{1}) - validator.keyManager = newMockKeymanager(t, pk) + validator.km = newMockKeymanager(t, pk) sig, sr, err := validator.signAtt(ctx, pk.pub, att.Data, att.Data.Slot) require.NoError(t, err, "%x,%x,%v", sig, sr, err) require.Equal(t, "b6a60f8497bd328908be83634d045"+ diff --git a/validator/client/beacon-api/beacon_api_beacon_chain_client.go b/validator/client/beacon-api/beacon_api_beacon_chain_client.go index d45204a29973..0ed7607b33da 100644 --- a/validator/client/beacon-api/beacon_api_beacon_chain_client.go +++ b/validator/client/beacon-api/beacon_api_beacon_chain_client.go @@ -17,15 +17,15 @@ import ( "github.com/prysmaticlabs/prysm/v5/validator/client/iface" ) -type beaconApiBeaconChainClient struct { - fallbackClient iface.BeaconChainClient +type beaconApiChainClient struct { + fallbackClient iface.ChainClient jsonRestHandler JsonRestHandler stateValidatorsProvider StateValidatorsProvider } const getValidatorPerformanceEndpoint = "/prysm/validators/performance" -func (c beaconApiBeaconChainClient) getHeadBlockHeaders(ctx context.Context) (*structs.GetBlockHeaderResponse, error) { +func (c beaconApiChainClient) getHeadBlockHeaders(ctx context.Context) (*structs.GetBlockHeaderResponse, error) { blockHeader := structs.GetBlockHeaderResponse{} err := c.jsonRestHandler.Get(ctx, "/eth/v1/beacon/headers/head", &blockHeader) if err != nil { @@ -43,7 +43,7 @@ func (c beaconApiBeaconChainClient) getHeadBlockHeaders(ctx context.Context) (*s return &blockHeader, nil } -func (c beaconApiBeaconChainClient) GetChainHead(ctx context.Context, _ *empty.Empty) (*ethpb.ChainHead, error) { +func (c beaconApiChainClient) GetChainHead(ctx context.Context, _ *empty.Empty) (*ethpb.ChainHead, error) { const endpoint = "/eth/v1/beacon/states/head/finality_checkpoints" finalityCheckpoints := structs.GetFinalityCheckpointsResponse{} @@ -146,16 +146,16 @@ func (c beaconApiBeaconChainClient) GetChainHead(ctx context.Context, _ *empty.E }, nil } -func (c beaconApiBeaconChainClient) ListValidatorBalances(ctx context.Context, in *ethpb.ListValidatorBalancesRequest) (*ethpb.ValidatorBalances, error) { +func (c beaconApiChainClient) ListValidatorBalances(ctx context.Context, in *ethpb.ListValidatorBalancesRequest) (*ethpb.ValidatorBalances, error) { if c.fallbackClient != nil { return c.fallbackClient.ListValidatorBalances(ctx, in) } // TODO: Implement me - panic("beaconApiBeaconChainClient.ListValidatorBalances is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiBeaconChainClientWithFallback.") + panic("beaconApiChainClient.ListValidatorBalances is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiChainClientWithFallback.") } -func (c beaconApiBeaconChainClient) ListValidators(ctx context.Context, in *ethpb.ListValidatorsRequest) (*ethpb.Validators, error) { +func (c beaconApiChainClient) ListValidators(ctx context.Context, in *ethpb.ListValidatorsRequest) (*ethpb.Validators, error) { pageSize := in.PageSize // We follow the gRPC behavior here, which returns a maximum of 250 results when pageSize == 0 @@ -310,16 +310,16 @@ func (c beaconApiBeaconChainClient) ListValidators(ctx context.Context, in *ethp }, nil } -func (c beaconApiBeaconChainClient) GetValidatorQueue(ctx context.Context, in *empty.Empty) (*ethpb.ValidatorQueue, error) { +func (c beaconApiChainClient) GetValidatorQueue(ctx context.Context, in *empty.Empty) (*ethpb.ValidatorQueue, error) { if c.fallbackClient != nil { return c.fallbackClient.GetValidatorQueue(ctx, in) } // TODO: Implement me - panic("beaconApiBeaconChainClient.GetValidatorQueue is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiBeaconChainClientWithFallback.") + panic("beaconApiChainClient.GetValidatorQueue is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiChainClientWithFallback.") } -func (c beaconApiBeaconChainClient) GetValidatorPerformance(ctx context.Context, in *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error) { +func (c beaconApiChainClient) GetValidatorPerformance(ctx context.Context, in *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error) { request, err := json.Marshal(structs.GetValidatorPerformanceRequest{ PublicKeys: in.PublicKeys, Indices: in.Indices, @@ -345,17 +345,17 @@ func (c beaconApiBeaconChainClient) GetValidatorPerformance(ctx context.Context, }, nil } -func (c beaconApiBeaconChainClient) GetValidatorParticipation(ctx context.Context, in *ethpb.GetValidatorParticipationRequest) (*ethpb.ValidatorParticipationResponse, error) { +func (c beaconApiChainClient) GetValidatorParticipation(ctx context.Context, in *ethpb.GetValidatorParticipationRequest) (*ethpb.ValidatorParticipationResponse, error) { if c.fallbackClient != nil { return c.fallbackClient.GetValidatorParticipation(ctx, in) } // TODO: Implement me - panic("beaconApiBeaconChainClient.GetValidatorParticipation is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiBeaconChainClientWithFallback.") + panic("beaconApiChainClient.GetValidatorParticipation is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiChainClientWithFallback.") } -func NewBeaconApiBeaconChainClientWithFallback(jsonRestHandler JsonRestHandler, fallbackClient iface.BeaconChainClient) iface.BeaconChainClient { - return &beaconApiBeaconChainClient{ +func NewBeaconApiChainClientWithFallback(jsonRestHandler JsonRestHandler, fallbackClient iface.ChainClient) iface.ChainClient { + return &beaconApiChainClient{ jsonRestHandler: jsonRestHandler, fallbackClient: fallbackClient, stateValidatorsProvider: beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler}, diff --git a/validator/client/beacon-api/beacon_api_beacon_chain_client_test.go b/validator/client/beacon-api/beacon_api_beacon_chain_client_test.go index 3ed8dbe476be..a7a32ecc2381 100644 --- a/validator/client/beacon-api/beacon_api_beacon_chain_client_test.go +++ b/validator/client/beacon-api/beacon_api_beacon_chain_client_test.go @@ -31,7 +31,7 @@ func TestListValidators(t *testing.T) { defer ctrl.Finish() ctx := context.Background() - beaconChainClient := beaconApiBeaconChainClient{} + beaconChainClient := beaconApiChainClient{} _, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{ PageToken: "foo", }) @@ -43,7 +43,7 @@ func TestListValidators(t *testing.T) { defer ctrl.Finish() ctx := context.Background() - beaconChainClient := beaconApiBeaconChainClient{} + beaconChainClient := beaconApiChainClient{} _, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{ QueryFilter: ðpb.ListValidatorsRequest_Epoch{ Epoch: math.MaxUint64, @@ -63,7 +63,7 @@ func TestListValidators(t *testing.T) { errors.New("foo error"), ) - beaconChainClient := beaconApiBeaconChainClient{stateValidatorsProvider: stateValidatorsProvider} + beaconChainClient := beaconApiChainClient{stateValidatorsProvider: stateValidatorsProvider} _, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{ QueryFilter: ðpb.ListValidatorsRequest_Epoch{ Epoch: 0, @@ -83,7 +83,7 @@ func TestListValidators(t *testing.T) { errors.New("bar error"), ) - beaconChainClient := beaconApiBeaconChainClient{stateValidatorsProvider: stateValidatorsProvider} + beaconChainClient := beaconApiChainClient{stateValidatorsProvider: stateValidatorsProvider} _, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{ QueryFilter: ðpb.ListValidatorsRequest_Genesis{}, }) @@ -101,7 +101,7 @@ func TestListValidators(t *testing.T) { errors.New("foo error"), ) - beaconChainClient := beaconApiBeaconChainClient{stateValidatorsProvider: stateValidatorsProvider} + beaconChainClient := beaconApiChainClient{stateValidatorsProvider: stateValidatorsProvider} _, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{ QueryFilter: nil, }) @@ -122,7 +122,7 @@ func TestListValidators(t *testing.T) { jsonRestHandler := mock.NewMockJsonRestHandler(ctrl) jsonRestHandler.EXPECT().Get(ctx, blockHeaderEndpoint, gomock.Any()).Return(errors.New("bar error")) - beaconChainClient := beaconApiBeaconChainClient{ + beaconChainClient := beaconApiChainClient{ stateValidatorsProvider: stateValidatorsProvider, jsonRestHandler: jsonRestHandler, } @@ -200,7 +200,7 @@ func TestListValidators(t *testing.T) { testCase.blockHeaderResponse, ) - beaconChainClient := beaconApiBeaconChainClient{ + beaconChainClient := beaconApiChainClient{ stateValidatorsProvider: stateValidatorsProvider, jsonRestHandler: jsonRestHandler, } @@ -333,7 +333,7 @@ func TestListValidators(t *testing.T) { nil, ) - beaconChainClient := beaconApiBeaconChainClient{stateValidatorsProvider: stateValidatorsProvider} + beaconChainClient := beaconApiChainClient{stateValidatorsProvider: stateValidatorsProvider} _, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{ QueryFilter: ðpb.ListValidatorsRequest_Genesis{}, }) @@ -561,7 +561,7 @@ func TestListValidators(t *testing.T) { nil, ) - beaconChainClient := beaconApiBeaconChainClient{stateValidatorsProvider: stateValidatorsProvider} + beaconChainClient := beaconApiChainClient{stateValidatorsProvider: stateValidatorsProvider} validators, err := beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{ QueryFilter: ðpb.ListValidatorsRequest_Genesis{}, PublicKeys: [][]byte{}, @@ -752,7 +752,7 @@ func TestGetChainHead(t *testing.T) { testCase.generateFinalityCheckpointsResponse(), ) - beaconChainClient := beaconApiBeaconChainClient{jsonRestHandler: jsonRestHandler} + beaconChainClient := beaconApiChainClient{jsonRestHandler: jsonRestHandler} _, err := beaconChainClient.GetChainHead(ctx, &emptypb.Empty{}) assert.ErrorContains(t, testCase.expectedError, err) }) @@ -859,7 +859,7 @@ func TestGetChainHead(t *testing.T) { testCase.generateHeadBlockHeadersResponse(), ) - beaconChainClient := beaconApiBeaconChainClient{jsonRestHandler: jsonRestHandler} + beaconChainClient := beaconApiChainClient{jsonRestHandler: jsonRestHandler} _, err := beaconChainClient.GetChainHead(ctx, &emptypb.Empty{}) assert.ErrorContains(t, testCase.expectedError, err) }) @@ -913,7 +913,7 @@ func TestGetChainHead(t *testing.T) { HeadEpoch: slots.ToEpoch(8), } - beaconChainClient := beaconApiBeaconChainClient{jsonRestHandler: jsonRestHandler} + beaconChainClient := beaconApiChainClient{jsonRestHandler: jsonRestHandler} chainHead, err := beaconChainClient.GetChainHead(ctx, &emptypb.Empty{}) require.NoError(t, err) assert.DeepEqual(t, expectedChainHead, chainHead) @@ -949,7 +949,7 @@ func Test_beaconApiBeaconChainClient_GetValidatorPerformance(t *testing.T) { nil, ) - c := beaconApiBeaconChainClient{ + c := beaconApiChainClient{ jsonRestHandler: jsonRestHandler, } diff --git a/validator/client/beacon-api/beacon_api_validator_client.go b/validator/client/beacon-api/beacon_api_validator_client.go index 7e59bd0ab77d..43eb64d3726d 100644 --- a/validator/client/beacon-api/beacon_api_validator_client.go +++ b/validator/client/beacon-api/beacon_api_validator_client.go @@ -23,7 +23,7 @@ type beaconApiValidatorClient struct { stateValidatorsProvider StateValidatorsProvider jsonRestHandler JsonRestHandler beaconBlockConverter BeaconBlockConverter - prysmBeaconChainCLient iface.PrysmBeaconChainClient + prysmChainClient iface.PrysmChainClient isEventStreamRunning bool } @@ -34,7 +34,7 @@ func NewBeaconApiValidatorClient(jsonRestHandler JsonRestHandler, opts ...Valida stateValidatorsProvider: beaconApiStateValidatorsProvider{jsonRestHandler: jsonRestHandler}, jsonRestHandler: jsonRestHandler, beaconBlockConverter: beaconApiBeaconBlockConverter{}, - prysmBeaconChainCLient: prysmBeaconChainClient{ + prysmChainClient: prysmChainClient{ nodeClient: &beaconApiNodeClient{jsonRestHandler: jsonRestHandler}, jsonRestHandler: jsonRestHandler, }, diff --git a/validator/client/beacon-api/prysm_beacon_chain_client.go b/validator/client/beacon-api/prysm_beacon_chain_client.go index 5dc5f1a2764b..d4bce8f37832 100644 --- a/validator/client/beacon-api/prysm_beacon_chain_client.go +++ b/validator/client/beacon-api/prysm_beacon_chain_client.go @@ -13,20 +13,20 @@ import ( "github.com/prysmaticlabs/prysm/v5/validator/client/iface" ) -// NewPrysmBeaconChainClient returns implementation of iface.PrysmBeaconChainClient. -func NewPrysmBeaconChainClient(jsonRestHandler JsonRestHandler, nodeClient iface.NodeClient) iface.PrysmBeaconChainClient { - return prysmBeaconChainClient{ +// NewPrysmChainClient returns implementation of iface.PrysmChainClient. +func NewPrysmChainClient(jsonRestHandler JsonRestHandler, nodeClient iface.NodeClient) iface.PrysmChainClient { + return prysmChainClient{ jsonRestHandler: jsonRestHandler, nodeClient: nodeClient, } } -type prysmBeaconChainClient struct { +type prysmChainClient struct { jsonRestHandler JsonRestHandler nodeClient iface.NodeClient } -func (c prysmBeaconChainClient) GetValidatorCount(ctx context.Context, stateID string, statuses []validator2.Status) ([]iface.ValidatorCount, error) { +func (c prysmChainClient) GetValidatorCount(ctx context.Context, stateID string, statuses []validator2.Status) ([]iface.ValidatorCount, error) { // Check node version for prysm beacon node as it is a custom endpoint for prysm beacon node. nodeVersion, err := c.nodeClient.GetVersion(ctx, nil) if err != nil { diff --git a/validator/client/beacon-api/status.go b/validator/client/beacon-api/status.go index c2e14c5640f5..a9dc536cc248 100644 --- a/validator/client/beacon-api/status.go +++ b/validator/client/beacon-api/status.go @@ -79,7 +79,7 @@ func (c *beaconApiValidatorClient) getValidatorsStatusResponse(ctx context.Conte return nil, nil, nil, errors.Wrap(err, "failed to get state validators") } - validatorsCountResponse, err := c.prysmBeaconChainCLient.GetValidatorCount(ctx, "head", nil) + validatorsCountResponse, err := c.prysmChainClient.GetValidatorCount(ctx, "head", nil) if err != nil && !errors.Is(err, iface.ErrNotSupported) { return nil, nil, nil, errors.Wrap(err, "failed to get total validator count") } diff --git a/validator/client/beacon-api/status_test.go b/validator/client/beacon-api/status_test.go index 23310a0d616f..15b318f88026 100644 --- a/validator/client/beacon-api/status_test.go +++ b/validator/client/beacon-api/status_test.go @@ -55,7 +55,7 @@ func TestValidatorStatus_Nominal(t *testing.T) { jsonRestHandler := mock.NewMockJsonRestHandler(ctrl) validatorClient := beaconApiValidatorClient{ stateValidatorsProvider: stateValidatorsProvider, - prysmBeaconChainCLient: prysmBeaconChainClient{ + prysmChainClient: prysmChainClient{ nodeClient: &beaconApiNodeClient{ jsonRestHandler: jsonRestHandler, }, @@ -181,7 +181,7 @@ func TestMultipleValidatorStatus_Nominal(t *testing.T) { validatorClient := beaconApiValidatorClient{ stateValidatorsProvider: stateValidatorsProvider, - prysmBeaconChainCLient: prysmBeaconChainClient{ + prysmChainClient: prysmChainClient{ nodeClient: &beaconApiNodeClient{ jsonRestHandler: jsonRestHandler, }, @@ -429,7 +429,7 @@ func TestGetValidatorsStatusResponse_Nominal_SomeActiveValidators(t *testing.T) validatorClient := beaconApiValidatorClient{ stateValidatorsProvider: stateValidatorsProvider, - prysmBeaconChainCLient: prysmBeaconChainClient{ + prysmChainClient: prysmChainClient{ nodeClient: &beaconApiNodeClient{ jsonRestHandler: jsonRestHandler, }, @@ -499,7 +499,7 @@ func TestGetValidatorsStatusResponse_Nominal_NoActiveValidators(t *testing.T) { validatorClient := beaconApiValidatorClient{ stateValidatorsProvider: stateValidatorsProvider, - prysmBeaconChainCLient: prysmBeaconChainClient{ + prysmChainClient: prysmChainClient{ nodeClient: &beaconApiNodeClient{ jsonRestHandler: jsonRestHandler, }, @@ -729,7 +729,7 @@ func TestValidatorStatusResponse_InvalidData(t *testing.T) { validatorClient := beaconApiValidatorClient{ stateValidatorsProvider: stateValidatorsProvider, - prysmBeaconChainCLient: prysmBeaconChainClient{ + prysmChainClient: prysmChainClient{ nodeClient: &beaconApiNodeClient{ jsonRestHandler: jsonRestHandler, }, diff --git a/validator/client/beacon-api/validator_count_test.go b/validator/client/beacon-api/validator_count_test.go index 6ab9fafe62fa..eb2206801a3f 100644 --- a/validator/client/beacon-api/validator_count_test.go +++ b/validator/client/beacon-api/validator_count_test.go @@ -141,7 +141,7 @@ func TestGetValidatorCount(t *testing.T) { ).Times(test.validatorCountCalled) // Type assertion. - var client iface.PrysmBeaconChainClient = &prysmBeaconChainClient{ + var client iface.PrysmChainClient = &prysmChainClient{ nodeClient: &beaconApiNodeClient{jsonRestHandler: jsonRestHandler}, jsonRestHandler: jsonRestHandler, } diff --git a/validator/client/beacon-chain-client-factory/beacon_chain_client_factory.go b/validator/client/beacon-chain-client-factory/beacon_chain_client_factory.go index 2af08b208f51..43e86ad6a7e9 100644 --- a/validator/client/beacon-chain-client-factory/beacon_chain_client_factory.go +++ b/validator/client/beacon-chain-client-factory/beacon_chain_client_factory.go @@ -9,19 +9,19 @@ import ( validatorHelpers "github.com/prysmaticlabs/prysm/v5/validator/helpers" ) -func NewBeaconChainClient(validatorConn validatorHelpers.NodeConnection, jsonRestHandler beaconApi.JsonRestHandler) iface.BeaconChainClient { - grpcClient := grpcApi.NewGrpcBeaconChainClient(validatorConn.GetGrpcClientConn()) +func NewChainClient(validatorConn validatorHelpers.NodeConnection, jsonRestHandler beaconApi.JsonRestHandler) iface.ChainClient { + grpcClient := grpcApi.NewGrpcChainClient(validatorConn.GetGrpcClientConn()) if features.Get().EnableBeaconRESTApi { - return beaconApi.NewBeaconApiBeaconChainClientWithFallback(jsonRestHandler, grpcClient) + return beaconApi.NewBeaconApiChainClientWithFallback(jsonRestHandler, grpcClient) } else { return grpcClient } } -func NewPrysmBeaconClient(validatorConn validatorHelpers.NodeConnection, jsonRestHandler beaconApi.JsonRestHandler) iface.PrysmBeaconChainClient { +func NewPrysmChainClient(validatorConn validatorHelpers.NodeConnection, jsonRestHandler beaconApi.JsonRestHandler) iface.PrysmChainClient { if features.Get().EnableBeaconRESTApi { - return beaconApi.NewPrysmBeaconChainClient(jsonRestHandler, nodeClientFactory.NewNodeClient(validatorConn, jsonRestHandler)) + return beaconApi.NewPrysmChainClient(jsonRestHandler, nodeClientFactory.NewNodeClient(validatorConn, jsonRestHandler)) } else { - return grpcApi.NewGrpcPrysmBeaconChainClient(validatorConn.GetGrpcClientConn()) + return grpcApi.NewGrpcPrysmChainClient(validatorConn.GetGrpcClientConn()) } } diff --git a/validator/client/grpc-api/grpc_beacon_chain_client.go b/validator/client/grpc-api/grpc_beacon_chain_client.go index d413e4bae404..9f31a3b57bee 100644 --- a/validator/client/grpc-api/grpc_beacon_chain_client.go +++ b/validator/client/grpc-api/grpc_beacon_chain_client.go @@ -9,34 +9,34 @@ import ( "google.golang.org/grpc" ) -type grpcBeaconChainClient struct { +type grpcChainClient struct { beaconChainClient ethpb.BeaconChainClient } -func (c *grpcBeaconChainClient) GetChainHead(ctx context.Context, in *empty.Empty) (*ethpb.ChainHead, error) { +func (c *grpcChainClient) GetChainHead(ctx context.Context, in *empty.Empty) (*ethpb.ChainHead, error) { return c.beaconChainClient.GetChainHead(ctx, in) } -func (c *grpcBeaconChainClient) ListValidatorBalances(ctx context.Context, in *ethpb.ListValidatorBalancesRequest) (*ethpb.ValidatorBalances, error) { +func (c *grpcChainClient) ListValidatorBalances(ctx context.Context, in *ethpb.ListValidatorBalancesRequest) (*ethpb.ValidatorBalances, error) { return c.beaconChainClient.ListValidatorBalances(ctx, in) } -func (c *grpcBeaconChainClient) ListValidators(ctx context.Context, in *ethpb.ListValidatorsRequest) (*ethpb.Validators, error) { +func (c *grpcChainClient) ListValidators(ctx context.Context, in *ethpb.ListValidatorsRequest) (*ethpb.Validators, error) { return c.beaconChainClient.ListValidators(ctx, in) } -func (c *grpcBeaconChainClient) GetValidatorQueue(ctx context.Context, in *empty.Empty) (*ethpb.ValidatorQueue, error) { +func (c *grpcChainClient) GetValidatorQueue(ctx context.Context, in *empty.Empty) (*ethpb.ValidatorQueue, error) { return c.beaconChainClient.GetValidatorQueue(ctx, in) } -func (c *grpcBeaconChainClient) GetValidatorPerformance(ctx context.Context, in *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error) { +func (c *grpcChainClient) GetValidatorPerformance(ctx context.Context, in *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error) { return c.beaconChainClient.GetValidatorPerformance(ctx, in) } -func (c *grpcBeaconChainClient) GetValidatorParticipation(ctx context.Context, in *ethpb.GetValidatorParticipationRequest) (*ethpb.ValidatorParticipationResponse, error) { +func (c *grpcChainClient) GetValidatorParticipation(ctx context.Context, in *ethpb.GetValidatorParticipationRequest) (*ethpb.ValidatorParticipationResponse, error) { return c.beaconChainClient.GetValidatorParticipation(ctx, in) } -func NewGrpcBeaconChainClient(cc grpc.ClientConnInterface) iface.BeaconChainClient { - return &grpcBeaconChainClient{ethpb.NewBeaconChainClient(cc)} +func NewGrpcChainClient(cc grpc.ClientConnInterface) iface.ChainClient { + return &grpcChainClient{ethpb.NewBeaconChainClient(cc)} } diff --git a/validator/client/grpc-api/grpc_prysm_beacon_chain_client.go b/validator/client/grpc-api/grpc_prysm_beacon_chain_client.go index 87fad7339cf6..be9f40b3a234 100644 --- a/validator/client/grpc-api/grpc_prysm_beacon_chain_client.go +++ b/validator/client/grpc-api/grpc_prysm_beacon_chain_client.go @@ -18,12 +18,12 @@ import ( "google.golang.org/grpc" ) -type grpcPrysmBeaconChainClient struct { - beaconChainClient iface.BeaconChainClient +type grpcPrysmChainClient struct { + chainClient iface.ChainClient } -func (g grpcPrysmBeaconChainClient) GetValidatorCount(ctx context.Context, _ string, statuses []validator.Status) ([]iface.ValidatorCount, error) { - resp, err := g.beaconChainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{PageSize: 0}) +func (g grpcPrysmChainClient) GetValidatorCount(ctx context.Context, _ string, statuses []validator.Status) ([]iface.ValidatorCount, error) { + resp, err := g.chainClient.ListValidators(ctx, ðpb.ListValidatorsRequest{PageSize: 0}) if err != nil { return nil, errors.Wrap(err, "list validators failed") } @@ -33,7 +33,7 @@ func (g grpcPrysmBeaconChainClient) GetValidatorCount(ctx context.Context, _ str vals = append(vals, val.Validator) } - head, err := g.beaconChainClient.GetChainHead(ctx, &empty.Empty{}) + head, err := g.chainClient.GetChainHead(ctx, &empty.Empty{}) if err != nil { return nil, errors.Wrap(err, "get chain head") } @@ -92,6 +92,6 @@ func validatorCountByStatus(validators []*ethpb.Validator, statuses []validator. return resp, nil } -func NewGrpcPrysmBeaconChainClient(cc grpc.ClientConnInterface) iface.PrysmBeaconChainClient { - return &grpcPrysmBeaconChainClient{beaconChainClient: &grpcBeaconChainClient{ethpb.NewBeaconChainClient(cc)}} +func NewGrpcPrysmChainClient(cc grpc.ClientConnInterface) iface.PrysmChainClient { + return &grpcPrysmChainClient{chainClient: &grpcChainClient{ethpb.NewBeaconChainClient(cc)}} } diff --git a/validator/client/grpc-api/grpc_prysm_beacon_chain_client_test.go b/validator/client/grpc-api/grpc_prysm_beacon_chain_client_test.go index dc32f284597c..d383f6f678d4 100644 --- a/validator/client/grpc-api/grpc_prysm_beacon_chain_client_test.go +++ b/validator/client/grpc-api/grpc_prysm_beacon_chain_client_test.go @@ -291,8 +291,8 @@ func TestGetValidatorCount(t *testing.T) { }) } - beaconChainClient := mock.NewMockBeaconChainClient(ctrl) - beaconChainClient.EXPECT().ListValidators( + chainClient := mock.NewMockChainClient(ctrl) + chainClient.EXPECT().ListValidators( gomock.Any(), gomock.Any(), ).Return( @@ -300,7 +300,7 @@ func TestGetValidatorCount(t *testing.T) { nil, ) - beaconChainClient.EXPECT().GetChainHead( + chainClient.EXPECT().GetChainHead( gomock.Any(), gomock.Any(), ).Return( @@ -308,8 +308,8 @@ func TestGetValidatorCount(t *testing.T) { nil, ) - prysmBeaconChainClient := &grpcPrysmBeaconChainClient{ - beaconChainClient: beaconChainClient, + prysmBeaconChainClient := &grpcPrysmChainClient{ + chainClient: chainClient, } var statuses []validator.Status diff --git a/validator/client/iface/beacon_chain_client.go b/validator/client/iface/beacon_chain_client.go index 88821e0c7e50..01ec65c3306b 100644 --- a/validator/client/iface/beacon_chain_client.go +++ b/validator/client/iface/beacon_chain_client.go @@ -7,7 +7,7 @@ import ( ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" ) -type BeaconChainClient interface { +type ChainClient interface { GetChainHead(ctx context.Context, in *empty.Empty) (*ethpb.ChainHead, error) ListValidatorBalances(ctx context.Context, in *ethpb.ListValidatorBalancesRequest) (*ethpb.ValidatorBalances, error) ListValidators(ctx context.Context, in *ethpb.ListValidatorsRequest) (*ethpb.Validators, error) diff --git a/validator/client/iface/prysm_beacon_chain_client.go b/validator/client/iface/prysm_beacon_chain_client.go index 477f74ca8d88..1cb0e2095562 100644 --- a/validator/client/iface/prysm_beacon_chain_client.go +++ b/validator/client/iface/prysm_beacon_chain_client.go @@ -14,7 +14,7 @@ type ValidatorCount struct { Count uint64 } -// PrysmBeaconChainClient defines an interface required to implement all the prysm specific custom endpoints. -type PrysmBeaconChainClient interface { +// PrysmChainClient defines an interface required to implement all the prysm specific custom endpoints. +type PrysmChainClient interface { GetValidatorCount(context.Context, string, []validator.Status) ([]ValidatorCount, error) } diff --git a/validator/client/key_reload.go b/validator/client/key_reload.go index 98731fcf8fa3..777177cff860 100644 --- a/validator/client/key_reload.go +++ b/validator/client/key_reload.go @@ -39,7 +39,7 @@ func (v *validator) HandleKeyReload(ctx context.Context, currentKeys [][fieldpar // "-1" indicates that validator count endpoint is not supported by the beacon node. var valCount int64 = -1 - valCounts, err := v.prysmBeaconClient.GetValidatorCount(ctx, "head", []validator2.Status{validator2.Active}) + valCounts, err := v.prysmChainClient.GetValidatorCount(ctx, "head", []validator2.Status{validator2.Active}) if err != nil && !errors.Is(err, iface.ErrNotSupported) { return false, errors.Wrap(err, "could not get active validator count") } diff --git a/validator/client/key_reload_test.go b/validator/client/key_reload_test.go index 82e7b5b723f2..ae48c159eba4 100644 --- a/validator/client/key_reload_test.go +++ b/validator/client/key_reload_test.go @@ -29,14 +29,14 @@ func TestValidator_HandleKeyReload(t *testing.T) { active := randKeypair(t) client := validatormock.NewMockValidatorClient(ctrl) - beaconClient := validatormock.NewMockBeaconChainClient(ctrl) - prysmBeaconClient := validatormock.NewMockPrysmBeaconChainClient(ctrl) + chainClient := validatormock.NewMockChainClient(ctrl) + prysmChainClient := validatormock.NewMockPrysmChainClient(ctrl) v := validator{ - validatorClient: client, - keyManager: newMockKeymanager(t, inactive), - genesisTime: 1, - beaconClient: beaconClient, - prysmBeaconClient: prysmBeaconClient, + validatorClient: client, + km: newMockKeymanager(t, inactive), + genesisTime: 1, + chainClient: chainClient, + prysmChainClient: prysmChainClient, } resp := testutil.GenerateMultipleValidatorStatusResponse([][]byte{inactive.pub[:], active.pub[:]}) @@ -48,7 +48,7 @@ func TestValidator_HandleKeyReload(t *testing.T) { PublicKeys: [][]byte{inactive.pub[:], active.pub[:]}, }, ).Return(resp, nil) - prysmBeaconClient.EXPECT().GetValidatorCount( + prysmChainClient.EXPECT().GetValidatorCount( gomock.Any(), "head", []validator2.Status{validator2.Active}, @@ -65,15 +65,15 @@ func TestValidator_HandleKeyReload(t *testing.T) { hook := logTest.NewGlobal() client := validatormock.NewMockValidatorClient(ctrl) - beaconClient := validatormock.NewMockBeaconChainClient(ctrl) - prysmBeaconClient := validatormock.NewMockPrysmBeaconChainClient(ctrl) + chainClient := validatormock.NewMockChainClient(ctrl) + prysmChainClient := validatormock.NewMockPrysmChainClient(ctrl) kp := randKeypair(t) v := validator{ - validatorClient: client, - keyManager: newMockKeymanager(t, kp), - genesisTime: 1, - beaconClient: beaconClient, - prysmBeaconClient: prysmBeaconClient, + validatorClient: client, + km: newMockKeymanager(t, kp), + genesisTime: 1, + chainClient: chainClient, + prysmChainClient: prysmChainClient, } resp := testutil.GenerateMultipleValidatorStatusResponse([][]byte{kp.pub[:]}) @@ -84,7 +84,7 @@ func TestValidator_HandleKeyReload(t *testing.T) { PublicKeys: [][]byte{kp.pub[:]}, }, ).Return(resp, nil) - prysmBeaconClient.EXPECT().GetValidatorCount( + prysmChainClient.EXPECT().GetValidatorCount( gomock.Any(), "head", []validator2.Status{validator2.Active}, @@ -102,7 +102,7 @@ func TestValidator_HandleKeyReload(t *testing.T) { client := validatormock.NewMockValidatorClient(ctrl) v := validator{ validatorClient: client, - keyManager: newMockKeymanager(t, kp), + km: newMockKeymanager(t, kp), genesisTime: 1, } diff --git a/validator/client/metrics.go b/validator/client/metrics.go index 69462d50a77c..b5668c154380 100644 --- a/validator/client/metrics.go +++ b/validator/client/metrics.go @@ -234,13 +234,13 @@ func (v *validator) LogValidatorGainsAndLosses(ctx context.Context, slot primiti // Do nothing unless we are at the end of the epoch, and not in the first epoch. return nil } - if !v.logValidatorBalances { + if !v.logValidatorPerformance { return nil } var pks [][fieldparams.BLSPubkeyLength]byte var err error - pks, err = v.keyManager.FetchValidatingPublicKeys(ctx) + pks, err = v.km.FetchValidatingPublicKeys(ctx) if err != nil { return err } @@ -249,7 +249,7 @@ func (v *validator) LogValidatorGainsAndLosses(ctx context.Context, slot primiti req := ðpb.ValidatorPerformanceRequest{ PublicKeys: pubKeys, } - resp, err := v.beaconClient.GetValidatorPerformance(ctx, req) + resp, err := v.chainClient.GetValidatorPerformance(ctx, req) if err != nil { return err } @@ -270,11 +270,11 @@ func (v *validator) LogValidatorGainsAndLosses(ctx context.Context, slot primiti v.voteStats.startEpoch = prevEpoch } } - v.prevBalanceLock.Lock() + v.prevEpochBalancesLock.Lock() for i, pubKey := range resp.PublicKeys { v.logForEachValidator(i, pubKey, resp, slot, prevEpoch) } - v.prevBalanceLock.Unlock() + v.prevEpochBalancesLock.Unlock() v.UpdateLogAggregateStats(resp, slot) return nil @@ -284,7 +284,7 @@ func (v *validator) logForEachValidator(index int, pubKey []byte, resp *ethpb.Va truncatedKey := fmt.Sprintf("%#x", bytesutil.Trunc(pubKey)) pubKeyBytes := bytesutil.ToBytes48(pubKey) if slot < params.BeaconConfig().SlotsPerEpoch { - v.prevBalance[pubKeyBytes] = params.BeaconConfig().MaxEffectiveBalance + v.prevEpochBalances[pubKeyBytes] = params.BeaconConfig().MaxEffectiveBalance } // Safely load data from response with slice out of bounds checks. The server should return @@ -325,7 +325,7 @@ func (v *validator) logForEachValidator(index int, pubKey []byte, resp *ethpb.Va fmtKey := fmt.Sprintf("%#x", pubKey) gweiPerEth := float64(params.BeaconConfig().GweiPerEth) - if v.prevBalance[pubKeyBytes] > 0 { + if v.prevEpochBalances[pubKeyBytes] > 0 { newBalance := float64(balAfterEpoch) / gweiPerEth prevBalance := float64(balBeforeEpoch) / gweiPerEth startBalance := float64(v.startBalances[pubKeyBytes]) / gweiPerEth @@ -380,7 +380,7 @@ func (v *validator) logForEachValidator(index int, pubKey []byte, resp *ethpb.Va } } } - v.prevBalance[pubKeyBytes] = balBeforeEpoch + v.prevEpochBalances[pubKeyBytes] = balBeforeEpoch } // UpdateLogAggregateStats updates and logs the voteStats struct of a validator using the RPC response obtained from LogValidatorGainsAndLosses. @@ -438,12 +438,12 @@ func (v *validator) UpdateLogAggregateStats(resp *ethpb.ValidatorPerformanceResp log.WithFields(epochSummaryFields).Info("Previous epoch aggregated voting summary") var totalStartBal, totalPrevBal uint64 - v.prevBalanceLock.RLock() + v.prevEpochBalancesLock.RLock() for i, val := range v.startBalances { totalStartBal += val - totalPrevBal += v.prevBalance[i] + totalPrevBal += v.prevEpochBalances[i] } - v.prevBalanceLock.RUnlock() + v.prevEpochBalancesLock.RUnlock() if totalStartBal == 0 || summary.totalAttestedCount == 0 { log.Error("Failed to print launch summary: one or more divisors is 0") diff --git a/validator/client/metrics_test.go b/validator/client/metrics_test.go index 494a990dfadd..86aae3bc1341 100644 --- a/validator/client/metrics_test.go +++ b/validator/client/metrics_test.go @@ -15,9 +15,9 @@ import ( func TestUpdateLogAggregateStats(t *testing.T) { v := &validator{ - logValidatorBalances: true, - startBalances: make(map[[fieldparams.BLSPubkeyLength]byte]uint64), - prevBalance: make(map[[fieldparams.BLSPubkeyLength]byte]uint64), + logValidatorPerformance: true, + startBalances: make(map[[fieldparams.BLSPubkeyLength]byte]uint64), + prevEpochBalances: make(map[[fieldparams.BLSPubkeyLength]byte]uint64), voteStats: voteStats{ startEpoch: 0, // this would otherwise have been previously set in LogValidatorGainsAndLosses() }, @@ -66,9 +66,9 @@ func TestUpdateLogAggregateStats(t *testing.T) { }, } - v.prevBalance[pubKeyBytes[0]] = uint64(33200000000) - v.prevBalance[pubKeyBytes[1]] = uint64(33300000000) - v.prevBalance[pubKeyBytes[2]] = uint64(31000000000) + v.prevEpochBalances[pubKeyBytes[0]] = uint64(33200000000) + v.prevEpochBalances[pubKeyBytes[1]] = uint64(33300000000) + v.prevEpochBalances[pubKeyBytes[2]] = uint64(31000000000) var hook *logTest.Hook @@ -89,9 +89,9 @@ func TestUpdateLogAggregateStats(t *testing.T) { func TestUpdateLogAltairAggregateStats(t *testing.T) { v := &validator{ - logValidatorBalances: true, - startBalances: make(map[[fieldparams.BLSPubkeyLength]byte]uint64), - prevBalance: make(map[[fieldparams.BLSPubkeyLength]byte]uint64), + logValidatorPerformance: true, + startBalances: make(map[[fieldparams.BLSPubkeyLength]byte]uint64), + prevEpochBalances: make(map[[fieldparams.BLSPubkeyLength]byte]uint64), voteStats: voteStats{ startEpoch: params.BeaconConfig().AltairForkEpoch, // this would otherwise have been previously set in LogValidatorGainsAndLosses() }, @@ -141,9 +141,9 @@ func TestUpdateLogAltairAggregateStats(t *testing.T) { }, } - v.prevBalance[pubKeyBytes[0]] = uint64(33200000000) - v.prevBalance[pubKeyBytes[1]] = uint64(33300000000) - v.prevBalance[pubKeyBytes[2]] = uint64(31000000000) + v.prevEpochBalances[pubKeyBytes[0]] = uint64(33200000000) + v.prevEpochBalances[pubKeyBytes[1]] = uint64(33300000000) + v.prevEpochBalances[pubKeyBytes[2]] = uint64(31000000000) var hook *logTest.Hook diff --git a/validator/client/propose.go b/validator/client/propose.go index 0864d389461e..3d70c42fb1a6 100644 --- a/validator/client/propose.go +++ b/validator/client/propose.go @@ -341,7 +341,7 @@ func (v *validator) signRandaoReveal(ctx context.Context, pubKey [fieldparams.BL if err != nil { return nil, err } - randaoReveal, err = v.keyManager.Sign(ctx, &validatorpb.SignRequest{ + randaoReveal, err = v.km.Sign(ctx, &validatorpb.SignRequest{ PublicKey: pubKey[:], SigningRoot: root[:], SignatureDomain: domain.SignatureDomain, @@ -373,7 +373,7 @@ func (v *validator) signBlock(ctx context.Context, pubKey [fieldparams.BLSPubkey if err != nil { return nil, [32]byte{}, err } - sig, err := v.keyManager.Sign(ctx, &validatorpb.SignRequest{ + sig, err := v.km.Sign(ctx, &validatorpb.SignRequest{ PublicKey: pubKey[:], SigningRoot: blockRoot[:], SignatureDomain: domain.SignatureDomain, diff --git a/validator/client/propose_test.go b/validator/client/propose_test.go index b7ab7018f27a..ac27dac94bea 100644 --- a/validator/client/propose_test.go +++ b/validator/client/propose_test.go @@ -94,7 +94,7 @@ func setupWithKey(t *testing.T, validatorKey bls.SecretKey, isSlashingProtection validator := &validator{ db: valDB, - keyManager: newMockKeymanager(t, keypair{pub: pubKey, pri: validatorKey}), + km: newMockKeymanager(t, keypair{pub: pubKey, pri: validatorKey}), validatorClient: m.validatorClient, graffiti: []byte{}, submittedAtts: make(map[submittedAttKey]*submittedAtt), @@ -879,7 +879,7 @@ func TestSignBlock(t *testing.T) { kp := testKeyFromBytes(t, []byte{1}) - validator.keyManager = newMockKeymanager(t, kp) + validator.km = newMockKeymanager(t, kp) b, err := blocks.NewBeaconBlock(blk.Block) require.NoError(t, err) sig, blockRoot, err := validator.signBlock(ctx, kp.pub, 0, 0, b) @@ -915,7 +915,7 @@ func TestSignAltairBlock(t *testing.T) { blk := util.NewBeaconBlockAltair() blk.Block.Slot = 1 blk.Block.ProposerIndex = 100 - validator.keyManager = newMockKeymanager(t, kp) + validator.km = newMockKeymanager(t, kp) wb, err := blocks.NewBeaconBlock(blk.Block) require.NoError(t, err) sig, blockRoot, err := validator.signBlock(ctx, kp.pub, 0, 0, wb) @@ -948,7 +948,7 @@ func TestSignBellatrixBlock(t *testing.T) { blk.Block.ProposerIndex = 100 kp := randKeypair(t) - validator.keyManager = newMockKeymanager(t, kp) + validator.km = newMockKeymanager(t, kp) wb, err := blocks.NewBeaconBlock(blk.Block) require.NoError(t, err) sig, blockRoot, err := validator.signBlock(ctx, kp.pub, 0, 0, wb) diff --git a/validator/client/service.go b/validator/client/service.go index a12ac3068f0a..6e5a4cd6900a 100644 --- a/validator/client/service.go +++ b/validator/client/service.go @@ -3,7 +3,6 @@ package client import ( "context" "net/http" - "strings" "time" "github.com/dgraph-io/ristretto" @@ -35,75 +34,54 @@ import ( "go.opencensus.io/plugin/ocgrpc" "google.golang.org/grpc" "google.golang.org/grpc/credentials" - "google.golang.org/protobuf/types/known/emptypb" ) -// SyncChecker is able to determine if a beacon node is currently -// going through chain synchronization. -type SyncChecker interface { - Syncing(ctx context.Context) (bool, error) -} - -// GenesisFetcher can retrieve genesis information such as -// the genesis time and the validator deposit contract address. -type GenesisFetcher interface { - GenesisInfo(ctx context.Context) (*ethpb.Genesis, error) -} - // ValidatorService represents a service to manage the validator client // routine. type ValidatorService struct { - useWeb bool - emitAccountMetrics bool - logValidatorBalances bool - distributed bool - interopKeysConfig *local.InteropKeymanagerConfig - conn validatorHelpers.NodeConnection - grpcRetryDelay time.Duration - grpcRetries uint - maxCallRecvMsgSize int - cancel context.CancelFunc - walletInitializedFeed *event.Feed - wallet *wallet.Wallet - graffitiStruct *graffiti.Graffiti - dataDir string - withCert string - endpoint string - ctx context.Context - validator iface.Validator - db db.Database - grpcHeaders []string - graffiti []byte - Web3SignerConfig *remoteweb3signer.SetupConfig - proposerSettings *proposer.Settings - validatorsRegBatchSize int + ctx context.Context + cancel context.CancelFunc + validator iface.Validator + db db.Database + conn validatorHelpers.NodeConnection + wallet *wallet.Wallet + walletInitializedFeed *event.Feed + graffiti []byte + graffitiStruct *graffiti.Graffiti + interopKeysConfig *local.InteropKeymanagerConfig + web3SignerConfig *remoteweb3signer.SetupConfig + proposerSettings *proposer.Settings + validatorsRegBatchSize int + useWeb bool + emitAccountMetrics bool + logValidatorPerformance bool + distributed bool } // Config for the validator service. type Config struct { - UseWeb bool - LogValidatorBalances bool - EmitAccountMetrics bool - Distributed bool - InteropKeysConfig *local.InteropKeymanagerConfig - Wallet *wallet.Wallet - WalletInitializedFeed *event.Feed - GrpcRetriesFlag uint - GrpcMaxCallRecvMsgSizeFlag int - GrpcRetryDelay time.Duration - GraffitiStruct *graffiti.Graffiti - Validator iface.Validator - ValDB db.Database - CertFlag string - DataDir string - GrpcHeadersFlag string - GraffitiFlag string - Endpoint string - Web3SignerConfig *remoteweb3signer.SetupConfig - ProposerSettings *proposer.Settings - BeaconApiEndpoint string - BeaconApiTimeout time.Duration - ValidatorsRegBatchSize int + Validator iface.Validator + DB db.Database + Wallet *wallet.Wallet + WalletInitializedFeed *event.Feed + GRPCMaxCallRecvMsgSize int + GRPCRetries uint + GRPCRetryDelay time.Duration + GRPCHeaders []string + BeaconNodeGRPCEndpoint string + BeaconNodeCert string + BeaconApiEndpoint string + BeaconApiTimeout time.Duration + Graffiti string + GraffitiStruct *graffiti.Graffiti + InteropKmConfig *local.InteropKeymanagerConfig + Web3SignerConfig *remoteweb3signer.SetupConfig + ProposerSettings *proposer.Settings + ValidatorsRegBatchSize int + UseWeb bool + LogValidatorPerformance bool + EmitAccountMetrics bool + Distributed bool } // NewValidatorService creates a new validator service for the service @@ -111,48 +89,41 @@ type Config struct { func NewValidatorService(ctx context.Context, cfg *Config) (*ValidatorService, error) { ctx, cancel := context.WithCancel(ctx) s := &ValidatorService{ - ctx: ctx, - cancel: cancel, - endpoint: cfg.Endpoint, - withCert: cfg.CertFlag, - dataDir: cfg.DataDir, - graffiti: []byte(cfg.GraffitiFlag), - logValidatorBalances: cfg.LogValidatorBalances, - emitAccountMetrics: cfg.EmitAccountMetrics, - maxCallRecvMsgSize: cfg.GrpcMaxCallRecvMsgSizeFlag, - grpcRetries: cfg.GrpcRetriesFlag, - grpcRetryDelay: cfg.GrpcRetryDelay, - grpcHeaders: strings.Split(cfg.GrpcHeadersFlag, ","), - validator: cfg.Validator, - db: cfg.ValDB, - wallet: cfg.Wallet, - walletInitializedFeed: cfg.WalletInitializedFeed, - useWeb: cfg.UseWeb, - interopKeysConfig: cfg.InteropKeysConfig, - graffitiStruct: cfg.GraffitiStruct, - Web3SignerConfig: cfg.Web3SignerConfig, - proposerSettings: cfg.ProposerSettings, - validatorsRegBatchSize: cfg.ValidatorsRegBatchSize, - distributed: cfg.Distributed, + ctx: ctx, + cancel: cancel, + validator: cfg.Validator, + db: cfg.DB, + wallet: cfg.Wallet, + walletInitializedFeed: cfg.WalletInitializedFeed, + graffiti: []byte(cfg.Graffiti), + graffitiStruct: cfg.GraffitiStruct, + interopKeysConfig: cfg.InteropKmConfig, + web3SignerConfig: cfg.Web3SignerConfig, + proposerSettings: cfg.ProposerSettings, + validatorsRegBatchSize: cfg.ValidatorsRegBatchSize, + useWeb: cfg.UseWeb, + emitAccountMetrics: cfg.EmitAccountMetrics, + logValidatorPerformance: cfg.LogValidatorPerformance, + distributed: cfg.Distributed, } dialOpts := ConstructDialOptions( - s.maxCallRecvMsgSize, - s.withCert, - s.grpcRetries, - s.grpcRetryDelay, + cfg.GRPCMaxCallRecvMsgSize, + cfg.BeaconNodeCert, + cfg.GRPCRetries, + cfg.GRPCRetryDelay, ) if dialOpts == nil { return s, nil } - s.ctx = grpcutil.AppendHeaders(ctx, s.grpcHeaders) + s.ctx = grpcutil.AppendHeaders(ctx, cfg.GRPCHeaders) - grpcConn, err := grpc.DialContext(ctx, s.endpoint, dialOpts...) + grpcConn, err := grpc.DialContext(ctx, cfg.BeaconNodeGRPCEndpoint, dialOpts...) if err != nil { return s, err } - if s.withCert != "" { + if cfg.BeaconNodeCert != "" { log.Info("Established secure gRPC connection") } s.conn = validatorHelpers.NewNodeConnection( @@ -202,38 +173,39 @@ func (v *ValidatorService) Start() { validatorClient := validatorClientFactory.NewValidatorClient(v.conn, restHandler) valStruct := &validator{ - validatorClient: validatorClient, - beaconClient: beaconChainClientFactory.NewBeaconChainClient(v.conn, restHandler), - nodeClient: nodeClientFactory.NewNodeClient(v.conn, restHandler), - prysmBeaconClient: beaconChainClientFactory.NewPrysmBeaconClient(v.conn, restHandler), - db: v.db, - graffiti: v.graffiti, - logValidatorBalances: v.logValidatorBalances, - emitAccountMetrics: v.emitAccountMetrics, + slotFeed: new(event.Feed), startBalances: make(map[[fieldparams.BLSPubkeyLength]byte]uint64), - prevBalance: make(map[[fieldparams.BLSPubkeyLength]byte]uint64), + prevEpochBalances: make(map[[fieldparams.BLSPubkeyLength]byte]uint64), + blacklistedPubkeys: slashablePublicKeys, pubkeyToValidatorIndex: make(map[[fieldparams.BLSPubkeyLength]byte]primitives.ValidatorIndex), - signedValidatorRegistrations: make(map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1), - submittedAtts: make(map[submittedAttKey]*submittedAtt), - submittedAggregates: make(map[submittedAttKey]*submittedAtt), - domainDataCache: cache, - aggregatedSlotCommitteeIDCache: aggregatedSlotCommitteeIDCache, - voteStats: voteStats{startEpoch: primitives.Epoch(^uint64(0))}, - syncCommitteeStats: syncCommitteeStats{}, - useWeb: v.useWeb, - interopKeysConfig: v.interopKeysConfig, wallet: v.wallet, + walletInitializedChan: make(chan *wallet.Wallet, 1), walletInitializedFeed: v.walletInitializedFeed, - slotFeed: new(event.Feed), + graffiti: v.graffiti, graffitiStruct: v.graffitiStruct, graffitiOrderedIndex: graffitiOrderedIndex, - eipImportBlacklistedPublicKeys: slashablePublicKeys, - Web3SignerConfig: v.Web3SignerConfig, + validatorClient: validatorClient, + chainClient: beaconChainClientFactory.NewChainClient(v.conn, restHandler), + nodeClient: nodeClientFactory.NewNodeClient(v.conn, restHandler), + prysmChainClient: beaconChainClientFactory.NewPrysmChainClient(v.conn, restHandler), + db: v.db, + km: nil, + web3SignerConfig: v.web3SignerConfig, proposerSettings: v.proposerSettings, - walletInitializedChannel: make(chan *wallet.Wallet, 1), + signedValidatorRegistrations: make(map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1), validatorsRegBatchSize: v.validatorsRegBatchSize, - distributed: v.distributed, + interopKeysConfig: v.interopKeysConfig, attSelections: make(map[attSelectionKey]iface.BeaconCommitteeSelection), + aggregatedSlotCommitteeIDCache: aggregatedSlotCommitteeIDCache, + domainDataCache: cache, + voteStats: voteStats{startEpoch: primitives.Epoch(^uint64(0))}, + syncCommitteeStats: syncCommitteeStats{}, + submittedAtts: make(map[submittedAttKey]*submittedAtt), + submittedAggregates: make(map[submittedAttKey]*submittedAtt), + logValidatorPerformance: v.logValidatorPerformance, + emitAccountMetrics: v.emitAccountMetrics, + useWeb: v.useWeb, + distributed: v.distributed, } v.validator = valStruct @@ -268,6 +240,11 @@ func (v *ValidatorService) Keymanager() (keymanager.IKeymanager, error) { return v.validator.Keymanager() } +// RemoteSignerConfig returns the web3signer configuration +func (v *ValidatorService) RemoteSignerConfig() *remoteweb3signer.SetupConfig { + return v.web3SignerConfig +} + // ProposerSettings returns a deep copy of the underlying proposer settings in the validator func (v *ValidatorService) ProposerSettings() *proposer.Settings { settings := v.validator.ProposerSettings() @@ -342,23 +319,6 @@ func ConstructDialOptions( return dialOpts } -// Syncing returns whether or not the beacon node is currently synchronizing the chain. -func (v *ValidatorService) Syncing(ctx context.Context) (bool, error) { - nc := ethpb.NewNodeClient(v.conn.GetGrpcClientConn()) - resp, err := nc.GetSyncStatus(ctx, &emptypb.Empty{}) - if err != nil { - return false, err - } - return resp.Syncing, nil -} - -// GenesisInfo queries the beacon node for the chain genesis info containing -// the genesis time along with the validator deposit contract address. -func (v *ValidatorService) GenesisInfo(ctx context.Context) (*ethpb.Genesis, error) { - nc := ethpb.NewNodeClient(v.conn.GetGrpcClientConn()) - return nc.GetGenesis(ctx, &emptypb.Empty{}) -} - func (v *ValidatorService) GetGraffiti(ctx context.Context, pubKey [fieldparams.BLSPubkeyLength]byte) ([]byte, error) { if v.validator == nil { return nil, errors.New("validator is unavailable") diff --git a/validator/client/service_test.go b/validator/client/service_test.go index 1b670aae7099..6e6c5e2bbca1 100644 --- a/validator/client/service_test.go +++ b/validator/client/service_test.go @@ -2,6 +2,7 @@ package client import ( "context" + "strings" "testing" "time" @@ -13,8 +14,6 @@ import ( ) var _ runtime.Service = (*ValidatorService)(nil) -var _ GenesisFetcher = (*ValidatorService)(nil) -var _ SyncChecker = (*ValidatorService)(nil) func TestStop_CancelsContext(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) @@ -59,7 +58,7 @@ func TestStart_GrpcHeaders(t *testing.T) { "Authorization", "this is a valid value", }, } { - cfg := &Config{GrpcHeadersFlag: input} + cfg := &Config{GRPCHeaders: strings.Split(input, ",")} validatorService, err := NewValidatorService(ctx, cfg) require.NoError(t, err) md, _ := metadata.FromOutgoingContext(validatorService.ctx) diff --git a/validator/client/sync_committee.go b/validator/client/sync_committee.go index 7658e49ad4a2..bea78e5e110a 100644 --- a/validator/client/sync_committee.go +++ b/validator/client/sync_committee.go @@ -58,7 +58,7 @@ func (v *validator) SubmitSyncCommitteeMessage(ctx context.Context, slot primiti return } - sig, err := v.keyManager.Sign(ctx, &validatorpb.SignRequest{ + sig, err := v.km.Sign(ctx, &validatorpb.SignRequest{ PublicKey: pubKey[:], SigningRoot: r[:], SignatureDomain: d.SignatureDomain, @@ -243,7 +243,7 @@ func (v *validator) signSyncSelectionData(ctx context.Context, pubKey [fieldpara if err != nil { return nil, err } - sig, err := v.keyManager.Sign(ctx, &validatorpb.SignRequest{ + sig, err := v.km.Sign(ctx, &validatorpb.SignRequest{ PublicKey: pubKey[:], SigningRoot: root[:], SignatureDomain: domain.SignatureDomain, @@ -266,7 +266,7 @@ func (v *validator) signContributionAndProof(ctx context.Context, pubKey [fieldp if err != nil { return nil, err } - sig, err := v.keyManager.Sign(ctx, &validatorpb.SignRequest{ + sig, err := v.km.Sign(ctx, &validatorpb.SignRequest{ PublicKey: pubKey[:], SigningRoot: root[:], SignatureDomain: d.SignatureDomain, diff --git a/validator/client/validator.go b/validator/client/validator.go index 83a0c431c155..c78ef5fd1246 100644 --- a/validator/client/validator.go +++ b/validator/client/validator.go @@ -41,7 +41,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/validator/accounts/wallet" beacon_api "github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api" "github.com/prysmaticlabs/prysm/v5/validator/client/iface" - vdb "github.com/prysmaticlabs/prysm/v5/validator/db" + "github.com/prysmaticlabs/prysm/v5/validator/db" dbCommon "github.com/prysmaticlabs/prysm/v5/validator/db/common" "github.com/prysmaticlabs/prysm/v5/validator/graffiti" "github.com/prysmaticlabs/prysm/v5/validator/keymanager" @@ -69,51 +69,51 @@ var ( ) type validator struct { - logValidatorBalances bool - useWeb bool - emitAccountMetrics bool - distributed bool - domainDataLock sync.RWMutex - attLogsLock sync.Mutex - aggregatedSlotCommitteeIDCacheLock sync.Mutex - highestValidSlotLock sync.Mutex - prevBalanceLock sync.RWMutex - slashableKeysLock sync.RWMutex - attSelectionLock sync.Mutex - eipImportBlacklistedPublicKeys map[[fieldparams.BLSPubkeyLength]byte]bool - walletInitializedFeed *event.Feed - submittedAtts map[submittedAttKey]*submittedAtt - submittedAggregates map[submittedAttKey]*submittedAtt - startBalances map[[fieldparams.BLSPubkeyLength]byte]uint64 - dutiesLock sync.RWMutex duties *ethpb.DutiesResponse - prevBalance map[[fieldparams.BLSPubkeyLength]byte]uint64 - pubkeyToValidatorIndex map[[fieldparams.BLSPubkeyLength]byte]primitives.ValidatorIndex - signedValidatorRegistrations map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1 - attSelections map[attSelectionKey]iface.BeaconCommitteeSelection - graffitiOrderedIndex uint64 - aggregatedSlotCommitteeIDCache *lru.Cache - domainDataCache *ristretto.Cache - highestValidSlot primitives.Slot + ticker slots.Ticker genesisTime uint64 + highestValidSlot primitives.Slot slotFeed *event.Feed - interopKeysConfig *local.InteropKeymanagerConfig + startBalances map[[fieldparams.BLSPubkeyLength]byte]uint64 + prevEpochBalances map[[fieldparams.BLSPubkeyLength]byte]uint64 + blacklistedPubkeys map[[fieldparams.BLSPubkeyLength]byte]bool + pubkeyToValidatorIndex map[[fieldparams.BLSPubkeyLength]byte]primitives.ValidatorIndex wallet *wallet.Wallet + walletInitializedChan chan *wallet.Wallet + walletInitializedFeed *event.Feed + graffiti []byte graffitiStruct *graffiti.Graffiti - beaconClient iface.BeaconChainClient - nodeClient iface.NodeClient + graffitiOrderedIndex uint64 validatorClient iface.ValidatorClient - prysmBeaconClient iface.PrysmBeaconChainClient - db vdb.Database - keyManager keymanager.IKeymanager - ticker slots.Ticker - graffiti []byte - voteStats voteStats - syncCommitteeStats syncCommitteeStats - Web3SignerConfig *remoteweb3signer.SetupConfig + chainClient iface.ChainClient + nodeClient iface.NodeClient + prysmChainClient iface.PrysmChainClient + db db.Database + km keymanager.IKeymanager + web3SignerConfig *remoteweb3signer.SetupConfig proposerSettings *proposer.Settings - walletInitializedChannel chan *wallet.Wallet + signedValidatorRegistrations map[[fieldparams.BLSPubkeyLength]byte]*ethpb.SignedValidatorRegistrationV1 validatorsRegBatchSize int + interopKeysConfig *local.InteropKeymanagerConfig + attSelections map[attSelectionKey]iface.BeaconCommitteeSelection + aggregatedSlotCommitteeIDCache *lru.Cache + domainDataCache *ristretto.Cache + voteStats voteStats + syncCommitteeStats syncCommitteeStats + submittedAtts map[submittedAttKey]*submittedAtt + submittedAggregates map[submittedAttKey]*submittedAtt + logValidatorPerformance bool + emitAccountMetrics bool + useWeb bool + distributed bool + domainDataLock sync.RWMutex + attLogsLock sync.Mutex + aggregatedSlotCommitteeIDCacheLock sync.Mutex + highestValidSlotLock sync.Mutex + prevEpochBalancesLock sync.RWMutex + blacklistedPubkeysLock sync.RWMutex + attSelectionLock sync.Mutex + dutiesLock sync.RWMutex } type validatorStatus struct { @@ -132,7 +132,7 @@ func (v *validator) Done() { v.ticker.Done() } -// WaitForKeymanagerInitialization checks if the validator needs to wait for +// WaitForKmInitialization checks if the validator needs to wait for keymanager initialization. func (v *validator) WaitForKeymanagerInitialization(ctx context.Context) error { genesisRoot, err := v.db.GenesisValidatorsRoot(ctx) if err != nil { @@ -142,32 +142,32 @@ func (v *validator) WaitForKeymanagerInitialization(ctx context.Context) error { if v.useWeb && v.wallet == nil { log.Info("Waiting for keymanager to initialize validator client with web UI") // if wallet is not set, wait for it to be set through the UI - km, err := waitForWebWalletInitialization(ctx, v.walletInitializedFeed, v.walletInitializedChannel) + km, err := waitForWebWalletInitialization(ctx, v.walletInitializedFeed, v.walletInitializedChan) if err != nil { return err } - v.keyManager = km + v.km = km } else { if v.interopKeysConfig != nil { keyManager, err := local.NewInteropKeymanager(ctx, v.interopKeysConfig.Offset, v.interopKeysConfig.NumValidatorKeys) if err != nil { return errors.Wrap(err, "could not generate interop keys for key manager") } - v.keyManager = keyManager + v.km = keyManager } else if v.wallet == nil { return errors.New("wallet not set") } else { - if v.Web3SignerConfig != nil { - v.Web3SignerConfig.GenesisValidatorsRoot = genesisRoot + if v.web3SignerConfig != nil { + v.web3SignerConfig.GenesisValidatorsRoot = genesisRoot } - keyManager, err := v.wallet.InitializeKeymanager(ctx, accountsiface.InitKeymanagerConfig{ListenForChanges: true, Web3SignerConfig: v.Web3SignerConfig}) + keyManager, err := v.wallet.InitializeKeymanager(ctx, accountsiface.InitKeymanagerConfig{ListenForChanges: true, Web3SignerConfig: v.web3SignerConfig}) if err != nil { return errors.Wrap(err, "could not initialize key manager") } - v.keyManager = keyManager + v.km = keyManager } } - recheckKeys(ctx, v.db, v.keyManager) + recheckKeys(ctx, v.db, v.km) return nil } @@ -197,23 +197,22 @@ func waitForWebWalletInitialization( } // recheckKeys checks if the validator has any keys that need to be rechecked. -// the keymanager implements a subscription to push these updates to the validator. -func recheckKeys(ctx context.Context, valDB vdb.Database, keyManager keymanager.IKeymanager) { +// The keymanager implements a subscription to push these updates to the validator. +func recheckKeys(ctx context.Context, valDB db.Database, km keymanager.IKeymanager) { var validatingKeys [][fieldparams.BLSPubkeyLength]byte var err error - validatingKeys, err = keyManager.FetchValidatingPublicKeys(ctx) + validatingKeys, err = km.FetchValidatingPublicKeys(ctx) if err != nil { log.WithError(err).Debug("Could not fetch validating keys") } if err := valDB.UpdatePublicKeysBuckets(validatingKeys); err != nil { - log.WithError(err).Debug("Could not update public keys buckets") + go recheckValidatingKeysBucket(ctx, valDB, km) } - go recheckValidatingKeysBucket(ctx, valDB, keyManager) } // to accounts changes in the keymanager, then updates those keys' // buckets in bolt DB if a bucket for a key does not exist. -func recheckValidatingKeysBucket(ctx context.Context, valDB vdb.Database, km keymanager.IKeymanager) { +func recheckValidatingKeysBucket(ctx context.Context, valDB db.Database, km keymanager.IKeymanager) { importedKeymanager, ok := km.(*local.Keymanager) if !ok { return @@ -403,7 +402,7 @@ func (v *validator) checkAndLogValidatorStatus(statuses []*validatorStatus, acti func (v *validator) CanonicalHeadSlot(ctx context.Context) (primitives.Slot, error) { ctx, span := trace.StartSpan(ctx, "validator.CanonicalHeadSlot") defer span.End() - head, err := v.beaconClient.GetChainHead(ctx, &emptypb.Empty{}) + head, err := v.chainClient.GetChainHead(ctx, &emptypb.Empty{}) if err != nil { return 0, errors.Wrap(client.ErrConnectionIssue, err.Error()) } @@ -427,7 +426,7 @@ func (v *validator) CheckDoppelGanger(ctx context.Context) error { if !features.Get().EnableDoppelGanger { return nil } - pubkeys, err := v.keyManager.FetchValidatingPublicKeys(ctx) + pubkeys, err := v.km.FetchValidatingPublicKeys(ctx) if err != nil { return err } @@ -533,16 +532,16 @@ func (v *validator) UpdateDuties(ctx context.Context, slot primitives.Slot) erro ctx, span := trace.StartSpan(ctx, "validator.UpdateAssignments") defer span.End() - validatingKeys, err := v.keyManager.FetchValidatingPublicKeys(ctx) + validatingKeys, err := v.km.FetchValidatingPublicKeys(ctx) if err != nil { return err } // Filter out the slashable public keys from the duties request. filteredKeys := make([][fieldparams.BLSPubkeyLength]byte, 0, len(validatingKeys)) - v.slashableKeysLock.RLock() + v.blacklistedPubkeysLock.RLock() for _, pubKey := range validatingKeys { - if ok := v.eipImportBlacklistedPublicKeys[pubKey]; !ok { + if ok := v.blacklistedPubkeys[pubKey]; !ok { filteredKeys = append(filteredKeys, pubKey) } else { log.WithField( @@ -551,7 +550,7 @@ func (v *validator) UpdateDuties(ctx context.Context, slot primitives.Slot) erro "in request to update validator duties") } } - v.slashableKeysLock.RUnlock() + v.blacklistedPubkeysLock.RUnlock() req := ðpb.DutiesRequest{ Epoch: primitives.Epoch(slot / params.BeaconConfig().SlotsPerEpoch), @@ -601,28 +600,28 @@ func (v *validator) UpdateDuties(ctx context.Context, slot primitives.Slot) erro // subscribeToSubnets iterates through each validator duty, signs each slot, and asks beacon node // to eagerly subscribe to subnets so that the aggregator has attestations to aggregate. -func (v *validator) subscribeToSubnets(ctx context.Context, res *ethpb.DutiesResponse) error { - subscribeSlots := make([]primitives.Slot, 0, len(res.CurrentEpochDuties)+len(res.NextEpochDuties)) - subscribeCommitteeIndices := make([]primitives.CommitteeIndex, 0, len(res.CurrentEpochDuties)+len(res.NextEpochDuties)) - subscribeIsAggregator := make([]bool, 0, len(res.CurrentEpochDuties)+len(res.NextEpochDuties)) - activeDuties := make([]*ethpb.DutiesResponse_Duty, 0, len(res.CurrentEpochDuties)+len(res.NextEpochDuties)) +func (v *validator) subscribeToSubnets(ctx context.Context, duties *ethpb.DutiesResponse) error { + subscribeSlots := make([]primitives.Slot, 0, len(duties.CurrentEpochDuties)+len(duties.NextEpochDuties)) + subscribeCommitteeIndices := make([]primitives.CommitteeIndex, 0, len(duties.CurrentEpochDuties)+len(duties.NextEpochDuties)) + subscribeIsAggregator := make([]bool, 0, len(duties.CurrentEpochDuties)+len(duties.NextEpochDuties)) + activeDuties := make([]*ethpb.DutiesResponse_Duty, 0, len(duties.CurrentEpochDuties)+len(duties.NextEpochDuties)) alreadySubscribed := make(map[[64]byte]bool) if v.distributed { // Get aggregated selection proofs to calculate isAggregator. - if err := v.getAggregatedSelectionProofs(ctx, res); err != nil { + if err := v.getAggregatedSelectionProofs(ctx, duties); err != nil { return errors.Wrap(err, "could not get aggregated selection proofs") } } - for _, duty := range res.CurrentEpochDuties { + for _, duty := range duties.CurrentEpochDuties { pk := bytesutil.ToBytes48(duty.PublicKey) if duty.Status == ethpb.ValidatorStatus_ACTIVE || duty.Status == ethpb.ValidatorStatus_EXITING { attesterSlot := duty.AttesterSlot committeeIndex := duty.CommitteeIndex validatorIndex := duty.ValidatorIndex - alreadySubscribedKey := validatorSubscribeKey(attesterSlot, committeeIndex) + alreadySubscribedKey := validatorSubnetSubscriptionKey(attesterSlot, committeeIndex) if _, ok := alreadySubscribed[alreadySubscribedKey]; ok { continue } @@ -642,13 +641,13 @@ func (v *validator) subscribeToSubnets(ctx context.Context, res *ethpb.DutiesRes } } - for _, duty := range res.NextEpochDuties { + for _, duty := range duties.NextEpochDuties { if duty.Status == ethpb.ValidatorStatus_ACTIVE || duty.Status == ethpb.ValidatorStatus_EXITING { attesterSlot := duty.AttesterSlot committeeIndex := duty.CommitteeIndex validatorIndex := duty.ValidatorIndex - alreadySubscribedKey := validatorSubscribeKey(attesterSlot, committeeIndex) + alreadySubscribedKey := validatorSubnetSubscriptionKey(attesterSlot, committeeIndex) if _, ok := alreadySubscribed[alreadySubscribedKey]; ok { continue } @@ -751,18 +750,24 @@ func (v *validator) RolesAt(ctx context.Context, slot primitives.Slot) (map[[fie // Keymanager returns the underlying validator's keymanager. func (v *validator) Keymanager() (keymanager.IKeymanager, error) { - if v.keyManager == nil { + if v.km == nil { return nil, errors.New("keymanager is not initialized") } - return v.keyManager, nil + return v.km, nil } // isAggregator checks if a validator is an aggregator of a given slot and committee, // it uses a modulo calculated by validator count in committee and samples randomness around it. -func (v *validator) isAggregator(ctx context.Context, committee []primitives.ValidatorIndex, slot primitives.Slot, pubKey [fieldparams.BLSPubkeyLength]byte, validatorIndex primitives.ValidatorIndex) (bool, error) { +func (v *validator) isAggregator( + ctx context.Context, + committeeIndex []primitives.ValidatorIndex, + slot primitives.Slot, + pubKey [fieldparams.BLSPubkeyLength]byte, + validatorIndex primitives.ValidatorIndex, +) (bool, error) { modulo := uint64(1) - if len(committee)/int(params.BeaconConfig().TargetAggregatorsPerCommittee) > 1 { - modulo = uint64(len(committee)) / params.BeaconConfig().TargetAggregatorsPerCommittee + if len(committeeIndex)/int(params.BeaconConfig().TargetAggregatorsPerCommittee) > 1 { + modulo = uint64(len(committeeIndex)) / params.BeaconConfig().TargetAggregatorsPerCommittee } var ( @@ -1041,7 +1046,7 @@ func (v *validator) PushProposerSettings(ctx context.Context, km keymanager.IKey if err != nil { return err } - proposerReqs, err := v.buildPrepProposerReqs(ctx, filteredKeys) + proposerReqs, err := v.buildPrepProposerReqs(filteredKeys) if err != nil { return err } @@ -1152,9 +1157,9 @@ func (v *validator) filterAndCacheActiveKeys(ctx context.Context, pubkeys [][fie return filteredKeys, nil } -func (v *validator) buildPrepProposerReqs(ctx context.Context, pubkeys [][fieldparams.BLSPubkeyLength]byte /* only active pubkeys */) ([]*ethpb.PrepareBeaconProposerRequest_FeeRecipientContainer, error) { +func (v *validator) buildPrepProposerReqs(activePubkeys [][fieldparams.BLSPubkeyLength]byte) ([]*ethpb.PrepareBeaconProposerRequest_FeeRecipientContainer, error) { var prepareProposerReqs []*ethpb.PrepareBeaconProposerRequest_FeeRecipientContainer - for _, k := range pubkeys { + for _, k := range activePubkeys { // Default case: Define fee recipient to burn address var feeRecipient common.Address @@ -1185,7 +1190,11 @@ func (v *validator) buildPrepProposerReqs(ctx context.Context, pubkeys [][fieldp return prepareProposerReqs, nil } -func (v *validator) buildSignedRegReqs(ctx context.Context, pubkeys [][fieldparams.BLSPubkeyLength]byte /* only active pubkeys */, signer iface.SigningFunc) []*ethpb.SignedValidatorRegistrationV1 { +func (v *validator) buildSignedRegReqs( + ctx context.Context, + activePubkeys [][fieldparams.BLSPubkeyLength]byte, + signer iface.SigningFunc, +) []*ethpb.SignedValidatorRegistrationV1 { var signedValRegRegs []*ethpb.SignedValidatorRegistrationV1 if v.ProposerSettings() == nil { return signedValRegRegs @@ -1194,7 +1203,7 @@ func (v *validator) buildSignedRegReqs(ctx context.Context, pubkeys [][fieldpara if v.genesisTime > uint64(time.Now().UTC().Unix()) { return signedValRegRegs } - for i, k := range pubkeys { + for i, k := range activePubkeys { feeRecipient := common.HexToAddress(params.BeaconConfig().EthBurnAddressHex) gasLimit := params.BeaconConfig().DefaultBuilderGasLimit enabled := false @@ -1244,7 +1253,7 @@ func (v *validator) buildSignedRegReqs(ctx context.Context, pubkeys [][fieldpara FeeRecipient: feeRecipient[:], GasLimit: gasLimit, Timestamp: uint64(time.Now().UTC().Unix()), - Pubkey: pubkeys[i][:], + Pubkey: activePubkeys[i][:], } signedReq, err := v.SignValidatorRegistrationRequest(ctx, signer, req) @@ -1372,8 +1381,8 @@ func (v *validator) getAttSelection(key attSelectionKey) ([]byte, error) { // This constructs a validator subscribed key, it's used to track // which subnet has already been pending requested. -func validatorSubscribeKey(slot primitives.Slot, committeeID primitives.CommitteeIndex) [64]byte { - return bytesutil.ToBytes64(append(bytesutil.Bytes32(uint64(slot)), bytesutil.Bytes32(uint64(committeeID))...)) +func validatorSubnetSubscriptionKey(slot primitives.Slot, committeeIndex primitives.CommitteeIndex) [64]byte { + return bytesutil.ToBytes64(append(bytesutil.Bytes32(uint64(slot)), bytesutil.Bytes32(uint64(committeeIndex))...)) } // This tracks all validators' voting status. diff --git a/validator/client/validator_test.go b/validator/client/validator_test.go index 3bdb48003d7d..23d26e18aff6 100644 --- a/validator/client/validator_test.go +++ b/validator/client/validator_test.go @@ -305,10 +305,10 @@ func TestWaitForChainStart_ReceiveErrorFromStream(t *testing.T) { func TestCanonicalHeadSlot_FailedRPC(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - client := validatormock.NewMockBeaconChainClient(ctrl) + client := validatormock.NewMockChainClient(ctrl) v := validator{ - beaconClient: client, - genesisTime: 1, + chainClient: client, + genesisTime: 1, } client.EXPECT().GetChainHead( gomock.Any(), @@ -321,9 +321,9 @@ func TestCanonicalHeadSlot_FailedRPC(t *testing.T) { func TestCanonicalHeadSlot_OK(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - client := validatormock.NewMockBeaconChainClient(ctrl) + client := validatormock.NewMockChainClient(ctrl) v := validator{ - beaconClient: client, + chainClient: client, } client.EXPECT().GetChainHead( gomock.Any(), @@ -339,22 +339,22 @@ func TestWaitMultipleActivation_LogsActivationEpochOK(t *testing.T) { hook := logTest.NewGlobal() ctrl := gomock.NewController(t) defer ctrl.Finish() - validatorClient := validatormock.NewMockValidatorClient(ctrl) - beaconClient := validatormock.NewMockBeaconChainClient(ctrl) - prysmBeaconClient := validatormock.NewMockPrysmBeaconChainClient(ctrl) + client := validatormock.NewMockValidatorClient(ctrl) + chainClient := validatormock.NewMockChainClient(ctrl) + prysmChainClient := validatormock.NewMockPrysmChainClient(ctrl) kp := randKeypair(t) v := validator{ - validatorClient: validatorClient, - keyManager: newMockKeymanager(t, kp), - beaconClient: beaconClient, - prysmBeaconClient: prysmBeaconClient, + validatorClient: client, + km: newMockKeymanager(t, kp), + chainClient: chainClient, + prysmChainClient: prysmChainClient, } resp := generateMockStatusResponse([][]byte{kp.pub[:]}) resp.Statuses[0].Status.Status = ethpb.ValidatorStatus_ACTIVE clientStream := mock2.NewMockBeaconNodeValidator_WaitForActivationClient(ctrl) - validatorClient.EXPECT().WaitForActivation( + client.EXPECT().WaitForActivation( gomock.Any(), ðpb.ValidatorActivationRequest{ PublicKeys: [][]byte{kp.pub[:]}, @@ -364,7 +364,7 @@ func TestWaitMultipleActivation_LogsActivationEpochOK(t *testing.T) { resp, nil, ) - prysmBeaconClient.EXPECT().GetValidatorCount( + prysmChainClient.EXPECT().GetValidatorCount( gomock.Any(), "head", []validatorType.Status{validatorType.Active}, @@ -465,7 +465,7 @@ func TestUpdateDuties_ReturnsError(t *testing.T) { v := validator{ validatorClient: client, - keyManager: newMockKeymanager(t, randKeypair(t)), + km: newMockKeymanager(t, randKeypair(t)), duties: ðpb.DutiesResponse{ CurrentEpochDuties: []*ethpb.DutiesResponse_Duty{ { @@ -505,7 +505,7 @@ func TestUpdateDuties_OK(t *testing.T) { }, } v := validator{ - keyManager: newMockKeymanager(t, randKeypair(t)), + km: newMockKeymanager(t, randKeypair(t)), validatorClient: client, } client.EXPECT().GetDuties( @@ -549,9 +549,9 @@ func TestUpdateDuties_OK_FilterBlacklistedPublicKeys(t *testing.T) { blacklistedPublicKeys[k] = true } v := validator{ - keyManager: km, - validatorClient: client, - eipImportBlacklistedPublicKeys: blacklistedPublicKeys, + km: km, + validatorClient: client, + blacklistedPubkeys: blacklistedPublicKeys, } resp := ðpb.DutiesResponse{ @@ -611,7 +611,7 @@ func TestUpdateDuties_AllValidatorsExited(t *testing.T) { }, } v := validator{ - keyManager: newMockKeymanager(t, randKeypair(t)), + km: newMockKeymanager(t, randKeypair(t)), validatorClient: client, } client.EXPECT().GetDuties( @@ -654,7 +654,7 @@ func TestUpdateDuties_Distributed(t *testing.T) { } v := validator{ - keyManager: newMockKeymanager(t, keys), + km: newMockKeymanager(t, keys), validatorClient: client, distributed: true, } @@ -997,7 +997,7 @@ func TestValidator_CheckDoppelGanger(t *testing.T) { } v := &validator{ validatorClient: client, - keyManager: km, + km: km, db: db, } client.EXPECT().CheckDoppelGanger( @@ -1038,7 +1038,7 @@ func TestValidator_CheckDoppelGanger(t *testing.T) { } v := &validator{ validatorClient: client, - keyManager: km, + km: km, db: db, } client.EXPECT().CheckDoppelGanger( @@ -1077,7 +1077,7 @@ func TestValidator_CheckDoppelGanger(t *testing.T) { } v := &validator{ validatorClient: client, - keyManager: km, + km: km, db: db, } client.EXPECT().CheckDoppelGanger( @@ -1122,7 +1122,7 @@ func TestValidator_CheckDoppelGanger(t *testing.T) { } v := &validator{ validatorClient: client, - keyManager: km, + km: km, db: db, } client.EXPECT().CheckDoppelGanger( @@ -1150,7 +1150,7 @@ func TestValidator_CheckDoppelGanger(t *testing.T) { } v := &validator{ validatorClient: client, - keyManager: km, + km: km, db: db, } client.EXPECT().CheckDoppelGanger( @@ -1366,7 +1366,7 @@ func TestValidator_WaitForKeymanagerInitialization_web3Signer(t *testing.T) { db: db, useWeb: false, wallet: w, - Web3SignerConfig: &remoteweb3signer.SetupConfig{ + web3SignerConfig: &remoteweb3signer.SetupConfig{ BaseEndpoint: "http://localhost:8545", ProvidedPublicKeys: keys, }, @@ -1391,10 +1391,10 @@ func TestValidator_WaitForKeymanagerInitialization_Web(t *testing.T) { require.NoError(t, err) walletChan := make(chan *wallet.Wallet, 1) v := validator{ - db: db, - useWeb: true, - walletInitializedFeed: &event.Feed{}, - walletInitializedChannel: walletChan, + db: db, + useWeb: true, + walletInitializedFeed: &event.Feed{}, + walletInitializedChan: walletChan, } wait := make(chan struct{}) go func() { @@ -1992,7 +1992,7 @@ func TestValidator_PushSettings(t *testing.T) { pubkeys, err := km.FetchValidatingPublicKeys(ctx) require.NoError(t, err) if tt.feeRecipientMap != nil { - feeRecipients, err := v.buildPrepProposerReqs(ctx, pubkeys) + feeRecipients, err := v.buildPrepProposerReqs(pubkeys) require.NoError(t, err) signedRegisterValidatorRequests := v.buildSignedRegReqs(ctx, pubkeys, km.Sign) for _, recipient := range feeRecipients { @@ -2148,7 +2148,7 @@ func TestValidator_buildPrepProposerReqs_WithoutDefaultConfig(t *testing.T) { } filteredKeys, err := v.filterAndCacheActiveKeys(ctx, pubkeys, 0) require.NoError(t, err) - actual, err := v.buildPrepProposerReqs(ctx, filteredKeys) + actual, err := v.buildPrepProposerReqs(filteredKeys) require.NoError(t, err) assert.DeepEqual(t, expected, actual) } @@ -2316,7 +2316,7 @@ func TestValidator_buildPrepProposerReqs_WithDefaultConfig(t *testing.T) { } filteredKeys, err := v.filterAndCacheActiveKeys(ctx, pubkeys, 641) require.NoError(t, err) - actual, err := v.buildPrepProposerReqs(ctx, filteredKeys) + actual, err := v.buildPrepProposerReqs(filteredKeys) require.NoError(t, err) assert.DeepEqual(t, expected, actual) } diff --git a/validator/client/wait_for_activation.go b/validator/client/wait_for_activation.go index b0b4396c2784..d4a61153d5f8 100644 --- a/validator/client/wait_for_activation.go +++ b/validator/client/wait_for_activation.go @@ -50,7 +50,7 @@ func (v *validator) WaitForActivation(ctx context.Context, accountsChangedChan c func (v *validator) internalWaitForActivation(ctx context.Context, accountsChangedChan <-chan [][fieldparams.BLSPubkeyLength]byte) error { ctx, span := trace.StartSpan(ctx, "validator.WaitForActivation") defer span.End() - validatingKeys, err := v.keyManager.FetchValidatingPublicKeys(ctx) + validatingKeys, err := v.km.FetchValidatingPublicKeys(ctx) if err != nil { return errors.Wrap(err, msgCouldNotFetchKeys) } @@ -120,7 +120,7 @@ func (v *validator) internalWaitForActivation(ctx context.Context, accountsChang // "-1" indicates that validator count endpoint is not supported by the beacon node. var valCount int64 = -1 - valCounts, err := v.prysmBeaconClient.GetValidatorCount(ctx, "head", []validator2.Status{validator2.Active}) + valCounts, err := v.prysmChainClient.GetValidatorCount(ctx, "head", []validator2.Status{validator2.Active}) if err != nil && !errors.Is(err, iface.ErrNotSupported) { return errors.Wrap(err, "could not get active validator count") } diff --git a/validator/client/wait_for_activation_test.go b/validator/client/wait_for_activation_test.go index 6d6a8d22eefa..5b6200466fa7 100644 --- a/validator/client/wait_for_activation_test.go +++ b/validator/client/wait_for_activation_test.go @@ -32,12 +32,12 @@ func TestWaitActivation_ContextCanceled(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() validatorClient := validatormock.NewMockValidatorClient(ctrl) - beaconClient := validatormock.NewMockBeaconChainClient(ctrl) + chainClient := validatormock.NewMockChainClient(ctrl) kp := randKeypair(t) v := validator{ validatorClient: validatorClient, - keyManager: newMockKeymanager(t, kp), - beaconClient: beaconClient, + km: newMockKeymanager(t, kp), + chainClient: chainClient, } clientStream := mock.NewMockBeaconNodeValidator_WaitForActivationClient(ctrl) ctx, cancel := context.WithCancel(context.Background()) @@ -58,14 +58,14 @@ func TestWaitActivation_StreamSetupFails_AttemptsToReconnect(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() validatorClient := validatormock.NewMockValidatorClient(ctrl) - beaconClient := validatormock.NewMockBeaconChainClient(ctrl) - prysmBeaconClient := validatormock.NewMockPrysmBeaconChainClient(ctrl) + chainClient := validatormock.NewMockChainClient(ctrl) + prysmChainClient := validatormock.NewMockPrysmChainClient(ctrl) kp := randKeypair(t) v := validator{ - validatorClient: validatorClient, - keyManager: newMockKeymanager(t, kp), - beaconClient: beaconClient, - prysmBeaconClient: prysmBeaconClient, + validatorClient: validatorClient, + km: newMockKeymanager(t, kp), + chainClient: chainClient, + prysmChainClient: prysmChainClient, } clientStream := mock.NewMockBeaconNodeValidator_WaitForActivationClient(ctrl) validatorClient.EXPECT().WaitForActivation( @@ -74,7 +74,7 @@ func TestWaitActivation_StreamSetupFails_AttemptsToReconnect(t *testing.T) { PublicKeys: [][]byte{kp.pub[:]}, }, ).Return(clientStream, errors.New("failed stream")).Return(clientStream, nil) - prysmBeaconClient.EXPECT().GetValidatorCount( + prysmChainClient.EXPECT().GetValidatorCount( gomock.Any(), "head", []validatorType.Status{validatorType.Active}, @@ -89,14 +89,14 @@ func TestWaitForActivation_ReceiveErrorFromStream_AttemptsReconnection(t *testin ctrl := gomock.NewController(t) defer ctrl.Finish() validatorClient := validatormock.NewMockValidatorClient(ctrl) - beaconClient := validatormock.NewMockBeaconChainClient(ctrl) - prysmBeaconClient := validatormock.NewMockPrysmBeaconChainClient(ctrl) + chainClient := validatormock.NewMockChainClient(ctrl) + prysmChainClient := validatormock.NewMockPrysmChainClient(ctrl) kp := randKeypair(t) v := validator{ - validatorClient: validatorClient, - keyManager: newMockKeymanager(t, kp), - beaconClient: beaconClient, - prysmBeaconClient: prysmBeaconClient, + validatorClient: validatorClient, + km: newMockKeymanager(t, kp), + chainClient: chainClient, + prysmChainClient: prysmChainClient, } clientStream := mock.NewMockBeaconNodeValidator_WaitForActivationClient(ctrl) validatorClient.EXPECT().WaitForActivation( @@ -105,7 +105,7 @@ func TestWaitForActivation_ReceiveErrorFromStream_AttemptsReconnection(t *testin PublicKeys: [][]byte{kp.pub[:]}, }, ).Return(clientStream, nil) - prysmBeaconClient.EXPECT().GetValidatorCount( + prysmChainClient.EXPECT().GetValidatorCount( gomock.Any(), "head", []validatorType.Status{validatorType.Active}, @@ -125,15 +125,15 @@ func TestWaitActivation_LogsActivationEpochOK(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() validatorClient := validatormock.NewMockValidatorClient(ctrl) - beaconClient := validatormock.NewMockBeaconChainClient(ctrl) - prysmBeaconClient := validatormock.NewMockPrysmBeaconChainClient(ctrl) + chainClient := validatormock.NewMockChainClient(ctrl) + prysmChainClient := validatormock.NewMockPrysmChainClient(ctrl) kp := randKeypair(t) v := validator{ - validatorClient: validatorClient, - keyManager: newMockKeymanager(t, kp), - genesisTime: 1, - beaconClient: beaconClient, - prysmBeaconClient: prysmBeaconClient, + validatorClient: validatorClient, + km: newMockKeymanager(t, kp), + genesisTime: 1, + chainClient: chainClient, + prysmChainClient: prysmChainClient, } resp := generateMockStatusResponse([][]byte{kp.pub[:]}) resp.Statuses[0].Status.Status = ethpb.ValidatorStatus_ACTIVE @@ -144,7 +144,7 @@ func TestWaitActivation_LogsActivationEpochOK(t *testing.T) { PublicKeys: [][]byte{kp.pub[:]}, }, ).Return(clientStream, nil) - prysmBeaconClient.EXPECT().GetValidatorCount( + prysmChainClient.EXPECT().GetValidatorCount( gomock.Any(), "head", []validatorType.Status{validatorType.Active}, @@ -161,14 +161,14 @@ func TestWaitForActivation_Exiting(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() validatorClient := validatormock.NewMockValidatorClient(ctrl) - beaconClient := validatormock.NewMockBeaconChainClient(ctrl) - prysmBeaconClient := validatormock.NewMockPrysmBeaconChainClient(ctrl) + chainClient := validatormock.NewMockChainClient(ctrl) + prysmChainClient := validatormock.NewMockPrysmChainClient(ctrl) kp := randKeypair(t) v := validator{ - validatorClient: validatorClient, - keyManager: newMockKeymanager(t, kp), - beaconClient: beaconClient, - prysmBeaconClient: prysmBeaconClient, + validatorClient: validatorClient, + km: newMockKeymanager(t, kp), + chainClient: chainClient, + prysmChainClient: prysmChainClient, } resp := generateMockStatusResponse([][]byte{kp.pub[:]}) resp.Statuses[0].Status.Status = ethpb.ValidatorStatus_EXITING @@ -179,7 +179,7 @@ func TestWaitForActivation_Exiting(t *testing.T) { PublicKeys: [][]byte{kp.pub[:]}, }, ).Return(clientStream, nil) - prysmBeaconClient.EXPECT().GetValidatorCount( + prysmChainClient.EXPECT().GetValidatorCount( gomock.Any(), "head", []validatorType.Status{validatorType.Active}, @@ -201,17 +201,17 @@ func TestWaitForActivation_RefetchKeys(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() validatorClient := validatormock.NewMockValidatorClient(ctrl) - beaconClient := validatormock.NewMockBeaconChainClient(ctrl) - prysmBeaconClient := validatormock.NewMockPrysmBeaconChainClient(ctrl) + chainClient := validatormock.NewMockChainClient(ctrl) + prysmChainClient := validatormock.NewMockPrysmChainClient(ctrl) kp := randKeypair(t) km := newMockKeymanager(t) v := validator{ - validatorClient: validatorClient, - keyManager: km, - beaconClient: beaconClient, - prysmBeaconClient: prysmBeaconClient, + validatorClient: validatorClient, + km: km, + chainClient: chainClient, + prysmChainClient: prysmChainClient, } resp := generateMockStatusResponse([][]byte{kp.pub[:]}) resp.Statuses[0].Status.Status = ethpb.ValidatorStatus_ACTIVE @@ -222,7 +222,7 @@ func TestWaitForActivation_RefetchKeys(t *testing.T) { PublicKeys: [][]byte{kp.pub[:]}, }, ).Return(clientStream, nil) - prysmBeaconClient.EXPECT().GetValidatorCount( + prysmChainClient.EXPECT().GetValidatorCount( gomock.Any(), "head", []validatorType.Status{validatorType.Active}, @@ -258,13 +258,13 @@ func TestWaitForActivation_AccountsChanged(t *testing.T) { active := randKeypair(t) km := newMockKeymanager(t, inactive) validatorClient := validatormock.NewMockValidatorClient(ctrl) - beaconClient := validatormock.NewMockBeaconChainClient(ctrl) - prysmBeaconClient := validatormock.NewMockPrysmBeaconChainClient(ctrl) + chainClient := validatormock.NewMockChainClient(ctrl) + prysmChainClient := validatormock.NewMockPrysmChainClient(ctrl) v := validator{ - validatorClient: validatorClient, - keyManager: km, - beaconClient: beaconClient, - prysmBeaconClient: prysmBeaconClient, + validatorClient: validatorClient, + km: km, + chainClient: chainClient, + prysmChainClient: prysmChainClient, } inactiveResp := generateMockStatusResponse([][]byte{inactive.pub[:]}) inactiveResp.Statuses[0].Status.Status = ethpb.ValidatorStatus_UNKNOWN_STATUS @@ -279,7 +279,7 @@ func TestWaitForActivation_AccountsChanged(t *testing.T) { time.Sleep(time.Second * 2) return inactiveClientStream, nil }) - prysmBeaconClient.EXPECT().GetValidatorCount( + prysmChainClient.EXPECT().GetValidatorCount( gomock.Any(), "head", []validatorType.Status{validatorType.Active}, @@ -348,14 +348,14 @@ func TestWaitForActivation_AccountsChanged(t *testing.T) { err = km.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, derived.DefaultMnemonicLanguage, "", 1) require.NoError(t, err) validatorClient := validatormock.NewMockValidatorClient(ctrl) - beaconClient := validatormock.NewMockBeaconChainClient(ctrl) - prysmBeaconClient := validatormock.NewMockPrysmBeaconChainClient(ctrl) + chainClient := validatormock.NewMockChainClient(ctrl) + prysmChainClient := validatormock.NewMockPrysmChainClient(ctrl) v := validator{ - validatorClient: validatorClient, - keyManager: km, - genesisTime: 1, - beaconClient: beaconClient, - prysmBeaconClient: prysmBeaconClient, + validatorClient: validatorClient, + km: km, + genesisTime: 1, + chainClient: chainClient, + prysmChainClient: prysmChainClient, } inactiveResp := generateMockStatusResponse([][]byte{inactivePubKey[:]}) @@ -371,7 +371,7 @@ func TestWaitForActivation_AccountsChanged(t *testing.T) { time.Sleep(time.Second * 2) return inactiveClientStream, nil }) - prysmBeaconClient.EXPECT().GetValidatorCount( + prysmChainClient.EXPECT().GetValidatorCount( gomock.Any(), "head", []validatorType.Status{validatorType.Active}, @@ -415,15 +415,15 @@ func TestWaitActivation_NotAllValidatorsActivatedOK(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() validatorClient := validatormock.NewMockValidatorClient(ctrl) - beaconClient := validatormock.NewMockBeaconChainClient(ctrl) - prysmBeaconClient := validatormock.NewMockPrysmBeaconChainClient(ctrl) + chainClient := validatormock.NewMockChainClient(ctrl) + prysmChainClient := validatormock.NewMockPrysmChainClient(ctrl) kp := randKeypair(t) v := validator{ - validatorClient: validatorClient, - keyManager: newMockKeymanager(t, kp), - beaconClient: beaconClient, - prysmBeaconClient: prysmBeaconClient, + validatorClient: validatorClient, + km: newMockKeymanager(t, kp), + chainClient: chainClient, + prysmChainClient: prysmChainClient, } resp := generateMockStatusResponse([][]byte{kp.pub[:]}) resp.Statuses[0].Status.Status = ethpb.ValidatorStatus_ACTIVE @@ -432,7 +432,7 @@ func TestWaitActivation_NotAllValidatorsActivatedOK(t *testing.T) { gomock.Any(), gomock.Any(), ).Return(clientStream, nil) - prysmBeaconClient.EXPECT().GetValidatorCount( + prysmChainClient.EXPECT().GetValidatorCount( gomock.Any(), "head", []validatorType.Status{validatorType.Active}, diff --git a/validator/node/node.go b/validator/node/node.go index ea2509dc0f07..7789666c24b3 100644 --- a/validator/node/node.go +++ b/validator/node/node.go @@ -63,15 +63,15 @@ import ( // ValidatorClient defines an instance of an Ethereum validator that manages // the entire lifecycle of services attached to it participating in proof of stake. type ValidatorClient struct { - cliCtx *cli.Context - ctx context.Context - cancel context.CancelFunc - db iface.ValidatorDB - services *runtime.ServiceRegistry // Lifecycle and service store. - lock sync.RWMutex - wallet *wallet.Wallet - walletInitialized *event.Feed - stop chan struct{} // Channel to wait for termination notifications. + cliCtx *cli.Context + ctx context.Context + cancel context.CancelFunc + db iface.ValidatorDB + services *runtime.ServiceRegistry // Lifecycle and service store. + lock sync.RWMutex + wallet *wallet.Wallet + walletInitializedFeed *event.Feed + stop chan struct{} // Channel to wait for termination notifications. } // NewValidatorClient creates a new instance of the Prysm validator client. @@ -100,12 +100,12 @@ func NewValidatorClient(cliCtx *cli.Context) (*ValidatorClient, error) { registry := runtime.NewServiceRegistry() ctx, cancel := context.WithCancel(cliCtx.Context) validatorClient := &ValidatorClient{ - cliCtx: cliCtx, - ctx: ctx, - cancel: cancel, - services: registry, - walletInitialized: new(event.Feed), - stop: make(chan struct{}), + cliCtx: cliCtx, + ctx: ctx, + cancel: cancel, + services: registry, + walletInitializedFeed: new(event.Feed), + stop: make(chan struct{}), } if err := features.ConfigureValidator(cliCtx); err != nil { @@ -485,23 +485,13 @@ func (c *ValidatorClient) registerPrometheusService(cliCtx *cli.Context) error { func (c *ValidatorClient) registerValidatorService(cliCtx *cli.Context) error { var ( - endpoint string = c.cliCtx.String(flags.BeaconRPCProviderFlag.Name) - dataDir string = c.cliCtx.String(cmd.DataDirFlag.Name) - logValidatorBalances bool = !c.cliCtx.Bool(flags.DisablePenaltyRewardLogFlag.Name) - emitAccountMetrics bool = !c.cliCtx.Bool(flags.DisableAccountMetricsFlag.Name) - cert string = c.cliCtx.String(flags.CertFlag.Name) - graffiti string = c.cliCtx.String(flags.GraffitiFlag.Name) - maxCallRecvMsgSize int = c.cliCtx.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name) - grpcRetries uint = c.cliCtx.Uint(flags.GrpcRetriesFlag.Name) - grpcRetryDelay time.Duration = c.cliCtx.Duration(flags.GrpcRetryDelayFlag.Name) - - interopKeysConfig *local.InteropKeymanagerConfig - err error + interopKmConfig *local.InteropKeymanagerConfig + err error ) // Configure interop. if c.cliCtx.IsSet(flags.InteropNumValidators.Name) { - interopKeysConfig = &local.InteropKeymanagerConfig{ + interopKmConfig = &local.InteropKeymanagerConfig{ Offset: cliCtx.Uint64(flags.InteropStartIndex.Name), NumValidatorKeys: cliCtx.Uint64(flags.InteropNumValidators.Name), } @@ -529,28 +519,27 @@ func (c *ValidatorClient) registerValidatorService(cliCtx *cli.Context) error { } validatorService, err := client.NewValidatorService(c.cliCtx.Context, &client.Config{ - Endpoint: endpoint, - DataDir: dataDir, - LogValidatorBalances: logValidatorBalances, - EmitAccountMetrics: emitAccountMetrics, - CertFlag: cert, - GraffitiFlag: g.ParseHexGraffiti(graffiti), - GrpcMaxCallRecvMsgSizeFlag: maxCallRecvMsgSize, - GrpcRetriesFlag: grpcRetries, - GrpcRetryDelay: grpcRetryDelay, - GrpcHeadersFlag: c.cliCtx.String(flags.GrpcHeadersFlag.Name), - ValDB: c.db, - UseWeb: c.cliCtx.Bool(flags.EnableWebFlag.Name), - InteropKeysConfig: interopKeysConfig, - Wallet: c.wallet, - WalletInitializedFeed: c.walletInitialized, - GraffitiStruct: graffitiStruct, - Web3SignerConfig: web3signerConfig, - ProposerSettings: ps, - BeaconApiTimeout: time.Second * 30, - BeaconApiEndpoint: c.cliCtx.String(flags.BeaconRESTApiProviderFlag.Name), - ValidatorsRegBatchSize: c.cliCtx.Int(flags.ValidatorsRegistrationBatchSizeFlag.Name), - Distributed: c.cliCtx.Bool(flags.EnableDistributed.Name), + DB: c.db, + Wallet: c.wallet, + WalletInitializedFeed: c.walletInitializedFeed, + GRPCMaxCallRecvMsgSize: c.cliCtx.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name), + GRPCRetries: c.cliCtx.Uint(flags.GrpcRetriesFlag.Name), + GRPCRetryDelay: c.cliCtx.Duration(flags.GrpcRetryDelayFlag.Name), + GRPCHeaders: strings.Split(c.cliCtx.String(flags.GrpcHeadersFlag.Name), ","), + BeaconNodeGRPCEndpoint: c.cliCtx.String(flags.BeaconRPCProviderFlag.Name), + BeaconNodeCert: c.cliCtx.String(flags.CertFlag.Name), + BeaconApiEndpoint: c.cliCtx.String(flags.BeaconRESTApiProviderFlag.Name), + BeaconApiTimeout: time.Second * 30, + Graffiti: g.ParseHexGraffiti(c.cliCtx.String(flags.GraffitiFlag.Name)), + GraffitiStruct: graffitiStruct, + InteropKmConfig: interopKmConfig, + Web3SignerConfig: web3signerConfig, + ProposerSettings: ps, + ValidatorsRegBatchSize: c.cliCtx.Int(flags.ValidatorsRegistrationBatchSizeFlag.Name), + UseWeb: c.cliCtx.Bool(flags.EnableWebFlag.Name), + LogValidatorPerformance: !c.cliCtx.Bool(flags.DisablePenaltyRewardLogFlag.Name), + EmitAccountMetrics: !c.cliCtx.Bool(flags.DisableAccountMetricsFlag.Name), + Distributed: c.cliCtx.Bool(flags.EnableDistributed.Name), }) if err != nil { return errors.Wrap(err, "could not initialize validator service") @@ -625,58 +614,27 @@ func (c *ValidatorClient) registerRPCService(router *mux.Router) error { if err := c.services.FetchService(&vs); err != nil { return err } - validatorGatewayHost := c.cliCtx.String(flags.GRPCGatewayHost.Name) - validatorGatewayPort := c.cliCtx.Int(flags.GRPCGatewayPort.Name) - validatorMonitoringHost := c.cliCtx.String(cmd.MonitoringHostFlag.Name) - validatorMonitoringPort := c.cliCtx.Int(flags.MonitoringPortFlag.Name) - rpcHost := c.cliCtx.String(flags.RPCHost.Name) - rpcPort := c.cliCtx.Int(flags.RPCPort.Name) - nodeGatewayEndpoint := c.cliCtx.String(flags.BeaconRPCGatewayProviderFlag.Name) - beaconClientEndpoint := c.cliCtx.String(flags.BeaconRPCProviderFlag.Name) - maxCallRecvMsgSize := c.cliCtx.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name) - grpcRetries := c.cliCtx.Uint(flags.GrpcRetriesFlag.Name) - grpcRetryDelay := c.cliCtx.Duration(flags.GrpcRetryDelayFlag.Name) - walletDir := c.cliCtx.String(flags.WalletDirFlag.Name) - grpcHeaders := c.cliCtx.String(flags.GrpcHeadersFlag.Name) - clientCert := c.cliCtx.String(flags.CertFlag.Name) - - authTokenPath := c.cliCtx.String(flags.AuthTokenPathFlag.Name) - // if no auth token path flag was passed try to set a default value - if authTokenPath == "" { - authTokenPath = flags.AuthTokenPathFlag.Value - // if a wallet dir is passed without an auth token then override the default with the wallet dir - if walletDir != "" { - authTokenPath = filepath.Join(walletDir, api.AuthTokenFileName) - } - } - - server := rpc.NewServer(c.cliCtx.Context, &rpc.Config{ - ValDB: c.db, - Host: rpcHost, - Port: fmt.Sprintf("%d", rpcPort), - WalletInitializedFeed: c.walletInitialized, - ValidatorService: vs, - SyncChecker: vs, - GenesisFetcher: vs, - NodeGatewayEndpoint: nodeGatewayEndpoint, - AuthTokenPath: authTokenPath, - WalletDir: walletDir, - Wallet: c.wallet, - ValidatorGatewayHost: validatorGatewayHost, - ValidatorGatewayPort: validatorGatewayPort, - ValidatorMonitoringHost: validatorMonitoringHost, - ValidatorMonitoringPort: validatorMonitoringPort, - BeaconClientEndpoint: beaconClientEndpoint, - ClientMaxCallRecvMsgSize: maxCallRecvMsgSize, - ClientGrpcRetries: grpcRetries, - ClientGrpcRetryDelay: grpcRetryDelay, - ClientGrpcHeaders: strings.Split(grpcHeaders, ","), - ClientWithCert: clientCert, - BeaconApiTimeout: time.Second * 30, - BeaconApiEndpoint: c.cliCtx.String(flags.BeaconRESTApiProviderFlag.Name), - Router: router, + s := rpc.NewServer(c.cliCtx.Context, &rpc.Config{ + Host: c.cliCtx.String(flags.RPCHost.Name), + Port: fmt.Sprintf("%d", c.cliCtx.Int(flags.RPCPort.Name)), + GRPCGatewayHost: c.cliCtx.String(flags.GRPCGatewayHost.Name), + GRPCGatewayPort: c.cliCtx.Int(flags.GRPCGatewayPort.Name), + GRPCMaxCallRecvMsgSize: c.cliCtx.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name), + GRPCRetries: c.cliCtx.Uint(flags.GrpcRetriesFlag.Name), + GRPCRetryDelay: c.cliCtx.Duration(flags.GrpcRetryDelayFlag.Name), + GRPCHeaders: strings.Split(c.cliCtx.String(flags.GrpcHeadersFlag.Name), ","), + BeaconNodeGRPCEndpoint: c.cliCtx.String(flags.BeaconRPCProviderFlag.Name), + BeaconApiEndpoint: c.cliCtx.String(flags.BeaconRPCGatewayProviderFlag.Name), + BeaconApiTimeout: time.Second * 30, + BeaconNodeCert: c.cliCtx.String(flags.CertFlag.Name), + DB: c.db, + Wallet: c.wallet, + WalletDir: c.cliCtx.String(flags.WalletDirFlag.Name), + WalletInitializedFeed: c.walletInitializedFeed, + ValidatorService: vs, + Router: router, }) - return c.services.RegisterService(server) + return c.services.RegisterService(s) } func (c *ValidatorClient) registerRPCGatewayService(router *mux.Router) error { diff --git a/validator/rpc/BUILD.bazel b/validator/rpc/BUILD.bazel index 2e270bdeec96..5c07cd7a9c09 100644 --- a/validator/rpc/BUILD.bazel +++ b/validator/rpc/BUILD.bazel @@ -81,7 +81,6 @@ go_library( "@io_opencensus_go//trace:go_default_library", "@org_golang_google_grpc//:go_default_library", "@org_golang_google_grpc//codes:go_default_library", - "@org_golang_google_grpc//credentials:go_default_library", "@org_golang_google_grpc//metadata:go_default_library", "@org_golang_google_grpc//reflection:go_default_library", "@org_golang_google_grpc//status:go_default_library", diff --git a/validator/rpc/auth_token.go b/validator/rpc/auth_token.go index a87dbfb596df..ecff1019b570 100644 --- a/validator/rpc/auth_token.go +++ b/validator/rpc/auth_token.go @@ -104,7 +104,7 @@ func (s *Server) refreshAuthTokenFromFileChanges(ctx context.Context, authTokenP log.WithError(err).Errorf("Could not watch for file changes for: %s", authTokenPath) continue } - validatorWebAddr := fmt.Sprintf("%s:%d", s.validatorGatewayHost, s.validatorGatewayPort) + validatorWebAddr := fmt.Sprintf("%s:%d", s.grpcGatewayHost, s.grpcGatewayPort) logValidatorWebAuth(validatorWebAddr, s.authToken, authTokenPath) case err := <-watcher.Errors: log.WithError(err).Errorf("Could not watch for file changes for: %s", authTokenPath) diff --git a/validator/rpc/beacon.go b/validator/rpc/beacon.go index 7355c93bd153..e86dd2a7ce6e 100644 --- a/validator/rpc/beacon.go +++ b/validator/rpc/beacon.go @@ -27,26 +27,26 @@ func (s *Server) registerBeaconClient() error { grpcretry.StreamClientInterceptor(), )) dialOpts := client.ConstructDialOptions( - s.clientMaxCallRecvMsgSize, - s.clientWithCert, - s.clientGrpcRetries, - s.clientGrpcRetryDelay, + s.grpcMaxCallRecvMsgSize, + s.beaconNodeCert, + s.grpcRetries, + s.grpcRetryDelay, streamInterceptor, ) if dialOpts == nil { return errors.New("no dial options for beacon chain gRPC client") } - s.ctx = grpcutil.AppendHeaders(s.ctx, s.clientGrpcHeaders) + s.ctx = grpcutil.AppendHeaders(s.ctx, s.grpcHeaders) - grpcConn, err := grpc.DialContext(s.ctx, s.beaconClientEndpoint, dialOpts...) + grpcConn, err := grpc.DialContext(s.ctx, s.beaconNodeEndpoint, dialOpts...) if err != nil { - return errors.Wrapf(err, "could not dial endpoint: %s", s.beaconClientEndpoint) + return errors.Wrapf(err, "could not dial endpoint: %s", s.beaconNodeEndpoint) } - if s.clientWithCert != "" { + if s.beaconNodeCert != "" { log.Info("Established secure gRPC connection") } - s.beaconNodeHealthClient = ethpb.NewHealthClient(grpcConn) + s.healthClient = ethpb.NewHealthClient(grpcConn) conn := validatorHelpers.NewNodeConnection( grpcConn, @@ -56,8 +56,8 @@ func (s *Server) registerBeaconClient() error { restHandler := beaconApi.NewBeaconApiJsonRestHandler(http.Client{Timeout: s.beaconApiTimeout}, s.beaconApiEndpoint) - s.beaconChainClient = beaconChainClientFactory.NewBeaconChainClient(conn, restHandler) - s.beaconNodeClient = nodeClientFactory.NewNodeClient(conn, restHandler) + s.chainClient = beaconChainClientFactory.NewChainClient(conn, restHandler) + s.nodeClient = nodeClientFactory.NewNodeClient(conn, restHandler) s.beaconNodeValidatorClient = validatorClientFactory.NewValidatorClient(conn, restHandler) return nil diff --git a/validator/rpc/beacon_test.go b/validator/rpc/beacon_test.go index 2fb873e4d9d7..ec7b957351d0 100644 --- a/validator/rpc/beacon_test.go +++ b/validator/rpc/beacon_test.go @@ -11,8 +11,8 @@ import ( func TestGrpcHeaders(t *testing.T) { s := &Server{ - ctx: context.Background(), - clientGrpcHeaders: []string{"first=value1", "second=value2"}, + ctx: context.Background(), + grpcHeaders: []string{"first=value1", "second=value2"}, } err := s.registerBeaconClient() require.NoError(t, err) diff --git a/validator/rpc/handlers_accounts.go b/validator/rpc/handlers_accounts.go index 06e2b31ba9f0..8ad2bbb85a32 100644 --- a/validator/rpc/handlers_accounts.go +++ b/validator/rpc/handlers_accounts.go @@ -258,7 +258,7 @@ func (s *Server) VoluntaryExit(w http.ResponseWriter, r *http.Request) { } cfg := accounts.PerformExitCfg{ ValidatorClient: s.beaconNodeValidatorClient, - NodeClient: s.beaconNodeClient, + NodeClient: s.nodeClient, Keymanager: km, RawPubKeys: pubKeys, FormattedPubKeys: req.PublicKeys, diff --git a/validator/rpc/handlers_accounts_test.go b/validator/rpc/handlers_accounts_test.go index 99779bf70038..a011ab9ee80f 100644 --- a/validator/rpc/handlers_accounts_test.go +++ b/validator/rpc/handlers_accounts_test.go @@ -292,7 +292,7 @@ func TestServer_VoluntaryExit(t *testing.T) { s := &Server{ walletInitialized: true, wallet: w, - beaconNodeClient: mockNodeClient, + nodeClient: mockNodeClient, beaconNodeValidatorClient: mockValidatorClient, validatorService: vs, } diff --git a/validator/rpc/handlers_beacon.go b/validator/rpc/handlers_beacon.go index 107cd5373407..9a6afc920a41 100644 --- a/validator/rpc/handlers_beacon.go +++ b/validator/rpc/handlers_beacon.go @@ -25,30 +25,30 @@ import ( func (s *Server) GetBeaconStatus(w http.ResponseWriter, r *http.Request) { ctx, span := trace.StartSpan(r.Context(), "validator.web.beacon.GetBeaconStatus") defer span.End() - syncStatus, err := s.beaconNodeClient.GetSyncStatus(ctx, &emptypb.Empty{}) + syncStatus, err := s.nodeClient.GetSyncStatus(ctx, &emptypb.Empty{}) if err != nil { log.WithError(err).Error("beacon node call to get sync status failed") httputil.WriteJson(w, &BeaconStatusResponse{ - BeaconNodeEndpoint: s.nodeGatewayEndpoint, + BeaconNodeEndpoint: s.beaconNodeEndpoint, Connected: false, Syncing: false, }) return } - genesis, err := s.beaconNodeClient.GetGenesis(ctx, &emptypb.Empty{}) + genesis, err := s.nodeClient.GetGenesis(ctx, &emptypb.Empty{}) if err != nil { httputil.HandleError(w, errors.Wrap(err, "GetGenesis call failed").Error(), http.StatusInternalServerError) return } genesisTime := uint64(time.Unix(genesis.GenesisTime.Seconds, 0).Unix()) address := genesis.DepositContractAddress - chainHead, err := s.beaconChainClient.GetChainHead(ctx, &emptypb.Empty{}) + chainHead, err := s.chainClient.GetChainHead(ctx, &emptypb.Empty{}) if err != nil { httputil.HandleError(w, errors.Wrap(err, "GetChainHead").Error(), http.StatusInternalServerError) return } httputil.WriteJson(w, &BeaconStatusResponse{ - BeaconNodeEndpoint: s.beaconClientEndpoint, + BeaconNodeEndpoint: s.beaconNodeEndpoint, Connected: true, Syncing: syncStatus.Syncing, GenesisTime: fmt.Sprintf("%d", genesisTime), @@ -85,7 +85,7 @@ func (s *Server) GetValidatorPerformance(w http.ResponseWriter, r *http.Request) req := ðpb.ValidatorPerformanceRequest{ PublicKeys: pubkeys, } - validatorPerformance, err := s.beaconChainClient.GetValidatorPerformance(ctx, req) + validatorPerformance, err := s.chainClient.GetValidatorPerformance(ctx, req) if err != nil { httputil.HandleError(w, errors.Wrap(err, "GetValidatorPerformance call failed").Error(), http.StatusInternalServerError) return @@ -133,7 +133,7 @@ func (s *Server) GetValidatorBalances(w http.ResponseWriter, r *http.Request) { PageSize: int32(ps), PageToken: pageToken, } - listValidatorBalances, err := s.beaconChainClient.ListValidatorBalances(ctx, req) + listValidatorBalances, err := s.chainClient.ListValidatorBalances(ctx, req) if err != nil { httputil.HandleError(w, errors.Wrap(err, "ListValidatorBalances call failed").Error(), http.StatusInternalServerError) return @@ -187,7 +187,7 @@ func (s *Server) GetValidators(w http.ResponseWriter, r *http.Request) { PageSize: int32(ps), PageToken: pageToken, } - validators, err := s.beaconChainClient.ListValidators(ctx, req) + validators, err := s.chainClient.ListValidators(ctx, req) if err != nil { httputil.HandleError(w, errors.Wrap(err, "ListValidators call failed").Error(), http.StatusInternalServerError) return @@ -204,7 +204,7 @@ func (s *Server) GetValidators(w http.ResponseWriter, r *http.Request) { func (s *Server) GetPeers(w http.ResponseWriter, r *http.Request) { ctx, span := trace.StartSpan(r.Context(), "validator.web.beacon.GetPeers") defer span.End() - peers, err := s.beaconNodeClient.ListPeers(ctx, &emptypb.Empty{}) + peers, err := s.nodeClient.ListPeers(ctx, &emptypb.Empty{}) if err != nil { httputil.HandleError(w, errors.Wrap(err, "ListPeers call failed").Error(), http.StatusInternalServerError) return diff --git a/validator/rpc/handlers_beacon_test.go b/validator/rpc/handlers_beacon_test.go index 5dd9bab4540a..83042cb1e3d7 100644 --- a/validator/rpc/handlers_beacon_test.go +++ b/validator/rpc/handlers_beacon_test.go @@ -27,7 +27,7 @@ func TestGetBeaconStatus_NotConnected(t *testing.T) { gomock.Any(), ).Return(nil /*response*/, errors.New("uh oh")) srv := &Server{ - beaconNodeClient: nodeClient, + nodeClient: nodeClient, } req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/v2/validator/beacon/status"), nil) wr := httptest.NewRecorder() @@ -47,7 +47,7 @@ func TestGetBeaconStatus_NotConnected(t *testing.T) { func TestGetBeaconStatus_OK(t *testing.T) { ctrl := gomock.NewController(t) nodeClient := validatormock.NewMockNodeClient(ctrl) - beaconChainClient := validatormock.NewMockBeaconChainClient(ctrl) + chainClient := validatormock.NewMockChainClient(ctrl) nodeClient.EXPECT().GetSyncStatus( gomock.Any(), // ctx gomock.Any(), @@ -60,15 +60,15 @@ func TestGetBeaconStatus_OK(t *testing.T) { GenesisTime: timeStamp, DepositContractAddress: []byte("hello"), }, nil) - beaconChainClient.EXPECT().GetChainHead( + chainClient.EXPECT().GetChainHead( gomock.Any(), // ctx gomock.Any(), ).Return(ðpb.ChainHead{ HeadEpoch: 1, }, nil) srv := &Server{ - beaconNodeClient: nodeClient, - beaconChainClient: beaconChainClient, + nodeClient: nodeClient, + chainClient: chainClient, } req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/v2/validator/beacon/status"), nil) @@ -228,7 +228,7 @@ func TestServer_GetValidators(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ctrl := gomock.NewController(t) - beaconChainClient := validatormock.NewMockBeaconChainClient(ctrl) + beaconChainClient := validatormock.NewMockChainClient(ctrl) if tt.wantErr == "" { beaconChainClient.EXPECT().ListValidators( gomock.Any(), // ctx @@ -236,7 +236,7 @@ func TestServer_GetValidators(t *testing.T) { ).Return(tt.chainResp, nil) } s := &Server{ - beaconChainClient: beaconChainClient, + chainClient: beaconChainClient, } req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/v2/validator/beacon/validators?%s", tt.query), http.NoBody) wr := httptest.NewRecorder() diff --git a/validator/rpc/handlers_health.go b/validator/rpc/handlers_health.go index 8e7f6f437922..dc6e05b068c0 100644 --- a/validator/rpc/handlers_health.go +++ b/validator/rpc/handlers_health.go @@ -18,7 +18,7 @@ func (s *Server) GetVersion(w http.ResponseWriter, r *http.Request) { ctx, span := trace.StartSpan(r.Context(), "validator.web.health.GetVersion") defer span.End() - beacon, err := s.beaconNodeClient.GetVersion(ctx, &emptypb.Empty{}) + beacon, err := s.nodeClient.GetVersion(ctx, &emptypb.Empty{}) if err != nil { httputil.HandleError(w, err.Error(), http.StatusInternalServerError) return @@ -51,7 +51,7 @@ func (s *Server) StreamBeaconLogs(w http.ResponseWriter, r *http.Request) { return } // TODO: StreamBeaconLogs grpc will need to be replaced in the future - client, err := s.beaconNodeHealthClient.StreamBeaconLogs(ctx, &emptypb.Empty{}) + client, err := s.healthClient.StreamBeaconLogs(ctx, &emptypb.Empty{}) if err != nil { httputil.HandleError(w, err.Error(), http.StatusInternalServerError) return @@ -102,8 +102,8 @@ func (s *Server) StreamValidatorLogs(w http.ResponseWriter, r *http.Request) { return } - ch := make(chan []byte, s.streamLogsBufferSize) - sub := s.logsStreamer.LogsFeed().Subscribe(ch) + ch := make(chan []byte, s.logStreamerBufferSize) + sub := s.logStreamer.LogsFeed().Subscribe(ch) defer func() { sub.Unsubscribe() close(ch) @@ -113,7 +113,7 @@ func (s *Server) StreamValidatorLogs(w http.ResponseWriter, r *http.Request) { w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Connection", api.KeepAlive) - recentLogs := s.logsStreamer.GetLastFewLogs() + recentLogs := s.logStreamer.GetLastFewLogs() logStrings := make([]string, len(recentLogs)) for i, l := range recentLogs { logStrings[i] = string(l) diff --git a/validator/rpc/handlers_health_test.go b/validator/rpc/handlers_health_test.go index 4a6e22ec2cfe..bb983d9e5c66 100644 --- a/validator/rpc/handlers_health_test.go +++ b/validator/rpc/handlers_health_test.go @@ -73,8 +73,8 @@ func TestStreamBeaconLogs(t *testing.T) { // Setting up the mock in the server struct s := Server{ - ctx: context.Background(), - beaconNodeHealthClient: mockClient, + ctx: context.Background(), + healthClient: mockClient, } // Create a mock ResponseWriter and Request @@ -119,9 +119,9 @@ func TestStreamValidatorLogs(t *testing.T) { logStreamer := mock.NewMockStreamer(mockLogs) // Setting up the mock in the server struct s := Server{ - ctx: ctx, - logsStreamer: logStreamer, - streamLogsBufferSize: 100, + ctx: ctx, + logStreamer: logStreamer, + logStreamerBufferSize: 100, } w := &flushableResponseRecorder{ @@ -170,8 +170,8 @@ func TestServer_GetVersion(t *testing.T) { ctx := context.Background() mockNodeClient := validatormock.NewMockNodeClient(ctrl) s := Server{ - ctx: ctx, - beaconNodeClient: mockNodeClient, + ctx: ctx, + nodeClient: mockNodeClient, } mockNodeClient.EXPECT().GetVersion(gomock.Any(), gomock.Any()).Return(ð.Version{ Version: "4.10.1", diff --git a/validator/rpc/handlers_keymanager.go b/validator/rpc/handlers_keymanager.go index d5c1d1fa2b9d..9725bde7651e 100644 --- a/validator/rpc/handlers_keymanager.go +++ b/validator/rpc/handlers_keymanager.go @@ -133,7 +133,7 @@ func (s *Server) ImportKeystores(w http.ResponseWriter, r *http.Request) { keystores[i] = k } if req.SlashingProtection != "" { - if s.valDB == nil || s.valDB.ImportStandardProtectionJSON(ctx, bytes.NewBufferString(req.SlashingProtection)) != nil { + if s.db == nil || s.db.ImportStandardProtectionJSON(ctx, bytes.NewBufferString(req.SlashingProtection)) != nil { statuses := make([]*keymanager.KeyStatus, len(req.Keystores)) for i := 0; i < len(req.Keystores); i++ { statuses[i] = &keymanager.KeyStatus{ @@ -285,11 +285,11 @@ func (s *Server) transformDeletedKeysStatuses( // Gets a map of all public keys in the database, useful for O(1) lookups. func (s *Server) publicKeysInDB(ctx context.Context) (map[[fieldparams.BLSPubkeyLength]byte]bool, error) { pubKeysInDB := make(map[[fieldparams.BLSPubkeyLength]byte]bool) - attestedPublicKeys, err := s.valDB.AttestedPublicKeys(ctx) + attestedPublicKeys, err := s.db.AttestedPublicKeys(ctx) if err != nil { return nil, fmt.Errorf("could not get attested public keys from DB: %v", err) } - proposedPublicKeys, err := s.valDB.ProposedPublicKeys(ctx) + proposedPublicKeys, err := s.db.ProposedPublicKeys(ctx) if err != nil { return nil, fmt.Errorf("could not get proposed public keys from DB: %v", err) } @@ -313,7 +313,7 @@ func (s *Server) slashingProtectionHistoryForDeletedKeys( filteredKeys = append(filteredKeys, pk) } } - return slashingprotection.ExportStandardProtectionJSON(ctx, s.valDB, filteredKeys...) + return slashingprotection.ExportStandardProtectionJSON(ctx, s.db, filteredKeys...) } // SetVoluntaryExit creates a signed voluntary exit message and returns a VoluntaryExit object. @@ -347,7 +347,7 @@ func (s *Server) SetVoluntaryExit(w http.ResponseWriter, r *http.Request) { epoch := primitives.Epoch(e) if rawEpoch == "" { - genesisResponse, err := s.beaconNodeClient.GetGenesis(ctx, &emptypb.Empty{}) + genesisResponse, err := s.nodeClient.GetGenesis(ctx, &emptypb.Empty{}) if err != nil { httputil.HandleError(w, errors.Wrap(err, "Failed to get genesis time").Error(), http.StatusInternalServerError) return @@ -414,7 +414,7 @@ func (s *Server) ListRemoteKeys(w http.ResponseWriter, r *http.Request) { for i := 0; i < len(pubKeys); i++ { keystoreResponse[i] = &RemoteKey{ Pubkey: hexutil.Encode(pubKeys[i][:]), - Url: s.validatorService.Web3SignerConfig.BaseEndpoint, + Url: s.validatorService.RemoteSignerConfig().BaseEndpoint, Readonly: true, } } diff --git a/validator/rpc/handlers_keymanager_test.go b/validator/rpc/handlers_keymanager_test.go index 48e08ef92b73..2ec1d6b42de9 100644 --- a/validator/rpc/handlers_keymanager_test.go +++ b/validator/rpc/handlers_keymanager_test.go @@ -289,7 +289,7 @@ func TestServer_ImportKeystores(t *testing.T) { }) } require.NoError(t, err) - s.valDB = validatorDB + s.db = validatorDB // Have to close it after import is done otherwise it complains db is not open. defer func() { @@ -413,7 +413,7 @@ func TestServer_DeleteKeystores(t *testing.T) { }) } require.NoError(t, err) - srv.valDB = validatorDB + srv.db = validatorDB // Have to close it after import is done otherwise it complains db is not open. defer func() { @@ -589,7 +589,7 @@ func TestServer_DeleteKeystores_FailedSlashingProtectionExport(t *testing.T) { require.NoError(t, err) err = validatorDB.SaveGenesisValidatorsRoot(ctx, make([]byte, fieldparams.RootLength)) require.NoError(t, err) - srv.valDB = validatorDB + srv.db = validatorDB // Have to close it after import is done otherwise it complains db is not open. defer func() { @@ -746,7 +746,7 @@ func TestServer_SetVoluntaryExit(t *testing.T) { validatorService: vs, beaconNodeValidatorClient: beaconClient, wallet: w, - beaconNodeClient: mockNodeClient, + nodeClient: mockNodeClient, walletInitialized: w != nil, } @@ -841,7 +841,7 @@ func TestServer_SetVoluntaryExit(t *testing.T) { resp := &SetVoluntaryExitResponse{} require.NoError(t, json.Unmarshal(w.Body.Bytes(), resp)) if tt.w.epoch == 0 { - genesisResponse, err := s.beaconNodeClient.GetGenesis(ctx, &emptypb.Empty{}) + genesisResponse, err := s.nodeClient.GetGenesis(ctx, &emptypb.Empty{}) require.NoError(t, err) tt.w.epoch, err = client.CurrentEpoch(genesisResponse.GenesisTime) require.NoError(t, err) @@ -1091,14 +1091,14 @@ func TestServer_SetGasLimit(t *testing.T) { validatorDB := dbtest.SetupDB(t, [][fieldparams.BLSPubkeyLength]byte{}, isSlashingProtectionMinimal) vs, err := client.NewValidatorService(ctx, &client.Config{ Validator: m, - ValDB: validatorDB, + DB: validatorDB, }) require.NoError(t, err) s := &Server{ validatorService: vs, beaconNodeValidatorClient: beaconClient, - valDB: validatorDB, + db: validatorDB, } if tt.beaconReturn != nil { @@ -1280,12 +1280,12 @@ func TestServer_DeleteGasLimit(t *testing.T) { validatorDB := dbtest.SetupDB(t, [][fieldparams.BLSPubkeyLength]byte{}, isSlashingProtectionMinimal) vs, err := client.NewValidatorService(ctx, &client.Config{ Validator: m, - ValDB: validatorDB, + DB: validatorDB, }) require.NoError(t, err) s := &Server{ validatorService: vs, - valDB: validatorDB, + db: validatorDB, } // Set up global default value for builder gas limit. params.BeaconConfig().DefaultBuilderGasLimit = uint64(globalDefaultGasLimit) @@ -1744,13 +1744,13 @@ func TestServer_FeeRecipientByPubkey(t *testing.T) { // save a default here vs, err := client.NewValidatorService(ctx, &client.Config{ Validator: m, - ValDB: validatorDB, + DB: validatorDB, }) require.NoError(t, err) s := &Server{ validatorService: vs, beaconNodeValidatorClient: beaconClient, - valDB: validatorDB, + db: validatorDB, } request := &SetFeeRecipientByPubkeyRequest{ Ethaddress: tt.args, @@ -1854,12 +1854,12 @@ func TestServer_DeleteFeeRecipientByPubkey(t *testing.T) { validatorDB := dbtest.SetupDB(t, [][fieldparams.BLSPubkeyLength]byte{}, isSlashingProtectionMinimal) vs, err := client.NewValidatorService(ctx, &client.Config{ Validator: m, - ValDB: validatorDB, + DB: validatorDB, }) require.NoError(t, err) s := &Server{ validatorService: vs, - valDB: validatorDB, + db: validatorDB, } req := httptest.NewRequest(http.MethodDelete, fmt.Sprintf("/eth/v1/validator/{pubkey}/feerecipient"), nil) req = mux.SetURLVars(req, map[string]string{"pubkey": pubkey}) diff --git a/validator/rpc/handlers_slashing.go b/validator/rpc/handlers_slashing.go index a1b8ae4d9d8f..49a1596bd66e 100644 --- a/validator/rpc/handlers_slashing.go +++ b/validator/rpc/handlers_slashing.go @@ -24,12 +24,12 @@ func (s *Server) ExportSlashingProtection(w http.ResponseWriter, r *http.Request ctx, span := trace.StartSpan(r.Context(), "validator.ExportSlashingProtection") defer span.End() - if s.valDB == nil { + if s.db == nil { httputil.HandleError(w, "could not find validator database", http.StatusInternalServerError) return } - eipJSON, err := slashing.ExportStandardProtectionJSON(ctx, s.valDB) + eipJSON, err := slashing.ExportStandardProtectionJSON(ctx, s.db) if err != nil { httputil.HandleError(w, errors.Wrap(err, "could not export slashing protection history").Error(), http.StatusInternalServerError) return @@ -54,7 +54,7 @@ func (s *Server) ImportSlashingProtection(w http.ResponseWriter, r *http.Request ctx, span := trace.StartSpan(r.Context(), "validator.ImportSlashingProtection") defer span.End() - if s.valDB == nil { + if s.db == nil { httputil.HandleError(w, "could not find validator database", http.StatusInternalServerError) return } @@ -76,7 +76,7 @@ func (s *Server) ImportSlashingProtection(w http.ResponseWriter, r *http.Request } enc := []byte(req.SlashingProtectionJson) buf := bytes.NewBuffer(enc) - if err := s.valDB.ImportStandardProtectionJSON(ctx, buf); err != nil { + if err := s.db.ImportStandardProtectionJSON(ctx, buf); err != nil { httputil.HandleError(w, errors.Wrap(err, "could not import slashing protection history").Error(), http.StatusInternalServerError) return } diff --git a/validator/rpc/handlers_slashing_test.go b/validator/rpc/handlers_slashing_test.go index 4ed09d1360d2..5bcc3140b0b8 100644 --- a/validator/rpc/handlers_slashing_test.go +++ b/validator/rpc/handlers_slashing_test.go @@ -77,7 +77,7 @@ func TestImportSlashingProtection_Preconditions(t *testing.T) { }) } require.NoError(t, err) - s.valDB = validatorDB + s.db = validatorDB // Have to close it after import is done otherwise it complains db is not open. defer func() { @@ -151,7 +151,7 @@ func TestExportSlashingProtection_Preconditions(t *testing.T) { }) } require.NoError(t, err) - s.valDB = validatorDB + s.db = validatorDB // Have to close it after export is done otherwise it complains db is not open. defer func() { @@ -189,7 +189,7 @@ func TestImportExportSlashingProtection_RoundTrip(t *testing.T) { PubKeys: pubKeys, }) require.NoError(t, err) - s.valDB = validatorDB + s.db = validatorDB // Have to close it after import is done otherwise it complains db is not open. defer func() { diff --git a/validator/rpc/server.go b/validator/rpc/server.go index a0737d485c64..eacc8eb7a259 100644 --- a/validator/rpc/server.go +++ b/validator/rpc/server.go @@ -23,122 +23,83 @@ import ( "github.com/prysmaticlabs/prysm/v5/validator/client" iface "github.com/prysmaticlabs/prysm/v5/validator/client/iface" "github.com/prysmaticlabs/prysm/v5/validator/db" - "github.com/sirupsen/logrus" "go.opencensus.io/plugin/ocgrpc" "google.golang.org/grpc" - "google.golang.org/grpc/credentials" "google.golang.org/grpc/reflection" ) // Config options for the gRPC server. type Config struct { - ValidatorGatewayHost string - ValidatorGatewayPort int - ValidatorMonitoringHost string - ValidatorMonitoringPort int - BeaconClientEndpoint string - ClientMaxCallRecvMsgSize int - ClientGrpcRetries uint - ClientGrpcRetryDelay time.Duration - ClientGrpcHeaders []string - ClientWithCert string - Host string - Port string - CertFlag string - KeyFlag string - ValDB db.Database - AuthTokenPath string - WalletDir string - ValidatorService *client.ValidatorService - SyncChecker client.SyncChecker - GenesisFetcher client.GenesisFetcher - WalletInitializedFeed *event.Feed - NodeGatewayEndpoint string - BeaconApiEndpoint string - BeaconApiTimeout time.Duration - Router *mux.Router - Wallet *wallet.Wallet + Host string + Port string + GRPCGatewayHost string + GRPCGatewayPort int + GRPCMaxCallRecvMsgSize int + GRPCRetries uint + GRPCRetryDelay time.Duration + GRPCHeaders []string + BeaconNodeGRPCEndpoint string + BeaconApiEndpoint string + BeaconApiTimeout time.Duration + BeaconNodeCert string + DB db.Database + Wallet *wallet.Wallet + WalletDir string + WalletInitializedFeed *event.Feed + ValidatorService *client.ValidatorService + Router *mux.Router } // Server defining a gRPC server for the remote signer API. type Server struct { - logsStreamer logs.Streamer - streamLogsBufferSize int - beaconChainClient iface.BeaconChainClient - beaconNodeClient iface.NodeClient - beaconNodeValidatorClient iface.ValidatorClient - beaconNodeHealthClient ethpb.HealthClient - valDB db.Database ctx context.Context cancel context.CancelFunc - beaconClientEndpoint string - clientMaxCallRecvMsgSize int - clientGrpcRetries uint - clientGrpcRetryDelay time.Duration - clientGrpcHeaders []string - clientWithCert string host string port string + grpcGatewayHost string + grpcGatewayPort int listener net.Listener - withCert string - withKey string - credentialError error + grpcMaxCallRecvMsgSize int + grpcRetries uint + grpcRetryDelay time.Duration + grpcHeaders []string grpcServer *grpc.Server + beaconNodeValidatorClient iface.ValidatorClient + chainClient iface.ChainClient + nodeClient iface.NodeClient + healthClient ethpb.HealthClient + beaconNodeEndpoint string + beaconApiEndpoint string + beaconApiTimeout time.Duration + beaconNodeCert string jwtSecret []byte - validatorService *client.ValidatorService - syncChecker client.SyncChecker - genesisFetcher client.GenesisFetcher authTokenPath string authToken string + db db.Database walletDir string wallet *wallet.Wallet walletInitializedFeed *event.Feed walletInitialized bool - nodeGatewayEndpoint string - validatorMonitoringHost string - validatorMonitoringPort int - validatorGatewayHost string - validatorGatewayPort int - beaconApiEndpoint string - beaconApiTimeout time.Duration + validatorService *client.ValidatorService router *mux.Router + logStreamer logs.Streamer + logStreamerBufferSize int } // NewServer instantiates a new gRPC server. func NewServer(ctx context.Context, cfg *Config) *Server { ctx, cancel := context.WithCancel(ctx) server := &Server{ - ctx: ctx, - cancel: cancel, - logsStreamer: logs.NewStreamServer(), - streamLogsBufferSize: 1000, // Enough to handle most bursts of logs in the validator client. - host: cfg.Host, - port: cfg.Port, - withCert: cfg.CertFlag, - withKey: cfg.KeyFlag, - beaconClientEndpoint: cfg.BeaconClientEndpoint, - clientMaxCallRecvMsgSize: cfg.ClientMaxCallRecvMsgSize, - clientGrpcRetries: cfg.ClientGrpcRetries, - clientGrpcRetryDelay: cfg.ClientGrpcRetryDelay, - clientGrpcHeaders: cfg.ClientGrpcHeaders, - clientWithCert: cfg.ClientWithCert, - valDB: cfg.ValDB, - validatorService: cfg.ValidatorService, - syncChecker: cfg.SyncChecker, - genesisFetcher: cfg.GenesisFetcher, - authTokenPath: cfg.AuthTokenPath, - walletDir: cfg.WalletDir, - walletInitializedFeed: cfg.WalletInitializedFeed, - walletInitialized: cfg.Wallet != nil, - wallet: cfg.Wallet, - nodeGatewayEndpoint: cfg.NodeGatewayEndpoint, - validatorMonitoringHost: cfg.ValidatorMonitoringHost, - validatorMonitoringPort: cfg.ValidatorMonitoringPort, - validatorGatewayHost: cfg.ValidatorGatewayHost, - validatorGatewayPort: cfg.ValidatorGatewayPort, - beaconApiTimeout: cfg.BeaconApiTimeout, - beaconApiEndpoint: cfg.BeaconApiEndpoint, - router: cfg.Router, + ctx: ctx, + cancel: cancel, + host: cfg.Host, + port: cfg.Port, + grpcGatewayHost: cfg.GRPCGatewayHost, + grpcGatewayPort: cfg.GRPCGatewayPort, + grpcMaxCallRecvMsgSize: cfg.GRPCMaxCallRecvMsgSize, + grpcRetries: cfg.GRPCRetries, + grpcRetryDelay: cfg.GRPCRetryDelay, + grpcHeaders: cfg.GRPCHeaders, } if server.authTokenPath == "" && server.walletDir != "" { @@ -149,7 +110,7 @@ func NewServer(ctx context.Context, cfg *Config) *Server { if err := server.initializeAuthToken(); err != nil { log.WithError(err).Error("Could not initialize web auth token") } - validatorWebAddr := fmt.Sprintf("%s:%d", server.validatorGatewayHost, server.validatorGatewayPort) + validatorWebAddr := fmt.Sprintf("%s:%d", server.grpcGatewayHost, server.grpcGatewayPort) logValidatorWebAuth(validatorWebAddr, server.authToken, server.authTokenPath) go server.refreshAuthTokenFromFileChanges(server.ctx, server.authTokenPath) } @@ -184,17 +145,7 @@ func (s *Server) Start() { )), } grpcprometheus.EnableHandlingTimeHistogram() - if s.withCert != "" && s.withKey != "" { - creds, err := credentials.NewServerTLSFromFile(s.withCert, s.withKey) - if err != nil { - log.WithError(err).Fatal("Could not load TLS keys") - } - opts = append(opts, grpc.Creds(creds)) - log.WithFields(logrus.Fields{ - "certPath": s.withCert, - "keyPath": s.withKey, - }).Info("Loaded TLS certificates") - } + s.grpcServer = grpc.NewServer(opts...) // Register a gRPC client to the beacon node. @@ -282,7 +233,7 @@ func (s *Server) Stop() error { return nil } -// Status returns nil or credentialError. +// Status returns an error if the service is unhealthy. func (s *Server) Status() error { - return s.credentialError + return nil }