mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-06 22:23:56 -05:00
230 lines
6.8 KiB
Go
230 lines
6.8 KiB
Go
package structs
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/OffchainLabs/prysm/v7/consensus-types/interfaces"
|
|
enginev1 "github.com/OffchainLabs/prysm/v7/proto/engine/v1"
|
|
"github.com/OffchainLabs/prysm/v7/runtime/version"
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
func LightClientUpdateFromConsensus(update interfaces.LightClientUpdate) (*LightClientUpdate, error) {
|
|
attestedHeader, err := lightClientHeaderToJSON(update.AttestedHeader())
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "could not marshal attested light client header")
|
|
}
|
|
finalizedHeader, err := lightClientHeaderToJSON(update.FinalizedHeader())
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "could not marshal finalized light client header")
|
|
}
|
|
|
|
var scBranch [][32]byte
|
|
var finalityBranch [][32]byte
|
|
if update.Version() >= version.Electra {
|
|
scb, err := update.NextSyncCommitteeBranchElectra()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
scBranch = scb[:]
|
|
fb, err := update.FinalityBranchElectra()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
finalityBranch = fb[:]
|
|
} else {
|
|
scb, err := update.NextSyncCommitteeBranch()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
scBranch = scb[:]
|
|
fb, err := update.FinalityBranch()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
finalityBranch = fb[:]
|
|
}
|
|
|
|
return &LightClientUpdate{
|
|
AttestedHeader: attestedHeader,
|
|
NextSyncCommittee: SyncCommitteeFromConsensus(update.NextSyncCommittee()),
|
|
NextSyncCommitteeBranch: branchToJSON(scBranch),
|
|
FinalizedHeader: finalizedHeader,
|
|
FinalityBranch: branchToJSON(finalityBranch),
|
|
SyncAggregate: SyncAggregateFromConsensus(update.SyncAggregate()),
|
|
SignatureSlot: fmt.Sprintf("%d", update.SignatureSlot()),
|
|
}, nil
|
|
}
|
|
|
|
func LightClientFinalityUpdateFromConsensus(update interfaces.LightClientFinalityUpdate) (*LightClientFinalityUpdate, error) {
|
|
attestedHeader, err := lightClientHeaderToJSON(update.AttestedHeader())
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "could not marshal attested light client header")
|
|
}
|
|
finalizedHeader, err := lightClientHeaderToJSON(update.FinalizedHeader())
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "could not marshal finalized light client header")
|
|
}
|
|
|
|
var finalityBranch [][32]byte
|
|
if update.Version() >= version.Electra {
|
|
b, err := update.FinalityBranchElectra()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
finalityBranch = b[:]
|
|
} else {
|
|
b, err := update.FinalityBranch()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
finalityBranch = b[:]
|
|
}
|
|
|
|
return &LightClientFinalityUpdate{
|
|
AttestedHeader: attestedHeader,
|
|
FinalizedHeader: finalizedHeader,
|
|
FinalityBranch: branchToJSON(finalityBranch),
|
|
SyncAggregate: SyncAggregateFromConsensus(update.SyncAggregate()),
|
|
SignatureSlot: fmt.Sprintf("%d", update.SignatureSlot()),
|
|
}, nil
|
|
}
|
|
|
|
func LightClientOptimisticUpdateFromConsensus(update interfaces.LightClientOptimisticUpdate) (*LightClientOptimisticUpdate, error) {
|
|
attestedHeader, err := lightClientHeaderToJSON(update.AttestedHeader())
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "could not marshal attested light client header")
|
|
}
|
|
|
|
return &LightClientOptimisticUpdate{
|
|
AttestedHeader: attestedHeader,
|
|
SyncAggregate: SyncAggregateFromConsensus(update.SyncAggregate()),
|
|
SignatureSlot: fmt.Sprintf("%d", update.SignatureSlot()),
|
|
}, nil
|
|
}
|
|
|
|
func branchToJSON[S [][32]byte](branchBytes S) []string {
|
|
if branchBytes == nil {
|
|
return nil
|
|
}
|
|
branch := make([]string, len(branchBytes))
|
|
for i, root := range branchBytes {
|
|
branch[i] = hexutil.Encode(root[:])
|
|
}
|
|
return branch
|
|
}
|
|
|
|
func lightClientHeaderToJSON(header interfaces.LightClientHeader) (json.RawMessage, error) {
|
|
// In the case that a finalizedHeader is nil.
|
|
if header == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
var result any
|
|
|
|
switch v := header.Version(); v {
|
|
case version.Altair:
|
|
result = &LightClientHeader{Beacon: BeaconBlockHeaderFromConsensus(header.Beacon())}
|
|
case version.Capella:
|
|
exInterface, err := header.Execution()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ex, ok := exInterface.Proto().(*enginev1.ExecutionPayloadHeaderCapella)
|
|
if !ok {
|
|
return nil, fmt.Errorf("execution data is not %T", &enginev1.ExecutionPayloadHeaderCapella{})
|
|
}
|
|
execution, err := ExecutionPayloadHeaderCapellaFromConsensus(ex)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
executionBranch, err := header.ExecutionBranch()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result = &LightClientHeaderCapella{
|
|
Beacon: BeaconBlockHeaderFromConsensus(header.Beacon()),
|
|
Execution: execution,
|
|
ExecutionBranch: branchToJSON(executionBranch[:]),
|
|
}
|
|
case version.Deneb:
|
|
exInterface, err := header.Execution()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ex, ok := exInterface.Proto().(*enginev1.ExecutionPayloadHeaderDeneb)
|
|
if !ok {
|
|
return nil, fmt.Errorf("execution data is not %T", &enginev1.ExecutionPayloadHeaderDeneb{})
|
|
}
|
|
execution, err := ExecutionPayloadHeaderDenebFromConsensus(ex)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
executionBranch, err := header.ExecutionBranch()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result = &LightClientHeaderDeneb{
|
|
Beacon: BeaconBlockHeaderFromConsensus(header.Beacon()),
|
|
Execution: execution,
|
|
ExecutionBranch: branchToJSON(executionBranch[:]),
|
|
}
|
|
case version.Electra:
|
|
exInterface, err := header.Execution()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ex, ok := exInterface.Proto().(*enginev1.ExecutionPayloadHeaderDeneb)
|
|
if !ok {
|
|
return nil, fmt.Errorf("execution data is not %T", &enginev1.ExecutionPayloadHeaderDeneb{})
|
|
}
|
|
execution, err := ExecutionPayloadHeaderElectraFromConsensus(ex)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
executionBranch, err := header.ExecutionBranch()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result = &LightClientHeaderDeneb{
|
|
Beacon: BeaconBlockHeaderFromConsensus(header.Beacon()),
|
|
Execution: execution,
|
|
ExecutionBranch: branchToJSON(executionBranch[:]),
|
|
}
|
|
default:
|
|
return nil, fmt.Errorf("unsupported header version %s", version.String(v))
|
|
}
|
|
|
|
return json.Marshal(result)
|
|
}
|
|
|
|
func LightClientBootstrapFromConsensus(bootstrap interfaces.LightClientBootstrap) (*LightClientBootstrap, error) {
|
|
header, err := lightClientHeaderToJSON(bootstrap.Header())
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "could not marshal light client header")
|
|
}
|
|
|
|
var scBranch [][32]byte
|
|
if bootstrap.Version() >= version.Electra {
|
|
b, err := bootstrap.CurrentSyncCommitteeBranchElectra()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
scBranch = b[:]
|
|
} else {
|
|
b, err := bootstrap.CurrentSyncCommitteeBranch()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
scBranch = b[:]
|
|
}
|
|
|
|
return &LightClientBootstrap{
|
|
Header: header,
|
|
CurrentSyncCommittee: SyncCommitteeFromConsensus(bootstrap.CurrentSyncCommittee()),
|
|
CurrentSyncCommitteeBranch: branchToJSON(scBranch),
|
|
}, nil
|
|
}
|