mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-07 20:43:57 -05:00
452 lines
13 KiB
Go
452 lines
13 KiB
Go
package light_client
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
fieldparams "github.com/OffchainLabs/prysm/v7/config/fieldparams"
|
|
consensustypes "github.com/OffchainLabs/prysm/v7/consensus-types"
|
|
"github.com/OffchainLabs/prysm/v7/consensus-types/interfaces"
|
|
pb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
|
|
"github.com/OffchainLabs/prysm/v7/runtime/version"
|
|
"github.com/OffchainLabs/prysm/v7/time/slots"
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
func NewWrappedBootstrap(m proto.Message) (interfaces.LightClientBootstrap, error) {
|
|
if m == nil {
|
|
return nil, consensustypes.ErrNilObjectWrapped
|
|
}
|
|
switch t := m.(type) {
|
|
case *pb.LightClientBootstrapAltair:
|
|
return NewWrappedBootstrapAltair(t)
|
|
case *pb.LightClientBootstrapCapella:
|
|
return NewWrappedBootstrapCapella(t)
|
|
case *pb.LightClientBootstrapDeneb:
|
|
return NewWrappedBootstrapDeneb(t)
|
|
case *pb.LightClientBootstrapElectra:
|
|
return NewWrappedBootstrapElectra(t)
|
|
default:
|
|
return nil, fmt.Errorf("cannot construct light client bootstrap from type %T", t)
|
|
}
|
|
}
|
|
|
|
// In addition to the proto object being wrapped, we store some fields that have to be
|
|
// constructed from the proto, so that we don't have to reconstruct them every time
|
|
// in getters.
|
|
type bootstrapAltair struct {
|
|
p *pb.LightClientBootstrapAltair
|
|
header interfaces.LightClientHeader
|
|
currentSyncCommitteeBranch interfaces.LightClientSyncCommitteeBranch
|
|
}
|
|
|
|
var _ interfaces.LightClientBootstrap = &bootstrapAltair{}
|
|
|
|
func NewWrappedBootstrapAltair(p *pb.LightClientBootstrapAltair) (interfaces.LightClientBootstrap, error) {
|
|
if p == nil {
|
|
return nil, consensustypes.ErrNilObjectWrapped
|
|
}
|
|
|
|
var header interfaces.LightClientHeader
|
|
var err error
|
|
if p.Header != nil {
|
|
header, err = NewWrappedHeader(p.Header)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
branch, err := createBranch[interfaces.LightClientSyncCommitteeBranch](
|
|
"sync committee",
|
|
p.CurrentSyncCommitteeBranch,
|
|
fieldparams.SyncCommitteeBranchDepth,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &bootstrapAltair{
|
|
p: p,
|
|
header: header,
|
|
currentSyncCommitteeBranch: branch,
|
|
}, nil
|
|
}
|
|
|
|
func (h *bootstrapAltair) MarshalSSZTo(dst []byte) ([]byte, error) {
|
|
return h.p.MarshalSSZTo(dst)
|
|
}
|
|
|
|
func (h *bootstrapAltair) MarshalSSZ() ([]byte, error) {
|
|
return h.p.MarshalSSZ()
|
|
}
|
|
|
|
func (h *bootstrapAltair) SizeSSZ() int {
|
|
return h.p.SizeSSZ()
|
|
}
|
|
|
|
func (h *bootstrapAltair) Version() int {
|
|
return slots.ToForkVersion(h.header.Beacon().Slot)
|
|
}
|
|
|
|
func (h *bootstrapAltair) Proto() proto.Message {
|
|
return h.p
|
|
}
|
|
|
|
func (h *bootstrapAltair) Header() interfaces.LightClientHeader {
|
|
return h.header
|
|
}
|
|
|
|
func (h *bootstrapAltair) SetHeader(header interfaces.LightClientHeader) error {
|
|
p, ok := header.Proto().(*pb.LightClientHeaderAltair)
|
|
if !ok {
|
|
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderAltair{})
|
|
}
|
|
h.p.Header = p
|
|
h.header = header
|
|
return nil
|
|
}
|
|
|
|
func (h *bootstrapAltair) CurrentSyncCommittee() *pb.SyncCommittee {
|
|
return h.p.CurrentSyncCommittee
|
|
}
|
|
|
|
func (h *bootstrapAltair) SetCurrentSyncCommittee(sc *pb.SyncCommittee) error {
|
|
h.p.CurrentSyncCommittee = sc
|
|
return nil
|
|
}
|
|
|
|
func (h *bootstrapAltair) CurrentSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) {
|
|
return h.currentSyncCommitteeBranch, nil
|
|
}
|
|
|
|
func (h *bootstrapAltair) SetCurrentSyncCommitteeBranch(branch [][]byte) error {
|
|
if len(branch) != fieldparams.SyncCommitteeBranchDepth {
|
|
return fmt.Errorf("branch length %d is not %d", len(branch), fieldparams.SyncCommitteeBranchDepth)
|
|
}
|
|
newBranch := [fieldparams.SyncCommitteeBranchDepth][32]byte{}
|
|
for i, root := range branch {
|
|
copy(newBranch[i][:], root)
|
|
}
|
|
h.currentSyncCommitteeBranch = newBranch
|
|
h.p.CurrentSyncCommitteeBranch = branch
|
|
return nil
|
|
}
|
|
|
|
func (h *bootstrapAltair) CurrentSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) {
|
|
return [6][32]byte{}, consensustypes.ErrNotSupported("CurrentSyncCommitteeBranchElectra", version.Altair)
|
|
}
|
|
|
|
// In addition to the proto object being wrapped, we store some fields that have to be
|
|
// constructed from the proto, so that we don't have to reconstruct them every time
|
|
// in getters.
|
|
type bootstrapCapella struct {
|
|
p *pb.LightClientBootstrapCapella
|
|
header interfaces.LightClientHeader
|
|
currentSyncCommitteeBranch interfaces.LightClientSyncCommitteeBranch
|
|
}
|
|
|
|
var _ interfaces.LightClientBootstrap = &bootstrapCapella{}
|
|
|
|
func NewWrappedBootstrapCapella(p *pb.LightClientBootstrapCapella) (interfaces.LightClientBootstrap, error) {
|
|
if p == nil {
|
|
return nil, consensustypes.ErrNilObjectWrapped
|
|
}
|
|
|
|
var header interfaces.LightClientHeader
|
|
var err error
|
|
if p.Header != nil {
|
|
header, err = NewWrappedHeader(p.Header)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
branch, err := createBranch[interfaces.LightClientSyncCommitteeBranch](
|
|
"sync committee",
|
|
p.CurrentSyncCommitteeBranch,
|
|
fieldparams.SyncCommitteeBranchDepth,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &bootstrapCapella{
|
|
p: p,
|
|
header: header,
|
|
currentSyncCommitteeBranch: branch,
|
|
}, nil
|
|
}
|
|
|
|
func (h *bootstrapCapella) MarshalSSZTo(dst []byte) ([]byte, error) {
|
|
return h.p.MarshalSSZTo(dst)
|
|
}
|
|
|
|
func (h *bootstrapCapella) MarshalSSZ() ([]byte, error) {
|
|
return h.p.MarshalSSZ()
|
|
}
|
|
|
|
func (h *bootstrapCapella) SizeSSZ() int {
|
|
return h.p.SizeSSZ()
|
|
}
|
|
|
|
func (h *bootstrapCapella) Version() int {
|
|
return slots.ToForkVersion(h.header.Beacon().Slot)
|
|
}
|
|
|
|
func (h *bootstrapCapella) Proto() proto.Message {
|
|
return h.p
|
|
}
|
|
|
|
func (h *bootstrapCapella) Header() interfaces.LightClientHeader {
|
|
return h.header
|
|
}
|
|
|
|
func (h *bootstrapCapella) SetHeader(header interfaces.LightClientHeader) error {
|
|
p, ok := header.Proto().(*pb.LightClientHeaderCapella)
|
|
if !ok {
|
|
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderCapella{})
|
|
}
|
|
h.p.Header = p
|
|
h.header = header
|
|
return nil
|
|
}
|
|
|
|
func (h *bootstrapCapella) CurrentSyncCommittee() *pb.SyncCommittee {
|
|
return h.p.CurrentSyncCommittee
|
|
}
|
|
|
|
func (h *bootstrapCapella) SetCurrentSyncCommittee(sc *pb.SyncCommittee) error {
|
|
h.p.CurrentSyncCommittee = sc
|
|
return nil
|
|
}
|
|
|
|
func (h *bootstrapCapella) CurrentSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) {
|
|
return h.currentSyncCommitteeBranch, nil
|
|
}
|
|
|
|
func (h *bootstrapCapella) SetCurrentSyncCommitteeBranch(branch [][]byte) error {
|
|
if len(branch) != fieldparams.SyncCommitteeBranchDepth {
|
|
return fmt.Errorf("branch length %d is not %d", len(branch), fieldparams.SyncCommitteeBranchDepth)
|
|
}
|
|
newBranch := [fieldparams.SyncCommitteeBranchDepth][32]byte{}
|
|
for i, root := range branch {
|
|
copy(newBranch[i][:], root)
|
|
}
|
|
h.currentSyncCommitteeBranch = newBranch
|
|
h.p.CurrentSyncCommitteeBranch = branch
|
|
return nil
|
|
}
|
|
|
|
func (h *bootstrapCapella) CurrentSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) {
|
|
return [6][32]byte{}, consensustypes.ErrNotSupported("CurrentSyncCommitteeBranchElectra", version.Capella)
|
|
}
|
|
|
|
// In addition to the proto object being wrapped, we store some fields that have to be
|
|
// constructed from the proto, so that we don't have to reconstruct them every time
|
|
// in getters.
|
|
type bootstrapDeneb struct {
|
|
p *pb.LightClientBootstrapDeneb
|
|
header interfaces.LightClientHeader
|
|
currentSyncCommitteeBranch interfaces.LightClientSyncCommitteeBranch
|
|
}
|
|
|
|
var _ interfaces.LightClientBootstrap = &bootstrapDeneb{}
|
|
|
|
func NewWrappedBootstrapDeneb(p *pb.LightClientBootstrapDeneb) (interfaces.LightClientBootstrap, error) {
|
|
if p == nil {
|
|
return nil, consensustypes.ErrNilObjectWrapped
|
|
}
|
|
|
|
var header interfaces.LightClientHeader
|
|
var err error
|
|
if p.Header != nil {
|
|
header, err = NewWrappedHeader(p.Header)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
branch, err := createBranch[interfaces.LightClientSyncCommitteeBranch](
|
|
"sync committee",
|
|
p.CurrentSyncCommitteeBranch,
|
|
fieldparams.SyncCommitteeBranchDepth,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &bootstrapDeneb{
|
|
p: p,
|
|
header: header,
|
|
currentSyncCommitteeBranch: branch,
|
|
}, nil
|
|
}
|
|
|
|
func (h *bootstrapDeneb) MarshalSSZTo(dst []byte) ([]byte, error) {
|
|
return h.p.MarshalSSZTo(dst)
|
|
}
|
|
|
|
func (h *bootstrapDeneb) MarshalSSZ() ([]byte, error) {
|
|
return h.p.MarshalSSZ()
|
|
}
|
|
|
|
func (h *bootstrapDeneb) SizeSSZ() int {
|
|
return h.p.SizeSSZ()
|
|
}
|
|
|
|
func (h *bootstrapDeneb) Version() int {
|
|
return slots.ToForkVersion(h.header.Beacon().Slot)
|
|
}
|
|
|
|
func (h *bootstrapDeneb) Proto() proto.Message {
|
|
return h.p
|
|
}
|
|
|
|
func (h *bootstrapDeneb) Header() interfaces.LightClientHeader {
|
|
return h.header
|
|
}
|
|
|
|
func (h *bootstrapDeneb) SetHeader(header interfaces.LightClientHeader) error {
|
|
p, ok := header.Proto().(*pb.LightClientHeaderDeneb)
|
|
if !ok {
|
|
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderDeneb{})
|
|
}
|
|
h.p.Header = p
|
|
h.header = header
|
|
return nil
|
|
}
|
|
|
|
func (h *bootstrapDeneb) CurrentSyncCommittee() *pb.SyncCommittee {
|
|
return h.p.CurrentSyncCommittee
|
|
}
|
|
|
|
func (h *bootstrapDeneb) SetCurrentSyncCommittee(sc *pb.SyncCommittee) error {
|
|
h.p.CurrentSyncCommittee = sc
|
|
return nil
|
|
}
|
|
|
|
func (h *bootstrapDeneb) CurrentSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) {
|
|
return h.currentSyncCommitteeBranch, nil
|
|
}
|
|
|
|
func (h *bootstrapDeneb) SetCurrentSyncCommitteeBranch(branch [][]byte) error {
|
|
if len(branch) != fieldparams.SyncCommitteeBranchDepth {
|
|
return fmt.Errorf("branch length %d is not %d", len(branch), fieldparams.SyncCommitteeBranchDepth)
|
|
}
|
|
newBranch := [fieldparams.SyncCommitteeBranchDepth][32]byte{}
|
|
for i, root := range branch {
|
|
copy(newBranch[i][:], root)
|
|
}
|
|
h.currentSyncCommitteeBranch = newBranch
|
|
h.p.CurrentSyncCommitteeBranch = branch
|
|
return nil
|
|
}
|
|
|
|
func (h *bootstrapDeneb) CurrentSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) {
|
|
return [6][32]byte{}, consensustypes.ErrNotSupported("CurrentSyncCommitteeBranchElectra", version.Deneb)
|
|
}
|
|
|
|
// In addition to the proto object being wrapped, we store some fields that have to be
|
|
// constructed from the proto, so that we don't have to reconstruct them every time
|
|
// in getters.
|
|
type bootstrapElectra struct {
|
|
p *pb.LightClientBootstrapElectra
|
|
header interfaces.LightClientHeader
|
|
currentSyncCommitteeBranch interfaces.LightClientSyncCommitteeBranchElectra
|
|
}
|
|
|
|
var _ interfaces.LightClientBootstrap = &bootstrapElectra{}
|
|
|
|
func NewWrappedBootstrapElectra(p *pb.LightClientBootstrapElectra) (interfaces.LightClientBootstrap, error) {
|
|
if p == nil {
|
|
return nil, consensustypes.ErrNilObjectWrapped
|
|
}
|
|
|
|
var header interfaces.LightClientHeader
|
|
var err error
|
|
if p.Header != nil {
|
|
header, err = NewWrappedHeader(p.Header)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
branch, err := createBranch[interfaces.LightClientSyncCommitteeBranchElectra](
|
|
"sync committee",
|
|
p.CurrentSyncCommitteeBranch,
|
|
fieldparams.SyncCommitteeBranchDepthElectra,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &bootstrapElectra{
|
|
p: p,
|
|
header: header,
|
|
currentSyncCommitteeBranch: branch,
|
|
}, nil
|
|
}
|
|
|
|
func (h *bootstrapElectra) MarshalSSZTo(dst []byte) ([]byte, error) {
|
|
return h.p.MarshalSSZTo(dst)
|
|
}
|
|
|
|
func (h *bootstrapElectra) MarshalSSZ() ([]byte, error) {
|
|
return h.p.MarshalSSZ()
|
|
}
|
|
|
|
func (h *bootstrapElectra) SizeSSZ() int {
|
|
return h.p.SizeSSZ()
|
|
}
|
|
|
|
func (h *bootstrapElectra) Version() int {
|
|
return slots.ToForkVersion(h.header.Beacon().Slot)
|
|
}
|
|
|
|
func (h *bootstrapElectra) Proto() proto.Message {
|
|
return h.p
|
|
}
|
|
|
|
func (h *bootstrapElectra) Header() interfaces.LightClientHeader {
|
|
return h.header
|
|
}
|
|
|
|
func (h *bootstrapElectra) SetHeader(header interfaces.LightClientHeader) error {
|
|
p, ok := header.Proto().(*pb.LightClientHeaderDeneb)
|
|
if !ok {
|
|
return fmt.Errorf("header type %T is not %T", header.Proto(), &pb.LightClientHeaderDeneb{})
|
|
}
|
|
h.p.Header = p
|
|
h.header = header
|
|
return nil
|
|
}
|
|
|
|
func (h *bootstrapElectra) CurrentSyncCommittee() *pb.SyncCommittee {
|
|
return h.p.CurrentSyncCommittee
|
|
}
|
|
|
|
func (h *bootstrapElectra) SetCurrentSyncCommittee(sc *pb.SyncCommittee) error {
|
|
h.p.CurrentSyncCommittee = sc
|
|
return nil
|
|
}
|
|
|
|
func (h *bootstrapElectra) CurrentSyncCommitteeBranch() (interfaces.LightClientSyncCommitteeBranch, error) {
|
|
return [5][32]byte{}, consensustypes.ErrNotSupported("CurrentSyncCommitteeBranch", version.Electra)
|
|
}
|
|
|
|
func (h *bootstrapElectra) SetCurrentSyncCommitteeBranch(branch [][]byte) error {
|
|
if len(branch) != fieldparams.SyncCommitteeBranchDepthElectra {
|
|
return fmt.Errorf("branch length %d is not %d", len(branch), fieldparams.SyncCommitteeBranchDepthElectra)
|
|
}
|
|
newBranch := [fieldparams.SyncCommitteeBranchDepthElectra][32]byte{}
|
|
for i, root := range branch {
|
|
copy(newBranch[i][:], root)
|
|
}
|
|
h.currentSyncCommitteeBranch = newBranch
|
|
h.p.CurrentSyncCommitteeBranch = branch
|
|
return nil
|
|
}
|
|
|
|
func (h *bootstrapElectra) CurrentSyncCommitteeBranchElectra() (interfaces.LightClientSyncCommitteeBranchElectra, error) {
|
|
return h.currentSyncCommitteeBranch, nil
|
|
}
|