mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-02-14 06:55:07 -05:00
Compare commits
3 Commits
gloas-api-
...
calculate-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0f9cf5f6c | ||
|
|
22e77add54 | ||
|
|
bccb69f03f |
@@ -9,7 +9,6 @@ go_library(
|
||||
"conversions_blob.go",
|
||||
"conversions_block.go",
|
||||
"conversions_block_execution.go",
|
||||
"conversions_gloas.go",
|
||||
"conversions_lightclient.go",
|
||||
"conversions_state.go",
|
||||
"endpoints_beacon.go",
|
||||
@@ -58,12 +57,10 @@ go_test(
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
],
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
package structs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/OffchainLabs/prysm/v7/consensus-types/interfaces"
|
||||
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
)
|
||||
|
||||
func ROExecutionPayloadBidFromConsensus(b interfaces.ROExecutionPayloadBid) *ExecutionPayloadBid {
|
||||
pbh := b.ParentBlockHash()
|
||||
pbr := b.ParentBlockRoot()
|
||||
bh := b.BlockHash()
|
||||
pr := b.PrevRandao()
|
||||
fr := b.FeeRecipient()
|
||||
var blobKzgCommitments []string
|
||||
for _, commitment := range b.BlobKzgCommitments() {
|
||||
blobKzgCommitments = append(blobKzgCommitments, hexutil.Encode(commitment))
|
||||
}
|
||||
return &ExecutionPayloadBid{
|
||||
ParentBlockHash: hexutil.Encode(pbh[:]),
|
||||
ParentBlockRoot: hexutil.Encode(pbr[:]),
|
||||
BlockHash: hexutil.Encode(bh[:]),
|
||||
PrevRandao: hexutil.Encode(pr[:]),
|
||||
FeeRecipient: hexutil.Encode(fr[:]),
|
||||
GasLimit: fmt.Sprintf("%d", b.GasLimit()),
|
||||
BuilderIndex: fmt.Sprintf("%d", b.BuilderIndex()),
|
||||
Slot: fmt.Sprintf("%d", b.Slot()),
|
||||
Value: fmt.Sprintf("%d", b.Value()),
|
||||
ExecutionPayment: fmt.Sprintf("%d", b.ExecutionPayment()),
|
||||
BlobKzgCommitments: blobKzgCommitments,
|
||||
}
|
||||
}
|
||||
|
||||
func BuildersFromConsensus(builders []*ethpb.Builder) []*Builder {
|
||||
newBuilders := make([]*Builder, len(builders))
|
||||
for i, b := range builders {
|
||||
newBuilders[i] = BuilderFromConsensus(b)
|
||||
}
|
||||
return newBuilders
|
||||
}
|
||||
|
||||
func BuilderFromConsensus(b *ethpb.Builder) *Builder {
|
||||
return &Builder{
|
||||
Pubkey: hexutil.Encode(b.Pubkey),
|
||||
Version: hexutil.Encode(b.Version),
|
||||
ExecutionAddress: hexutil.Encode(b.ExecutionAddress),
|
||||
Balance: fmt.Sprintf("%d", b.Balance),
|
||||
DepositEpoch: fmt.Sprintf("%d", b.DepositEpoch),
|
||||
WithdrawableEpoch: fmt.Sprintf("%d", b.WithdrawableEpoch),
|
||||
}
|
||||
}
|
||||
|
||||
func BuilderPendingPaymentsFromConsensus(payments []*ethpb.BuilderPendingPayment) []*BuilderPendingPayment {
|
||||
newPayments := make([]*BuilderPendingPayment, len(payments))
|
||||
for i, p := range payments {
|
||||
newPayments[i] = BuilderPendingPaymentFromConsensus(p)
|
||||
}
|
||||
return newPayments
|
||||
}
|
||||
|
||||
func BuilderPendingPaymentFromConsensus(p *ethpb.BuilderPendingPayment) *BuilderPendingPayment {
|
||||
return &BuilderPendingPayment{
|
||||
Weight: fmt.Sprintf("%d", p.Weight),
|
||||
Withdrawal: BuilderPendingWithdrawalFromConsensus(p.Withdrawal),
|
||||
}
|
||||
}
|
||||
|
||||
func BuilderPendingWithdrawalsFromConsensus(withdrawals []*ethpb.BuilderPendingWithdrawal) []*BuilderPendingWithdrawal {
|
||||
newWithdrawals := make([]*BuilderPendingWithdrawal, len(withdrawals))
|
||||
for i, w := range withdrawals {
|
||||
newWithdrawals[i] = BuilderPendingWithdrawalFromConsensus(w)
|
||||
}
|
||||
return newWithdrawals
|
||||
}
|
||||
|
||||
func BuilderPendingWithdrawalFromConsensus(w *ethpb.BuilderPendingWithdrawal) *BuilderPendingWithdrawal {
|
||||
return &BuilderPendingWithdrawal{
|
||||
FeeRecipient: hexutil.Encode(w.FeeRecipient),
|
||||
Amount: fmt.Sprintf("%d", w.Amount),
|
||||
BuilderIndex: fmt.Sprintf("%d", w.BuilderIndex),
|
||||
}
|
||||
}
|
||||
@@ -972,223 +972,3 @@ func BeaconStateFuluFromConsensus(st beaconState.BeaconState) (*BeaconStateFulu,
|
||||
ProposerLookahead: lookahead,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Gloas
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
func BeaconStateGloasFromConsensus(st beaconState.BeaconState) (*BeaconStateGloas, error) {
|
||||
srcBr := st.BlockRoots()
|
||||
br := make([]string, len(srcBr))
|
||||
for i, r := range srcBr {
|
||||
br[i] = hexutil.Encode(r)
|
||||
}
|
||||
srcSr := st.StateRoots()
|
||||
sr := make([]string, len(srcSr))
|
||||
for i, r := range srcSr {
|
||||
sr[i] = hexutil.Encode(r)
|
||||
}
|
||||
srcHr := st.HistoricalRoots()
|
||||
hr := make([]string, len(srcHr))
|
||||
for i, r := range srcHr {
|
||||
hr[i] = hexutil.Encode(r)
|
||||
}
|
||||
srcVotes := st.Eth1DataVotes()
|
||||
votes := make([]*Eth1Data, len(srcVotes))
|
||||
for i, e := range srcVotes {
|
||||
votes[i] = Eth1DataFromConsensus(e)
|
||||
}
|
||||
srcVals := st.Validators()
|
||||
vals := make([]*Validator, len(srcVals))
|
||||
for i, v := range srcVals {
|
||||
vals[i] = ValidatorFromConsensus(v)
|
||||
}
|
||||
srcBals := st.Balances()
|
||||
bals := make([]string, len(srcBals))
|
||||
for i, b := range srcBals {
|
||||
bals[i] = fmt.Sprintf("%d", b)
|
||||
}
|
||||
srcRm := st.RandaoMixes()
|
||||
rm := make([]string, len(srcRm))
|
||||
for i, m := range srcRm {
|
||||
rm[i] = hexutil.Encode(m)
|
||||
}
|
||||
srcSlashings := st.Slashings()
|
||||
slashings := make([]string, len(srcSlashings))
|
||||
for i, s := range srcSlashings {
|
||||
slashings[i] = fmt.Sprintf("%d", s)
|
||||
}
|
||||
srcPrevPart, err := st.PreviousEpochParticipation()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
prevPart := make([]string, len(srcPrevPart))
|
||||
for i, p := range srcPrevPart {
|
||||
prevPart[i] = fmt.Sprintf("%d", p)
|
||||
}
|
||||
srcCurrPart, err := st.CurrentEpochParticipation()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currPart := make([]string, len(srcCurrPart))
|
||||
for i, p := range srcCurrPart {
|
||||
currPart[i] = fmt.Sprintf("%d", p)
|
||||
}
|
||||
srcIs, err := st.InactivityScores()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
is := make([]string, len(srcIs))
|
||||
for i, s := range srcIs {
|
||||
is[i] = fmt.Sprintf("%d", s)
|
||||
}
|
||||
currSc, err := st.CurrentSyncCommittee()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nextSc, err := st.NextSyncCommittee()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
srcHs, err := st.HistoricalSummaries()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hs := make([]*HistoricalSummary, len(srcHs))
|
||||
for i, s := range srcHs {
|
||||
hs[i] = HistoricalSummaryFromConsensus(s)
|
||||
}
|
||||
nwi, err := st.NextWithdrawalIndex()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nwvi, err := st.NextWithdrawalValidatorIndex()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
drsi, err := st.DepositRequestsStartIndex()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dbtc, err := st.DepositBalanceToConsume()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ebtc, err := st.ExitBalanceToConsume()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
eee, err := st.EarliestExitEpoch()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cbtc, err := st.ConsolidationBalanceToConsume()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ece, err := st.EarliestConsolidationEpoch()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pbd, err := st.PendingDeposits()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ppw, err := st.PendingPartialWithdrawals()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pc, err := st.PendingConsolidations()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
srcLookahead, err := st.ProposerLookahead()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lookahead := make([]string, len(srcLookahead))
|
||||
for i, v := range srcLookahead {
|
||||
lookahead[i] = fmt.Sprintf("%d", uint64(v))
|
||||
}
|
||||
// Gloas-specific fields
|
||||
lepb, err := st.LatestExecutionPayloadBid()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builders, err := st.Builders()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nwbi, err := st.NextWithdrawalBuilderIndex()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
epa, err := st.ExecutionPayloadAvailabilityVector()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bpp, err := st.BuilderPendingPayments()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bpw, err := st.BuilderPendingWithdrawals()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lbh, err := st.LatestBlockHash()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pew, err := st.PayloadExpectedWithdrawals()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &BeaconStateGloas{
|
||||
GenesisTime: fmt.Sprintf("%d", st.GenesisTime().Unix()),
|
||||
GenesisValidatorsRoot: hexutil.Encode(st.GenesisValidatorsRoot()),
|
||||
Slot: fmt.Sprintf("%d", st.Slot()),
|
||||
Fork: ForkFromConsensus(st.Fork()),
|
||||
LatestBlockHeader: BeaconBlockHeaderFromConsensus(st.LatestBlockHeader()),
|
||||
BlockRoots: br,
|
||||
StateRoots: sr,
|
||||
HistoricalRoots: hr,
|
||||
Eth1Data: Eth1DataFromConsensus(st.Eth1Data()),
|
||||
Eth1DataVotes: votes,
|
||||
Eth1DepositIndex: fmt.Sprintf("%d", st.Eth1DepositIndex()),
|
||||
Validators: vals,
|
||||
Balances: bals,
|
||||
RandaoMixes: rm,
|
||||
Slashings: slashings,
|
||||
PreviousEpochParticipation: prevPart,
|
||||
CurrentEpochParticipation: currPart,
|
||||
JustificationBits: hexutil.Encode(st.JustificationBits()),
|
||||
PreviousJustifiedCheckpoint: CheckpointFromConsensus(st.PreviousJustifiedCheckpoint()),
|
||||
CurrentJustifiedCheckpoint: CheckpointFromConsensus(st.CurrentJustifiedCheckpoint()),
|
||||
FinalizedCheckpoint: CheckpointFromConsensus(st.FinalizedCheckpoint()),
|
||||
InactivityScores: is,
|
||||
CurrentSyncCommittee: SyncCommitteeFromConsensus(currSc),
|
||||
NextSyncCommittee: SyncCommitteeFromConsensus(nextSc),
|
||||
NextWithdrawalIndex: fmt.Sprintf("%d", nwi),
|
||||
NextWithdrawalValidatorIndex: fmt.Sprintf("%d", nwvi),
|
||||
HistoricalSummaries: hs,
|
||||
DepositRequestsStartIndex: fmt.Sprintf("%d", drsi),
|
||||
DepositBalanceToConsume: fmt.Sprintf("%d", dbtc),
|
||||
ExitBalanceToConsume: fmt.Sprintf("%d", ebtc),
|
||||
EarliestExitEpoch: fmt.Sprintf("%d", eee),
|
||||
ConsolidationBalanceToConsume: fmt.Sprintf("%d", cbtc),
|
||||
EarliestConsolidationEpoch: fmt.Sprintf("%d", ece),
|
||||
PendingDeposits: PendingDepositsFromConsensus(pbd),
|
||||
PendingPartialWithdrawals: PendingPartialWithdrawalsFromConsensus(ppw),
|
||||
PendingConsolidations: PendingConsolidationsFromConsensus(pc),
|
||||
ProposerLookahead: lookahead,
|
||||
LatestExecutionPayloadBid: ROExecutionPayloadBidFromConsensus(lepb),
|
||||
Builders: BuildersFromConsensus(builders),
|
||||
NextWithdrawalBuilderIndex: fmt.Sprintf("%d", nwbi),
|
||||
ExecutionPayloadAvailability: hexutil.Encode(epa),
|
||||
BuilderPendingPayments: BuilderPendingPaymentsFromConsensus(bpp),
|
||||
BuilderPendingWithdrawals: BuilderPendingWithdrawalsFromConsensus(bpw),
|
||||
LatestBlockHash: hexutil.Encode(lbh[:]),
|
||||
PayloadExpectedWithdrawals: WithdrawalsFromConsensus(pew),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
package structs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/OffchainLabs/prysm/v7/consensus-types/blocks"
|
||||
enginev1 "github.com/OffchainLabs/prysm/v7/proto/engine/v1"
|
||||
eth "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
|
||||
"github.com/OffchainLabs/prysm/v7/testing/assert"
|
||||
"github.com/OffchainLabs/prysm/v7/testing/require"
|
||||
"github.com/OffchainLabs/prysm/v7/testing/util"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
)
|
||||
|
||||
@@ -359,178 +355,3 @@ func TestIndexedAttestation_ToConsensus(t *testing.T) {
|
||||
_, err := a.ToConsensus()
|
||||
require.ErrorContains(t, errNilValue.Error(), err)
|
||||
}
|
||||
|
||||
func TestROExecutionPayloadBidFromConsensus(t *testing.T) {
|
||||
bid := ð.ExecutionPayloadBid{
|
||||
ParentBlockHash: bytes.Repeat([]byte{0x01}, 32),
|
||||
ParentBlockRoot: bytes.Repeat([]byte{0x02}, 32),
|
||||
BlockHash: bytes.Repeat([]byte{0x03}, 32),
|
||||
PrevRandao: bytes.Repeat([]byte{0x04}, 32),
|
||||
FeeRecipient: bytes.Repeat([]byte{0x05}, 20),
|
||||
GasLimit: 100,
|
||||
BuilderIndex: 7,
|
||||
Slot: 9,
|
||||
Value: 11,
|
||||
ExecutionPayment: 22,
|
||||
BlobKzgCommitments: [][]byte{bytes.Repeat([]byte{0x06}, 48)},
|
||||
}
|
||||
roBid, err := blocks.WrappedROExecutionPayloadBid(bid)
|
||||
require.NoError(t, err)
|
||||
|
||||
var bkcs []string
|
||||
for _, commitment := range roBid.BlobKzgCommitments() {
|
||||
bkcs = append(bkcs, hexutil.Encode(commitment))
|
||||
}
|
||||
|
||||
got := ROExecutionPayloadBidFromConsensus(roBid)
|
||||
want := &ExecutionPayloadBid{
|
||||
ParentBlockHash: hexutil.Encode(bid.ParentBlockHash),
|
||||
ParentBlockRoot: hexutil.Encode(bid.ParentBlockRoot),
|
||||
BlockHash: hexutil.Encode(bid.BlockHash),
|
||||
PrevRandao: hexutil.Encode(bid.PrevRandao),
|
||||
FeeRecipient: hexutil.Encode(bid.FeeRecipient),
|
||||
GasLimit: "100",
|
||||
BuilderIndex: "7",
|
||||
Slot: "9",
|
||||
Value: "11",
|
||||
ExecutionPayment: "22",
|
||||
BlobKzgCommitments: bkcs,
|
||||
}
|
||||
assert.DeepEqual(t, want, got)
|
||||
}
|
||||
|
||||
func TestBuilderConversionsFromConsensus(t *testing.T) {
|
||||
builder := ð.Builder{
|
||||
Pubkey: bytes.Repeat([]byte{0xAA}, 48),
|
||||
Version: bytes.Repeat([]byte{0x01}, 4),
|
||||
ExecutionAddress: bytes.Repeat([]byte{0xBB}, 20),
|
||||
Balance: 42,
|
||||
DepositEpoch: 3,
|
||||
WithdrawableEpoch: 4,
|
||||
}
|
||||
wantBuilder := &Builder{
|
||||
Pubkey: hexutil.Encode(builder.Pubkey),
|
||||
Version: hexutil.Encode(builder.Version),
|
||||
ExecutionAddress: hexutil.Encode(builder.ExecutionAddress),
|
||||
Balance: "42",
|
||||
DepositEpoch: "3",
|
||||
WithdrawableEpoch: "4",
|
||||
}
|
||||
|
||||
assert.DeepEqual(t, wantBuilder, BuilderFromConsensus(builder))
|
||||
assert.DeepEqual(t, []*Builder{wantBuilder}, BuildersFromConsensus([]*eth.Builder{builder}))
|
||||
}
|
||||
|
||||
func TestBuilderPendingPaymentConversionsFromConsensus(t *testing.T) {
|
||||
withdrawal := ð.BuilderPendingWithdrawal{
|
||||
FeeRecipient: bytes.Repeat([]byte{0x10}, 20),
|
||||
Amount: 15,
|
||||
BuilderIndex: 2,
|
||||
}
|
||||
payment := ð.BuilderPendingPayment{
|
||||
Weight: 5,
|
||||
Withdrawal: withdrawal,
|
||||
}
|
||||
wantWithdrawal := &BuilderPendingWithdrawal{
|
||||
FeeRecipient: hexutil.Encode(withdrawal.FeeRecipient),
|
||||
Amount: "15",
|
||||
BuilderIndex: "2",
|
||||
}
|
||||
wantPayment := &BuilderPendingPayment{
|
||||
Weight: "5",
|
||||
Withdrawal: wantWithdrawal,
|
||||
}
|
||||
|
||||
assert.DeepEqual(t, wantPayment, BuilderPendingPaymentFromConsensus(payment))
|
||||
assert.DeepEqual(t, []*BuilderPendingPayment{wantPayment}, BuilderPendingPaymentsFromConsensus([]*eth.BuilderPendingPayment{payment}))
|
||||
assert.DeepEqual(t, wantWithdrawal, BuilderPendingWithdrawalFromConsensus(withdrawal))
|
||||
assert.DeepEqual(t, []*BuilderPendingWithdrawal{wantWithdrawal}, BuilderPendingWithdrawalsFromConsensus([]*eth.BuilderPendingWithdrawal{withdrawal}))
|
||||
}
|
||||
|
||||
func TestBeaconStateGloasFromConsensus(t *testing.T) {
|
||||
st, err := util.NewBeaconStateGloas(func(state *eth.BeaconStateGloas) error {
|
||||
state.GenesisTime = 123
|
||||
state.GenesisValidatorsRoot = bytes.Repeat([]byte{0x10}, 32)
|
||||
state.Slot = 5
|
||||
state.ProposerLookahead = []uint64{1, 2}
|
||||
state.LatestExecutionPayloadBid = ð.ExecutionPayloadBid{
|
||||
ParentBlockHash: bytes.Repeat([]byte{0x11}, 32),
|
||||
ParentBlockRoot: bytes.Repeat([]byte{0x12}, 32),
|
||||
BlockHash: bytes.Repeat([]byte{0x13}, 32),
|
||||
PrevRandao: bytes.Repeat([]byte{0x14}, 32),
|
||||
FeeRecipient: bytes.Repeat([]byte{0x15}, 20),
|
||||
GasLimit: 64,
|
||||
BuilderIndex: 3,
|
||||
Slot: 5,
|
||||
Value: 99,
|
||||
ExecutionPayment: 7,
|
||||
BlobKzgCommitments: [][]byte{bytes.Repeat([]byte{0x16}, 48)},
|
||||
}
|
||||
state.Builders = []*eth.Builder{
|
||||
{
|
||||
Pubkey: bytes.Repeat([]byte{0x20}, 48),
|
||||
Version: bytes.Repeat([]byte{0x21}, 4),
|
||||
ExecutionAddress: bytes.Repeat([]byte{0x22}, 20),
|
||||
Balance: 88,
|
||||
DepositEpoch: 1,
|
||||
WithdrawableEpoch: 2,
|
||||
},
|
||||
}
|
||||
state.NextWithdrawalBuilderIndex = 9
|
||||
state.ExecutionPayloadAvailability = []byte{0x01, 0x02}
|
||||
state.BuilderPendingPayments = []*eth.BuilderPendingPayment{
|
||||
{
|
||||
Weight: 3,
|
||||
Withdrawal: ð.BuilderPendingWithdrawal{
|
||||
FeeRecipient: bytes.Repeat([]byte{0x23}, 20),
|
||||
Amount: 4,
|
||||
BuilderIndex: 5,
|
||||
},
|
||||
},
|
||||
}
|
||||
state.BuilderPendingWithdrawals = []*eth.BuilderPendingWithdrawal{
|
||||
{
|
||||
FeeRecipient: bytes.Repeat([]byte{0x24}, 20),
|
||||
Amount: 6,
|
||||
BuilderIndex: 7,
|
||||
},
|
||||
}
|
||||
state.LatestBlockHash = bytes.Repeat([]byte{0x25}, 32)
|
||||
state.PayloadExpectedWithdrawals = []*enginev1.Withdrawal{
|
||||
{Index: 1, ValidatorIndex: 2, Address: bytes.Repeat([]byte{0x26}, 20), Amount: 10},
|
||||
}
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
got, err := BeaconStateGloasFromConsensus(st)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "123", got.GenesisTime)
|
||||
require.Equal(t, hexutil.Encode(bytes.Repeat([]byte{0x10}, 32)), got.GenesisValidatorsRoot)
|
||||
require.Equal(t, "5", got.Slot)
|
||||
require.DeepEqual(t, []string{"1", "2"}, got.ProposerLookahead)
|
||||
require.Equal(t, "9", got.NextWithdrawalBuilderIndex)
|
||||
require.Equal(t, hexutil.Encode([]byte{0x01, 0x02}), got.ExecutionPayloadAvailability)
|
||||
require.Equal(t, hexutil.Encode(bytes.Repeat([]byte{0x25}, 32)), got.LatestBlockHash)
|
||||
|
||||
require.NotNil(t, got.LatestExecutionPayloadBid)
|
||||
require.Equal(t, "64", got.LatestExecutionPayloadBid.GasLimit)
|
||||
require.Equal(t, hexutil.Encode(bytes.Repeat([]byte{0x11}, 32)), got.LatestExecutionPayloadBid.ParentBlockHash)
|
||||
|
||||
require.NotNil(t, got.Builders)
|
||||
require.Equal(t, hexutil.Encode(bytes.Repeat([]byte{0x20}, 48)), got.Builders[0].Pubkey)
|
||||
require.Equal(t, "88", got.Builders[0].Balance)
|
||||
|
||||
require.Equal(t, "3", got.BuilderPendingPayments[0].Weight)
|
||||
require.Equal(t, "4", got.BuilderPendingPayments[0].Withdrawal.Amount)
|
||||
require.Equal(t, hexutil.Encode(bytes.Repeat([]byte{0x23}, 20)), got.BuilderPendingPayments[0].Withdrawal.FeeRecipient)
|
||||
|
||||
require.Equal(t, "6", got.BuilderPendingWithdrawals[0].Amount)
|
||||
require.Equal(t, hexutil.Encode(bytes.Repeat([]byte{0x24}, 20)), got.BuilderPendingWithdrawals[0].FeeRecipient)
|
||||
|
||||
require.Equal(t, "1", got.PayloadExpectedWithdrawals[0].WithdrawalIndex)
|
||||
require.Equal(t, "2", got.PayloadExpectedWithdrawals[0].ValidatorIndex)
|
||||
require.Equal(t, hexutil.Encode(bytes.Repeat([]byte{0x26}, 20)), got.PayloadExpectedWithdrawals[0].ExecutionAddress)
|
||||
require.Equal(t, "10", got.PayloadExpectedWithdrawals[0].Amount)
|
||||
}
|
||||
|
||||
@@ -262,23 +262,3 @@ type PendingConsolidation struct {
|
||||
SourceIndex string `json:"source_index"`
|
||||
TargetIndex string `json:"target_index"`
|
||||
}
|
||||
|
||||
type Builder struct {
|
||||
Pubkey string `json:"pubkey"`
|
||||
Version string `json:"version"`
|
||||
ExecutionAddress string `json:"execution_address"`
|
||||
Balance string `json:"balance"`
|
||||
DepositEpoch string `json:"deposit_epoch"`
|
||||
WithdrawableEpoch string `json:"withdrawable_epoch"`
|
||||
}
|
||||
|
||||
type BuilderPendingPayment struct {
|
||||
Weight string `json:"weight"`
|
||||
Withdrawal *BuilderPendingWithdrawal `json:"withdrawal"`
|
||||
}
|
||||
|
||||
type BuilderPendingWithdrawal struct {
|
||||
FeeRecipient string `json:"fee_recipient"`
|
||||
Amount string `json:"amount"`
|
||||
BuilderIndex string `json:"builder_index"`
|
||||
}
|
||||
|
||||
@@ -221,51 +221,3 @@ type BeaconStateFulu struct {
|
||||
PendingConsolidations []*PendingConsolidation `json:"pending_consolidations"`
|
||||
ProposerLookahead []string `json:"proposer_lookahead"`
|
||||
}
|
||||
|
||||
type BeaconStateGloas struct {
|
||||
GenesisTime string `json:"genesis_time"`
|
||||
GenesisValidatorsRoot string `json:"genesis_validators_root"`
|
||||
Slot string `json:"slot"`
|
||||
Fork *Fork `json:"fork"`
|
||||
LatestBlockHeader *BeaconBlockHeader `json:"latest_block_header"`
|
||||
BlockRoots []string `json:"block_roots"`
|
||||
StateRoots []string `json:"state_roots"`
|
||||
HistoricalRoots []string `json:"historical_roots"`
|
||||
Eth1Data *Eth1Data `json:"eth1_data"`
|
||||
Eth1DataVotes []*Eth1Data `json:"eth1_data_votes"`
|
||||
Eth1DepositIndex string `json:"eth1_deposit_index"`
|
||||
Validators []*Validator `json:"validators"`
|
||||
Balances []string `json:"balances"`
|
||||
RandaoMixes []string `json:"randao_mixes"`
|
||||
Slashings []string `json:"slashings"`
|
||||
PreviousEpochParticipation []string `json:"previous_epoch_participation"`
|
||||
CurrentEpochParticipation []string `json:"current_epoch_participation"`
|
||||
JustificationBits string `json:"justification_bits"`
|
||||
PreviousJustifiedCheckpoint *Checkpoint `json:"previous_justified_checkpoint"`
|
||||
CurrentJustifiedCheckpoint *Checkpoint `json:"current_justified_checkpoint"`
|
||||
FinalizedCheckpoint *Checkpoint `json:"finalized_checkpoint"`
|
||||
InactivityScores []string `json:"inactivity_scores"`
|
||||
CurrentSyncCommittee *SyncCommittee `json:"current_sync_committee"`
|
||||
NextSyncCommittee *SyncCommittee `json:"next_sync_committee"`
|
||||
NextWithdrawalIndex string `json:"next_withdrawal_index"`
|
||||
NextWithdrawalValidatorIndex string `json:"next_withdrawal_validator_index"`
|
||||
HistoricalSummaries []*HistoricalSummary `json:"historical_summaries"`
|
||||
DepositRequestsStartIndex string `json:"deposit_requests_start_index"`
|
||||
DepositBalanceToConsume string `json:"deposit_balance_to_consume"`
|
||||
ExitBalanceToConsume string `json:"exit_balance_to_consume"`
|
||||
EarliestExitEpoch string `json:"earliest_exit_epoch"`
|
||||
ConsolidationBalanceToConsume string `json:"consolidation_balance_to_consume"`
|
||||
EarliestConsolidationEpoch string `json:"earliest_consolidation_epoch"`
|
||||
PendingDeposits []*PendingDeposit `json:"pending_deposits"`
|
||||
PendingPartialWithdrawals []*PendingPartialWithdrawal `json:"pending_partial_withdrawals"`
|
||||
PendingConsolidations []*PendingConsolidation `json:"pending_consolidations"`
|
||||
ProposerLookahead []string `json:"proposer_lookahead"`
|
||||
LatestExecutionPayloadBid *ExecutionPayloadBid `json:"latest_execution_payload_bid"`
|
||||
Builders []*Builder `json:"builders"`
|
||||
NextWithdrawalBuilderIndex string `json:"next_withdrawal_builder_index"`
|
||||
ExecutionPayloadAvailability string `json:"execution_payload_availability"`
|
||||
BuilderPendingPayments []*BuilderPendingPayment `json:"builder_pending_payments"`
|
||||
BuilderPendingWithdrawals []*BuilderPendingWithdrawal `json:"builder_pending_withdrawals"`
|
||||
LatestBlockHash string `json:"latest_block_hash"`
|
||||
PayloadExpectedWithdrawals []*Withdrawal `json:"payload_expected_withdrawals"`
|
||||
}
|
||||
|
||||
@@ -112,6 +112,34 @@ func ProcessExecutionPayload(
|
||||
return errors.Wrap(err, "signature verification failed")
|
||||
}
|
||||
|
||||
envelope, err := signedEnvelope.Envelope()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get envelope from signed envelope")
|
||||
}
|
||||
|
||||
if err := ApplyExecutionPayload(ctx, st, envelope); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r, err := st.HashTreeRoot(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get hash tree root")
|
||||
}
|
||||
if r != envelope.StateRoot() {
|
||||
return fmt.Errorf("state root mismatch: expected %#x, got %#x", envelope.StateRoot(), r)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ApplyExecutionPayload applies the execution payload envelope to the state and performs the same
|
||||
// consistency checks as the full processing path. This keeps the post-payload state root computation
|
||||
// on a shared code path, even though some bid/payload checks are not strictly required for the root itself.
|
||||
func ApplyExecutionPayload(
|
||||
ctx context.Context,
|
||||
st state.BeaconState,
|
||||
envelope interfaces.ROExecutionPayloadEnvelope,
|
||||
) error {
|
||||
latestHeader := st.LatestBlockHeader()
|
||||
if len(latestHeader.StateRoot) == 0 || bytes.Equal(latestHeader.StateRoot, make([]byte, 32)) {
|
||||
previousStateRoot, err := st.HashTreeRoot(ctx)
|
||||
@@ -128,10 +156,6 @@ func ProcessExecutionPayload(
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not compute block header root")
|
||||
}
|
||||
envelope, err := signedEnvelope.Envelope()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get envelope from signed envelope")
|
||||
}
|
||||
|
||||
beaconBlockRoot := envelope.BeaconBlockRoot()
|
||||
if !bytes.Equal(beaconBlockRoot[:], blockHeaderRoot[:]) {
|
||||
@@ -217,14 +241,6 @@ func ProcessExecutionPayload(
|
||||
return errors.Wrap(err, "could not set latest block hash")
|
||||
}
|
||||
|
||||
r, err := st.HashTreeRoot(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get hash tree root")
|
||||
}
|
||||
if r != envelope.StateRoot() {
|
||||
return fmt.Errorf("state root mismatch: expected %#x, got %#x", envelope.StateRoot(), r)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -116,17 +116,32 @@ func CalculateStateRoot(
|
||||
rollback state.BeaconState,
|
||||
signed interfaces.ReadOnlySignedBeaconBlock,
|
||||
) ([32]byte, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "core.state.CalculateStateRoot")
|
||||
st, err := CalculatePostState(ctx, rollback, signed)
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
return st.HashTreeRoot(ctx)
|
||||
}
|
||||
|
||||
// CalculatePostState returns the post-block state after processing the given
|
||||
// block on a copy of the input state. It is identical to CalculateStateRoot
|
||||
// but returns the full state instead of just its hash tree root.
|
||||
func CalculatePostState(
|
||||
ctx context.Context,
|
||||
rollback state.BeaconState,
|
||||
signed interfaces.ReadOnlySignedBeaconBlock,
|
||||
) (state.BeaconState, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "core.state.CalculatePostState")
|
||||
defer span.End()
|
||||
if ctx.Err() != nil {
|
||||
tracing.AnnotateError(span, ctx.Err())
|
||||
return [32]byte{}, ctx.Err()
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
if rollback == nil || rollback.IsNil() {
|
||||
return [32]byte{}, errors.New("nil state")
|
||||
return nil, errors.New("nil state")
|
||||
}
|
||||
if signed == nil || signed.IsNil() || signed.Block().IsNil() {
|
||||
return [32]byte{}, errors.New("nil block")
|
||||
return nil, errors.New("nil block")
|
||||
}
|
||||
|
||||
// Copy state to avoid mutating the state reference.
|
||||
@@ -137,22 +152,22 @@ func CalculateStateRoot(
|
||||
parentRoot := signed.Block().ParentRoot()
|
||||
state, err = ProcessSlotsUsingNextSlotCache(ctx, state, parentRoot[:], signed.Block().Slot())
|
||||
if err != nil {
|
||||
return [32]byte{}, errors.Wrap(err, "could not process slots")
|
||||
return nil, errors.Wrap(err, "could not process slots")
|
||||
}
|
||||
|
||||
// Execute per block transition.
|
||||
if features.Get().EnableProposerPreprocessing {
|
||||
state, err = processBlockForProposing(ctx, state, signed)
|
||||
if err != nil {
|
||||
return [32]byte{}, errors.Wrap(err, "could not process block for proposing")
|
||||
return nil, errors.Wrap(err, "could not process block for proposing")
|
||||
}
|
||||
} else {
|
||||
state, err = ProcessBlockForStateRoot(ctx, state, signed)
|
||||
if err != nil {
|
||||
return [32]byte{}, errors.Wrap(err, "could not process block")
|
||||
return nil, errors.Wrap(err, "could not process block")
|
||||
}
|
||||
}
|
||||
return state.HashTreeRoot(ctx)
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// processBlockVerifySigs processes the block and verifies the signatures within it. Block signatures are not verified as this block is not yet signed.
|
||||
|
||||
@@ -609,21 +609,31 @@ func (vs *Server) GetFeeRecipientByPubKey(ctx context.Context, request *ethpb.Fe
|
||||
// computeStateRoot computes the state root after a block has been processed through a state transition and
|
||||
// returns it to the validator client.
|
||||
func (vs *Server) computeStateRoot(ctx context.Context, block interfaces.SignedBeaconBlock) ([]byte, error) {
|
||||
st, err := vs.computePostBlockState(ctx, block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
root, err := st.HashTreeRoot(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not compute state root")
|
||||
}
|
||||
log.WithField("beaconStateRoot", fmt.Sprintf("%#x", root)).Debugf("Computed state root")
|
||||
return root[:], nil
|
||||
}
|
||||
|
||||
// computePostBlockState computes the post-block state by running the state transition.
|
||||
// It uses the same logic as CalculateStateRoot (Copy, feature flags, slot processing)
|
||||
// but returns the full state instead of just its hash.
|
||||
func (vs *Server) computePostBlockState(ctx context.Context, block interfaces.SignedBeaconBlock) (state.BeaconState, error) {
|
||||
beaconState, err := vs.StateGen.StateByRoot(ctx, block.Block().ParentRoot())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not retrieve beacon state")
|
||||
}
|
||||
root, err := transition.CalculateStateRoot(
|
||||
ctx,
|
||||
beaconState,
|
||||
block,
|
||||
)
|
||||
st, err := transition.CalculatePostState(ctx, beaconState, block)
|
||||
if err != nil {
|
||||
return vs.handleStateRootError(ctx, block, err)
|
||||
return vs.handlePostBlockStateError(ctx, block, err)
|
||||
}
|
||||
|
||||
log.WithField("beaconStateRoot", fmt.Sprintf("%#x", root)).Debugf("Computed state root")
|
||||
return root[:], nil
|
||||
return st, nil
|
||||
}
|
||||
|
||||
type computeStateRootAttemptsKeyType string
|
||||
@@ -631,8 +641,8 @@ type computeStateRootAttemptsKeyType string
|
||||
const computeStateRootAttemptsKey = computeStateRootAttemptsKeyType("compute-state-root-attempts")
|
||||
const maxComputeStateRootAttempts = 3
|
||||
|
||||
// handleStateRootError retries block construction in some error cases.
|
||||
func (vs *Server) handleStateRootError(ctx context.Context, block interfaces.SignedBeaconBlock, err error) ([]byte, error) {
|
||||
// handlePostBlockStateError retries block construction in some error cases.
|
||||
func (vs *Server) handlePostBlockStateError(ctx context.Context, block interfaces.SignedBeaconBlock, err error) (state.BeaconState, error) {
|
||||
if ctx.Err() != nil {
|
||||
return nil, status.Errorf(codes.Canceled, "context error: %v", ctx.Err())
|
||||
}
|
||||
@@ -681,8 +691,8 @@ func (vs *Server) handleStateRootError(ctx context.Context, block interfaces.Sig
|
||||
} else {
|
||||
ctx = context.WithValue(ctx, computeStateRootAttemptsKey, v+1)
|
||||
}
|
||||
// recursive call to compute state root again
|
||||
return vs.computeStateRoot(ctx, block)
|
||||
// recursive call to compute post-block state again
|
||||
return vs.computePostBlockState(ctx, block)
|
||||
}
|
||||
|
||||
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
|
||||
|
||||
@@ -1313,8 +1313,8 @@ func TestProposer_ComputeStateRoot_OK(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestHandleStateRootError_MaxAttemptsReached(t *testing.T) {
|
||||
// Test that handleStateRootError returns an error when max attempts is reached
|
||||
func TestHandlePostBlockStateError_MaxAttemptsReached(t *testing.T) {
|
||||
// Test that handlePostBlockStateError returns an error when max attempts is reached
|
||||
// instead of recursing infinitely.
|
||||
ctx := t.Context()
|
||||
vs := &Server{}
|
||||
@@ -1327,15 +1327,15 @@ func TestHandleStateRootError_MaxAttemptsReached(t *testing.T) {
|
||||
// Pre-seed the context with max attempts already reached
|
||||
ctx = context.WithValue(ctx, computeStateRootAttemptsKey, maxComputeStateRootAttempts)
|
||||
|
||||
// Call handleStateRootError with a retryable error
|
||||
_, err = vs.handleStateRootError(ctx, wsb, transition.ErrAttestationsSignatureInvalid)
|
||||
// Call handlePostBlockStateError with a retryable error
|
||||
_, err = vs.handlePostBlockStateError(ctx, wsb, transition.ErrAttestationsSignatureInvalid)
|
||||
|
||||
// Should return an error about max attempts instead of recursing
|
||||
require.ErrorContains(t, "attempted max compute state root attempts", err)
|
||||
}
|
||||
|
||||
func TestHandleStateRootError_IncrementsAttempts(t *testing.T) {
|
||||
// Test that handleStateRootError properly increments the attempts counter
|
||||
func TestHandlePostBlockStateError_IncrementsAttempts(t *testing.T) {
|
||||
// Test that handlePostBlockStateError properly increments the attempts counter
|
||||
// and eventually fails after max attempts.
|
||||
db := dbutil.SetupDB(t)
|
||||
ctx := t.Context()
|
||||
@@ -1357,10 +1357,10 @@ func TestHandleStateRootError_IncrementsAttempts(t *testing.T) {
|
||||
// Add a state for the parent root so StateByRoot succeeds
|
||||
require.NoError(t, stateGen.SaveState(ctx, parentRoot, beaconState))
|
||||
|
||||
// Call handleStateRootError with a retryable error - it will recurse
|
||||
// but eventually hit the max attempts limit since CalculateStateRoot
|
||||
// Call handlePostBlockStateError with a retryable error - it will recurse
|
||||
// but eventually hit the max attempts limit since CalculatePostState
|
||||
// will keep failing (no valid attestations, randao, etc.)
|
||||
_, err = vs.handleStateRootError(ctx, wsb, transition.ErrAttestationsSignatureInvalid)
|
||||
_, err = vs.handlePostBlockStateError(ctx, wsb, transition.ErrAttestationsSignatureInvalid)
|
||||
|
||||
// Should eventually fail - either with max attempts or another error
|
||||
require.NotNil(t, err)
|
||||
|
||||
@@ -39,15 +39,12 @@ type readOnlyGloasFields interface {
|
||||
// Builder pending payments / withdrawals.
|
||||
BuilderPendingPayments() ([]*ethpb.BuilderPendingPayment, error)
|
||||
WithdrawalsMatchPayloadExpected(withdrawals []*enginev1.Withdrawal) (bool, error)
|
||||
BuilderPendingWithdrawals() ([]*ethpb.BuilderPendingWithdrawal, error)
|
||||
PayloadExpectedWithdrawals() ([]*enginev1.Withdrawal, error)
|
||||
|
||||
// Misc.
|
||||
LatestBlockHash() ([32]byte, error)
|
||||
|
||||
// Builders.
|
||||
Builder(index primitives.BuilderIndex) (*ethpb.Builder, error)
|
||||
Builders() ([]*ethpb.Builder, error)
|
||||
BuilderPubkey(primitives.BuilderIndex) ([48]byte, error)
|
||||
BuilderIndexByPubkey(pubkey [fieldparams.BLSPubkeyLength]byte) (primitives.BuilderIndex, bool)
|
||||
IsActiveBuilder(primitives.BuilderIndex) (bool, error)
|
||||
@@ -55,6 +52,4 @@ type readOnlyGloasFields interface {
|
||||
IsAttestationSameSlot(blockRoot [32]byte, slot primitives.Slot) (bool, error)
|
||||
BuilderPendingPayment(index uint64) (*ethpb.BuilderPendingPayment, error)
|
||||
ExecutionPayloadAvailability(slot primitives.Slot) (uint64, error)
|
||||
ExecutionPayloadAvailabilityVector() ([]byte, error)
|
||||
NextWithdrawalBuilderIndex() (primitives.BuilderIndex, error)
|
||||
}
|
||||
|
||||
@@ -281,18 +281,6 @@ func (b *BeaconState) ExecutionPayloadAvailability(slot primitives.Slot) (uint64
|
||||
return uint64(bit), nil
|
||||
}
|
||||
|
||||
// ExecutionPayloadAvailabilityVector returns a copy of the execution payload availability bitvector.
|
||||
func (b *BeaconState) ExecutionPayloadAvailabilityVector() ([]byte, error) {
|
||||
if b.version < version.Gloas {
|
||||
return nil, errNotSupported("ExecutionPayloadAvailabilityVector", b.version)
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return b.executionPayloadAvailabilityVal(), nil
|
||||
}
|
||||
|
||||
// Builder returns the builder at the given index.
|
||||
func (b *BeaconState) Builder(index primitives.BuilderIndex) (*ethpb.Builder, error) {
|
||||
b.lock.RLock()
|
||||
@@ -326,51 +314,3 @@ func (b *BeaconState) BuilderIndexByPubkey(pubkey [fieldparams.BLSPubkeyLength]b
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// BuilderPendingWithdrawals returns a copy of the builder pending withdrawals.
|
||||
func (b *BeaconState) BuilderPendingWithdrawals() ([]*ethpb.BuilderPendingWithdrawal, error) {
|
||||
if b.version < version.Gloas {
|
||||
return nil, errNotSupported("BuilderPendingWithdrawals", b.version)
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return b.builderPendingWithdrawalsVal(), nil
|
||||
}
|
||||
|
||||
// PayloadExpectedWithdrawals returns a copy of the payload expected withdrawals.
|
||||
func (b *BeaconState) PayloadExpectedWithdrawals() ([]*enginev1.Withdrawal, error) {
|
||||
if b.version < version.Gloas {
|
||||
return nil, errNotSupported("PayloadExpectedWithdrawals", b.version)
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return b.payloadExpectedWithdrawalsVal(), nil
|
||||
}
|
||||
|
||||
// Builders returns a copy of the builders registry.
|
||||
func (b *BeaconState) Builders() ([]*ethpb.Builder, error) {
|
||||
if b.version < version.Gloas {
|
||||
return nil, errNotSupported("Builders", b.version)
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return b.buildersVal(), nil
|
||||
}
|
||||
|
||||
// NextWithdrawalBuilderIndex returns the next withdrawal builder index.
|
||||
func (b *BeaconState) NextWithdrawalBuilderIndex() (primitives.BuilderIndex, error) {
|
||||
if b.version < version.Gloas {
|
||||
return 0, errNotSupported("NextWithdrawalBuilderIndex", b.version)
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return b.nextWithdrawalBuilderIndex, nil
|
||||
}
|
||||
|
||||
@@ -470,150 +470,3 @@ func TestExecutionPayloadAvailability(t *testing.T) {
|
||||
require.Equal(t, uint64(0), otherBit)
|
||||
})
|
||||
}
|
||||
|
||||
func TestBuilderPendingWithdrawals(t *testing.T) {
|
||||
t.Run("returns error before gloas", func(t *testing.T) {
|
||||
stIface, err := state_native.InitializeFromProtoElectra(ðpb.BeaconStateElectra{})
|
||||
require.NoError(t, err)
|
||||
st := stIface.(*state_native.BeaconState)
|
||||
|
||||
_, err = st.BuilderPendingWithdrawals()
|
||||
require.ErrorContains(t, "BuilderPendingWithdrawals", err)
|
||||
})
|
||||
|
||||
t.Run("returns copy", func(t *testing.T) {
|
||||
original := []*ethpb.BuilderPendingWithdrawal{
|
||||
{Amount: 10, BuilderIndex: 1},
|
||||
}
|
||||
st, err := state_native.InitializeFromProtoGloas(ðpb.BeaconStateGloas{
|
||||
BuilderPendingWithdrawals: original,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
got1, err := st.BuilderPendingWithdrawals()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, original, got1)
|
||||
|
||||
got1[0].Amount = 99
|
||||
got2, err := st.BuilderPendingWithdrawals()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, original, got2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestBuildersGetter(t *testing.T) {
|
||||
t.Run("returns error before gloas", func(t *testing.T) {
|
||||
stIface, err := state_native.InitializeFromProtoElectra(ðpb.BeaconStateElectra{})
|
||||
require.NoError(t, err)
|
||||
st := stIface.(*state_native.BeaconState)
|
||||
|
||||
_, err = st.Builders()
|
||||
require.ErrorContains(t, "Builders", err)
|
||||
})
|
||||
|
||||
t.Run("returns copy", func(t *testing.T) {
|
||||
pubkey := bytes.Repeat([]byte{0xAB}, fieldparams.BLSPubkeyLength)
|
||||
buildr := ðpb.Builder{
|
||||
Pubkey: pubkey,
|
||||
Balance: 42,
|
||||
DepositEpoch: 3,
|
||||
WithdrawableEpoch: 4,
|
||||
}
|
||||
st, err := state_native.InitializeFromProtoGloas(ðpb.BeaconStateGloas{
|
||||
Builders: []*ethpb.Builder{buildr},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
got1, err := st.Builders()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, buildr, got1[0])
|
||||
|
||||
got1[0].Pubkey[0] = 0xFF
|
||||
got2, err := st.Builders()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, buildr, got2[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestNextWithdrawalBuilderIndex(t *testing.T) {
|
||||
t.Run("returns error before gloas", func(t *testing.T) {
|
||||
stIface, err := state_native.InitializeFromProtoElectra(ðpb.BeaconStateElectra{})
|
||||
require.NoError(t, err)
|
||||
st := stIface.(*state_native.BeaconState)
|
||||
|
||||
_, err = st.NextWithdrawalBuilderIndex()
|
||||
require.ErrorContains(t, "NextWithdrawalBuilderIndex", err)
|
||||
})
|
||||
|
||||
t.Run("returns configured value", func(t *testing.T) {
|
||||
st, err := state_native.InitializeFromProtoGloas(ðpb.BeaconStateGloas{
|
||||
NextWithdrawalBuilderIndex: 2,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
got, err := st.NextWithdrawalBuilderIndex()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, primitives.BuilderIndex(2), got)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPayloadExpectedWithdrawals(t *testing.T) {
|
||||
t.Run("returns error before gloas", func(t *testing.T) {
|
||||
stIface, err := state_native.InitializeFromProtoElectra(ðpb.BeaconStateElectra{})
|
||||
require.NoError(t, err)
|
||||
st := stIface.(*state_native.BeaconState)
|
||||
|
||||
_, err = st.PayloadExpectedWithdrawals()
|
||||
require.ErrorContains(t, "PayloadExpectedWithdrawals", err)
|
||||
})
|
||||
|
||||
t.Run("returns copy", func(t *testing.T) {
|
||||
original := enginev1.Withdrawal{
|
||||
Index: 1,
|
||||
ValidatorIndex: 2,
|
||||
Address: bytes.Repeat([]byte{0x01}, 20),
|
||||
Amount: 10,
|
||||
}
|
||||
st, err := state_native.InitializeFromProtoGloas(ðpb.BeaconStateGloas{
|
||||
PayloadExpectedWithdrawals: []*enginev1.Withdrawal{&original},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
got1, err := st.PayloadExpectedWithdrawals()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, &original, got1[0])
|
||||
|
||||
got1[0].Amount = 99
|
||||
got2, err := st.PayloadExpectedWithdrawals()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, &original, got2[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestExecutionPayloadAvailabilityVector(t *testing.T) {
|
||||
t.Run("returns error before gloas", func(t *testing.T) {
|
||||
stIface, err := state_native.InitializeFromProtoElectra(ðpb.BeaconStateElectra{})
|
||||
require.NoError(t, err)
|
||||
st := stIface.(*state_native.BeaconState)
|
||||
|
||||
_, err = st.ExecutionPayloadAvailabilityVector()
|
||||
require.ErrorContains(t, "ExecutionPayloadAvailabilityVector", err)
|
||||
})
|
||||
|
||||
t.Run("returns copy", func(t *testing.T) {
|
||||
availability := []byte{0xAA, 0xBB, 0xCC}
|
||||
st, err := state_native.InitializeFromProtoGloas(ðpb.BeaconStateGloas{
|
||||
ExecutionPayloadAvailability: availability,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
got1, err := st.ExecutionPayloadAvailabilityVector()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, availability, got1)
|
||||
|
||||
got1[0] = 0xFF
|
||||
got2, err := st.ExecutionPayloadAvailabilityVector()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, availability, got2)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
### Added
|
||||
|
||||
- Gloas state API structs.
|
||||
3
changelog/james-prysm_calculate-post-state.md
Normal file
3
changelog/james-prysm_calculate-post-state.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Ignored
|
||||
|
||||
- refactors calculate state root and breaks up into calculate post state function.
|
||||
2
changelog/tt_apply_execution_payload.md
Normal file
2
changelog/tt_apply_execution_payload.md
Normal file
@@ -0,0 +1,2 @@
|
||||
### Ignored
|
||||
- Refactor ProcessExecutionPayload to ApplyExecutionPayload
|
||||
Reference in New Issue
Block a user