Compare commits

..

4 Commits

Author SHA1 Message Date
james-prysm
b64c7d57a1 Merge branch 'develop' into simplify-parse-beacon-block 2026-02-03 13:49:05 -08:00
james-prysm
e5e0bf7426 changelog 2026-02-03 15:47:37 -06:00
Aarsh Shah
75895c1e0b fix: Set Beacon Node Options after reading the config file (#16320)
**What type of PR is this?**
Bug fix

**What does this PR do? Why is it needed?**
This PR ensures that we set the beacon node options AFTER reading the
config file (if one is given to override the defaults).

**Which issues(s) does this PR fix?**
It fixes the issue that Barnabas reported around the
"MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS" override not being
respected (and potentially other issues resulting from setting the
options before reading the config).

Fixes #

**Other notes for review**

**Acknowledgements**

- [x] I have read
[CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [x] I have included a uniquely named [changelog fragment
file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
- [x] I have added a description with sufficient context for reviewers
to understand this PR.
- [x] I have tested that my changes work as expected and I added a
testing plan to the PR description (if applicable).
2026-02-03 16:51:01 +00:00
james-prysm
7bcbc1f8f4 refactor 2026-01-30 15:35:27 -06:00
15 changed files with 345 additions and 627 deletions

View File

@@ -85,7 +85,6 @@ go_library(
"//consensus-types/primitives:go_default_library",
"//crypto/bls:go_default_library",
"//encoding/bytesutil:go_default_library",
"//io/logs:go_default_library",
"//math:go_default_library",
"//monitoring/tracing:go_default_library",
"//monitoring/tracing/trace:go_default_library",

View File

@@ -10,7 +10,6 @@ import (
consensus_types "github.com/OffchainLabs/prysm/v7/consensus-types"
"github.com/OffchainLabs/prysm/v7/consensus-types/interfaces"
"github.com/OffchainLabs/prysm/v7/encoding/bytesutil"
"github.com/OffchainLabs/prysm/v7/io/logs"
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v7/runtime/version"
prysmTime "github.com/OffchainLabs/prysm/v7/time"
@@ -90,39 +89,34 @@ func logBlockSyncStatus(block interfaces.ReadOnlyBeaconBlock, blockRoot [32]byte
if err != nil {
return err
}
parentRoot := block.ParentRoot()
lessFields := logrus.Fields{
"slot": block.Slot(),
"block": fmt.Sprintf("0x%s...", hex.EncodeToString(blockRoot[:])[:8]),
"finalizedEpoch": finalized.Epoch,
"finalizedRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(finalized.Root)[:8]),
"epoch": slots.ToEpoch(block.Slot()),
}
moreFields := logrus.Fields{
"slot": block.Slot(),
"slotInEpoch": block.Slot() % params.BeaconConfig().SlotsPerEpoch,
"block": fmt.Sprintf("0x%s...", hex.EncodeToString(blockRoot[:])[:8]),
"epoch": slots.ToEpoch(block.Slot()),
"justifiedEpoch": justified.Epoch,
"justifiedRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(justified.Root)[:8]),
"finalizedEpoch": finalized.Epoch,
"finalizedRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(finalized.Root)[:8]),
"parentRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(parentRoot[:])[:8]),
"version": version.String(block.Version()),
"sinceSlotStartTime": prysmTime.Now().Sub(startTime),
"chainServiceProcessedTime": prysmTime.Now().Sub(receivedTime) - daWaitedTime,
"dataAvailabilityWaitedTime": daWaitedTime,
}
level := logs.PackageVerbosity("beacon-chain/blockchain")
level := log.Logger.GetLevel()
if level >= logrus.DebugLevel {
log.WithFields(moreFields).Info("Synced new block")
parentRoot := block.ParentRoot()
lf := logrus.Fields{
"slot": block.Slot(),
"slotInEpoch": block.Slot() % params.BeaconConfig().SlotsPerEpoch,
"block": fmt.Sprintf("0x%s...", hex.EncodeToString(blockRoot[:])[:8]),
"epoch": slots.ToEpoch(block.Slot()),
"justifiedEpoch": justified.Epoch,
"justifiedRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(justified.Root)[:8]),
"finalizedEpoch": finalized.Epoch,
"finalizedRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(finalized.Root)[:8]),
"parentRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(parentRoot[:])[:8]),
"version": version.String(block.Version()),
"sinceSlotStartTime": prysmTime.Now().Sub(startTime),
"chainServiceProcessedTime": prysmTime.Now().Sub(receivedTime) - daWaitedTime,
"dataAvailabilityWaitedTime": daWaitedTime,
}
log.WithFields(lf).Debug("Synced new block")
} else {
log.WithFields(lessFields).WithField(logs.LogTargetField, logs.LogTargetUser).Info("Synced new block")
log.WithFields(moreFields).WithField(logs.LogTargetField, logs.LogTargetEphemeral).Info("Synced new block")
log.WithFields(logrus.Fields{
"slot": block.Slot(),
"block": fmt.Sprintf("0x%s...", hex.EncodeToString(blockRoot[:])[:8]),
"finalizedEpoch": finalized.Epoch,
"finalizedRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(finalized.Root)[:8]),
"epoch": slots.ToEpoch(block.Slot()),
}).Info("Synced new block")
}
return nil
}

View File

@@ -134,10 +134,20 @@ type BeaconNode struct {
// New creates a new node instance, sets up configuration options, and registers
// every required service to the node.
func New(cliCtx *cli.Context, cancel context.CancelFunc, opts ...Option) (*BeaconNode, error) {
func New(cliCtx *cli.Context, cancel context.CancelFunc, optFuncs []func(*cli.Context) ([]Option, error), opts ...Option) (*BeaconNode, error) {
if err := configureBeacon(cliCtx); err != nil {
return nil, errors.Wrap(err, "could not set beacon configuration options")
}
for _, of := range optFuncs {
ofo, err := of(cliCtx)
if err != nil {
return nil, err
}
if ofo != nil {
opts = append(opts, ofo...)
}
}
ctx := cliCtx.Context
beacon := &BeaconNode{

View File

@@ -59,7 +59,7 @@ func TestNodeClose_OK(t *testing.T) {
WithDataColumnStorage(filesystem.NewEphemeralDataColumnStorage(t)),
}
node, err := New(ctx, cancel, options...)
node, err := New(ctx, cancel, nil, options...)
require.NoError(t, err)
node.Close()
@@ -87,7 +87,7 @@ func TestNodeStart_Ok(t *testing.T) {
WithDataColumnStorage(filesystem.NewEphemeralDataColumnStorage(t)),
}
node, err := New(ctx, cancel, options...)
node, err := New(ctx, cancel, nil, options...)
require.NoError(t, err)
require.NotNil(t, node.lcStore)
node.services = &runtime.ServiceRegistry{}
@@ -116,7 +116,7 @@ func TestNodeStart_SyncChecker(t *testing.T) {
WithDataColumnStorage(filesystem.NewEphemeralDataColumnStorage(t)),
}
node, err := New(ctx, cancel, options...)
node, err := New(ctx, cancel, nil, options...)
require.NoError(t, err)
go func() {
node.Start()
@@ -151,7 +151,7 @@ func TestClearDB(t *testing.T) {
WithDataColumnStorage(filesystem.NewEphemeralDataColumnStorage(t)),
}
_, err = New(context, cancel, options...)
_, err = New(context, cancel, nil, options...)
require.NoError(t, err)
require.LogsContain(t, hook, "Removing database")
}

View File

@@ -0,0 +1,3 @@
### Added
- Set beacon node options after reading the config file.

View File

@@ -1,3 +0,0 @@
### Changed
- Fixed the logging issue described in #16314.

View File

@@ -0,0 +1,3 @@
### Ignored
- improving maintainability and deduplication on get and post block parsing.

View File

@@ -188,8 +188,8 @@ func before(ctx *cli.Context) error {
return errors.Wrap(err, "failed to parse log vmodule")
}
// set the global logging level and data
logs.SetLoggingLevelAndData(verbosityLevel, vmodule, maxLevel, ctx.Bool(flags.DisableEphemeralLogFile.Name))
// set the global logging level to allow for the highest verbosity requested
logs.SetLoggingLevel(max(verbosityLevel, maxLevel))
format := ctx.String(cmd.LogFormat.Name)
switch format {
@@ -210,7 +210,6 @@ func before(ctx *cli.Context) error {
Formatter: formatter,
Writer: os.Stderr,
AllowedLevels: logrus.AllLevels[:max(verbosityLevel, maxLevel)+1],
Identifier: logs.LogTargetUser,
})
case "fluentd":
f := joonix.NewFormatter()
@@ -368,17 +367,8 @@ func startNode(ctx *cli.Context, cancel context.CancelFunc) error {
backfill.BeaconNodeOptions,
das.BeaconNodeOptions,
}
for _, of := range optFuncs {
ofo, err := of(ctx)
if err != nil {
return err
}
if ofo != nil {
opts = append(opts, ofo...)
}
}
beacon, err := node.New(ctx, cancel, opts...)
beacon, err := node.New(ctx, cancel, optFuncs, opts...)
if err != nil {
return fmt.Errorf("unable to start beacon node: %w", err)
}

View File

@@ -164,8 +164,8 @@ func main() {
return errors.Wrap(err, "failed to parse log vmodule")
}
// set the global logging level and data
logs.SetLoggingLevelAndData(verbosityLevel, vmodule, maxLevel, ctx.Bool(flags.DisableEphemeralLogFile.Name))
// set the global logging level to allow for the highest verbosity requested
logs.SetLoggingLevel(max(maxLevel, verbosityLevel))
logFileName := ctx.String(cmd.LogFileName.Name)
@@ -188,7 +188,6 @@ func main() {
Formatter: formatter,
Writer: os.Stderr,
AllowedLevels: logrus.AllLevels[:max(verbosityLevel, maxLevel)+1],
Identifier: logs.LogTargetUser,
})
case "fluentd":
f := joonix.NewFormatter()

View File

@@ -1,7 +1,6 @@
package logs
import (
"fmt"
"io"
"github.com/sirupsen/logrus"
@@ -11,7 +10,6 @@ type WriterHook struct {
AllowedLevels []logrus.Level
Writer io.Writer
Formatter logrus.Formatter
Identifier string
}
func (hook *WriterHook) Levels() []logrus.Level {
@@ -22,11 +20,6 @@ func (hook *WriterHook) Levels() []logrus.Level {
}
func (hook *WriterHook) Fire(entry *logrus.Entry) error {
val, ok := entry.Data[LogTargetField]
if ok && fmt.Sprint(val) != hook.Identifier {
return nil
}
line, err := hook.Formatter.Format(entry)
if err != nil {
return err

View File

@@ -17,43 +17,11 @@ import (
"gopkg.in/natefinch/lumberjack.v2"
)
var (
userVerbosity = logrus.InfoLevel
vmodule = make(map[string]logrus.Level)
)
var ephemeralLogFileVerbosity = logrus.DebugLevel
const (
ephemeralLogFileVerbosity = logrus.DebugLevel
LogTargetField = "log_target"
LogTargetEphemeral = "ephemeral"
LogTargetUser = "user"
)
// SetLoggingLevelAndData sets the base logging level for logrus.
func SetLoggingLevelAndData(baseVerbosity logrus.Level, vmoduleMap map[string]logrus.Level, maxVmoduleLevel logrus.Level, disableEphemeral bool) {
userVerbosity = baseVerbosity
vmodule = vmoduleMap
globalLevel := max(baseVerbosity, maxVmoduleLevel)
if !disableEphemeral {
globalLevel = max(globalLevel, ephemeralLogFileVerbosity)
}
logrus.SetLevel(globalLevel)
}
// PackageVerbosity returns the verbosity of a given package.
func PackageVerbosity(packagePath string) logrus.Level {
bestLen := 0
bestLevel := userVerbosity
for k, v := range vmodule {
if k == packagePath || strings.HasPrefix(packagePath, k+"/") {
if len(k) > bestLen {
bestLen = len(k)
bestLevel = v
}
}
}
return bestLevel
// SetLoggingLevel sets the base logging level for logrus.
func SetLoggingLevel(lvl logrus.Level) {
logrus.SetLevel(max(lvl, ephemeralLogFileVerbosity))
}
func addLogWriter(w io.Writer) {
@@ -100,7 +68,6 @@ func ConfigurePersistentLogging(logFileName string, format string, lvl logrus.Le
Formatter: formatter,
Writer: f,
AllowedLevels: logrus.AllLevels[:max(lvl, maxVmoduleLevel)+1],
Identifier: LogTargetUser,
})
logrus.Debug("File logging initialized")
@@ -134,7 +101,6 @@ func ConfigureEphemeralLogFile(datadirPath string, app string) error {
Formatter: formatter,
Writer: debugWriter,
AllowedLevels: logrus.AllLevels[:ephemeralLogFileVerbosity+1],
Identifier: LogTargetEphemeral,
})
logrus.WithField("path", logFilePath).Debug("Ephemeral log file initialized")

View File

@@ -334,7 +334,7 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *logrus.Entry, keys
_, err = fmt.Fprintf(b, "%s %s%s "+messageFormat, colorScheme.TimestampColor(timestamp), level, prefix, message)
}
for _, k := range keys {
if k != "package" && k != "log_target" {
if k != "package" {
v := entry.Data[k]
format := "%+v"

View File

@@ -51,6 +51,7 @@ go_library(
"//consensus-types/primitives:go_default_library",
"//consensus-types/validator:go_default_library",
"//encoding/bytesutil:go_default_library",
"//encoding/ssz:go_default_library",
"//monitoring/tracing/trace:go_default_library",
"//network/httputil:go_default_library",
"//proto/engine/v1:go_default_library",

View File

@@ -55,114 +55,153 @@ func (c *beaconApiValidatorClient) beaconBlock(ctx context.Context, slot primiti
}
}
// sszBlockCodec defines SSZ unmarshalers for a fork's block and blinded block types.
type sszBlockCodec struct {
unmarshalBlock func([]byte) (*ethpb.GenericBeaconBlock, error)
unmarshalBlinded func([]byte) (*ethpb.GenericBeaconBlock, error) // nil for Phase0/Altair
}
type sszCodecEntry struct {
minVersion int
codec sszBlockCodec
}
// sszCodecs is ordered descending by version so that unknown future versions
// fall through to the latest known fork (matching the original if-cascade).
var sszCodecs = []sszCodecEntry{
{
minVersion: version.Fulu,
codec: sszBlockCodec{
unmarshalBlock: func(data []byte) (*ethpb.GenericBeaconBlock, error) {
block := &ethpb.BeaconBlockContentsFulu{}
if err := block.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Fulu{Fulu: block}}, nil
},
unmarshalBlinded: func(data []byte) (*ethpb.GenericBeaconBlock, error) {
blindedBlock := &ethpb.BlindedBeaconBlockFulu{}
if err := blindedBlock.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedFulu{BlindedFulu: blindedBlock}, IsBlinded: true}, nil
},
},
},
{
minVersion: version.Electra,
codec: sszBlockCodec{
unmarshalBlock: func(data []byte) (*ethpb.GenericBeaconBlock, error) {
block := &ethpb.BeaconBlockContentsElectra{}
if err := block.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Electra{Electra: block}}, nil
},
unmarshalBlinded: func(data []byte) (*ethpb.GenericBeaconBlock, error) {
blindedBlock := &ethpb.BlindedBeaconBlockElectra{}
if err := blindedBlock.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedElectra{BlindedElectra: blindedBlock}, IsBlinded: true}, nil
},
},
},
{
minVersion: version.Deneb,
codec: sszBlockCodec{
unmarshalBlock: func(data []byte) (*ethpb.GenericBeaconBlock, error) {
block := &ethpb.BeaconBlockContentsDeneb{}
if err := block.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Deneb{Deneb: block}}, nil
},
unmarshalBlinded: func(data []byte) (*ethpb.GenericBeaconBlock, error) {
blindedBlock := &ethpb.BlindedBeaconBlockDeneb{}
if err := blindedBlock.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedDeneb{BlindedDeneb: blindedBlock}, IsBlinded: true}, nil
},
},
},
{
minVersion: version.Capella,
codec: sszBlockCodec{
unmarshalBlock: func(data []byte) (*ethpb.GenericBeaconBlock, error) {
block := &ethpb.BeaconBlockCapella{}
if err := block.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Capella{Capella: block}}, nil
},
unmarshalBlinded: func(data []byte) (*ethpb.GenericBeaconBlock, error) {
blindedBlock := &ethpb.BlindedBeaconBlockCapella{}
if err := blindedBlock.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedCapella{BlindedCapella: blindedBlock}, IsBlinded: true}, nil
},
},
},
{
minVersion: version.Bellatrix,
codec: sszBlockCodec{
unmarshalBlock: func(data []byte) (*ethpb.GenericBeaconBlock, error) {
block := &ethpb.BeaconBlockBellatrix{}
if err := block.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Bellatrix{Bellatrix: block}}, nil
},
unmarshalBlinded: func(data []byte) (*ethpb.GenericBeaconBlock, error) {
blindedBlock := &ethpb.BlindedBeaconBlockBellatrix{}
if err := blindedBlock.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedBellatrix{BlindedBellatrix: blindedBlock}, IsBlinded: true}, nil
},
},
},
{
minVersion: version.Altair,
codec: sszBlockCodec{
unmarshalBlock: func(data []byte) (*ethpb.GenericBeaconBlock, error) {
block := &ethpb.BeaconBlockAltair{}
if err := block.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Altair{Altair: block}}, nil
},
},
},
{
minVersion: version.Phase0,
codec: sszBlockCodec{
unmarshalBlock: func(data []byte) (*ethpb.GenericBeaconBlock, error) {
block := &ethpb.BeaconBlock{}
if err := block.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Phase0{Phase0: block}}, nil
},
},
},
}
func processBlockSSZResponse(ver int, data []byte, isBlinded bool) (*ethpb.GenericBeaconBlock, error) {
if ver >= version.Fulu {
return processBlockSSZResponseFulu(data, isBlinded)
}
if ver >= version.Electra {
return processBlockSSZResponseElectra(data, isBlinded)
}
if ver >= version.Deneb {
return processBlockSSZResponseDeneb(data, isBlinded)
}
if ver >= version.Capella {
return processBlockSSZResponseCapella(data, isBlinded)
}
if ver >= version.Bellatrix {
return processBlockSSZResponseBellatrix(data, isBlinded)
}
if ver >= version.Altair {
block := &ethpb.BeaconBlockAltair{}
if err := block.UnmarshalSSZ(data); err != nil {
return nil, err
for _, entry := range sszCodecs {
if ver >= entry.minVersion {
if isBlinded && entry.codec.unmarshalBlinded != nil {
return entry.codec.unmarshalBlinded(data)
}
return entry.codec.unmarshalBlock(data)
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Altair{Altair: block}}, nil
}
if ver >= version.Phase0 {
block := &ethpb.BeaconBlock{}
if err := block.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Phase0{Phase0: block}}, nil
}
return nil, fmt.Errorf("unsupported block version %s", version.String(ver))
}
func processBlockSSZResponseFulu(data []byte, isBlinded bool) (*ethpb.GenericBeaconBlock, error) {
if isBlinded {
blindedBlock := &ethpb.BlindedBeaconBlockFulu{}
if err := blindedBlock.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedFulu{BlindedFulu: blindedBlock}, IsBlinded: true}, nil
}
block := &ethpb.BeaconBlockContentsFulu{}
if err := block.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Fulu{Fulu: block}}, nil
}
func processBlockSSZResponseElectra(data []byte, isBlinded bool) (*ethpb.GenericBeaconBlock, error) {
if isBlinded {
blindedBlock := &ethpb.BlindedBeaconBlockElectra{}
if err := blindedBlock.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedElectra{BlindedElectra: blindedBlock}, IsBlinded: true}, nil
}
block := &ethpb.BeaconBlockContentsElectra{}
if err := block.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Electra{Electra: block}}, nil
}
func processBlockSSZResponseDeneb(data []byte, isBlinded bool) (*ethpb.GenericBeaconBlock, error) {
if isBlinded {
blindedBlock := &ethpb.BlindedBeaconBlockDeneb{}
if err := blindedBlock.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedDeneb{BlindedDeneb: blindedBlock}, IsBlinded: true}, nil
}
block := &ethpb.BeaconBlockContentsDeneb{}
if err := block.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Deneb{Deneb: block}}, nil
}
func processBlockSSZResponseCapella(data []byte, isBlinded bool) (*ethpb.GenericBeaconBlock, error) {
if isBlinded {
blindedBlock := &ethpb.BlindedBeaconBlockCapella{}
if err := blindedBlock.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedCapella{BlindedCapella: blindedBlock}, IsBlinded: true}, nil
}
block := &ethpb.BeaconBlockCapella{}
if err := block.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Capella{Capella: block}}, nil
}
func processBlockSSZResponseBellatrix(data []byte, isBlinded bool) (*ethpb.GenericBeaconBlock, error) {
if isBlinded {
blindedBlock := &ethpb.BlindedBeaconBlockBellatrix{}
if err := blindedBlock.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_BlindedBellatrix{BlindedBellatrix: blindedBlock}, IsBlinded: true}, nil
}
block := &ethpb.BeaconBlockBellatrix{}
if err := block.UnmarshalSSZ(data); err != nil {
return nil, err
}
return &ethpb.GenericBeaconBlock{Block: &ethpb.GenericBeaconBlock_Bellatrix{Bellatrix: block}}, nil
}
func convertBlockToGeneric(decoder *json.Decoder, dest ethpb.GenericConverter, version string, isBlinded bool) (*ethpb.GenericBeaconBlock, error) {
typeName := version
if isBlinded {
@@ -180,69 +219,52 @@ func convertBlockToGeneric(decoder *json.Decoder, dest ethpb.GenericConverter, v
return genericBlock, nil
}
// jsonBlockTypes defines factory functions for creating block and blinded block structs for JSON decoding.
type jsonBlockTypes struct {
newBlock func() ethpb.GenericConverter
newBlinded func() ethpb.GenericConverter // nil for Phase0/Altair
}
var jsonBlockFactories = map[string]jsonBlockTypes{
version.String(version.Phase0): {
newBlock: func() ethpb.GenericConverter { return &structs.BeaconBlock{} },
},
version.String(version.Altair): {
newBlock: func() ethpb.GenericConverter { return &structs.BeaconBlockAltair{} },
},
version.String(version.Bellatrix): {
newBlock: func() ethpb.GenericConverter { return &structs.BeaconBlockBellatrix{} },
newBlinded: func() ethpb.GenericConverter { return &structs.BlindedBeaconBlockBellatrix{} },
},
version.String(version.Capella): {
newBlock: func() ethpb.GenericConverter { return &structs.BeaconBlockCapella{} },
newBlinded: func() ethpb.GenericConverter { return &structs.BlindedBeaconBlockCapella{} },
},
version.String(version.Deneb): {
newBlock: func() ethpb.GenericConverter { return &structs.BeaconBlockContentsDeneb{} },
newBlinded: func() ethpb.GenericConverter { return &structs.BlindedBeaconBlockDeneb{} },
},
version.String(version.Electra): {
newBlock: func() ethpb.GenericConverter { return &structs.BeaconBlockContentsElectra{} },
newBlinded: func() ethpb.GenericConverter { return &structs.BlindedBeaconBlockElectra{} },
},
version.String(version.Fulu): {
newBlock: func() ethpb.GenericConverter { return &structs.BeaconBlockContentsFulu{} },
newBlinded: func() ethpb.GenericConverter { return &structs.BlindedBeaconBlockFulu{} },
},
}
func processBlockJSONResponse(ver string, isBlinded bool, decoder *json.Decoder) (*ethpb.GenericBeaconBlock, error) {
if decoder == nil {
return nil, errors.New("no produce block json decoder found")
}
switch ver {
case version.String(version.Phase0):
return convertBlockToGeneric(decoder, &structs.BeaconBlock{}, version.String(version.Phase0), false)
case version.String(version.Altair):
return convertBlockToGeneric(decoder, &structs.BeaconBlockAltair{}, "altair", false)
case version.String(version.Bellatrix):
return processBellatrixBlock(decoder, isBlinded)
case version.String(version.Capella):
return processCapellaBlock(decoder, isBlinded)
case version.String(version.Deneb):
return processDenebBlock(decoder, isBlinded)
case version.String(version.Electra):
return processElectraBlock(decoder, isBlinded)
case version.String(version.Fulu):
return processFuluBlock(decoder, isBlinded)
default:
factory, ok := jsonBlockFactories[ver]
if !ok {
return nil, errors.Errorf("unsupported consensus version `%s`", ver)
}
}
func processBellatrixBlock(decoder *json.Decoder, isBlinded bool) (*ethpb.GenericBeaconBlock, error) {
if isBlinded {
return convertBlockToGeneric(decoder, &structs.BlindedBeaconBlockBellatrix{}, "bellatrix", true)
if isBlinded && factory.newBlinded != nil {
return convertBlockToGeneric(decoder, factory.newBlinded(), ver, true)
}
return convertBlockToGeneric(decoder, &structs.BeaconBlockBellatrix{}, "bellatrix", false)
}
func processCapellaBlock(decoder *json.Decoder, isBlinded bool) (*ethpb.GenericBeaconBlock, error) {
if isBlinded {
return convertBlockToGeneric(decoder, &structs.BlindedBeaconBlockCapella{}, "capella", true)
}
return convertBlockToGeneric(decoder, &structs.BeaconBlockCapella{}, "capella", false)
}
func processDenebBlock(decoder *json.Decoder, isBlinded bool) (*ethpb.GenericBeaconBlock, error) {
if isBlinded {
return convertBlockToGeneric(decoder, &structs.BlindedBeaconBlockDeneb{}, "deneb", true)
}
return convertBlockToGeneric(decoder, &structs.BeaconBlockContentsDeneb{}, "deneb", false)
}
func processElectraBlock(decoder *json.Decoder, isBlinded bool) (*ethpb.GenericBeaconBlock, error) {
if isBlinded {
return convertBlockToGeneric(decoder, &structs.BlindedBeaconBlockElectra{}, "electra", true)
}
return convertBlockToGeneric(decoder, &structs.BeaconBlockContentsElectra{}, "electra", false)
}
func processFuluBlock(decoder *json.Decoder, isBlinded bool) (*ethpb.GenericBeaconBlock, error) {
if isBlinded {
return convertBlockToGeneric(decoder, &structs.BlindedBeaconBlockFulu{}, "fulu", true)
}
return convertBlockToGeneric(decoder, &structs.BeaconBlockContentsFulu{}, "fulu", false)
return convertBlockToGeneric(decoder, factory.newBlock(), ver, false)
}

View File

@@ -7,6 +7,7 @@ import (
"net/http"
"github.com/OffchainLabs/prysm/v7/api/server/structs"
"github.com/OffchainLabs/prysm/v7/encoding/ssz"
"github.com/OffchainLabs/prysm/v7/network/httputil"
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
"github.com/pkg/errors"
@@ -21,34 +22,128 @@ type blockProcessingResult struct {
marshalJSON func() ([]byte, error)
}
type sszMarshaler interface {
MarshalSSZ() ([]byte, error)
}
func buildBlockResult(
versionName string,
blinded bool,
sszObj sszMarshaler,
rootObj ssz.Hashable,
jsonFn func() ([]byte, error),
) (*blockProcessingResult, error) {
beaconBlockRoot, err := rootObj.HashTreeRoot()
if err != nil {
return nil, errors.Wrapf(err, "failed to compute block root for %s beacon block", versionName)
}
ssz, err := sszObj.MarshalSSZ()
if err != nil {
return nil, errors.Wrapf(err, "failed to serialize %s beacon block", versionName)
}
return &blockProcessingResult{
consensusVersion: versionName,
blinded: blinded,
beaconBlockRoot: beaconBlockRoot,
marshalledSSZ: ssz,
marshalJSON: jsonFn,
}, nil
}
func (c *beaconApiValidatorClient) proposeBeaconBlock(ctx context.Context, in *ethpb.GenericSignedBeaconBlock) (*ethpb.ProposeResponse, error) {
var res *blockProcessingResult
var err error
switch blockType := in.Block.(type) {
case *ethpb.GenericSignedBeaconBlock_Phase0:
res, err = handlePhase0Block(blockType)
res, err = buildBlockResult("phase0", false, blockType.Phase0, blockType.Phase0.Block, func() ([]byte, error) {
return json.Marshal(structs.SignedBeaconBlockPhase0FromConsensus(blockType.Phase0))
})
case *ethpb.GenericSignedBeaconBlock_Altair:
res, err = handleAltairBlock(blockType)
res, err = buildBlockResult("altair", false, blockType.Altair, blockType.Altair.Block, func() ([]byte, error) {
return json.Marshal(structs.SignedBeaconBlockAltairFromConsensus(blockType.Altair))
})
case *ethpb.GenericSignedBeaconBlock_Bellatrix:
res, err = handleBellatrixBlock(blockType)
res, err = buildBlockResult("bellatrix", false, blockType.Bellatrix, blockType.Bellatrix.Block, func() ([]byte, error) {
signedBlock, err := structs.SignedBeaconBlockBellatrixFromConsensus(blockType.Bellatrix)
if err != nil {
return nil, errors.Wrap(err, "failed to convert bellatrix beacon block")
}
return json.Marshal(signedBlock)
})
case *ethpb.GenericSignedBeaconBlock_BlindedBellatrix:
res, err = handleBlindedBellatrixBlock(blockType)
res, err = buildBlockResult("bellatrix", true, blockType.BlindedBellatrix, blockType.BlindedBellatrix.Block, func() ([]byte, error) {
signedBlock, err := structs.SignedBlindedBeaconBlockBellatrixFromConsensus(blockType.BlindedBellatrix)
if err != nil {
return nil, errors.Wrap(err, "failed to convert blinded bellatrix beacon block")
}
return json.Marshal(signedBlock)
})
case *ethpb.GenericSignedBeaconBlock_Capella:
res, err = handleCapellaBlock(blockType)
res, err = buildBlockResult("capella", false, blockType.Capella, blockType.Capella.Block, func() ([]byte, error) {
signedBlock, err := structs.SignedBeaconBlockCapellaFromConsensus(blockType.Capella)
if err != nil {
return nil, errors.Wrap(err, "failed to convert capella beacon block")
}
return json.Marshal(signedBlock)
})
case *ethpb.GenericSignedBeaconBlock_BlindedCapella:
res, err = handleBlindedCapellaBlock(blockType)
res, err = buildBlockResult("capella", true, blockType.BlindedCapella, blockType.BlindedCapella.Block, func() ([]byte, error) {
signedBlock, err := structs.SignedBlindedBeaconBlockCapellaFromConsensus(blockType.BlindedCapella)
if err != nil {
return nil, errors.Wrap(err, "failed to convert blinded capella beacon block")
}
return json.Marshal(signedBlock)
})
case *ethpb.GenericSignedBeaconBlock_Deneb:
res, err = handleDenebBlockContents(blockType)
res, err = buildBlockResult("deneb", false, blockType.Deneb, blockType.Deneb.Block, func() ([]byte, error) {
signedBlock, err := structs.SignedBeaconBlockContentsDenebFromConsensus(blockType.Deneb)
if err != nil {
return nil, errors.Wrap(err, "failed to convert deneb beacon block contents")
}
return json.Marshal(signedBlock)
})
case *ethpb.GenericSignedBeaconBlock_BlindedDeneb:
res, err = handleBlindedDenebBlock(blockType)
res, err = buildBlockResult("deneb", true, blockType.BlindedDeneb, blockType.BlindedDeneb, func() ([]byte, error) {
signedBlock, err := structs.SignedBlindedBeaconBlockDenebFromConsensus(blockType.BlindedDeneb)
if err != nil {
return nil, errors.Wrap(err, "failed to convert deneb blinded beacon block")
}
return json.Marshal(signedBlock)
})
case *ethpb.GenericSignedBeaconBlock_Electra:
res, err = handleElectraBlockContents(blockType)
res, err = buildBlockResult("electra", false, blockType.Electra, blockType.Electra.Block, func() ([]byte, error) {
signedBlock, err := structs.SignedBeaconBlockContentsElectraFromConsensus(blockType.Electra)
if err != nil {
return nil, errors.Wrap(err, "failed to convert electra beacon block contents")
}
return json.Marshal(signedBlock)
})
case *ethpb.GenericSignedBeaconBlock_BlindedElectra:
res, err = handleBlindedElectraBlock(blockType)
res, err = buildBlockResult("electra", true, blockType.BlindedElectra, blockType.BlindedElectra, func() ([]byte, error) {
signedBlock, err := structs.SignedBlindedBeaconBlockElectraFromConsensus(blockType.BlindedElectra)
if err != nil {
return nil, errors.Wrap(err, "failed to convert electra blinded beacon block")
}
return json.Marshal(signedBlock)
})
case *ethpb.GenericSignedBeaconBlock_Fulu:
res, err = handleFuluBlockContents(blockType)
res, err = buildBlockResult("fulu", false, blockType.Fulu, blockType.Fulu.Block, func() ([]byte, error) {
signedBlock, err := structs.SignedBeaconBlockContentsFuluFromConsensus(blockType.Fulu)
if err != nil {
return nil, errors.Wrap(err, "failed to convert fulu beacon block contents")
}
return json.Marshal(signedBlock)
})
case *ethpb.GenericSignedBeaconBlock_BlindedFulu:
res, err = handleBlindedFuluBlock(blockType)
res, err = buildBlockResult("fulu", true, blockType.BlindedFulu, blockType.BlindedFulu, func() ([]byte, error) {
signedBlock, err := structs.SignedBlindedBeaconBlockFuluFromConsensus(blockType.BlindedFulu)
if err != nil {
return nil, errors.Wrap(err, "failed to convert fulu blinded beacon block")
}
return json.Marshal(signedBlock)
})
default:
return nil, errors.Errorf("unsupported block type %T", in.Block)
}
@@ -116,357 +211,3 @@ func (c *beaconApiValidatorClient) proposeBeaconBlock(ctx context.Context, in *e
return &ethpb.ProposeResponse{BlockRoot: res.beaconBlockRoot[:]}, nil
}
func handlePhase0Block(block *ethpb.GenericSignedBeaconBlock_Phase0) (*blockProcessingResult, error) {
var res blockProcessingResult
res.consensusVersion = "phase0"
res.blinded = false
beaconBlockRoot, err := block.Phase0.Block.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to compute block root for phase0 beacon block")
}
res.beaconBlockRoot = beaconBlockRoot
// Marshal SSZ
ssz, err := block.Phase0.MarshalSSZ()
if err != nil {
return nil, errors.Wrap(err, "failed to serialize block for phase0 beacon block")
}
res.marshalledSSZ = ssz
// Set up JSON marshalling function for fallback
res.marshalJSON = func() ([]byte, error) {
signedBlock := structs.SignedBeaconBlockPhase0FromConsensus(block.Phase0)
return json.Marshal(signedBlock)
}
return &res, nil
}
func handleAltairBlock(block *ethpb.GenericSignedBeaconBlock_Altair) (*blockProcessingResult, error) {
var res blockProcessingResult
res.consensusVersion = "altair"
res.blinded = false
beaconBlockRoot, err := block.Altair.Block.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to compute block root for altair beacon block")
}
res.beaconBlockRoot = beaconBlockRoot
// Marshal SSZ
ssz, err := block.Altair.MarshalSSZ()
if err != nil {
return nil, errors.Wrap(err, "failed to serialize block for altair beacon block")
}
res.marshalledSSZ = ssz
// Set up JSON marshalling function for fallback
res.marshalJSON = func() ([]byte, error) {
signedBlock := structs.SignedBeaconBlockAltairFromConsensus(block.Altair)
return json.Marshal(signedBlock)
}
return &res, nil
}
func handleBellatrixBlock(block *ethpb.GenericSignedBeaconBlock_Bellatrix) (*blockProcessingResult, error) {
var res blockProcessingResult
res.consensusVersion = "bellatrix"
res.blinded = false
beaconBlockRoot, err := block.Bellatrix.Block.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to compute block root for bellatrix beacon block")
}
res.beaconBlockRoot = beaconBlockRoot
// Marshal SSZ
ssz, err := block.Bellatrix.MarshalSSZ()
if err != nil {
return nil, errors.Wrap(err, "failed to serialize block for bellatrix beacon block")
}
res.marshalledSSZ = ssz
// Set up JSON marshalling function for fallback
res.marshalJSON = func() ([]byte, error) {
signedBlock, err := structs.SignedBeaconBlockBellatrixFromConsensus(block.Bellatrix)
if err != nil {
return nil, errors.Wrap(err, "failed to convert bellatrix beacon block")
}
return json.Marshal(signedBlock)
}
return &res, nil
}
func handleBlindedBellatrixBlock(block *ethpb.GenericSignedBeaconBlock_BlindedBellatrix) (*blockProcessingResult, error) {
var res blockProcessingResult
res.consensusVersion = "bellatrix"
res.blinded = true
beaconBlockRoot, err := block.BlindedBellatrix.Block.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to compute block root for bellatrix beacon block")
}
res.beaconBlockRoot = beaconBlockRoot
// Marshal SSZ
ssz, err := block.BlindedBellatrix.MarshalSSZ()
if err != nil {
return nil, errors.Wrap(err, "failed to serialize block for bellatrix beacon block")
}
res.marshalledSSZ = ssz
// Set up JSON marshalling function for fallback
res.marshalJSON = func() ([]byte, error) {
signedBlock, err := structs.SignedBlindedBeaconBlockBellatrixFromConsensus(block.BlindedBellatrix)
if err != nil {
return nil, errors.Wrap(err, "failed to convert blinded bellatrix beacon block")
}
return json.Marshal(signedBlock)
}
return &res, nil
}
func handleCapellaBlock(block *ethpb.GenericSignedBeaconBlock_Capella) (*blockProcessingResult, error) {
var res blockProcessingResult
res.consensusVersion = "capella"
res.blinded = false
beaconBlockRoot, err := block.Capella.Block.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to compute block root for capella beacon block")
}
res.beaconBlockRoot = beaconBlockRoot
// Marshal SSZ
ssz, err := block.Capella.MarshalSSZ()
if err != nil {
return nil, errors.Wrap(err, "failed to serialize capella beacon block")
}
res.marshalledSSZ = ssz
// Set up JSON marshalling function for fallback
res.marshalJSON = func() ([]byte, error) {
signedBlock, err := structs.SignedBeaconBlockCapellaFromConsensus(block.Capella)
if err != nil {
return nil, errors.Wrap(err, "failed to convert capella beacon block")
}
return json.Marshal(signedBlock)
}
return &res, nil
}
func handleBlindedCapellaBlock(block *ethpb.GenericSignedBeaconBlock_BlindedCapella) (*blockProcessingResult, error) {
var res blockProcessingResult
res.consensusVersion = "capella"
res.blinded = true
beaconBlockRoot, err := block.BlindedCapella.Block.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to compute block root for blinded capella beacon block")
}
res.beaconBlockRoot = beaconBlockRoot
// Marshal SSZ
ssz, err := block.BlindedCapella.MarshalSSZ()
if err != nil {
return nil, errors.Wrap(err, "failed to serialize blinded capella beacon block")
}
res.marshalledSSZ = ssz
// Set up JSON marshalling function for fallback
res.marshalJSON = func() ([]byte, error) {
signedBlock, err := structs.SignedBlindedBeaconBlockCapellaFromConsensus(block.BlindedCapella)
if err != nil {
return nil, errors.Wrap(err, "failed to convert blinded capella beacon block")
}
return json.Marshal(signedBlock)
}
return &res, nil
}
func handleDenebBlockContents(block *ethpb.GenericSignedBeaconBlock_Deneb) (*blockProcessingResult, error) {
var res blockProcessingResult
res.consensusVersion = "deneb"
res.blinded = false
beaconBlockRoot, err := block.Deneb.Block.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to compute block root for deneb beacon block")
}
res.beaconBlockRoot = beaconBlockRoot
// Marshal SSZ
ssz, err := block.Deneb.MarshalSSZ()
if err != nil {
return nil, errors.Wrap(err, "failed to serialize deneb beacon block")
}
res.marshalledSSZ = ssz
// Set up JSON marshalling function for fallback
res.marshalJSON = func() ([]byte, error) {
signedBlock, err := structs.SignedBeaconBlockContentsDenebFromConsensus(block.Deneb)
if err != nil {
return nil, errors.Wrap(err, "failed to convert deneb beacon block contents")
}
return json.Marshal(signedBlock)
}
return &res, nil
}
func handleBlindedDenebBlock(block *ethpb.GenericSignedBeaconBlock_BlindedDeneb) (*blockProcessingResult, error) {
var res blockProcessingResult
res.consensusVersion = "deneb"
res.blinded = true
beaconBlockRoot, err := block.BlindedDeneb.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to compute block root for deneb blinded beacon block")
}
res.beaconBlockRoot = beaconBlockRoot
// Marshal SSZ
ssz, err := block.BlindedDeneb.MarshalSSZ()
if err != nil {
return nil, errors.Wrap(err, "failed to serialize blinded deneb beacon block")
}
res.marshalledSSZ = ssz
// Set up JSON marshalling function for fallback
res.marshalJSON = func() ([]byte, error) {
signedBlock, err := structs.SignedBlindedBeaconBlockDenebFromConsensus(block.BlindedDeneb)
if err != nil {
return nil, errors.Wrap(err, "failed to convert deneb blinded beacon block")
}
return json.Marshal(signedBlock)
}
return &res, nil
}
func handleElectraBlockContents(block *ethpb.GenericSignedBeaconBlock_Electra) (*blockProcessingResult, error) {
var res blockProcessingResult
res.consensusVersion = "electra"
res.blinded = false
beaconBlockRoot, err := block.Electra.Block.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to compute block root for electra beacon block")
}
res.beaconBlockRoot = beaconBlockRoot
// Marshal SSZ
ssz, err := block.Electra.MarshalSSZ()
if err != nil {
return nil, errors.Wrap(err, "failed to serialize electra beacon block")
}
res.marshalledSSZ = ssz
// Set up JSON marshalling function for fallback
res.marshalJSON = func() ([]byte, error) {
signedBlock, err := structs.SignedBeaconBlockContentsElectraFromConsensus(block.Electra)
if err != nil {
return nil, errors.Wrap(err, "failed to convert electra beacon block contents")
}
return json.Marshal(signedBlock)
}
return &res, nil
}
func handleBlindedElectraBlock(block *ethpb.GenericSignedBeaconBlock_BlindedElectra) (*blockProcessingResult, error) {
var res blockProcessingResult
res.consensusVersion = "electra"
res.blinded = true
beaconBlockRoot, err := block.BlindedElectra.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to compute block root for electra blinded beacon block")
}
res.beaconBlockRoot = beaconBlockRoot
// Marshal SSZ
ssz, err := block.BlindedElectra.MarshalSSZ()
if err != nil {
return nil, errors.Wrap(err, "failed to serialize blinded electra beacon block")
}
res.marshalledSSZ = ssz
// Set up JSON marshalling function for fallback
res.marshalJSON = func() ([]byte, error) {
signedBlock, err := structs.SignedBlindedBeaconBlockElectraFromConsensus(block.BlindedElectra)
if err != nil {
return nil, errors.Wrap(err, "failed to convert electra blinded beacon block")
}
return json.Marshal(signedBlock)
}
return &res, nil
}
func handleFuluBlockContents(block *ethpb.GenericSignedBeaconBlock_Fulu) (*blockProcessingResult, error) {
var res blockProcessingResult
res.consensusVersion = "fulu"
res.blinded = false
beaconBlockRoot, err := block.Fulu.Block.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to compute block root for fulu beacon block")
}
res.beaconBlockRoot = beaconBlockRoot
// Marshal SSZ
ssz, err := block.Fulu.MarshalSSZ()
if err != nil {
return nil, errors.Wrap(err, "failed to serialize fulu beacon block")
}
res.marshalledSSZ = ssz
// Set up JSON marshalling function for fallback
res.marshalJSON = func() ([]byte, error) {
signedBlock, err := structs.SignedBeaconBlockContentsFuluFromConsensus(block.Fulu)
if err != nil {
return nil, errors.Wrap(err, "failed to convert fulu beacon block contents")
}
return json.Marshal(signedBlock)
}
return &res, nil
}
func handleBlindedFuluBlock(block *ethpb.GenericSignedBeaconBlock_BlindedFulu) (*blockProcessingResult, error) {
var res blockProcessingResult
res.consensusVersion = "fulu"
res.blinded = true
beaconBlockRoot, err := block.BlindedFulu.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "failed to compute block root for fulu blinded beacon block")
}
res.beaconBlockRoot = beaconBlockRoot
// Marshal SSZ
ssz, err := block.BlindedFulu.MarshalSSZ()
if err != nil {
return nil, errors.Wrap(err, "failed to serialize blinded fulu beacon block")
}
res.marshalledSSZ = ssz
// Set up JSON marshalling function for fallback
res.marshalJSON = func() ([]byte, error) {
signedBlock, err := structs.SignedBlindedBeaconBlockFuluFromConsensus(block.BlindedFulu)
if err != nil {
return nil, errors.Wrap(err, "failed to convert fulu blinded beacon block")
}
return json.Marshal(signedBlock)
}
return &res, nil
}