Compare commits

...

64 Commits

Author SHA1 Message Date
nisdas
962ce28b7b Merge commit '29953cb7340b2f2668ee2283fa1d551c924aa9d4' into capella-hotfix 2022-11-30 19:28:50 +08:00
Potuz
5fa1fd84b9 Hook the BLSTOExecution Pool to the proposer 2022-11-25 09:33:17 -03:00
nisdas
bd0c9f9e8d fix 2022-11-25 09:06:59 -03:00
Potuz
2532bb370c Merge branch 'develop' into capella 2022-11-25 08:16:32 -03:00
nisdas
12efc6c2c1 make it reject 2022-11-24 22:21:12 +08:00
nisdas
a6cc9ac9c5 add sig validation 2022-11-24 22:19:55 +08:00
nisdas
031f5845a2 add gossip handler for bls change object 2022-11-24 21:22:18 +08:00
nisdas
b88559726c Merge branch 'develop' of https://github.com/prysmaticlabs/geth-sharding into capella 2022-11-24 20:05:41 +08:00
nisdas
62f6b07cba fix gossip registration 2022-11-23 20:10:44 +08:00
terence tsao
f956f1ed6e Handle capella version for packing atts 2022-11-22 17:21:21 -08:00
Potuz
16b0820193 Merge branch 'develop' into capella 2022-11-22 13:43:03 -03:00
Potuz
4b02267e96 add more minimal fixes 2022-11-22 13:34:33 -03:00
Potuz
746584c453 fix missing minimal test 2022-11-22 13:34:33 -03:00
Potuz
b56daaaca2 Fix empty withdrawals slice 2022-11-22 10:38:42 -03:00
terence tsao
931e5e10c3 Fix mainnet fork transition tests 2022-11-16 08:49:06 -05:00
Potuz
c172f838b1 Mark capella fields as dirty 2022-11-15 09:58:34 -05:00
Potuz
c07ae29cd9 move MaxWithdrawalsPerPayload to fieldparams 2022-11-14 22:59:31 -05:00
Potuz
214c9bfd8b fix bls_to_execution_changes 2022-11-14 16:41:17 -05:00
Potuz
716140d64d add bls_to_execution_change tests 2022-11-14 16:26:39 -05:00
Potuz
088cb4ef59 fix expected_withdrawals 2022-11-14 14:50:41 -05:00
Potuz
d1472fc351 Add withdrawals operations tests 2022-11-13 08:54:59 -03:00
terence tsao
5c8c0c31d8 Merge branch 'capella-withdrawal-minimal' into capella 2022-11-12 22:06:43 -08:00
terence tsao
7f3c00c7a2 Can build 2022-11-12 22:06:22 -08:00
terencechain
c180dab791 Merge branch 'develop' into capella 2022-11-12 18:28:18 -08:00
terence tsao
f24acc21c7 Fix bazel 2022-11-12 17:43:19 -08:00
terence tsao
40b637849d Fix miminal capella tests 2022-11-12 17:26:05 -08:00
terence tsao
e7db1685df Add mainnet capella tests 2022-11-12 17:13:26 -08:00
terence tsao
eccbfd1011 Add shared capella spec tests helpers 2022-11-12 17:13:16 -08:00
terence tsao
90211f6769 Fix prev epoch attested precompute 2022-11-12 17:12:29 -08:00
terence tsao
edc32ac18e Fix slashing quotient 2022-11-12 17:12:04 -08:00
terence tsao
fe68e020e3 Add selector with minimal withdrawal size 2022-11-12 16:18:16 -08:00
terence tsao
81e1e3544d Add mainnet ssz vectors 2022-11-12 15:50:07 -08:00
Potuz
09372d5c35 Revert "added mainnet ssz tests"
This reverts commit 078a89e4ca.
2022-11-12 18:40:28 -03:00
Potuz
078a89e4ca added mainnet ssz tests 2022-11-12 18:39:11 -03:00
Potuz
dbc6ae26a6 Add minimal support for capella spec tests
Fixed many issues about hashing
Added fork typing in the state replayer
2022-11-12 18:18:35 -03:00
Potuz
b6f429867a Merge branch 'develop' into capella 2022-11-12 16:35:20 -03:00
Potuz
09f50660ce Merge branch 'develop' into capella 2022-11-12 11:51:06 -03:00
Potuz
189825b495 fix withdrawal hashing 2022-11-11 23:21:41 -03:00
Potuz
764b7ff610 Don't build capella payload twice 2022-11-11 10:47:29 -03:00
Potuz
d499db7f0e Merge branch 'develop' into capella 2022-11-09 21:27:18 -03:00
Potuz
ed2d1c7bf9 Merge branch 'develop' into capella 2022-11-09 09:14:55 -03:00
nisdas
14b73cbd47 register flag 2022-11-09 08:48:36 +08:00
Potuz
3124785a08 Merge branch 'develop' into capella 2022-11-07 10:08:09 -03:00
Potuz
60e6306107 working withrawals initial commits 2022-11-06 16:53:57 -03:00
terence tsao
42ccb7830a Add Capella DB changes 2022-11-06 15:25:34 -03:00
Potuz
0bb03b9292 fix marshalling and engine calls 2022-11-06 15:24:22 -03:00
nisdas
ed6fbf1480 stupid bug 2022-11-07 00:18:01 +08:00
nisdas
477cec6021 wei it 2022-11-07 00:13:12 +08:00
nisdas
924500d111 add unmarshal 2022-11-06 23:57:37 +08:00
Potuz
0677504ef1 Revert "proposer changes"
This reverts commit ca2a7c4d9c.
2022-11-06 12:16:53 -03:00
Potuz
ca2a7c4d9c proposer changes 2022-11-06 12:14:17 -03:00
Potuz
28606629ad marshalling stub 2022-11-06 12:03:25 -03:00
Potuz
c817279464 fix capella payload 2022-11-06 11:14:39 -03:00
Potuz
009d6ed8ed proposer logic 2022-11-06 10:49:32 -03:00
Potuz
5cec1282a9 FCU two versions 2022-11-06 10:22:45 -03:00
Potuz
340170fd29 propose block V2 2022-11-06 09:42:20 -03:00
Potuz
7ed0cc139a marshalling first attempt 2022-11-06 07:47:43 -03:00
Potuz
2c822213eb rpc changes 2022-11-06 00:24:56 -03:00
Potuz
c08bb39ffe add fork versions 2022-11-05 13:38:11 -03:00
Potuz
5083d8ab34 propose capella blocks 2022-11-05 12:38:27 -03:00
Potuz
7552a5dd07 capella fork logic 2022-11-05 07:33:20 -03:00
Potuz
c93d68f853 Capella state transition 2022-11-05 06:06:15 -03:00
Potuz
3e8aa4023d Fix config test and export method 2022-11-04 11:59:49 -03:00
Potuz
b443875e66 Implement get_expected_withdrawals 2022-11-04 11:45:45 -03:00
151 changed files with 3758 additions and 164 deletions

View File

@@ -231,8 +231,8 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "eded065f923a99b78372d6f748c9b3f1de8229f8f574c1fec9c5fe76c8affb65",
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/general.tar.gz" % consensus_spec_version,
sha256 = "42f66a2b8c139c07843ac2898f2cb61729ea6eb7a080d151e3bac78e207bfe52",
urls = ["file:///tmp/general-f5c7cf78.tar.gz"],
)
http_archive(
@@ -247,8 +247,8 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "2ed83783129e93360f4bf9d5d5f606ee28adbe8b458acdfac61b8d99218d16a9",
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/minimal.tar.gz" % consensus_spec_version,
sha256 = "ec762b0cede38c8edc93a2c215053fa7834a906004333cd2e2a44a6247e0338b",
urls = ["file:///tmp/minimal-f5c7cf78.tar.gz"],
)
http_archive(
@@ -263,8 +263,8 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
sha256 = "f5eff2adac78c99a4180491f373328465263caa2cba0206308a7c598abf76cda",
url = "https://github.com/ethereum/consensus-spec-tests/releases/download/%s/mainnet.tar.gz" % consensus_spec_version,
sha256 = "2a98e39e5729a2e364492a7b82d710010eaee8f7a4968c91023dd4ae58f7c3d6",
urls = ["file:///tmp/mainnet-f5c7cf78.tar.gz"],
)
http_archive(

View File

@@ -24,6 +24,7 @@ import (
)
var defaultLatestValidHash = bytesutil.PadTo([]byte{0xff}, 32)
var errNoAttribute = errors.New("could not get payload attributes")
// notifyForkchoiceUpdateArg is the argument for the forkchoice update notification `notifyForkchoiceUpdate`.
type notifyForkchoiceUpdateArg struct {
@@ -32,6 +33,58 @@ type notifyForkchoiceUpdateArg struct {
headBlock interfaces.BeaconBlock
}
type callForkchoiceUpdatedReturn struct {
hasAttr bool
proposerId types.ValidatorIndex
payloadID *enginev1.PayloadIDBytes
lastValidHash []byte
err error
}
// callFforkchoiceUpdatedV1 wraps a call to the engine methods `engine_forkchoiceUpdatedV1`
func (s *Service) callForkchoiceUpdatedV1(
ctx context.Context,
st state.BeaconState,
nextSlot types.Slot,
fcs *enginev1.ForkchoiceState) callForkchoiceUpdatedReturn {
hasAttr, attr, proposerId, err := s.getPayloadAttribute(ctx, st, nextSlot)
if err != nil {
return callForkchoiceUpdatedReturn{false, 0, nil, nil, errNoAttribute}
}
payloadID, lastValidHash, err := s.cfg.ExecutionEngineCaller.ForkchoiceUpdated(ctx, fcs, attr)
return callForkchoiceUpdatedReturn{
hasAttr: hasAttr,
proposerId: proposerId,
payloadID: payloadID,
lastValidHash: lastValidHash,
err: err,
}
}
// callFforkchoiceUpdatedV2 wraps a call to the engine methods `engine_forkchoiceUpdatedV2`
func (s *Service) callForkchoiceUpdatedV2(
ctx context.Context,
st state.BeaconState,
nextSlot types.Slot,
fcs *enginev1.ForkchoiceState) callForkchoiceUpdatedReturn {
hasAttr, attr, proposerId, err := s.getPayloadAttributeV2(ctx, st, nextSlot)
if err != nil {
return callForkchoiceUpdatedReturn{false, 0, nil, nil, errNoAttribute}
}
payloadID, lastValidHash, err := s.cfg.ExecutionEngineCaller.ForkchoiceUpdatedV2(ctx, fcs, attr)
return callForkchoiceUpdatedReturn{
hasAttr: hasAttr,
proposerId: proposerId,
payloadID: payloadID,
lastValidHash: lastValidHash,
err: err,
}
}
// notifyForkchoiceUpdate signals execution engine the fork choice updates. Execution engine should:
// 1. Re-organizes the execution payload chain and corresponding state to make head_block_hash the head.
// 2. Applies finality to the execution state: it irreversibly persists the chain of all execution payloads and corresponding state, up to and including finalized_block_hash.
@@ -67,15 +120,16 @@ func (s *Service) notifyForkchoiceUpdate(ctx context.Context, arg *notifyForkcho
}
nextSlot := s.CurrentSlot() + 1 // Cache payload ID for next slot proposer.
hasAttr, attr, proposerId, err := s.getPayloadAttribute(ctx, arg.headState, nextSlot)
if err != nil {
log.WithError(err).Error("Could not get head payload attribute")
return nil, nil
var fcuReturn callForkchoiceUpdatedReturn
if slots.ToEpoch(nextSlot) >= params.BeaconConfig().CapellaForkEpoch {
fcuReturn = s.callForkchoiceUpdatedV2(ctx, arg.headState, nextSlot, fcs)
} else {
fcuReturn = s.callForkchoiceUpdatedV1(ctx, arg.headState, nextSlot, fcs)
}
payloadID, lastValidHash, err := s.cfg.ExecutionEngineCaller.ForkchoiceUpdated(ctx, fcs, attr)
if err != nil {
switch err {
if fcuReturn.err != nil {
switch fcuReturn.err {
case errNoAttribute:
return nil, errNoAttribute
case execution.ErrAcceptedSyncingPayloadStatus:
forkchoiceUpdatedOptimisticNodeCount.Inc()
log.WithFields(logrus.Fields{
@@ -83,14 +137,14 @@ func (s *Service) notifyForkchoiceUpdate(ctx context.Context, arg *notifyForkcho
"headPayloadBlockHash": fmt.Sprintf("%#x", bytesutil.Trunc(headPayload.BlockHash())),
"finalizedPayloadBlockHash": fmt.Sprintf("%#x", bytesutil.Trunc(finalizedHash[:])),
}).Info("Called fork choice updated with optimistic block")
return payloadID, nil
return fcuReturn.payloadID, nil
case execution.ErrInvalidPayloadStatus:
forkchoiceUpdatedInvalidNodeCount.Inc()
headRoot := arg.headRoot
if len(lastValidHash) == 0 {
lastValidHash = defaultLatestValidHash
if len(fcuReturn.lastValidHash) == 0 {
fcuReturn.lastValidHash = defaultLatestValidHash
}
invalidRoots, err := s.ForkChoicer().SetOptimisticToInvalid(ctx, headRoot, headBlk.ParentRoot(), bytesutil.ToBytes32(lastValidHash))
invalidRoots, err := s.ForkChoicer().SetOptimisticToInvalid(ctx, headRoot, headBlk.ParentRoot(), bytesutil.ToBytes32(fcuReturn.lastValidHash))
if err != nil {
log.WithError(err).Error("Could not set head root to invalid")
return nil, nil
@@ -150,17 +204,23 @@ func (s *Service) notifyForkchoiceUpdate(ctx context.Context, arg *notifyForkcho
log.WithError(err).Error("Could not set head root to valid")
return nil, nil
}
if hasAttr && payloadID != nil { // If the forkchoice update call has an attribute, update the proposer payload ID cache.
// If the forkchoice update call has an attribute, update the proposer payload ID cache.
if fcuReturn.hasAttr && fcuReturn.payloadID != nil {
var pId [8]byte
copy(pId[:], payloadID[:])
s.cfg.ProposerSlotIndexCache.SetProposerAndPayloadIDs(nextSlot, proposerId, pId, arg.headRoot)
} else if hasAttr && payloadID == nil {
copy(pId[:], fcuReturn.payloadID[:])
s.cfg.ProposerSlotIndexCache.SetProposerAndPayloadIDs(
nextSlot,
fcuReturn.proposerId,
pId,
arg.headRoot,
)
} else if fcuReturn.hasAttr && fcuReturn.payloadID == nil {
log.WithFields(logrus.Fields{
"blockHash": fmt.Sprintf("%#x", headPayload.BlockHash()),
"slot": headBlk.Slot(),
}).Error("Received nil payload ID on VALID engine response")
}
return payloadID, nil
return fcuReturn.payloadID, nil
}
// getPayloadHash returns the payload hash given the block root.
@@ -302,6 +362,68 @@ func (s *Service) getPayloadAttribute(ctx context.Context, st state.BeaconState,
return true, attr, proposerID, nil
}
// getPayloadAttributesV2 returns the payload attributes for the given state and slot.
// The attribute is required to initiate a payload build process in the context of an `engine_forkchoiceUpdatedV2` call.
func (s *Service) getPayloadAttributeV2(
ctx context.Context,
st state.BeaconState,
slot types.Slot) (bool, *enginev1.PayloadAttributesV2, types.ValidatorIndex, error) {
// Root is `[32]byte{}` since we are retrieving proposer ID of a given slot.
// During insertion at assignment the root was not known.
proposerID, _, ok := s.cfg.ProposerSlotIndexCache.GetProposerPayloadIDs(slot, [32]byte{} /* root */)
if !ok { // There's no need to build attribute if there is no proposer for slot.
return false, nil, 0, nil
}
// Get previous randao.
st = st.Copy()
st, err := transition.ProcessSlotsIfPossible(ctx, st, slot)
if err != nil {
return false, nil, 0, err
}
prevRando, err := helpers.RandaoMix(st, time.CurrentEpoch(st))
if err != nil {
return false, nil, 0, nil
}
// Get fee recipient.
feeRecipient := params.BeaconConfig().DefaultFeeRecipient
recipient, err := s.cfg.BeaconDB.FeeRecipientByValidatorID(ctx, proposerID)
switch {
case errors.Is(err, kv.ErrNotFoundFeeRecipient):
if feeRecipient.String() == params.BeaconConfig().EthBurnAddressHex {
logrus.WithFields(logrus.Fields{
"validatorIndex": proposerID,
"burnAddress": params.BeaconConfig().EthBurnAddressHex,
}).Warn("Fee recipient is currently using the burn address, " +
"you will not be rewarded transaction fees on this setting. " +
"Please set a different eth address as the fee recipient. " +
"Please refer to our documentation for instructions")
}
case err != nil:
return false, nil, 0, errors.Wrap(err, "could not get fee recipient in db")
default:
feeRecipient = recipient
}
// Get timestamp.
t, err := slots.ToTime(uint64(s.genesisTime.Unix()), slot)
if err != nil {
return false, nil, 0, err
}
withdrawals, err := st.ExpectedWithdrawals()
if err != nil {
return false, nil, 0, errors.Wrap(err, "could not get expected withdrawals")
}
attr := &enginev1.PayloadAttributesV2{
Timestamp: uint64(t.Unix()),
PrevRandao: prevRando,
SuggestedFeeRecipient: feeRecipient.Bytes(),
Withdrawals: withdrawals,
}
return true, attr, proposerID, nil
}
// removeInvalidBlockAndState removes the invalid block and its corresponding state from the cache and DB.
func (s *Service) removeInvalidBlockAndState(ctx context.Context, blkRoots [][32]byte) error {
for _, root := range blkRoots {

View File

@@ -117,12 +117,20 @@ func logPayload(block interfaces.BeaconBlock) error {
return errors.New("gas limit should not be 0")
}
gasUtilized := float64(payload.GasUsed()) / float64(payload.GasLimit())
log.WithFields(logrus.Fields{
fields := logrus.Fields{
"blockHash": fmt.Sprintf("%#x", bytesutil.Trunc(payload.BlockHash())),
"parentHash": fmt.Sprintf("%#x", bytesutil.Trunc(payload.ParentHash())),
"blockNumber": payload.BlockNumber,
"gasUtilized": fmt.Sprintf("%.2f", gasUtilized),
}).Debug("Synced new payload")
}
if block.Version() >= version.Capella {
withdrawals, err := payload.Withdrawals()
if err != nil {
return errors.Wrap(err, "could not get withdrawals")
}
fields["withdrawals"] = len(withdrawals)
}
log.WithFields(fields).Debug("Synced new payload")
return nil
}

View File

@@ -328,7 +328,7 @@ func reportEpochMetrics(ctx context.Context, postState, headState state.BeaconSt
if err != nil {
return err
}
case version.Altair, version.Bellatrix:
case version.Altair, version.Bellatrix, version.Capella:
v, b, err = altair.InitializePrecomputeValidators(ctx, headState)
if err != nil {
return err

View File

@@ -69,6 +69,7 @@ func (s *Service) verifyBlkPreState(ctx context.Context, b interfaces.BeaconBloc
// during initial syncing. There's no risk given a state summary object is just a
// a subset of the block object.
if !s.cfg.BeaconDB.HasStateSummary(ctx, parentRoot) && !s.cfg.BeaconDB.HasBlock(ctx, parentRoot) {
log.Errorf("requesting blockroot %#x", bytesutil.Trunc(parentRoot[:]))
return errors.New("could not reconstruct parent state")
}

View File

@@ -53,7 +53,7 @@ func (c *SyncCommitteeHeadStateCache) Get(slot types.Slot) (state.BeaconState, e
return nil, ErrIncorrectType
}
switch st.Version() {
case version.Altair, version.Bellatrix:
case version.Altair, version.Bellatrix, version.Capella:
default:
return nil, ErrIncorrectType
}

View File

@@ -136,6 +136,7 @@ func ValidatePayloadWhenMergeCompletes(st state.BeaconState, payload interfaces.
return err
}
if !bytes.Equal(payload.ParentHash(), header.BlockHash()) {
log.Errorf("parent Hash %#x, header Hash: %#x", bytesutil.Trunc(payload.ParentHash()), bytesutil.Trunc(header.BlockHash()))
return ErrInvalidPayloadBlockHash
}
return nil

View File

@@ -124,6 +124,7 @@ func ProcessWithdrawals(st state.BeaconState, withdrawals []*enginev1.Withdrawal
return nil, errInvalidWithdrawalIndex
}
if withdrawal.ValidatorIndex != expected[i].ValidatorIndex {
log.Errorf("Expected %v, got %v", expected[i], withdrawal)
return nil, errInvalidValidatorIndex
}
if !bytes.Equal(withdrawal.ExecutionAddress, expected[i].ExecutionAddress) {

View File

@@ -28,10 +28,16 @@ import (
const (
// NewPayloadMethod v1 request string for JSON-RPC.
NewPayloadMethod = "engine_newPayloadV1"
// NewPayloadMethod v2 request string for JSON-RPC.
NewPayloadMethodV2 = "engine_newPayloadV2"
// ForkchoiceUpdatedMethod v1 request string for JSON-RPC.
ForkchoiceUpdatedMethod = "engine_forkchoiceUpdatedV1"
// ForkchoiceUpdatedMethod v2 request string for JSON-RPC.
ForkchoiceUpdatedMethodV2 = "engine_forkchoiceUpdatedV2"
// GetPayloadMethod v1 request string for JSON-RPC.
GetPayloadMethod = "engine_getPayloadV1"
// GetPayloadMethod v2 request string for JSON-RPC.
GetPayloadMethodV2 = "engine_getPayloadV2"
// ExchangeTransitionConfigurationMethod v1 request string for JSON-RPC.
ExchangeTransitionConfigurationMethod = "engine_exchangeTransitionConfigurationV1"
// ExecutionBlockByHashMethod request string for JSON-RPC.
@@ -68,7 +74,11 @@ type EngineCaller interface {
ForkchoiceUpdated(
ctx context.Context, state *pb.ForkchoiceState, attrs *pb.PayloadAttributes,
) (*pb.PayloadIDBytes, []byte, error)
ForkchoiceUpdatedV2(
ctx context.Context, state *pb.ForkchoiceState, attrs *pb.PayloadAttributesV2,
) (*pb.PayloadIDBytes, []byte, error)
GetPayload(ctx context.Context, payloadId [8]byte) (*pb.ExecutionPayload, error)
GetPayloadV2(ctx context.Context, payloadId [8]byte) (*pb.ExecutionPayloadCapella, error)
ExchangeTransitionConfiguration(
ctx context.Context, cfg *pb.TransitionConfiguration,
) error
@@ -89,13 +99,21 @@ func (s *Service) NewPayload(ctx context.Context, payload interfaces.ExecutionDa
ctx, cancel := context.WithDeadline(ctx, d)
defer cancel()
result := &pb.PayloadStatus{}
payloadPb, ok := payload.Proto().(*pb.ExecutionPayload)
payloadPb, ok := payload.Proto().(*pb.ExecutionPayloadCapella)
if !ok {
return nil, errors.New("execution data must be an execution payload")
}
err := s.rpcClient.CallContext(ctx, result, NewPayloadMethod, payloadPb)
if err != nil {
return nil, handleRPCError(err)
payloadPb, ok := payload.Proto().(*pb.ExecutionPayload)
if !ok {
return nil, errors.New("execution data must be a Bellatrix or Capella execution payload")
}
err := s.rpcClient.CallContext(ctx, result, NewPayloadMethod, payloadPb)
if err != nil {
return nil, handleRPCError(err)
}
} else {
err := s.rpcClient.CallContext(ctx, result, NewPayloadMethodV2, payloadPb)
if err != nil {
return nil, handleRPCError(err)
}
}
switch result.Status {
@@ -148,6 +166,42 @@ func (s *Service) ForkchoiceUpdated(
}
}
// ForkchoiceUpdatedV2 calls the engine_forkchoiceUpdatedV2 method via JSON-RPC.
func (s *Service) ForkchoiceUpdatedV2(
ctx context.Context, state *pb.ForkchoiceState, attrs *pb.PayloadAttributesV2,
) (*pb.PayloadIDBytes, []byte, error) {
ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.ForkchoiceUpdatedV2")
defer span.End()
start := time.Now()
defer func() {
forkchoiceUpdatedLatency.Observe(float64(time.Since(start).Milliseconds()))
}()
d := time.Now().Add(time.Duration(params.BeaconConfig().ExecutionEngineTimeoutValue) * time.Second)
ctx, cancel := context.WithDeadline(ctx, d)
defer cancel()
result := &ForkchoiceUpdatedResponse{}
err := s.rpcClient.CallContext(ctx, result, ForkchoiceUpdatedMethodV2, state, attrs)
if err != nil {
return nil, nil, handleRPCError(err)
}
if result.Status == nil {
return nil, nil, ErrNilResponse
}
resp := result.Status
switch resp.Status {
case pb.PayloadStatus_SYNCING:
return nil, nil, ErrAcceptedSyncingPayloadStatus
case pb.PayloadStatus_INVALID:
return nil, resp.LatestValidHash, ErrInvalidPayloadStatus
case pb.PayloadStatus_VALID:
return result.PayloadId, resp.LatestValidHash, nil
default:
return nil, nil, ErrUnknownPayloadStatus
}
}
// GetPayload calls the engine_getPayloadV1 method via JSON-RPC.
func (s *Service) GetPayload(ctx context.Context, payloadId [8]byte) (*pb.ExecutionPayload, error) {
ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.GetPayload")
@@ -165,6 +219,23 @@ func (s *Service) GetPayload(ctx context.Context, payloadId [8]byte) (*pb.Execut
return result, handleRPCError(err)
}
// GetPayloadV2 calls the engine_getPayloadV2 method via JSON-RPC.
func (s *Service) GetPayloadV2(ctx context.Context, payloadId [8]byte) (*pb.ExecutionPayloadCapella, error) {
ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.GetPayloadV2")
defer span.End()
start := time.Now()
defer func() {
getPayloadLatency.Observe(float64(time.Since(start).Milliseconds()))
}()
d := time.Now().Add(defaultEngineTimeout)
ctx, cancel := context.WithDeadline(ctx, d)
defer cancel()
result := &pb.ExecutionPayloadCapella{}
err := s.rpcClient.CallContext(ctx, result, GetPayloadMethodV2, pb.PayloadIDBytes(payloadId))
return result, handleRPCError(err)
}
// ExchangeTransitionConfiguration calls the engine_exchangeTransitionConfigurationV1 method via JSON-RPC.
func (s *Service) ExchangeTransitionConfiguration(
ctx context.Context, cfg *pb.TransitionConfiguration,

View File

@@ -814,6 +814,7 @@ func (b *BeaconNode) registerRPCService() error {
AttestationsPool: b.attestationPool,
ExitPool: b.exitPool,
SlashingsPool: b.slashingsPool,
BLSChangesPool: b.blsToExecPool,
SlashingChecker: slasherService,
SyncCommitteeObjectPool: b.syncCommitteePool,
ExecutionChainService: web3Service,

View File

@@ -38,16 +38,9 @@ func TestPendingBLSToExecChanges(t *testing.T) {
func TestBLSToExecChangesForInclusion(t *testing.T) {
t.Run("empty pool", func(t *testing.T) {
pool := NewPool()
for i := uint64(0); i < params.BeaconConfig().MaxBlsToExecutionChanges-1; i++ {
pool.InsertBLSToExecChange(&eth.SignedBLSToExecutionChange{
Message: &eth.BLSToExecutionChange{
ValidatorIndex: types.ValidatorIndex(i),
},
})
}
changes, err := pool.BLSToExecChangesForInclusion()
require.NoError(t, err)
assert.Equal(t, int(params.BeaconConfig().MaxBlsToExecutionChanges-1), len(changes))
assert.Equal(t, 0, len(changes))
})
t.Run("MaxBlsToExecutionChanges in pool", func(t *testing.T) {
pool := NewPool()

View File

@@ -19,6 +19,7 @@ go_library(
"//beacon-chain/db:go_default_library",
"//beacon-chain/execution:go_default_library",
"//beacon-chain/operations/attestations:go_default_library",
"//beacon-chain/operations/blstoexec:go_default_library",
"//beacon-chain/operations/slashings:go_default_library",
"//beacon-chain/operations/synccommittee:go_default_library",
"//beacon-chain/operations/voluntaryexits:go_default_library",

View File

@@ -269,8 +269,10 @@ func setInitialPublishBlockPostRequest(endpoint *apimiddleware.Endpoint,
endpoint.PostRequest = &SignedBeaconBlockContainerJson{}
} else if currentEpoch < params.BeaconConfig().BellatrixForkEpoch {
endpoint.PostRequest = &SignedBeaconBlockAltairContainerJson{}
} else {
} else if currentEpoch < params.BeaconConfig().CapellaForkEpoch {
endpoint.PostRequest = &SignedBeaconBlockBellatrixContainerJson{}
} else {
endpoint.PostRequest = &SignedBeaconBlockCapellaContainerJson{}
}
req.Body = io.NopCloser(bytes.NewBuffer(buf))
return true, nil

View File

@@ -350,6 +350,7 @@ type SignedBeaconBlockContainerV2Json struct {
Phase0Block *BeaconBlockJson `json:"phase0_block"`
AltairBlock *BeaconBlockAltairJson `json:"altair_block"`
BellatrixBlock *BeaconBlockBellatrixJson `json:"bellatrix_block"`
CapellaBlock *BeaconBlockCapellaJson `json:"capella_block"`
Signature string `json:"signature" hex:"true"`
}
@@ -357,6 +358,7 @@ type SignedBlindedBeaconBlockContainerJson struct {
Phase0Block *BeaconBlockJson `json:"phase0_block"`
AltairBlock *BeaconBlockAltairJson `json:"altair_block"`
BellatrixBlock *BlindedBeaconBlockBellatrixJson `json:"bellatrix_block"`
CapellaBlock *BlindedBeaconBlockCapellaJson `json:"capella_block"`
Signature string `json:"signature" hex:"true"`
}
@@ -364,12 +366,14 @@ type BeaconBlockContainerV2Json struct {
Phase0Block *BeaconBlockJson `json:"phase0_block"`
AltairBlock *BeaconBlockAltairJson `json:"altair_block"`
BellatrixBlock *BeaconBlockBellatrixJson `json:"bellatrix_block"`
CapellaBlock *BeaconBlockCapellaJson `json:"capella_block"`
}
type BlindedBeaconBlockContainerJson struct {
Phase0Block *BeaconBlockJson `json:"phase0_block"`
AltairBlock *BeaconBlockAltairJson `json:"altair_block"`
BellatrixBlock *BlindedBeaconBlockBellatrixJson `json:"bellatrix_block"`
CapellaBlock *BlindedBeaconBlockCapellaJson `json:"capella_block"`
}
type SignedBeaconBlockAltairContainerJson struct {
@@ -382,11 +386,21 @@ type SignedBeaconBlockBellatrixContainerJson struct {
Signature string `json:"signature" hex:"true"`
}
type SignedBeaconBlockCapellaContainerJson struct {
Message *BeaconBlockCapellaJson `json:"message"`
Signature string `json:"signature" hex:"true"`
}
type SignedBlindedBeaconBlockBellatrixContainerJson struct {
Message *BlindedBeaconBlockBellatrixJson `json:"message"`
Signature string `json:"signature" hex:"true"`
}
type SignedBlindedBeaconBlockCapellaContainerJson struct {
Message *BlindedBeaconBlockCapellaJson `json:"message"`
Signature string `json:"signature" hex:"true"`
}
type BeaconBlockAltairJson struct {
Slot string `json:"slot"`
ProposerIndex string `json:"proposer_index"`
@@ -403,6 +417,14 @@ type BeaconBlockBellatrixJson struct {
Body *BeaconBlockBodyBellatrixJson `json:"body"`
}
type BeaconBlockCapellaJson struct {
Slot string `json:"slot"`
ProposerIndex string `json:"proposer_index"`
ParentRoot string `json:"parent_root" hex:"true"`
StateRoot string `json:"state_root" hex:"true"`
Body *BeaconBlockBodyCapellaJson `json:"body"`
}
type BlindedBeaconBlockBellatrixJson struct {
Slot string `json:"slot"`
ProposerIndex string `json:"proposer_index"`
@@ -411,6 +433,14 @@ type BlindedBeaconBlockBellatrixJson struct {
Body *BlindedBeaconBlockBodyBellatrixJson `json:"body"`
}
type BlindedBeaconBlockCapellaJson struct {
Slot string `json:"slot"`
ProposerIndex string `json:"proposer_index"`
ParentRoot string `json:"parent_root" hex:"true"`
StateRoot string `json:"state_root" hex:"true"`
Body *BlindedBeaconBlockBodyCapellaJson `json:"body"`
}
type BeaconBlockBodyAltairJson struct {
RandaoReveal string `json:"randao_reveal" hex:"true"`
Eth1Data *Eth1DataJson `json:"eth1_data"`
@@ -436,6 +466,20 @@ type BeaconBlockBodyBellatrixJson struct {
ExecutionPayload *ExecutionPayloadJson `json:"execution_payload"`
}
type BeaconBlockBodyCapellaJson struct {
RandaoReveal string `json:"randao_reveal" hex:"true"`
Eth1Data *Eth1DataJson `json:"eth1_data"`
Graffiti string `json:"graffiti" hex:"true"`
ProposerSlashings []*ProposerSlashingJson `json:"proposer_slashings"`
AttesterSlashings []*AttesterSlashingJson `json:"attester_slashings"`
Attestations []*AttestationJson `json:"attestations"`
Deposits []*DepositJson `json:"deposits"`
VoluntaryExits []*SignedVoluntaryExitJson `json:"voluntary_exits"`
SyncAggregate *SyncAggregateJson `json:"sync_aggregate"`
ExecutionPayload *ExecutionPayloadCapellaJson `json:"execution_payload"`
BLSToExecutionChanges []*BLSToExecutionChangeJson `json:"bls_to_execution_changes"`
}
type BlindedBeaconBlockBodyBellatrixJson struct {
RandaoReveal string `json:"randao_reveal" hex:"true"`
Eth1Data *Eth1DataJson `json:"eth1_data"`
@@ -449,6 +493,20 @@ type BlindedBeaconBlockBodyBellatrixJson struct {
ExecutionPayloadHeader *ExecutionPayloadHeaderJson `json:"execution_payload_header"`
}
type BlindedBeaconBlockBodyCapellaJson struct {
RandaoReveal string `json:"randao_reveal" hex:"true"`
Eth1Data *Eth1DataJson `json:"eth1_data"`
Graffiti string `json:"graffiti" hex:"true"`
ProposerSlashings []*ProposerSlashingJson `json:"proposer_slashings"`
AttesterSlashings []*AttesterSlashingJson `json:"attester_slashings"`
Attestations []*AttestationJson `json:"attestations"`
Deposits []*DepositJson `json:"deposits"`
VoluntaryExits []*SignedVoluntaryExitJson `json:"voluntary_exits"`
SyncAggregate *SyncAggregateJson `json:"sync_aggregate"`
ExecutionPayloadHeader *ExecutionPayloadHeaderCapellaJson `json:"execution_payload_header"`
BLSToExecutionChanges []*BLSToExecutionChangeJson `json:"bls_to_execution_changes"`
}
type ExecutionPayloadJson struct {
ParentHash string `json:"parent_hash" hex:"true"`
FeeRecipient string `json:"fee_recipient" hex:"true"`
@@ -466,6 +524,24 @@ type ExecutionPayloadJson struct {
Transactions []string `json:"transactions" hex:"true"`
}
type ExecutionPayloadCapellaJson struct {
ParentHash string `json:"parent_hash" hex:"true"`
FeeRecipient string `json:"fee_recipient" hex:"true"`
StateRoot string `json:"state_root" hex:"true"`
ReceiptsRoot string `json:"receipts_root" hex:"true"`
LogsBloom string `json:"logs_bloom" hex:"true"`
PrevRandao string `json:"prev_randao" hex:"true"`
BlockNumber string `json:"block_number"`
GasLimit string `json:"gas_limit"`
GasUsed string `json:"gas_used"`
TimeStamp string `json:"timestamp"`
ExtraData string `json:"extra_data" hex:"true"`
BaseFeePerGas string `json:"base_fee_per_gas" uint256:"true"`
BlockHash string `json:"block_hash" hex:"true"`
Transactions []string `json:"transactions" hex:"true"`
Withdrawals []*WithdrawalJson `json:"withdrawals"`
}
type ExecutionPayloadHeaderJson struct {
ParentHash string `json:"parent_hash" hex:"true"`
FeeRecipient string `json:"fee_recipient" hex:"true"`
@@ -483,6 +559,24 @@ type ExecutionPayloadHeaderJson struct {
TransactionsRoot string `json:"transactions_root" hex:"true"`
}
type ExecutionPayloadHeaderCapellaJson struct {
ParentHash string `json:"parent_hash" hex:"true"`
FeeRecipient string `json:"fee_recipient" hex:"true"`
StateRoot string `json:"state_root" hex:"true"`
ReceiptsRoot string `json:"receipts_root" hex:"true"`
LogsBloom string `json:"logs_bloom" hex:"true"`
PrevRandao string `json:"prev_randao" hex:"true"`
BlockNumber string `json:"block_number"`
GasLimit string `json:"gas_limit"`
GasUsed string `json:"gas_used"`
TimeStamp string `json:"timestamp"`
ExtraData string `json:"extra_data" hex:"true"`
BaseFeePerGas string `json:"base_fee_per_gas" uint256:"true"`
BlockHash string `json:"block_hash" hex:"true"`
TransactionsRoot string `json:"transactions_root" hex:"true"`
WithdrawalsRoot string `json:"withdrawals_root" hex:"true"`
}
type SyncAggregateJson struct {
SyncCommitteeBits string `json:"sync_committee_bits" hex:"true"`
SyncCommitteeSignature string `json:"sync_committee_signature" hex:"true"`
@@ -553,6 +647,17 @@ type AttestationDataJson struct {
Target *CheckpointJson `json:"target"`
}
type BLSToExecutionChangeJson struct {
ValidatorIndex string `json:"validator_index"`
FromBLSPubkey string `json:"from_bls_pubkey" hex:"true"`
ToExecutionAddress string `jston:"to_execution_address" hex:"true"`
}
type SigledBLSToExecutionChangeJson struct {
BLSToExecutionChange *BLSToExecutionChangeJson `json:"message"`
Signature string `json:"signature" hex:"true"`
}
type DepositJson struct {
Proof []string `json:"proof" hex:"true"`
Data *Deposit_DataJson `json:"data"`
@@ -607,6 +712,13 @@ type VersionJson struct {
Version string `json:"version"`
}
type WithdrawalJson struct {
WithdrawalIndex string `json:"index"`
ValidatorIndex string `json:"validator_index"`
ExecutionAddress string `json:"address" hex:"true"`
Amount string `json:"amount"`
}
type BeaconStateJson struct {
GenesisTime string `json:"genesis_time"`
GenesisValidatorsRoot string `json:"genesis_validators_root" hex:"true"`
@@ -686,10 +798,41 @@ type BeaconStateBellatrixJson struct {
LatestExecutionPayloadHeader *ExecutionPayloadHeaderJson `json:"latest_execution_payload_header"`
}
type BeaconStateCapellaJson struct {
GenesisTime string `json:"genesis_time"`
GenesisValidatorsRoot string `json:"genesis_validators_root" hex:"true"`
Slot string `json:"slot"`
Fork *ForkJson `json:"fork"`
LatestBlockHeader *BeaconBlockHeaderJson `json:"latest_block_header"`
BlockRoots []string `json:"block_roots" hex:"true"`
StateRoots []string `json:"state_roots" hex:"true"`
HistoricalRoots []string `json:"historical_roots" hex:"true"`
Eth1Data *Eth1DataJson `json:"eth1_data"`
Eth1DataVotes []*Eth1DataJson `json:"eth1_data_votes"`
Eth1DepositIndex string `json:"eth1_deposit_index"`
Validators []*ValidatorJson `json:"validators"`
Balances []string `json:"balances"`
RandaoMixes []string `json:"randao_mixes" hex:"true"`
Slashings []string `json:"slashings"`
PreviousEpochParticipation EpochParticipation `json:"previous_epoch_participation"`
CurrentEpochParticipation EpochParticipation `json:"current_epoch_participation"`
JustificationBits string `json:"justification_bits" hex:"true"`
PreviousJustifiedCheckpoint *CheckpointJson `json:"previous_justified_checkpoint"`
CurrentJustifiedCheckpoint *CheckpointJson `json:"current_justified_checkpoint"`
FinalizedCheckpoint *CheckpointJson `json:"finalized_checkpoint"`
InactivityScores []string `json:"inactivity_scores"`
CurrentSyncCommittee *SyncCommitteeJson `json:"current_sync_committee"`
NextSyncCommittee *SyncCommitteeJson `json:"next_sync_committee"`
LatestExecutionPayloadHeader *ExecutionPayloadHeaderCapellaJson `json:"latest_execution_payload_header"`
NextWithdrawalIndex string `json:"next_withdrawal_index"`
LastWithdrawalValidatorIndex string `json:"latest_withdrawal_validator_index"`
}
type BeaconStateContainerV2Json struct {
Phase0State *BeaconStateJson `json:"phase0_state"`
AltairState *BeaconStateAltairJson `json:"altair_state"`
BellatrixState *BeaconStateBellatrixJson `json:"bellatrix_state"`
CapellaState *BeaconStateCapellaJson `json:"capella_state"`
}
type ForkJson struct {

View File

@@ -16,6 +16,7 @@ go_library(
"//beacon-chain/core/transition:go_default_library",
"//beacon-chain/db/kv:go_default_library",
"//beacon-chain/operations/attestations:go_default_library",
"//beacon-chain/operations/blstoexec:go_default_library",
"//beacon-chain/operations/synccommittee:go_default_library",
"//beacon-chain/p2p:go_default_library",
"//beacon-chain/rpc/eth/helpers:go_default_library",

View File

@@ -4,6 +4,7 @@ import (
"github.com/prysmaticlabs/prysm/v3/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/operations/blstoexec"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/operations/synccommittee"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/p2p"
v1alpha1validator "github.com/prysmaticlabs/prysm/v3/beacon-chain/rpc/prysm/v1alpha1/validator"
@@ -24,6 +25,7 @@ type Server struct {
StateFetcher statefetcher.Fetcher
OptimisticModeFetcher blockchain.OptimisticModeFetcher
SyncCommitteePool synccommittee.Pool
BLSChangesPool blstoexec.PoolManager
V1Alpha1Server *v1alpha1validator.Server
ProposerSlotIndexCache *cache.ProposerPayloadIDsCache
}

View File

@@ -47,6 +47,7 @@ go_library(
"//beacon-chain/execution:go_default_library",
"//beacon-chain/operations/attestations:go_default_library",
"//beacon-chain/operations/slashings:go_default_library",
"//beacon-chain/operations/blstoexec:go_default_library",
"//beacon-chain/operations/synccommittee:go_default_library",
"//beacon-chain/operations/voluntaryexits:go_default_library",
"//beacon-chain/p2p:go_default_library",

View File

@@ -35,8 +35,8 @@ var eth1DataNotification bool
const eth1dataTimeout = 2 * time.Second
// GetBeaconBlock is called by a proposer during its assigned slot to request a block to sign
// by passing in the slot and the signed randao reveal of the slot. Returns phase0 beacon blocks
// before the Altair fork epoch and Altair blocks post-fork epoch.
// by passing in the slot and the signed randao reveal of the slot. Returns a full block
// corresponding to the fork epoch
func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (*ethpb.GenericBeaconBlock, error) {
ctx, span := trace.StartSpan(ctx, "ProposerServer.GetBeaconBlock")
defer span.End()
@@ -59,7 +59,6 @@ func (vs *Server) GetBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (
if err := vs.optimisticStatus(ctx); err != nil {
return nil, err
}
return vs.getBellatrixBeaconBlock(ctx, req)
}

View File

@@ -15,26 +15,12 @@ import (
"go.opencensus.io/trace"
)
func (vs *Server) BuildAltairBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (*ethpb.BeaconBlockAltair, error) {
ctx, span := trace.StartSpan(ctx, "ProposerServer.BuildAltairBeaconBlock")
defer span.End()
blkData, err := vs.buildPhase0BlockData(ctx, req)
if err != nil {
return nil, fmt.Errorf("could not build block data: %v", err)
}
func buildAltairBeaconBlockFromBlockData(blkData *blockData) *ethpb.BeaconBlockAltair {
// Use zero hash as stub for state root to compute later.
stateRoot := params.BeaconConfig().ZeroHash[:]
// No need for safe sub as req.Slot cannot be 0 if requesting Altair blocks. If 0, we will be throwing
// an error in the first validity check of this endpoint.
syncAggregate, err := vs.getSyncAggregate(ctx, req.Slot-1, bytesutil.ToBytes32(blkData.ParentRoot))
if err != nil {
return nil, err
}
return &ethpb.BeaconBlockAltair{
Slot: req.Slot,
Slot: blkData.Slot,
ParentRoot: blkData.ParentRoot,
StateRoot: stateRoot,
ProposerIndex: blkData.ProposerIdx,
@@ -42,14 +28,24 @@ func (vs *Server) BuildAltairBeaconBlock(ctx context.Context, req *ethpb.BlockRe
Eth1Data: blkData.Eth1Data,
Deposits: blkData.Deposits,
Attestations: blkData.Attestations,
RandaoReveal: req.RandaoReveal,
RandaoReveal: blkData.RandaoReveal,
ProposerSlashings: blkData.ProposerSlashings,
AttesterSlashings: blkData.AttesterSlashings,
VoluntaryExits: blkData.VoluntaryExits,
Graffiti: blkData.Graffiti[:],
SyncAggregate: syncAggregate,
SyncAggregate: blkData.SyncAggregate,
},
}, nil
}
}
func (vs *Server) BuildAltairBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (*ethpb.BeaconBlockAltair, error) {
ctx, span := trace.StartSpan(ctx, "ProposerServer.BuildAltairBeaconBlock")
defer span.End()
blkData, err := vs.buildPhase0BlockData(ctx, req)
if err != nil {
return nil, fmt.Errorf("could not build block data: %v", err)
}
return buildAltairBeaconBlockFromBlockData(blkData), nil
}
func (vs *Server) getAltairBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (*ethpb.BeaconBlockAltair, error) {

View File

@@ -80,7 +80,7 @@ func (vs *Server) packAttestations(ctx context.Context, latestState state.Beacon
// filter separates attestation list into two groups: valid and invalid attestations.
// The first group passes the all the required checks for attestation to be considered for proposing.
// And attestations from the second group should be deleted.
func (a proposerAtts) filter(ctx context.Context, st state.BeaconState) (proposerAtts, proposerAtts) {
func (a proposerAtts) filter(ctx context.Context, st state.BeaconState) (proposerAtts, proposerAtts, error) {
validAtts := make([]*ethpb.Attestation, 0, len(a))
invalidAtts := make([]*ethpb.Attestation, 0, len(a))
var attestationProcessor func(context.Context, state.BeaconState, *ethpb.Attestation) (state.BeaconState, error)
@@ -88,7 +88,7 @@ func (a proposerAtts) filter(ctx context.Context, st state.BeaconState) (propose
switch st.Version() {
case version.Phase0:
attestationProcessor = blocks.ProcessAttestationNoVerifySignature
case version.Altair, version.Bellatrix:
case version.Altair, version.Bellatrix, version.Capella:
// Use a wrapper here, as go needs strong typing for the function signature.
attestationProcessor = func(ctx context.Context, st state.BeaconState, attestation *ethpb.Attestation) (state.BeaconState, error) {
totalBalance, err := helpers.TotalActiveBalance(st)
@@ -99,7 +99,7 @@ func (a proposerAtts) filter(ctx context.Context, st state.BeaconState) (propose
}
default:
// Exit early if there is an unknown state type.
return validAtts, invalidAtts
return validAtts, invalidAtts, errors.Errorf("unknown state type: %v", st.Version())
}
for _, att := range a {
if _, err := attestationProcessor(ctx, st, att); err == nil {
@@ -108,7 +108,7 @@ func (a proposerAtts) filter(ctx context.Context, st state.BeaconState) (propose
}
invalidAtts = append(invalidAtts, att)
}
return validAtts, invalidAtts
return validAtts, invalidAtts, nil
}
// sortByProfitability orders attestations by highest slot and by highest aggregation bit count.
@@ -247,7 +247,10 @@ func (vs *Server) validateAndDeleteAttsInPool(ctx context.Context, st state.Beac
ctx, span := trace.StartSpan(ctx, "ProposerServer.validateAndDeleteAttsInPool")
defer span.End()
validAtts, invalidAtts := proposerAtts(atts).filter(ctx, st)
validAtts, invalidAtts, err := proposerAtts(atts).filter(ctx, st)
if err != nil {
return nil, err
}
if err := vs.deleteAttsInPool(ctx, invalidAtts); err != nil {
return nil, err
}

View File

@@ -12,6 +12,7 @@ import (
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/signing"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/transition"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/transition/interop"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/db/kv"
"github.com/prysmaticlabs/prysm/v3/config/params"
@@ -38,68 +39,124 @@ var builderGetPayloadMissCount = promauto.NewCounter(prometheus.CounterOpts{
// block request. This value is known as `BUILDER_PROPOSAL_DELAY_TOLERANCE` in builder spec.
const blockBuilderTimeout = 1 * time.Second
func (vs *Server) getBlockFromBuilder(ctx context.Context, altairBlk *ethpb.BeaconBlockAltair) (
*ethpb.GenericBeaconBlock, error) {
registered, err := vs.validatorRegistered(ctx, altairBlk.ProposerIndex)
if registered && err == nil {
builderReady, b, err := vs.GetAndBuildBlindBlock(ctx, altairBlk)
if err != nil {
// In the event of an error, the node should fall back to default execution engine for building block.
builderGetPayloadMissCount.Inc()
return nil, err
} else if builderReady {
return b, nil
}
} else if err != nil {
return nil, err
}
return nil, errors.New("validator is not registered")
}
func (vs *Server) getBellatrixBeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (*ethpb.GenericBeaconBlock, error) {
altairBlk, err := vs.BuildAltairBeaconBlock(ctx, req)
blkData, err := vs.buildPhase0BlockData(ctx, req)
if err != nil {
return nil, err
}
if !req.SkipMevBoost {
registered, err := vs.validatorRegistered(ctx, altairBlk.ProposerIndex)
if registered && err == nil {
builderReady, b, err := vs.GetAndBuildBlindBlock(ctx, altairBlk)
if err != nil {
// In the event of an error, the node should fall back to default execution engine for building block.
log.WithError(err).Error("Failed to build a block from external builder, falling " +
"back to local execution client")
builderGetPayloadMissCount.Inc()
} else if builderReady {
return b, nil
}
} else if err != nil {
log.WithError(err).WithFields(logrus.Fields{
"slot": req.Slot,
"validatorIndex": altairBlk.ProposerIndex,
}).Error("Could not determine validator has registered. Defaulting to local execution client")
// If the validator was not registered then we computed already an execution payload
if !req.SkipMevBoost && blkData.ExecutionPayload == nil && blkData.ExecutionPayloadV2 == nil {
altairBlk := buildAltairBeaconBlockFromBlockData(blkData)
b, err := vs.getBlockFromBuilder(ctx, altairBlk)
if err == nil {
return b, nil
}
log.WithError(err).Error("falling back to local execution")
head, err := vs.HeadFetcher.HeadState(ctx)
if err != nil {
return nil, fmt.Errorf("could not get head state %v", err)
}
head, err = transition.ProcessSlotsUsingNextSlotCache(ctx, head, blkData.ParentRoot, req.Slot)
if err != nil {
return nil, fmt.Errorf("could not advance slots to calculate proposer index: %v", err)
}
blkData.ExecutionPayload, err = vs.getExecutionPayload(ctx, req.Slot, blkData.ProposerIdx, bytesutil.ToBytes32(blkData.ParentRoot), head)
if err != nil {
return nil, errors.Wrap(err, "could not get execution payload")
}
}
payload, err := vs.getExecutionPayload(ctx, req.Slot, altairBlk.ProposerIndex, bytesutil.ToBytes32(altairBlk.ParentRoot))
if err != nil {
return nil, err
}
blk := &ethpb.BeaconBlockBellatrix{
Slot: altairBlk.Slot,
ProposerIndex: altairBlk.ProposerIndex,
ParentRoot: altairBlk.ParentRoot,
StateRoot: params.BeaconConfig().ZeroHash[:],
Body: &ethpb.BeaconBlockBodyBellatrix{
RandaoReveal: altairBlk.Body.RandaoReveal,
Eth1Data: altairBlk.Body.Eth1Data,
Graffiti: altairBlk.Body.Graffiti,
ProposerSlashings: altairBlk.Body.ProposerSlashings,
AttesterSlashings: altairBlk.Body.AttesterSlashings,
Attestations: altairBlk.Body.Attestations,
Deposits: altairBlk.Body.Deposits,
VoluntaryExits: altairBlk.Body.VoluntaryExits,
SyncAggregate: altairBlk.Body.SyncAggregate,
ExecutionPayload: payload,
},
}
// Compute state root with the newly constructed block.
wsb, err := consensusblocks.NewSignedBeaconBlock(
&ethpb.SignedBeaconBlockBellatrix{Block: blk, Signature: make([]byte, 96)},
)
if err != nil {
return nil, err
var wsb interfaces.SignedBeaconBlock
if slots.ToEpoch(req.Slot) < params.BeaconConfig().CapellaForkEpoch {
blk := &ethpb.BeaconBlockBellatrix{
Slot: blkData.Slot,
ProposerIndex: blkData.ProposerIdx,
ParentRoot: blkData.ParentRoot,
StateRoot: params.BeaconConfig().ZeroHash[:],
Body: &ethpb.BeaconBlockBodyBellatrix{
RandaoReveal: blkData.RandaoReveal,
Eth1Data: blkData.Eth1Data,
Graffiti: blkData.Graffiti[:],
ProposerSlashings: blkData.ProposerSlashings,
AttesterSlashings: blkData.AttesterSlashings,
Attestations: blkData.Attestations,
Deposits: blkData.Deposits,
VoluntaryExits: blkData.VoluntaryExits,
SyncAggregate: blkData.SyncAggregate,
ExecutionPayload: blkData.ExecutionPayload,
},
}
// Compute state root with the newly constructed block.
wsb, err = consensusblocks.NewSignedBeaconBlock(
&ethpb.SignedBeaconBlockBellatrix{Block: blk, Signature: make([]byte, 96)},
)
if err != nil {
return nil, err
}
} else {
blk := &ethpb.BeaconBlockCapella{
Slot: blkData.Slot,
ProposerIndex: blkData.ProposerIdx,
ParentRoot: blkData.ParentRoot,
StateRoot: params.BeaconConfig().ZeroHash[:],
Body: &ethpb.BeaconBlockBodyCapella{
RandaoReveal: blkData.RandaoReveal,
Eth1Data: blkData.Eth1Data,
Graffiti: blkData.Graffiti[:],
ProposerSlashings: blkData.ProposerSlashings,
AttesterSlashings: blkData.AttesterSlashings,
Attestations: blkData.Attestations,
Deposits: blkData.Deposits,
VoluntaryExits: blkData.VoluntaryExits,
SyncAggregate: blkData.SyncAggregate,
ExecutionPayload: blkData.ExecutionPayloadV2,
BlsToExecutionChanges: blkData.BlsToExecutionChanges,
},
}
// Compute state root with the newly constructed block.
wsb, err = consensusblocks.NewSignedBeaconBlock(
&ethpb.SignedBeaconBlockCapella{Block: blk, Signature: make([]byte, 96)},
)
if err != nil {
return nil, err
}
}
stateRoot, err := vs.computeStateRoot(ctx, wsb)
if err != nil {
interop.WriteBlockToDisk(wsb, true /*failed*/)
return nil, fmt.Errorf("could not compute state root: %v", err)
}
blk.StateRoot = stateRoot
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Bellatrix{Bellatrix: blk}}, nil
wsb.Block().SetStateRoot(stateRoot)
pb, err := wsb.Block().Proto()
if err != nil {
return nil, errors.Wrap(err, "could not unmarshal block")
}
if slots.ToEpoch(req.Slot) < params.BeaconConfig().CapellaForkEpoch {
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Bellatrix{Bellatrix: pb.(*ethpb.BeaconBlockBellatrix)}}, nil
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Capella{Capella: pb.(*ethpb.BeaconBlockCapella)}}, nil
}
// This function retrieves the payload header given the slot number and the validator index.

View File

@@ -12,8 +12,8 @@ import (
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/time"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/core/transition"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/db/kv"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/state"
fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams"
"github.com/prysmaticlabs/prysm/v3/config/params"
consensusblocks "github.com/prysmaticlabs/prysm/v3/consensus-types/blocks"
@@ -38,9 +38,14 @@ var (
})
)
// This returns the execution payload of a given slot. The function has full awareness of pre and post merge.
// This returns the execution payload of a given slot.
// The function has full awareness of pre and post merge.
// The payload is computed given the respected time of merge.
func (vs *Server) getExecutionPayload(ctx context.Context, slot types.Slot, vIdx types.ValidatorIndex, headRoot [32]byte) (*enginev1.ExecutionPayload, error) {
func (vs *Server) getExecutionPayload(ctx context.Context,
slot types.Slot,
vIdx types.ValidatorIndex,
headRoot [32]byte,
st state.BeaconState) (*enginev1.ExecutionPayload, error) {
proposerID, payloadId, ok := vs.ProposerSlotIndexCache.GetProposerPayloadIDs(slot, headRoot)
feeRecipient := params.BeaconConfig().DefaultFeeRecipient
recipient, err := vs.BeaconDB.FeeRecipientByValidatorID(ctx, vIdx)
@@ -70,7 +75,7 @@ func (vs *Server) getExecutionPayload(ctx context.Context, slot types.Slot, vIdx
payload, err := vs.ExecutionEngineCaller.GetPayload(ctx, pid)
switch {
case err == nil:
warnIfFeeRecipientDiffers(payload, feeRecipient)
warnIfFeeRecipientDiffers(payload.FeeRecipient, feeRecipient)
return payload, nil
case errors.Is(err, context.DeadlineExceeded):
default:
@@ -78,15 +83,6 @@ func (vs *Server) getExecutionPayload(ctx context.Context, slot types.Slot, vIdx
}
}
st, err := vs.HeadFetcher.HeadState(ctx)
if err != nil {
return nil, err
}
st, err = transition.ProcessSlotsIfPossible(ctx, st, slot)
if err != nil {
return nil, err
}
var parentHash []byte
var hasTerminalBlock bool
mergeComplete, err := blocks.IsMergeTransitionComplete(st)
@@ -165,18 +161,129 @@ func (vs *Server) getExecutionPayload(ctx context.Context, slot types.Slot, vIdx
if err != nil {
return nil, err
}
warnIfFeeRecipientDiffers(payload, feeRecipient)
warnIfFeeRecipientDiffers(payload.FeeRecipient, feeRecipient)
return payload, nil
}
// This returns the execution payload of a given slot after the Capella upgrade
func (vs *Server) getExecutionPayloadV2(ctx context.Context,
slot types.Slot,
vIdx types.ValidatorIndex,
headRoot [32]byte,
st state.BeaconState) (*enginev1.ExecutionPayloadCapella, error) {
proposerID, payloadId, ok := vs.ProposerSlotIndexCache.GetProposerPayloadIDs(slot, headRoot)
feeRecipient := params.BeaconConfig().DefaultFeeRecipient
recipient, err := vs.BeaconDB.FeeRecipientByValidatorID(ctx, vIdx)
switch err == nil {
case true:
feeRecipient = recipient
case errors.As(err, kv.ErrNotFoundFeeRecipient):
// If fee recipient is not found in DB and not set from beacon node CLI,
// use the burn address.
if feeRecipient.String() == params.BeaconConfig().EthBurnAddressHex {
logrus.WithFields(logrus.Fields{
"validatorIndex": vIdx,
"burnAddress": params.BeaconConfig().EthBurnAddressHex,
}).Warn("Fee recipient is currently using the burn address, " +
"you will not be rewarded transaction fees on this setting. " +
"Please set a different eth address as the fee recipient. " +
"Please refer to our documentation for instructions")
}
default:
return nil, errors.Wrap(err, "could not get fee recipient in db")
}
if ok && proposerID == vIdx && payloadId != [8]byte{} { // Payload ID is cache hit. Return the cached payload ID.
var pid [8]byte
copy(pid[:], payloadId[:])
payloadIDCacheHit.Inc()
payload, err := vs.ExecutionEngineCaller.GetPayloadV2(ctx, pid)
switch {
case err == nil:
warnIfFeeRecipientDiffers(payload.FeeRecipient, feeRecipient)
return payload, nil
case errors.Is(err, context.DeadlineExceeded):
default:
return nil, errors.Wrap(err, "could not get cached payload from execution client")
}
}
payloadIDCacheMiss.Inc()
header, err := st.LatestExecutionPayloadHeader()
if err != nil {
return nil, errors.Wrap(err, "could not get latest execution payload header")
}
parentHash := header.BlockHash()
random, err := helpers.RandaoMix(st, time.CurrentEpoch(st))
if err != nil {
return nil, err
}
finalizedBlockHash := params.BeaconConfig().ZeroHash[:]
finalizedRoot := bytesutil.ToBytes32(st.FinalizedCheckpoint().Root)
if finalizedRoot != [32]byte{} { // finalized root could be zeros before the first finalized block.
finalizedBlock, err := vs.BeaconDB.Block(ctx, bytesutil.ToBytes32(st.FinalizedCheckpoint().Root))
if err != nil {
return nil, err
}
if err := consensusblocks.BeaconBlockIsNil(finalizedBlock); err != nil {
return nil, err
}
switch finalizedBlock.Version() {
case version.Phase0, version.Altair: // Blocks before Bellatrix don't have execution payloads. Use zeros as the hash.
default:
finalizedPayload, err := finalizedBlock.Block().Body().Execution()
if err != nil {
return nil, err
}
finalizedBlockHash = finalizedPayload.BlockHash()
}
}
f := &enginev1.ForkchoiceState{
HeadBlockHash: parentHash,
SafeBlockHash: parentHash,
FinalizedBlockHash: finalizedBlockHash,
}
t, err := slots.ToTime(st.GenesisTime(), slot)
if err != nil {
return nil, err
}
withdrawals, err := st.ExpectedWithdrawals()
if err != nil {
return nil, errors.Wrap(err, "could not get expected withdrawals")
}
p := &enginev1.PayloadAttributesV2{
Timestamp: uint64(t.Unix()),
PrevRandao: random,
SuggestedFeeRecipient: feeRecipient.Bytes(),
Withdrawals: withdrawals,
}
payloadID, _, err := vs.ExecutionEngineCaller.ForkchoiceUpdatedV2(ctx, f, p)
if err != nil {
return nil, errors.Wrap(err, "could not prepare payload")
}
if payloadID == nil {
return nil, fmt.Errorf("nil payload with block hash: %#x", parentHash)
}
payload, err := vs.ExecutionEngineCaller.GetPayloadV2(ctx, *payloadID)
if err != nil {
return nil, err
}
warnIfFeeRecipientDiffers(payload.FeeRecipient, feeRecipient)
return payload, nil
}
// warnIfFeeRecipientDiffers logs a warning if the fee recipient in the included payload does not
// match the requested one.
func warnIfFeeRecipientDiffers(payload *enginev1.ExecutionPayload, feeRecipient common.Address) {
func warnIfFeeRecipientDiffers(payloadRecipient []byte, feeRecipient common.Address) {
// Warn if the fee recipient is not the value we expect.
if payload != nil && !bytes.Equal(payload.FeeRecipient, feeRecipient[:]) {
if !bytes.Equal(payloadRecipient, feeRecipient[:]) {
logrus.WithFields(logrus.Fields{
"wantedFeeRecipient": fmt.Sprintf("%#x", feeRecipient),
"received": fmt.Sprintf("%#x", payload.FeeRecipient),
"received": fmt.Sprintf("%#x", payloadRecipient),
}).Warn("Fee recipient address from execution client is not what was expected. " +
"It is possible someone has compromised your client to try and take your transaction fees")
}

View File

@@ -14,21 +14,29 @@ import (
consensusblocks "github.com/prysmaticlabs/prysm/v3/consensus-types/blocks"
types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v3/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v3/time/slots"
"go.opencensus.io/trace"
)
// blockData required to create a beacon block.
type blockData struct {
ParentRoot []byte
Graffiti [32]byte
ProposerIdx types.ValidatorIndex
Eth1Data *ethpb.Eth1Data
Deposits []*ethpb.Deposit
Attestations []*ethpb.Attestation
ProposerSlashings []*ethpb.ProposerSlashing
AttesterSlashings []*ethpb.AttesterSlashing
VoluntaryExits []*ethpb.SignedVoluntaryExit
Slot types.Slot
ParentRoot []byte
Graffiti [32]byte
ProposerIdx types.ValidatorIndex
Eth1Data *ethpb.Eth1Data
Deposits []*ethpb.Deposit
Attestations []*ethpb.Attestation
RandaoReveal []byte
ProposerSlashings []*ethpb.ProposerSlashing
AttesterSlashings []*ethpb.AttesterSlashing
VoluntaryExits []*ethpb.SignedVoluntaryExit
SyncAggregate *ethpb.SyncAggregate
ExecutionPayload *enginev1.ExecutionPayload
ExecutionPayloadV2 *enginev1.ExecutionPayloadCapella
BlsToExecutionChanges []*ethpb.SignedBLSToExecutionChange
}
func (vs *Server) getPhase0BeaconBlock(ctx context.Context, req *ethpb.BlockRequest) (*ethpb.BeaconBlock, error) {
@@ -43,7 +51,7 @@ func (vs *Server) getPhase0BeaconBlock(ctx context.Context, req *ethpb.BlockRequ
stateRoot := params.BeaconConfig().ZeroHash[:]
blk := &ethpb.BeaconBlock{
Slot: req.Slot,
Slot: blkData.Slot,
ParentRoot: blkData.ParentRoot,
StateRoot: stateRoot,
ProposerIndex: blkData.ProposerIdx,
@@ -51,7 +59,7 @@ func (vs *Server) getPhase0BeaconBlock(ctx context.Context, req *ethpb.BlockRequ
Eth1Data: blkData.Eth1Data,
Deposits: blkData.Deposits,
Attestations: blkData.Attestations,
RandaoReveal: req.RandaoReveal,
RandaoReveal: blkData.RandaoReveal,
ProposerSlashings: blkData.ProposerSlashings,
AttesterSlashings: blkData.AttesterSlashings,
VoluntaryExits: blkData.VoluntaryExits,
@@ -156,15 +164,66 @@ func (vs *Server) buildPhase0BlockData(ctx context.Context, req *ethpb.BlockRequ
validExits = append(validExits, exit)
}
return &blockData{
blk := &blockData{
Slot: req.Slot,
ParentRoot: parentRoot,
Graffiti: graffiti,
ProposerIdx: idx,
Eth1Data: eth1Data,
Deposits: deposits,
Attestations: atts,
RandaoReveal: req.RandaoReveal,
ProposerSlashings: validProposerSlashings,
AttesterSlashings: validAttSlashings,
VoluntaryExits: validExits,
}, nil
}
if slots.ToEpoch(req.Slot) >= params.BeaconConfig().AltairForkEpoch {
syncAggregate, err := vs.getSyncAggregate(ctx, req.Slot-1, bytesutil.ToBytes32(parentRoot))
if err != nil {
return nil, errors.Wrap(err, "could not compute the sync aggregate")
}
blk.SyncAggregate = syncAggregate
}
if slots.ToEpoch(req.Slot) >= params.BeaconConfig().BellatrixForkEpoch {
// We request the execution payload only if the validator is not registered
// with a relayer
registered, err := vs.validatorRegistered(ctx, idx)
if !registered || err != nil {
if slots.ToEpoch(req.Slot) >= params.BeaconConfig().CapellaForkEpoch {
executionPayloadV2, err := vs.getExecutionPayloadV2(
ctx,
req.Slot,
idx,
bytesutil.ToBytes32(parentRoot),
head,
)
if err != nil {
return nil, errors.Wrap(err, "could not get execution payload")
}
blk.ExecutionPayloadV2 = executionPayloadV2
changes, err := vs.BLSChangesPool.BLSToExecChangesForInclusion()
if err != nil {
return nil, errors.Wrap(err, "could not pack BLSToExecutionChanges")
}
blk.BlsToExecutionChanges = changes
} else {
executionPayload, err := vs.getExecutionPayload(
ctx,
req.Slot,
idx,
bytesutil.ToBytes32(parentRoot),
head,
)
if err != nil {
return nil, errors.Wrap(err, "could not get execution payload")
}
blk.ExecutionPayload = executionPayload
}
}
}
return blk, nil
}

View File

@@ -20,6 +20,7 @@ import (
"github.com/prysmaticlabs/prysm/v3/beacon-chain/db"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/execution"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/operations/blstoexec"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/operations/slashings"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/operations/synccommittee"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/operations/voluntaryexits"
@@ -62,6 +63,7 @@ type Server struct {
SlashingsPool slashings.PoolManager
ExitPool voluntaryexits.PoolManager
SyncCommitteePool synccommittee.Pool
BLSChangesPool blstoexec.PoolManager
BlockReceiver blockchain.BlockReceiver
MockEth1Votes bool
Eth1BlockFetcher execution.POWBlockFetcher

View File

@@ -23,6 +23,7 @@ import (
"github.com/prysmaticlabs/prysm/v3/beacon-chain/db"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/execution"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/operations/blstoexec"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/operations/slashings"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/operations/synccommittee"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/operations/voluntaryexits"
@@ -99,6 +100,7 @@ type Config struct {
SlashingsPool slashings.PoolManager
SlashingChecker slasherservice.SlashingChecker
SyncCommitteeObjectPool synccommittee.Pool
BLSChangesPool blstoexec.PoolManager
SyncService chainSync.Checker
Broadcaster p2p.Broadcaster
PeersFetcher p2p.PeersProvider
@@ -216,6 +218,7 @@ func (s *Service) Start() {
SlashingsPool: s.cfg.SlashingsPool,
StateGen: s.cfg.StateGen,
SyncCommitteePool: s.cfg.SyncCommitteeObjectPool,
BLSChangesPool: s.cfg.BLSChangesPool,
ReplayerBuilder: ch,
ExecutionEngineCaller: s.cfg.ExecutionEngineCaller,
BeaconDB: s.cfg.BeaconDB,
@@ -240,6 +243,7 @@ func (s *Service) Start() {
ReplayerBuilder: ch,
},
SyncCommitteePool: s.cfg.SyncCommitteeObjectPool,
BLSChangesPool: s.cfg.BLSChangesPool,
ProposerSlotIndexCache: s.cfg.ProposerIdsCache,
}

View File

@@ -1,6 +1,7 @@
package state_native
import (
fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams"
"github.com/prysmaticlabs/prysm/v3/config/params"
types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v3/encoding/bytesutil"
@@ -48,7 +49,7 @@ func (b *BeaconState) ExpectedWithdrawals() ([]*enginev1.Withdrawal, error) {
b.lock.RLock()
defer b.lock.RUnlock()
withdrawals := make([]*enginev1.Withdrawal, 0, params.BeaconConfig().MaxWithdrawalsPerPayload)
withdrawals := make([]*enginev1.Withdrawal, 0, fieldparams.MaxWithdrawalsPerPayload)
validatorIndex := b.nextWithdrawalValidatorIndex
withdrawalIndex := b.nextWithdrawalIndex
epoch := slots.ToEpoch(b.slot)
@@ -72,7 +73,7 @@ func (b *BeaconState) ExpectedWithdrawals() ([]*enginev1.Withdrawal, error) {
})
withdrawalIndex++
}
if uint64(len(withdrawals)) == params.BeaconConfig().MaxWithdrawalsPerPayload {
if uint64(len(withdrawals)) == fieldparams.MaxWithdrawalsPerPayload {
break
}
validatorIndex += 1

View File

@@ -165,6 +165,7 @@ var BeaconChainFlags = append(deprecatedBeaconFlags, append(deprecatedFlags, []c
disableBroadcastSlashingFlag,
enableSlasherFlag,
enableHistoricalSpaceRepresentation,
disableStakinContractCheck,
disablePullTips,
disableVecHTR,
disableForkChoiceDoublyLinkedTree,

View File

@@ -26,6 +26,4 @@ const (
SyncCommitteeAggregationBytesLength = 16 // SyncCommitteeAggregationBytesLength defines the length of sync committee aggregate bytes.
SyncAggregateSyncCommitteeBytesLength = 64 // SyncAggregateSyncCommitteeBytesLength defines the length of sync committee bytes in a sync aggregate.
MaxWithdrawalsPerPayload = 16 // MaxWithdrawalsPerPayloadLength defines the maximum number of withdrawals that can be included in a payload.
WithdrawalQueueLimit = 1099511627776 // WithdrawalQueueLimit defines the maximum number of withdrawals queued in the state.
ExecutionAddressLength = 20 // ExecutionAddressLength defines the length of an execution layer address.
)

View File

@@ -25,6 +25,5 @@ const (
SlotsPerEpoch = 8 // SlotsPerEpoch defines the number of slots per epoch.
SyncCommitteeAggregationBytesLength = 1 // SyncCommitteeAggregationBytesLength defines the sync committee aggregate bytes.
SyncAggregateSyncCommitteeBytesLength = 4 // SyncAggregateSyncCommitteeBytesLength defines the length of sync committee bytes in a sync aggregate.
MaxWithdrawalsPerPayload = 16 // MaxWithdrawalsPerPayloadLength defines the maximum number of withdrawals that can be included in a payload.
WithdrawalQueueLimit = 1099511627776 // WithdrawalQueueLimit defines the maximum number of withdrawals queued in the state.
MaxWithdrawalsPerPayload = 4 // MaxWithdrawalsPerPayloadLength defines the maximum number of withdrawals that can be included in a payload.
)

View File

@@ -226,6 +226,8 @@ func configForkSchedule(b *BeaconChainConfig) map[[fieldparams.VersionLength]byt
fvs[bytesutil.ToBytes4(b.AltairForkVersion)] = b.AltairForkEpoch
// Set Bellatrix fork data.
fvs[bytesutil.ToBytes4(b.BellatrixForkVersion)] = b.BellatrixForkEpoch
// Set Capella fork data.
fvs[bytesutil.ToBytes4(b.CapellaForkVersion)] = b.CapellaForkEpoch
return fvs
}
@@ -237,5 +239,7 @@ func configForkNames(b *BeaconChainConfig) map[[fieldparams.VersionLength]byte]s
fvn[bytesutil.ToBytes4(b.AltairForkVersion)] = "altair"
// Set Bellatrix fork data.
fvn[bytesutil.ToBytes4(b.BellatrixForkVersion)] = "bellatrix"
// Set Capella fork data.
fvn[bytesutil.ToBytes4(b.CapellaForkVersion)] = "capella"
return fvn
}

View File

@@ -9,7 +9,8 @@ func InteropConfig() *BeaconChainConfig {
c.GenesisForkVersion = []byte{0, 0, 0, 235}
c.AltairForkVersion = []byte{1, 0, 0, 235}
c.BellatrixForkVersion = []byte{2, 0, 0, 235}
c.ShardingForkVersion = []byte{3, 0, 0, 235}
c.CapellaForkVersion = []byte{3, 0, 0, 235}
c.ShardingForkVersion = []byte{4, 0, 0, 235}
c.InitializeForkSchedule()
return c

View File

@@ -42,7 +42,8 @@ func E2ETestConfig() *BeaconChainConfig {
e2eConfig.GenesisForkVersion = []byte{0, 0, 0, 253}
e2eConfig.AltairForkVersion = []byte{1, 0, 0, 253}
e2eConfig.BellatrixForkVersion = []byte{2, 0, 0, 253}
e2eConfig.ShardingForkVersion = []byte{3, 0, 0, 253}
e2eConfig.CapellaForkVersion = []byte{3, 0, 0, 253}
e2eConfig.ShardingForkVersion = []byte{4, 0, 0, 253}
e2eConfig.InitializeForkSchedule()
return e2eConfig
@@ -79,7 +80,8 @@ func E2EMainnetTestConfig() *BeaconChainConfig {
e2eConfig.GenesisForkVersion = []byte{0, 0, 0, 254}
e2eConfig.AltairForkVersion = []byte{1, 0, 0, 254}
e2eConfig.BellatrixForkVersion = []byte{2, 0, 0, 254}
e2eConfig.ShardingForkVersion = []byte{3, 0, 0, 254}
e2eConfig.CapellaForkVersion = []byte{3, 0, 0, 254}
e2eConfig.ShardingForkVersion = []byte{4, 0, 0, 254}
e2eConfig.InitializeForkSchedule()
return e2eConfig

View File

@@ -32,6 +32,7 @@ func RopstenConfig() *BeaconChainConfig {
cfg.AltairForkVersion = []byte{0x80, 0x00, 0x00, 0x70}
cfg.BellatrixForkEpoch = 750
cfg.BellatrixForkVersion = []byte{0x80, 0x00, 0x00, 0x71}
cfg.CapellaForkVersion = []byte{0x80, 0x00, 0x00, 0x72}
cfg.TerminalTotalDifficulty = "50000000000000000"
cfg.DepositContractAddress = "0x6f22fFbC56eFF051aECF839396DD1eD9aD6BBA9D"
cfg.InitializeForkSchedule()

View File

@@ -647,10 +647,6 @@ func PayloadToHeaderCapella(payload interfaces.ExecutionData) (*enginev1.Executi
// IsEmptyExecutionData checks if an execution data is empty underneath. If a single field has
// a non-zero value, this function will return false.
func IsEmptyExecutionData(data interfaces.ExecutionData) (bool, error) {
_, ok := data.Proto().(*enginev1.ExecutionPayloadCapella)
if ok {
return false, nil
}
if !bytes.Equal(data.ParentHash(), make([]byte, fieldparams.RootLength)) {
return false, nil
}

View File

@@ -473,6 +473,13 @@ func (b *BeaconBlock) StateRoot() [field_params.RootLength]byte {
return b.stateRoot
}
// SetStateRoot sets the state root of the underlying beacon block
// This function is not thread safe, it is only used during block
// proposal to set the state root of a new block
func (b *BeaconBlock) SetStateRoot(root []byte) {
copy(b.stateRoot[:], root)
}
// Body returns the underlying block body.
func (b *BeaconBlock) Body() interfaces.BeaconBlockBody {
return b.body

View File

@@ -40,6 +40,7 @@ type BeaconBlock interface {
ProposerIndex() types.ValidatorIndex
ParentRoot() [field_params.RootLength]byte
StateRoot() [field_params.RootLength]byte
SetStateRoot([]byte)
Body() BeaconBlockBody
IsNil() bool
IsBlinded() bool

View File

@@ -99,6 +99,15 @@ func ToBytes4(x []byte) [4]byte {
return y
}
// ToBytes20 is a convenience method for converting a byte slice to a fix
// sized 20 byte array. This method will truncate the input if it is larger
// than 20 bytes.
func ToBytes20(x []byte) [20]byte {
var y [20]byte
copy(y[:], x)
return y
}
// ToBytes32 is a convenience method for converting a byte slice to a fix
// sized 32 byte array. This method will truncate the input if it is larger
// than 32 bytes.

View File

@@ -41,7 +41,6 @@ go_test(
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",
"//crypto/hash: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",

View File

@@ -7,7 +7,6 @@ import (
fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams"
"github.com/prysmaticlabs/prysm/v3/crypto/hash"
"github.com/prysmaticlabs/prysm/v3/encoding/ssz"
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v3/testing/assert"
"github.com/prysmaticlabs/prysm/v3/testing/require"

View File

@@ -11,6 +11,7 @@ import (
gethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/pkg/errors"
fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams"
types "github.com/prysmaticlabs/prysm/v3/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v3/encoding/bytesutil"
)
@@ -109,6 +110,58 @@ func (b *PayloadIDBytes) UnmarshalJSON(enc []byte) error {
return nil
}
type withdrawalJSON struct {
Index *hexutil.Uint64 `json:"index"`
Validator *hexutil.Uint64 `json:"validatorIndex"`
Address *common.Address `json:"address"`
Amount string `json:"amount"`
}
func (w *Withdrawal) MarshalJSON() ([]byte, error) {
index := hexutil.Uint64(w.WithdrawalIndex)
validatorIndex := hexutil.Uint64(w.ValidatorIndex)
address := common.BytesToAddress(w.ExecutionAddress)
wei := new(big.Int).SetUint64(1000000000)
amountWei := new(big.Int).Mul(new(big.Int).SetUint64(w.Amount), wei)
return json.Marshal(withdrawalJSON{
Index: &index,
Validator: &validatorIndex,
Address: &address,
Amount: hexutil.EncodeBig(amountWei),
})
}
func (w *Withdrawal) UnmarshalJSON(enc []byte) error {
dec := withdrawalJSON{}
if err := json.Unmarshal(enc, &dec); err != nil {
return err
}
if dec.Index == nil {
return errors.New("missing withdrawal index")
}
if dec.Validator == nil {
return errors.New("missing validator index")
}
if dec.Address == nil {
return errors.New("missing execution address")
}
*w = Withdrawal{}
w.WithdrawalIndex = uint64(*dec.Index)
w.ValidatorIndex = types.ValidatorIndex(*dec.Validator)
w.ExecutionAddress = dec.Address.Bytes()
wei := new(big.Int).SetUint64(1000000000)
amountWei, err := hexutil.DecodeBig(dec.Amount)
if err != nil {
return err
}
amount := new(big.Int).Div(amountWei, wei)
if !amount.IsUint64() {
return errors.New("withdrawal amount overflow")
}
w.Amount = amount.Uint64()
return nil
}
type executionPayloadJSON struct {
ParentHash *common.Hash `json:"parentHash"`
FeeRecipient *common.Address `json:"feeRecipient"`
@@ -126,6 +179,24 @@ type executionPayloadJSON struct {
Transactions []hexutil.Bytes `json:"transactions"`
}
type executionPayloadCapellaJSON struct {
ParentHash *common.Hash `json:"parentHash"`
FeeRecipient *common.Address `json:"feeRecipient"`
StateRoot *common.Hash `json:"stateRoot"`
ReceiptsRoot *common.Hash `json:"receiptsRoot"`
LogsBloom *hexutil.Bytes `json:"logsBloom"`
PrevRandao *common.Hash `json:"prevRandao"`
BlockNumber *hexutil.Uint64 `json:"blockNumber"`
GasLimit *hexutil.Uint64 `json:"gasLimit"`
GasUsed *hexutil.Uint64 `json:"gasUsed"`
Timestamp *hexutil.Uint64 `json:"timestamp"`
ExtraData hexutil.Bytes `json:"extraData"`
BaseFeePerGas string `json:"baseFeePerGas"`
BlockHash *common.Hash `json:"blockHash"`
Transactions []hexutil.Bytes `json:"transactions"`
Withdrawals []*Withdrawal `json:"withdrawals"`
}
// MarshalJSON --
func (e *ExecutionPayload) MarshalJSON() ([]byte, error) {
transactions := make([]hexutil.Bytes, len(e.Transactions))
@@ -163,6 +234,47 @@ func (e *ExecutionPayload) MarshalJSON() ([]byte, error) {
})
}
// MarshalJSON --
func (e *ExecutionPayloadCapella) MarshalJSON() ([]byte, error) {
transactions := make([]hexutil.Bytes, len(e.Transactions))
for i, tx := range e.Transactions {
transactions[i] = tx
}
baseFee := new(big.Int).SetBytes(bytesutil.ReverseByteOrder(e.BaseFeePerGas))
baseFeeHex := hexutil.EncodeBig(baseFee)
pHash := common.BytesToHash(e.ParentHash)
sRoot := common.BytesToHash(e.StateRoot)
recRoot := common.BytesToHash(e.ReceiptsRoot)
prevRan := common.BytesToHash(e.PrevRandao)
bHash := common.BytesToHash(e.BlockHash)
blockNum := hexutil.Uint64(e.BlockNumber)
gasLimit := hexutil.Uint64(e.GasLimit)
gasUsed := hexutil.Uint64(e.GasUsed)
timeStamp := hexutil.Uint64(e.Timestamp)
recipient := common.BytesToAddress(e.FeeRecipient)
logsBloom := hexutil.Bytes(e.LogsBloom)
if e.Withdrawals == nil {
e.Withdrawals = make([]*Withdrawal, 0)
}
return json.Marshal(executionPayloadCapellaJSON{
ParentHash: &pHash,
FeeRecipient: &recipient,
StateRoot: &sRoot,
ReceiptsRoot: &recRoot,
LogsBloom: &logsBloom,
PrevRandao: &prevRan,
BlockNumber: &blockNum,
GasLimit: &gasLimit,
GasUsed: &gasUsed,
Timestamp: &timeStamp,
ExtraData: e.ExtraData,
BaseFeePerGas: baseFeeHex,
BlockHash: &bHash,
Transactions: transactions,
Withdrawals: e.Withdrawals,
})
}
// UnmarshalJSON --
func (e *ExecutionPayload) UnmarshalJSON(enc []byte) error {
dec := executionPayloadJSON{}
@@ -236,12 +348,96 @@ func (e *ExecutionPayload) UnmarshalJSON(enc []byte) error {
return nil
}
// UnmarshalJSON --
func (e *ExecutionPayloadCapella) UnmarshalJSON(enc []byte) error {
dec := executionPayloadCapellaJSON{}
if err := json.Unmarshal(enc, &dec); err != nil {
return err
}
if dec.ParentHash == nil {
return errors.New("missing required field 'parentHash' for ExecutionPayload")
}
if dec.FeeRecipient == nil {
return errors.New("missing required field 'feeRecipient' for ExecutionPayload")
}
if dec.StateRoot == nil {
return errors.New("missing required field 'stateRoot' for ExecutionPayload")
}
if dec.ReceiptsRoot == nil {
return errors.New("missing required field 'receiptsRoot' for ExecutableDataV1")
}
if dec.LogsBloom == nil {
return errors.New("missing required field 'logsBloom' for ExecutionPayload")
}
if dec.PrevRandao == nil {
return errors.New("missing required field 'prevRandao' for ExecutionPayload")
}
if dec.ExtraData == nil {
return errors.New("missing required field 'extraData' for ExecutionPayload")
}
if dec.BlockHash == nil {
return errors.New("missing required field 'blockHash' for ExecutionPayload")
}
if dec.Transactions == nil {
return errors.New("missing required field 'transactions' for ExecutionPayload")
}
if dec.BlockNumber == nil {
return errors.New("missing required field 'blockNumber' for ExecutionPayload")
}
if dec.Timestamp == nil {
return errors.New("missing required field 'timestamp' for ExecutionPayload")
}
if dec.GasUsed == nil {
return errors.New("missing required field 'gasUsed' for ExecutionPayload")
}
if dec.GasLimit == nil {
return errors.New("missing required field 'gasLimit' for ExecutionPayload")
}
*e = ExecutionPayloadCapella{}
e.ParentHash = dec.ParentHash.Bytes()
e.FeeRecipient = dec.FeeRecipient.Bytes()
e.StateRoot = dec.StateRoot.Bytes()
e.ReceiptsRoot = dec.ReceiptsRoot.Bytes()
e.LogsBloom = *dec.LogsBloom
e.PrevRandao = dec.PrevRandao.Bytes()
e.BlockNumber = uint64(*dec.BlockNumber)
e.GasLimit = uint64(*dec.GasLimit)
e.GasUsed = uint64(*dec.GasUsed)
e.Timestamp = uint64(*dec.Timestamp)
e.ExtraData = dec.ExtraData
baseFee, err := hexutil.DecodeBig(dec.BaseFeePerGas)
if err != nil {
return err
}
e.BaseFeePerGas = bytesutil.PadTo(bytesutil.ReverseByteOrder(baseFee.Bytes()), fieldparams.RootLength)
e.BlockHash = dec.BlockHash.Bytes()
transactions := make([][]byte, len(dec.Transactions))
for i, tx := range dec.Transactions {
transactions[i] = tx
}
e.Transactions = transactions
if dec.Withdrawals == nil {
dec.Withdrawals = make([]*Withdrawal, 0)
}
e.Withdrawals = dec.Withdrawals
return nil
}
type payloadAttributesJSON struct {
Timestamp hexutil.Uint64 `json:"timestamp"`
PrevRandao hexutil.Bytes `json:"prevRandao"`
SuggestedFeeRecipient hexutil.Bytes `json:"suggestedFeeRecipient"`
}
type payloadAttributesV2JSON struct {
Timestamp hexutil.Uint64 `json:"timestamp"`
PrevRandao hexutil.Bytes `json:"prevRandao"`
SuggestedFeeRecipient hexutil.Bytes `json:"suggestedFeeRecipient"`
Withdrawals []*Withdrawal `json:"withdrawals"`
}
// MarshalJSON --
func (p *PayloadAttributes) MarshalJSON() ([]byte, error) {
return json.Marshal(payloadAttributesJSON{
@@ -251,6 +447,16 @@ func (p *PayloadAttributes) MarshalJSON() ([]byte, error) {
})
}
// MarshalJSON --
func (p *PayloadAttributesV2) MarshalJSON() ([]byte, error) {
return json.Marshal(payloadAttributesV2JSON{
Timestamp: hexutil.Uint64(p.Timestamp),
PrevRandao: p.PrevRandao,
SuggestedFeeRecipient: p.SuggestedFeeRecipient,
Withdrawals: p.Withdrawals,
})
}
// UnmarshalJSON --
func (p *PayloadAttributes) UnmarshalJSON(enc []byte) error {
dec := payloadAttributesJSON{}
@@ -264,6 +470,19 @@ func (p *PayloadAttributes) UnmarshalJSON(enc []byte) error {
return nil
}
func (p *PayloadAttributesV2) UnmarshalJSON(enc []byte) error {
dec := payloadAttributesV2JSON{}
if err := json.Unmarshal(enc, &dec); err != nil {
return err
}
*p = PayloadAttributesV2{}
p.Timestamp = uint64(dec.Timestamp)
p.PrevRandao = dec.PrevRandao
p.SuggestedFeeRecipient = dec.SuggestedFeeRecipient
p.Withdrawals = dec.Withdrawals
return nil
}
type payloadStatusJSON struct {
LatestValidHash *common.Hash `json:"latestValidHash"`
Status string `json:"status"`

View File

@@ -193,5 +193,5 @@ func createDepositData(privKey bls.SecretKey, pubKey bls.PublicKey) (*ethpb.Depo
// where withdrawal_credentials is of type bytes32.
func withdrawalCredentialsHash(pubKey []byte) []byte {
h := hash.Hash(pubKey)
return append([]byte{blsWithdrawalPrefixByte}, h[1:]...)[:32]
return append([]byte{1}, h[1:]...)[:32]
}

View File

@@ -0,0 +1,25 @@
load("@prysm//tools/go:def.bzl", "go_test")
go_test(
name = "go_default_test",
size = "small",
srcs = [
"effective_balance_updates_test.go",
"eth1_data_reset_test.go",
"historical_roots_update_test.go",
"inactivity_updates_test.go",
"justification_and_finalization_test.go",
"participation_flag_updates_test.go",
"randao_mixes_reset_test.go",
"registry_updates_test.go",
"rewards_and_penalties_test.go",
"slashings_reset_test.go",
"slashings_test.go",
],
data = glob(["*.yaml"]) + [
"@consensus_spec_tests_mainnet//:test_data",
],
shard_count = 4,
tags = ["spectest"],
deps = ["//testing/spectest/shared/capella/epoch_processing:go_default_library"],
)

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMainnet_Capella_EpochProcessing_EffectiveBalanceUpdates(t *testing.T) {
epoch_processing.RunEffectiveBalanceUpdatesTests(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMainnet_Capella_EpochProcessing_Eth1DataReset(t *testing.T) {
epoch_processing.RunEth1DataResetTests(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMainnet_Capella_EpochProcessing_HistoricalRootsUpdate(t *testing.T) {
epoch_processing.RunHistoricalRootsUpdateTests(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMainnet_Capella_EpochProcessing_InactivityUpdates(t *testing.T) {
epoch_processing.RunInactivityUpdatesTest(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMainnet_Capella_EpochProcessing_JustificationAndFinalization(t *testing.T) {
epoch_processing.RunJustificationAndFinalizationTests(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMainnet_Capella_EpochProcessing_ParticipationFlag(t *testing.T) {
epoch_processing.RunParticipationFlagUpdatesTests(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMainnet_Capella_EpochProcessing_RandaoMixesReset(t *testing.T) {
epoch_processing.RunRandaoMixesResetTests(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMainnet_Capella_EpochProcessing_ResetRegistryUpdates(t *testing.T) {
epoch_processing.RunRegistryUpdatesTests(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMainnet_Capella_EpochProcessing_RewardsAndPenalties(t *testing.T) {
epoch_processing.RunRewardsAndPenaltiesTests(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMainnet_Capella_EpochProcessing_SlashingsReset(t *testing.T) {
epoch_processing.RunSlashingsResetTests(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMainnet_Capella_EpochProcessing_Slashings(t *testing.T) {
epoch_processing.RunSlashingsTests(t, "mainnet")
}

View File

@@ -0,0 +1,14 @@
load("@prysm//tools/go:def.bzl", "go_test")
go_test(
name = "go_default_test",
size = "medium",
timeout = "short",
srcs = ["finality_test.go"],
data = glob(["*.yaml"]) + [
"@consensus_spec_tests_mainnet//:test_data",
],
shard_count = 4,
tags = ["spectest"],
deps = ["//testing/spectest/shared/capella/finality:go_default_library"],
)

View File

@@ -0,0 +1,11 @@
package finality
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/finality"
)
func TestMainnet_Capella_Finality(t *testing.T) {
finality.RunFinalityTest(t, "mainnet")
}

View File

@@ -0,0 +1,13 @@
load("@prysm//tools/go:def.bzl", "go_test")
go_test(
name = "go_default_test",
size = "small",
srcs = ["upgrade_to_capella_test.go"],
data = glob(["*.yaml"]) + [
"@consensus_spec_tests_mainnet//:test_data",
],
shard_count = 4,
tags = ["spectest"],
deps = ["//testing/spectest/shared/capella/fork:go_default_library"],
)

View File

@@ -0,0 +1,11 @@
package fork_helper
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/fork"
)
func TestMainnet_Capella_UpgradeToCapella(t *testing.T) {
fork.RunUpgradeToCapella(t, "mainnet")
}

View File

@@ -0,0 +1,12 @@
load("@prysm//tools/go:def.bzl", "go_test")
go_test(
name = "go_default_test",
size = "small",
srcs = ["transition_test.go"],
data = glob(["*.yaml"]) + [
"@consensus_spec_tests_mainnet//:test_data",
],
tags = ["spectest"],
deps = ["//testing/spectest/shared/capella/fork:go_default_library"],
)

View File

@@ -0,0 +1,11 @@
package fork_transition
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/fork"
)
func TestMainnet_Capella_Transition(t *testing.T) {
fork.RunForkTransitionTest(t, "mainnet")
}

View File

@@ -0,0 +1,17 @@
load("@prysm//tools/go:def.bzl", "go_test")
go_test(
name = "go_default_test",
size = "enormous",
timeout = "short",
srcs = ["forkchoice_test.go"],
data = glob(["*.yaml"]) + [
"@consensus_spec_tests_mainnet//:test_data",
],
tags = ["spectest"],
deps = [
"//config/features:go_default_library",
"//runtime/version:go_default_library",
"//testing/spectest/shared/common/forkchoice:go_default_library",
],
)

View File

@@ -0,0 +1,18 @@
package forkchoice
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/config/features"
"github.com/prysmaticlabs/prysm/v3/runtime/version"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/common/forkchoice"
)
func TestMainnet_Capella_Forkchoice(t *testing.T) {
resetCfg := features.InitWithReset(&features.Flags{
EnableDefensivePull: false,
DisablePullTips: true,
})
defer resetCfg()
forkchoice.Run(t, "mainnet", version.Capella)
}

View File

@@ -0,0 +1,21 @@
load("@prysm//tools/go:def.bzl", "go_test")
go_test(
name = "go_default_test",
size = "small",
srcs = [
"attestation_test.go",
"attester_slashing_test.go",
"block_header_test.go",
"deposit_test.go",
"proposer_slashing_test.go",
"sync_committee_test.go",
"voluntary_exit_test.go",
],
data = glob(["*.yaml"]) + [
"@consensus_spec_tests_mainnet//:test_data",
],
shard_count = 4,
tags = ["spectest"],
deps = ["//testing/spectest/shared/capella/operations:go_default_library"],
)

View File

@@ -0,0 +1,11 @@
package operations
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/operations"
)
func TestMainnet_Capella_Operations_Attestation(t *testing.T) {
operations.RunAttestationTest(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package operations
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/operations"
)
func TestMainnet_Capella_Operations_AttesterSlashing(t *testing.T) {
operations.RunAttesterSlashingTest(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package operations
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/operations"
)
func TestMainnet_Capella_Operations_BlockHeader(t *testing.T) {
operations.RunBlockHeaderTest(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package operations
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/operations"
)
func TestMainnet_Capella_Operations_Deposit(t *testing.T) {
operations.RunDepositTest(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package operations
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/operations"
)
func TestMainnet_Capella_Operations_ProposerSlashing(t *testing.T) {
operations.RunProposerSlashingTest(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package operations
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/operations"
)
func TestMainnet_Capella_Operations_SyncCommittee(t *testing.T) {
operations.RunSyncCommitteeTest(t, "mainnet")
}

View File

@@ -0,0 +1,11 @@
package operations
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/operations"
)
func TestMainnet_Capella_Operations_VoluntaryExit(t *testing.T) {
operations.RunVoluntaryExitTest(t, "mainnet")
}

View File

@@ -0,0 +1,12 @@
load("@prysm//tools/go:def.bzl", "go_test")
go_test(
name = "go_default_test",
size = "small",
srcs = ["rewards_test.go"],
data = glob(["*.yaml"]) + [
"@consensus_spec_tests_mainnet//:test_data",
],
tags = ["spectest"],
deps = ["//testing/spectest/shared/capella/rewards:go_default_library"],
)

View File

@@ -0,0 +1,11 @@
package rewards
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/rewards"
)
func TestMainnet_Capella_Rewards(t *testing.T) {
rewards.RunPrecomputeRewardsAndPenaltiesTests(t, "mainnet")
}

View File

@@ -0,0 +1,16 @@
load("@prysm//tools/go:def.bzl", "go_test")
go_test(
name = "go_default_test",
size = "medium",
timeout = "short",
srcs = [
"blocks_test.go",
"slots_test.go",
],
data = glob(["*.yaml"]) + [
"@consensus_spec_tests_mainnet//:test_data",
],
tags = ["spectest"],
deps = ["//testing/spectest/shared/capella/sanity:go_default_library"],
)

View File

@@ -0,0 +1,11 @@
package sanity
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/sanity"
)
func TestMainnet_Capella_Sanity_Blocks(t *testing.T) {
sanity.RunBlockProcessingTest(t, "mainnet", "sanity/blocks/pyspec_tests")
}

View File

@@ -0,0 +1,11 @@
package sanity
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/sanity"
)
func TestMainnet_Capella_Sanity_Slots(t *testing.T) {
sanity.RunSlotProcessingTests(t, "mainnet")
}

View File

@@ -0,0 +1,12 @@
load("@prysm//tools/go:def.bzl", "go_test")
go_test(
name = "go_default_test",
size = "small",
srcs = ["ssz_static_test.go"],
data = glob(["*.yaml"]) + [
"@consensus_spec_tests_mainnet//:test_data",
],
tags = ["spectest"],
deps = ["//testing/spectest/shared/capella/ssz_static:go_default_library"],
)

View File

@@ -0,0 +1,11 @@
package ssz_static
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/ssz_static"
)
func TestMainnet_Capella_SSZStatic(t *testing.T) {
ssz_static.RunSSZStaticTests(t, "mainnet")
}

View File

@@ -0,0 +1,28 @@
load("@prysm//tools/go:def.bzl", "go_test")
go_test(
name = "go_default_test",
size = "small",
srcs = [
"effective_balance_updates_test.go",
"eth1_data_reset_test.go",
"historical_roots_update_test.go",
"inactivity_updates_test.go",
"justification_and_finalization_test.go",
"participation_flag_updates_test.go",
"randao_mixes_reset_test.go",
"registry_updates_test.go",
"rewards_and_penalties_test.go",
"slashings_reset_test.go",
"slashings_test.go",
],
data = glob(["*.yaml"]) + [
"@consensus_spec_tests_minimal//:test_data",
],
eth_network = "minimal",
tags = [
"minimal",
"spectest",
],
deps = ["//testing/spectest/shared/capella/epoch_processing:go_default_library"],
)

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMinimal_Capella_EpochProcessing_EffectiveBalanceUpdates(t *testing.T) {
epoch_processing.RunEffectiveBalanceUpdatesTests(t, "minimal")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMinimal_Capella_EpochProcessing_Eth1DataReset(t *testing.T) {
epoch_processing.RunEth1DataResetTests(t, "minimal")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMinimal_Capella_EpochProcessing_HistoricalRootsUpdate(t *testing.T) {
epoch_processing.RunHistoricalRootsUpdateTests(t, "minimal")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMinimal_Capella_EpochProcessing_InactivityUpdates(t *testing.T) {
epoch_processing.RunInactivityUpdatesTest(t, "minimal")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMinimal_Capella_EpochProcessing_JustificationAndFinalization(t *testing.T) {
epoch_processing.RunJustificationAndFinalizationTests(t, "minimal")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMinimal_Capella_EpochProcessing_ParticipationFlag(t *testing.T) {
epoch_processing.RunParticipationFlagUpdatesTests(t, "minimal")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMinimal_Capella_EpochProcessing_RandaoMixesReset(t *testing.T) {
epoch_processing.RunRandaoMixesResetTests(t, "minimal")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMinimal_Capella_EpochProcessing_ResetRegistryUpdates(t *testing.T) {
epoch_processing.RunRegistryUpdatesTests(t, "minimal")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMinimal_Capella_EpochProcessing_RewardsAndPenalties(t *testing.T) {
epoch_processing.RunRewardsAndPenaltiesTests(t, "minimal")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMinimal_Capella_EpochProcessing_SlashingsReset(t *testing.T) {
epoch_processing.RunSlashingsResetTests(t, "minimal")
}

View File

@@ -0,0 +1,11 @@
package epoch_processing
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/epoch_processing"
)
func TestMinimal_Capella_EpochProcessing_Slashings(t *testing.T) {
epoch_processing.RunSlashingsTests(t, "minimal")
}

View File

@@ -0,0 +1,17 @@
load("@prysm//tools/go:def.bzl", "go_test")
go_test(
name = "go_default_test",
size = "small",
srcs = ["finality_test.go"],
data = glob(["*.yaml"]) + [
"@consensus_spec_tests_minimal//:test_data",
],
eth_network = "minimal",
shard_count = 4,
tags = [
"minimal",
"spectest",
],
deps = ["//testing/spectest/shared/capella/finality:go_default_library"],
)

View File

@@ -0,0 +1,11 @@
package finality
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/finality"
)
func TestMinimal_Capella_Finality(t *testing.T) {
finality.RunFinalityTest(t, "minimal")
}

View File

@@ -0,0 +1,17 @@
load("@prysm//tools/go:def.bzl", "go_test")
go_test(
name = "go_default_test",
size = "small",
srcs = ["upgrade_to_capella_test.go"],
data = glob(["*.yaml"]) + [
"@consensus_spec_tests_minimal//:test_data",
],
eth_network = "minimal",
shard_count = 4,
tags = [
"minimal",
"spectest",
],
deps = ["//testing/spectest/shared/capella/fork:go_default_library"],
)

View File

@@ -0,0 +1,11 @@
package fork
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/fork"
)
func TestMinimal_Capella_UpgradeToCapella(t *testing.T) {
fork.RunUpgradeToCapella(t, "minimal")
}

View File

@@ -0,0 +1,21 @@
load("@prysm//tools/go:def.bzl", "go_test")
go_test(
name = "go_default_test",
size = "enormous",
timeout = "short",
srcs = ["forkchoice_test.go"],
data = glob(["*.yaml"]) + [
"@consensus_spec_tests_minimal//:test_data",
],
eth_network = "minimal",
tags = [
"minimal",
"spectest",
],
deps = [
"//config/features:go_default_library",
"//runtime/version:go_default_library",
"//testing/spectest/shared/common/forkchoice:go_default_library",
],
)

View File

@@ -0,0 +1,18 @@
package forkchoice
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/config/features"
"github.com/prysmaticlabs/prysm/v3/runtime/version"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/common/forkchoice"
)
func TestMinimal_Capella_Forkchoice(t *testing.T) {
resetCfg := features.InitWithReset(&features.Flags{
EnableDefensivePull: false,
DisablePullTips: true,
})
defer resetCfg()
forkchoice.Run(t, "minimal", version.Capella)
}

View File

@@ -0,0 +1,26 @@
load("@prysm//tools/go:def.bzl", "go_test")
go_test(
name = "go_default_test",
size = "small",
srcs = [
"attestation_test.go",
"attester_slashing_test.go",
"block_header_test.go",
"bls_to_execution_change_test.go",
"deposit_test.go",
"proposer_slashing_test.go",
"sync_committee_test.go",
"voluntary_exit_test.go",
"withdrawals_test.go",
],
data = glob(["*.yaml"]) + [
"@consensus_spec_tests_minimal//:test_data",
],
eth_network = "minimal",
tags = [
"minimal",
"spectest",
],
deps = ["//testing/spectest/shared/capella/operations:go_default_library"],
)

View File

@@ -0,0 +1,11 @@
package operations
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/operations"
)
func TestMinimal_Capella_Operations_Attestation(t *testing.T) {
operations.RunAttestationTest(t, "minimal")
}

View File

@@ -0,0 +1,11 @@
package operations
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/operations"
)
func TestMinimal_Capella_Operations_AttesterSlashing(t *testing.T) {
operations.RunAttesterSlashingTest(t, "minimal")
}

View File

@@ -0,0 +1,11 @@
package operations
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/operations"
)
func TestMinimal_Capella_Operations_BlockHeader(t *testing.T) {
operations.RunBlockHeaderTest(t, "minimal")
}

View File

@@ -0,0 +1,11 @@
package operations
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/operations"
)
func TestMinimal_Capella_Operations_BLSToExecutionChange(t *testing.T) {
operations.RunBLSToExecutionChangeTest(t, "minimal")
}

View File

@@ -0,0 +1,11 @@
package operations
import (
"testing"
"github.com/prysmaticlabs/prysm/v3/testing/spectest/shared/capella/operations"
)
func TestMinimal_Capella_Operations_Deposit(t *testing.T) {
operations.RunDepositTest(t, "minimal")
}

Some files were not shown because too many files have changed in this diff Show More