Skip to content

Commit

Permalink
[Prototype] EIP-7251: MaxEB
Browse files Browse the repository at this point in the history
Add has_compounding_withdrawal_credential helper

Progress

Tuesday night progress

Thursday night progress

Sunday afternoon progress

Tuesday progress

Monday night progress: tests are passing

Progress from last week, mostly on state

monday night progress: had to refactor a lot of tests to be blackbox tests

tuesday progress

wednesday progress

thursday progress

Friday progress

Monday progress

Fix up eip-7251 branch, fix issues, update to spec v1.5.0-alpha.0

More updates to spec 1.5.0-alpha.0, refactorings

Prepping for spectests

WIP: Electra beacon state HTR

Progress on custom HTR for beaconStateElectra
  • Loading branch information
prestonvanloon committed Apr 25, 2024
1 parent 8d9024f commit 2dc3c74
Show file tree
Hide file tree
Showing 157 changed files with 7,181 additions and 488 deletions.
21 changes: 21 additions & 0 deletions MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions api/client/builder/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ func (c *Client) SubmitBlindedBlock(ctx context.Context, sb interfaces.ReadOnlyS
return nil, nil, errors.Wrapf(err, "could not wrap execution payload in interface")
}
return payload, blobBundle, nil
// TODO: Electra
default:
return nil, nil, fmt.Errorf("unsupported block version %s", version.String(sb.Version()))
}
Expand Down
6 changes: 4 additions & 2 deletions beacon-chain/blockchain/execution_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,10 @@ func (s *Service) getPayloadAttribute(ctx context.Context, st state.BeaconState,

var attr payloadattribute.Attributer
switch st.Version() {
case version.Electra:
panic("implement me") // TODO
case version.Deneb:
withdrawals, err := st.ExpectedWithdrawals()
withdrawals, _, err := st.ExpectedWithdrawals()
if err != nil {
log.WithError(err).Error("Could not get expected withdrawals to get payload attribute")
return emptyAttri
Expand All @@ -342,7 +344,7 @@ func (s *Service) getPayloadAttribute(ctx context.Context, st state.BeaconState,
return emptyAttri
}
case version.Capella:
withdrawals, err := st.ExpectedWithdrawals()
withdrawals, _, err := st.ExpectedWithdrawals()
if err != nil {
log.WithError(err).Error("Could not get expected withdrawals to get payload attribute")
return emptyAttri
Expand Down
7 changes: 7 additions & 0 deletions beacon-chain/builder/testing/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type MockBuilderService struct {
Payload *v1.ExecutionPayload
PayloadCapella *v1.ExecutionPayloadCapella
PayloadDeneb *v1.ExecutionPayloadDeneb
PayloadElectra *v1.ExecutionPayloadElectra
BlobBundle *v1.BlobsBundle
ErrSubmitBlindedBlock error
Bid *ethpb.SignedBuilderBid
Expand Down Expand Up @@ -66,6 +67,12 @@ func (s *MockBuilderService) SubmitBlindedBlock(_ context.Context, b interfaces.
return nil, nil, errors.Wrap(err, "could not wrap deneb payload")
}
return w, s.BlobBundle, s.ErrSubmitBlindedBlock
case version.Electra:
w, err := blocks.WrappedExecutionPayloadElectra(s.PayloadElectra, big.NewInt(0))
if err != nil {
return nil, nil, errors.Wrap(err, "could not wrap electra payload")
}
return w, s.BlobBundle, s.ErrSubmitBlindedBlock
default:
return nil, nil, errors.New("unknown block version for mocking")
}
Expand Down
2 changes: 2 additions & 0 deletions beacon-chain/cache/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ go_test(
"committee_fuzz_test.go",
"committee_test.go",
"payload_id_test.go",
"private_access_test.go",
"proposer_indices_test.go",
"registration_test.go",
"skip_slot_cache_test.go",
Expand All @@ -93,6 +94,7 @@ go_test(
"//testing/util:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_google_gofuzz//:go_default_library",
"@com_github_hashicorp_golang_lru//:go_default_library",
"@com_github_stretchr_testify//require:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
],
Expand Down
31 changes: 16 additions & 15 deletions beacon-chain/cache/active_balance_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
//go:build !fuzz

package cache
package cache_test

import (
"encoding/binary"
"math"
"testing"

"github.com/prysmaticlabs/prysm/v5/beacon-chain/cache"
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"
Expand All @@ -27,33 +28,33 @@ func TestBalanceCache_AddGetBalance(t *testing.T) {
st, err := state_native.InitializeFromProtoPhase0(raw)
require.NoError(t, err)

cache := NewEffectiveBalanceCache()
_, err = cache.Get(st)
require.ErrorContains(t, ErrNotFound.Error(), err)
cc := cache.NewEffectiveBalanceCache()
_, err = cc.Get(st)
require.ErrorContains(t, cache.ErrNotFound.Error(), err)

b := uint64(100)
require.NoError(t, cache.AddTotalEffectiveBalance(st, b))
cachedB, err := cache.Get(st)
require.NoError(t, cc.AddTotalEffectiveBalance(st, b))
cachedB, err := cc.Get(st)
require.NoError(t, err)
require.Equal(t, b, cachedB)

require.NoError(t, st.SetSlot(1000))
_, err = cache.Get(st)
require.ErrorContains(t, ErrNotFound.Error(), err)
_, err = cc.Get(st)
require.ErrorContains(t, cache.ErrNotFound.Error(), err)

b = uint64(200)
require.NoError(t, cache.AddTotalEffectiveBalance(st, b))
cachedB, err = cache.Get(st)
require.NoError(t, cc.AddTotalEffectiveBalance(st, b))
cachedB, err = cc.Get(st)
require.NoError(t, err)
require.Equal(t, b, cachedB)

require.NoError(t, st.SetSlot(1000+params.BeaconConfig().SlotsPerHistoricalRoot))
_, err = cache.Get(st)
require.ErrorContains(t, ErrNotFound.Error(), err)
_, err = cc.Get(st)
require.ErrorContains(t, cache.ErrNotFound.Error(), err)

b = uint64(300)
require.NoError(t, cache.AddTotalEffectiveBalance(st, b))
cachedB, err = cache.Get(st)
require.NoError(t, cc.AddTotalEffectiveBalance(st, b))
cachedB, err = cc.Get(st)
require.NoError(t, err)
require.Equal(t, b, cachedB)
}
Expand All @@ -72,6 +73,6 @@ func TestBalanceCache_BalanceKey(t *testing.T) {
require.NoError(t, err)
require.NoError(t, st.SetSlot(primitives.Slot(math.MaxUint64)))

_, err = balanceCacheKey(st)
_, err = cache.BalanceCacheKey(st)
require.NoError(t, err)
}
11 changes: 6 additions & 5 deletions beacon-chain/cache/checkpoint_state_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package cache
package cache_test

import (
"testing"

"github.com/prysmaticlabs/prysm/v5/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
"github.com/prysmaticlabs/prysm/v5/config/params"
Expand All @@ -15,7 +16,7 @@ import (
)

func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
cache := NewCheckpointStateCache()
cache := cache.NewCheckpointStateCache()

cp1 := &ethpb.Checkpoint{Epoch: 1, Root: bytesutil.PadTo([]byte{'A'}, 32)}
st, err := state_native.InitializeFromProtoPhase0(&ethpb.BeaconState{
Expand Down Expand Up @@ -58,16 +59,16 @@ func TestCheckpointStateCache_StateByCheckpoint(t *testing.T) {
}

func TestCheckpointStateCache_MaxSize(t *testing.T) {
c := NewCheckpointStateCache()
c := cache.NewCheckpointStateCache()
st, err := state_native.InitializeFromProtoPhase0(&ethpb.BeaconState{
Slot: 0,
})
require.NoError(t, err)

for i := uint64(0); i < uint64(maxCheckpointStateSize+100); i++ {
for i := uint64(0); i < uint64(cache.MaxCheckpointStateSize()+100); i++ {
require.NoError(t, st.SetSlot(primitives.Slot(i)))
require.NoError(t, c.AddCheckpointState(&ethpb.Checkpoint{Epoch: primitives.Epoch(i), Root: make([]byte, 32)}, st))
}

assert.Equal(t, maxCheckpointStateSize, len(c.cache.Keys()))
assert.Equal(t, cache.MaxCheckpointStateSize(), len(c.Cache().Keys()))
}
18 changes: 18 additions & 0 deletions beacon-chain/cache/private_access_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package cache

import (
lru "github.com/hashicorp/golang-lru"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
)

func BalanceCacheKey(st state.ReadOnlyBeaconState) (string, error) {
return balanceCacheKey(st)

Check failure on line 9 in beacon-chain/cache/private_access_test.go

View workflow job for this annotation

GitHub Actions / Build

undefined: balanceCacheKey
}

func MaxCheckpointStateSize() int {
return maxCheckpointStateSize
}

func (c *CheckpointStateCache) Cache() *lru.Cache {
return c.cache
}
5 changes: 3 additions & 2 deletions beacon-chain/cache/sync_committee_head_state_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package cache
package cache_test

import (
"testing"

"github.com/prysmaticlabs/prysm/v5/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
"github.com/prysmaticlabs/prysm/v5/config/params"
Expand Down Expand Up @@ -125,7 +126,7 @@ func TestSyncCommitteeHeadState(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := NewSyncCommitteeHeadState()
c := cache.NewSyncCommitteeHeadState()
if tt.put != nil {
err := c.Put(tt.put.slot, tt.put.state)
if (err != nil) != tt.wantPutErr {
Expand Down
63 changes: 42 additions & 21 deletions beacon-chain/core/blocks/deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ 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/container/trie"
"github.com/prysmaticlabs/prysm/v5/contracts/deposit"
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
Expand Down Expand Up @@ -136,26 +137,25 @@ func BatchVerifyDepositsSignatures(ctx context.Context, deposits []*ethpb.Deposi
//
// pubkey = deposit.data.pubkey
// amount = deposit.data.amount
// validator_pubkeys = [v.pubkey for v in state.validators]
// if pubkey not in validator_pubkeys:
// # Verify the deposit signature (proof of possession) which is not checked by the deposit contract
// deposit_message = DepositMessage(
// pubkey=deposit.data.pubkey,
// withdrawal_credentials=deposit.data.withdrawal_credentials,
// amount=deposit.data.amount,
// )
// domain = compute_domain(DOMAIN_DEPOSIT) # Fork-agnostic domain since deposits are valid across forks
// signing_root = compute_signing_root(deposit_message, domain)
// if not bls.Verify(pubkey, signing_root, deposit.data.signature):
// return
//
// # Add validator and balance entries
// state.validators.append(get_validator_from_deposit(state, deposit))
// state.balances.append(amount)
// else:
// # Increase balance by deposit amount
// index = ValidatorIndex(validator_pubkeys.index(pubkey))
// increase_balance(state, index, amount)
// TODO: This is apply_deposit, refactor to another function for readability.
//
// validator_pubkeys = [v.pubkey for v in state.validators]
// if pubkey not in validator_pubkeys:
// # Verify the deposit signature (proof of possession) which is not checked by the deposit contract
// deposit_message = DepositMessage(
// pubkey=deposit.data.pubkey,
// withdrawal_credentials=deposit.data.withdrawal_credentials,
// amount=deposit.data.amount,
// )
// domain = compute_domain(DOMAIN_DEPOSIT) # Fork-agnostic domain since deposits are valid across forks
// signing_root = compute_signing_root(deposit_message, domain)
// if bls.Verify(pubkey, signing_root, signature):
// add_validator_to_registry(state, pubkey, withdrawal_credentials, amount) // TODO: Missing spec def here
// else:
// # Increase balance by deposit amount
// index = ValidatorIndex(validator_pubkeys.index(pubkey))
// state.pending_balance_deposits.append(PendingBalanceDeposit(index, amount)) # [Modified in EIP-7251]
func ProcessDeposit(beaconState state.BeaconState, deposit *ethpb.Deposit, verifySignature bool) (state.BeaconState, bool, error) {
var newValidator bool
if err := verifyDeposit(beaconState, deposit); err != nil {
Expand All @@ -167,6 +167,7 @@ func ProcessDeposit(beaconState state.BeaconState, deposit *ethpb.Deposit, verif
if err := beaconState.SetEth1DepositIndex(beaconState.Eth1DepositIndex() + 1); err != nil {
return nil, newValidator, err
}
isElectraOrLater := beaconState.Fork() != nil && beaconState.Fork().Epoch >= params.BeaconConfig().ElectraForkEpoch
pubKey := deposit.Data.PublicKey
amount := deposit.Data.Amount
index, ok := beaconState.ValidatorIndexByPubkey(bytesutil.ToBytes48(pubKey))
Expand All @@ -183,10 +184,16 @@ func ProcessDeposit(beaconState state.BeaconState, deposit *ethpb.Deposit, verif
}
}

// NOTE: This is get_validator_from_deposit. There are changes in EIP-7251.
effectiveBalance := amount - (amount % params.BeaconConfig().EffectiveBalanceIncrement)
if params.BeaconConfig().MaxEffectiveBalance < effectiveBalance {
effectiveBalance = params.BeaconConfig().MaxEffectiveBalance
}
if isElectraOrLater {
// In EIP-7251, the balance updates happen in the process_pending_balance_deposits method of
// the epoch transition function.
effectiveBalance = 0 // New in EIP-7251
}
if err := beaconState.AppendValidator(&ethpb.Validator{
PublicKey: pubKey,
WithdrawalCredentials: deposit.Data.WithdrawalCredentials,
Expand All @@ -202,10 +209,24 @@ func ProcessDeposit(beaconState state.BeaconState, deposit *ethpb.Deposit, verif
if err := beaconState.AppendBalance(amount); err != nil {
return nil, newValidator, err
}
} else if err := helpers.IncreaseBalance(beaconState, index, amount); err != nil {
return nil, newValidator, err
numVals := beaconState.NumValidators()
if numVals == 0 { // Cautiously prevent impossible underflow
return nil, false, errors.New("underflow: zero validators")
}
index = primitives.ValidatorIndex(numVals - 1)
} else {
if !isElectraOrLater {
if err := helpers.IncreaseBalance(beaconState, index, amount); err != nil {
return nil, newValidator, err
}
}
}

if isElectraOrLater {
if err := beaconState.AppendPendingBalanceDeposit(index, amount); err != nil {
return nil, newValidator, err
}
}
return beaconState, newValidator, nil
}

Expand Down
Loading

0 comments on commit 2dc3c74

Please sign in to comment.