diff --git a/Makefile b/Makefile index e87459a..15078f8 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ clean: create-test-dir: mkdir -p $(TEST_OUT_DIR) -SPEC_VERSION ?= v1.4.0-beta.7-hotfix +SPEC_VERSION ?= v1.4.0 clear-tests: rm -rf tests/spec/eth2.0-spec-tests diff --git a/eth2/beacon/altair/lightclient.go b/eth2/beacon/altair/lightclient.go index 26a5100..39cf018 100644 --- a/eth2/beacon/altair/lightclient.go +++ b/eth2/beacon/altair/lightclient.go @@ -136,10 +136,10 @@ func (fb FinalizedRootProofBranch) HashTreeRoot(hFn tree.HashFn) common.Root { func LightClientUpdateType(spec *common.Spec) *ContainerTypeDef { return ContainerType("SyncCommittee", []FieldDef{ - {"attested_header", common.BeaconBlockHeaderType}, + {"attested_header", LightClientHeaderType}, {"next_sync_committee", common.SyncCommitteeType(spec)}, {"next_sync_committee_branch", SyncCommitteeProofBranchType}, - {"finalized_header", common.BeaconBlockHeaderType}, + {"finalized_header", LightClientHeaderType}, {"finality_branch", FinalizedRootProofBranchType}, {"sync_aggregate", SyncAggregateType(spec)}, {"signature_slot", common.SlotType}, @@ -148,12 +148,12 @@ func LightClientUpdateType(spec *common.Spec) *ContainerTypeDef { type LightClientUpdate struct { // Update beacon block header - AttestedHeader common.BeaconBlockHeader `yaml:"attested_header" json:"attested_header"` + AttestedHeader LightClientHeader `yaml:"attested_header" json:"attested_header"` // Next sync committee corresponding to the header NextSyncCommittee common.SyncCommittee `yaml:"next_sync_committee" json:"next_sync_committee"` NextSyncCommitteeBranch SyncCommitteeProofBranch `yaml:"next_sync_committee_branch" json:"next_sync_committee_branch"` // Finality proof for the update header - FinalizedHeader common.BeaconBlockHeader `yaml:"finalized_header" json:"finalized_header"` + FinalizedHeader LightClientHeader `yaml:"finalized_header" json:"finalized_header"` FinalityBranch FinalizedRootProofBranch `yaml:"finality_branch" json:"finality_branch"` // Sync committee aggregate signature SyncAggregate SyncAggregate `yaml:"sync_aggregate" json:"sync_aggregate"` @@ -220,3 +220,163 @@ func (lcu *LightClientUpdate) HashTreeRoot(spec *common.Spec, hFn tree.HashFn) c &lcu.SignatureSlot, ) } + +var LightClientHeaderType = ContainerType("LightClientHeaderType", []FieldDef{ + {Name: "beacon", Type: common.BeaconBlockHeaderType}, +}) + +type LightClientHeader struct { + Beacon common.BeaconBlockHeader `yaml:"beacon" json:"beacon"` +} + +func (lch *LightClientHeader) Deserialize(dr *codec.DecodingReader) error { + return dr.FixedLenContainer( + &lch.Beacon, + ) +} + +func (lch *LightClientHeader) Serialize(w *codec.EncodingWriter) error { + return w.FixedLenContainer( + &lch.Beacon, + ) +} + +func (lch *LightClientHeader) ByteLength() uint64 { + return codec.ContainerLength( + &lch.Beacon, + ) +} + +func (lch *LightClientHeader) FixedLength() uint64 { + return codec.ContainerLength( + &lch.Beacon, + ) +} + +func (lch *LightClientHeader) HashTreeRoot(hFn tree.HashFn) common.Root { + return hFn.HashTreeRoot( + &lch.Beacon, + ) +} + +type LightClientBootstrap struct { + Header LightClientHeader `yaml:"header" json:"header"` + CurrentSyncCommittee common.SyncCommittee `yaml:"current_sync_committee" json:"current_sync_committee"` + CurrentSyncCommitteeBranch SyncCommitteeProofBranch `yaml:"current_sync_committee_branch" json:"current_sync_committee_branch"` +} + +func NewLightClientBootstrapType(spec *common.Spec) *ContainerTypeDef { + return ContainerType("LightClientHeader", []FieldDef{ + {Name: "header", Type: LightClientHeaderType}, + {Name: "current_sync_committee", Type: common.SyncCommitteeType(spec)}, + {Name: "current_sync_committee_branch", Type: SyncCommitteeProofBranchType}, + }) +} + +func (lcb *LightClientBootstrap) FixedLength(spec *common.Spec) uint64 { + return codec.ContainerLength(&lcb.Header, spec.Wrap(&lcb.CurrentSyncCommittee), &lcb.CurrentSyncCommitteeBranch) +} + +func (lcb *LightClientBootstrap) Deserialize(spec *common.Spec, dr *codec.DecodingReader) error { + return dr.Container(&lcb.Header, spec.Wrap(&lcb.CurrentSyncCommittee), &lcb.CurrentSyncCommitteeBranch) +} + +func (lcb *LightClientBootstrap) Serialize(spec *common.Spec, w *codec.EncodingWriter) error { + return w.Container(&lcb.Header, spec.Wrap(&lcb.CurrentSyncCommittee), &lcb.CurrentSyncCommitteeBranch) +} + +func (lcb *LightClientBootstrap) ByteLength(spec *common.Spec) uint64 { + return codec.ContainerLength(&lcb.Header, spec.Wrap(&lcb.CurrentSyncCommittee), &lcb.CurrentSyncCommitteeBranch) +} + +func (lcb *LightClientBootstrap) HashTreeRoot(spec *common.Spec, hFn tree.HashFn) common.Root { + return hFn.HashTreeRoot( + &lcb.Header, + spec.Wrap(&lcb.CurrentSyncCommittee), + &lcb.CurrentSyncCommitteeBranch, + ) +} + +type LightClientFinalityUpdate struct { + AttestedHeader LightClientHeader `yaml:"attested_header" json:"attested_header"` + FinalizedHeader common.BeaconBlockHeader `yaml:"finalized_header" json:"finalized_header"` + FinalityBranch FinalizedRootProofBranch `yaml:"finality_branch" json:"finality_branch"` + SyncAggregate SyncAggregate `yaml:"sync_aggregate" json:"sync_aggregate"` + SignatureSlot common.Slot `yaml:"signature_slot" json:"signature_slot"` +} + +func LightClientFinalityUpdateType(spec *common.Spec) *ContainerTypeDef { + return ContainerType("SyncCommittee", []FieldDef{ + {Name: "attested_header", Type: common.BeaconBlockHeaderType}, + {Name: "finalized_header", Type: common.BeaconBlockHeaderType}, + {Name: "finality_branch", Type: FinalizedRootProofBranchType}, + {Name: "sync_aggregate", Type: SyncAggregateType(spec)}, + {Name: "signature_slot", Type: common.SlotType}, + }) +} + +func (lcfu *LightClientFinalityUpdate) FixedLength(spec *common.Spec) uint64 { + return codec.ContainerLength(&lcfu.AttestedHeader, &lcfu.FinalizedHeader, &lcfu.FinalityBranch, spec.Wrap(&lcfu.SyncAggregate), &lcfu.SignatureSlot) +} + +func (lcfu *LightClientFinalityUpdate) Deserialize(spec *common.Spec, dr *codec.DecodingReader) error { + return dr.Container(&lcfu.AttestedHeader, &lcfu.FinalizedHeader, &lcfu.FinalityBranch, spec.Wrap(&lcfu.SyncAggregate), &lcfu.SignatureSlot) +} + +func (lcfu *LightClientFinalityUpdate) Serialize(spec *common.Spec, w *codec.EncodingWriter) error { + return w.Container(&lcfu.AttestedHeader, &lcfu.FinalizedHeader, &lcfu.FinalityBranch, spec.Wrap(&lcfu.SyncAggregate), &lcfu.SignatureSlot) +} + +func (lcfu *LightClientFinalityUpdate) ByteLength(spec *common.Spec) uint64 { + return codec.ContainerLength(&lcfu.AttestedHeader, &lcfu.FinalizedHeader, &lcfu.FinalityBranch, spec.Wrap(&lcfu.SyncAggregate), &lcfu.SignatureSlot) +} + +func (lcfu *LightClientFinalityUpdate) HashTreeRoot(spec *common.Spec, hFn tree.HashFn) common.Root { + return hFn.HashTreeRoot( + &lcfu.AttestedHeader, + &lcfu.FinalizedHeader, + &lcfu.FinalityBranch, + spec.Wrap(&lcfu.SyncAggregate), + &lcfu.SignatureSlot, + ) +} + +type LightClientOptimisticUpdate struct { + AttestedHeader LightClientHeader `yaml:"attested_header" json:"attested_header"` + SyncAggregate SyncAggregate `yaml:"sync_aggregate" json:"sync_aggregate"` + SignatureSlot common.Slot `yaml:"signature_slot" json:"signature_slot"` +} + +func LightClientOptimisticUpdateType(spec *common.Spec) *ContainerTypeDef { + return ContainerType("SyncCommittee", []FieldDef{ + {Name: "attested_header", Type: common.BeaconBlockHeaderType}, + {Name: "finalized_header", Type: common.BeaconBlockHeaderType}, + {Name: "finality_branch", Type: FinalizedRootProofBranchType}, + {Name: "sync_aggregate", Type: SyncAggregateType(spec)}, + {Name: "signature_slot", Type: common.SlotType}, + }) +} + +func (lcou *LightClientOptimisticUpdate) FixedLength(spec *common.Spec) uint64 { + return codec.ContainerLength(&lcou.AttestedHeader, spec.Wrap(&lcou.SyncAggregate), &lcou.SignatureSlot) +} + +func (lcou *LightClientOptimisticUpdate) Deserialize(spec *common.Spec, dr *codec.DecodingReader) error { + return dr.Container(&lcou.AttestedHeader, spec.Wrap(&lcou.SyncAggregate), &lcou.SignatureSlot) +} + +func (lcou *LightClientOptimisticUpdate) Serialize(spec *common.Spec, w *codec.EncodingWriter) error { + return w.Container(&lcou.AttestedHeader, spec.Wrap(&lcou.SyncAggregate), &lcou.SignatureSlot) +} + +func (lcou *LightClientOptimisticUpdate) ByteLength(spec *common.Spec) uint64 { + return codec.ContainerLength(&lcou.AttestedHeader, spec.Wrap(&lcou.SyncAggregate), &lcou.SignatureSlot) +} + +func (lcou *LightClientOptimisticUpdate) HashTreeRoot(spec *common.Spec, hFn tree.HashFn) common.Root { + return hFn.HashTreeRoot( + &lcou.AttestedHeader, + spec.Wrap(&lcou.SyncAggregate), + &lcou.SignatureSlot, + ) +} diff --git a/eth2/beacon/capella/lightclient.go b/eth2/beacon/capella/lightclient.go new file mode 100644 index 0000000..7f75f70 --- /dev/null +++ b/eth2/beacon/capella/lightclient.go @@ -0,0 +1,275 @@ +package capella + +import ( + "github.com/protolambda/zrnt/eth2/beacon/altair" + "github.com/protolambda/zrnt/eth2/beacon/common" + "github.com/protolambda/ztyp/codec" + "github.com/protolambda/ztyp/tree" + "github.com/protolambda/ztyp/view" +) + +// https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/light-client/sync-protocol.md +const ExecutionBranchLength = 4 + +var ExecutionBranchType = view.VectorType(common.Bytes32Type, ExecutionBranchLength) + +type ExecutionBranch [ExecutionBranchLength]common.Bytes32 + +func (eb *ExecutionBranch) Deserialize(dr *codec.DecodingReader) error { + roots := eb[:] + return tree.ReadRoots(dr, &roots, 4) +} + +func (eb *ExecutionBranch) FixedLength() uint64 { + return ExecutionBranchType.TypeByteLength() +} + +func (eb *ExecutionBranch) Serialize(w *codec.EncodingWriter) error { + return tree.WriteRoots(w, eb[:]) +} + +func (eb *ExecutionBranch) ByteLength() (out uint64) { + return ExecutionBranchType.TypeByteLength() +} + +func (eb *ExecutionBranch) HashTreeRoot(hFn tree.HashFn) common.Root { + return hFn.ComplexVectorHTR(func(i uint64) tree.HTR { + if i < ExecutionBranchLength { + return &eb[i] + } + return nil + }, ExecutionBranchLength) +} + +type LightClientHeader struct { + Beacon common.BeaconBlockHeader `yaml:"beacon" json:"beacon"` + Execution ExecutionPayloadHeader `yaml:"execution" json:"execution"` + ExecutionBranch ExecutionBranch `yaml:"execution_branch" json:"execution_branch"` +} + +var LightClientHeaderType = view.ContainerType("LightClientHeader", []view.FieldDef{ + {Name: "beacon", Type: common.BeaconBlockHeaderType}, + {Name: "execution", Type: ExecutionPayloadHeaderType}, + {Name: "execution_branch", Type: ExecutionBranchType}, +}) + +func (l *LightClientHeader) Deserialize(dr *codec.DecodingReader) error { + return dr.Container(&l.Beacon, &l.Execution, &l.ExecutionBranch) +} + +func (l *LightClientHeader) FixedLength() uint64 { + return LightClientHeaderType.TypeByteLength() +} + +func (l *LightClientHeader) Serialize(w *codec.EncodingWriter) error { + return w.Container(&l.Beacon, &l.Execution, &l.ExecutionBranch) +} + +func (l *LightClientHeader) ByteLength() (out uint64) { + return codec.ContainerLength(&l.Beacon, &l.Execution, &l.ExecutionBranch) +} + +func (l *LightClientHeader) HashTreeRoot(h tree.HashFn) common.Root { + return h.HashTreeRoot(&l.Beacon, &l.Execution, &l.ExecutionBranch) +} + +type LightClientBootstrap struct { + Header LightClientHeader `yaml:"header" json:"header"` + CurrentSyncCommittee common.SyncCommittee `yaml:"current_sync_committee" json:"current_sync_committee"` + CurrentSyncCommitteeBranch altair.SyncCommitteeProofBranch `yaml:"current_sync_committee_branch" json:"current_sync_committee_branch"` +} + +func NewLightClientBootstrapType(spec *common.Spec) *view.ContainerTypeDef { + return view.ContainerType("LightClientHeader", []view.FieldDef{ + {Name: "header", Type: LightClientHeaderType}, + {Name: "next_sync_committee", Type: common.SyncCommitteeType(spec)}, + {Name: "next_sync_committee_branch", Type: altair.SyncCommitteeProofBranchType}, + }) +} + +func (lcb *LightClientBootstrap) FixedLength(spec *common.Spec) uint64 { + return 0 +} + +func (lcb *LightClientBootstrap) Deserialize(spec *common.Spec, dr *codec.DecodingReader) error { + return dr.Container(&lcb.Header, spec.Wrap(&lcb.CurrentSyncCommittee), &lcb.CurrentSyncCommitteeBranch) +} + +func (lcb *LightClientBootstrap) Serialize(spec *common.Spec, w *codec.EncodingWriter) error { + return w.Container(&lcb.Header, spec.Wrap(&lcb.CurrentSyncCommittee), &lcb.CurrentSyncCommitteeBranch) +} + +func (lcb *LightClientBootstrap) ByteLength(spec *common.Spec) uint64 { + return codec.ContainerLength(&lcb.Header, spec.Wrap(&lcb.CurrentSyncCommittee), &lcb.CurrentSyncCommitteeBranch) +} + +func (lcb *LightClientBootstrap) HashTreeRoot(spec *common.Spec, hFn tree.HashFn) common.Root { + return hFn.HashTreeRoot( + &lcb.Header, + spec.Wrap(&lcb.CurrentSyncCommittee), + &lcb.CurrentSyncCommitteeBranch, + ) +} + +func LightClientUpdateType(spec *common.Spec) *view.ContainerTypeDef { + return view.ContainerType("SyncCommittee", []view.FieldDef{ + {Name: "attested_header", Type: common.BeaconBlockHeaderType}, + {Name: "next_sync_committee", Type: common.SyncCommitteeType(spec)}, + {Name: "next_sync_committee_branch", Type: altair.SyncCommitteeProofBranchType}, + {Name: "finalized_header", Type: LightClientHeaderType}, + {Name: "finality_branch", Type: altair.FinalizedRootProofBranchType}, + {Name: "sync_aggregate", Type: altair.SyncAggregateType(spec)}, + {Name: "signature_slot", Type: common.SlotType}, + }) +} + +type LightClientUpdate struct { + // Update beacon block header + AttestedHeader LightClientHeader `yaml:"attested_header" json:"attested_header"` + // Next sync committee corresponding to the header + NextSyncCommittee common.SyncCommittee `yaml:"next_sync_committee" json:"next_sync_committee"` + NextSyncCommitteeBranch altair.SyncCommitteeProofBranch `yaml:"next_sync_committee_branch" json:"next_sync_committee_branch"` + // Finality proof for the update header + FinalizedHeader LightClientHeader `yaml:"finalized_header" json:"finalized_header"` + FinalityBranch altair.FinalizedRootProofBranch `yaml:"finality_branch" json:"finality_branch"` + // Sync committee aggregate signature + SyncAggregate altair.SyncAggregate `yaml:"sync_aggregate" json:"sync_aggregate"` + // Slot at which the aggregate signature was created (untrusted) + SignatureSlot common.Slot `yaml:"signature_slot" json:"signature_slot"` +} + +func (lcu *LightClientUpdate) Deserialize(spec *common.Spec, dr *codec.DecodingReader) error { + return dr.Container( + &lcu.AttestedHeader, + spec.Wrap(&lcu.NextSyncCommittee), + &lcu.NextSyncCommitteeBranch, + &lcu.FinalizedHeader, + &lcu.FinalityBranch, + spec.Wrap(&lcu.SyncAggregate), + &lcu.SignatureSlot, + ) +} + +func (lcu *LightClientUpdate) Serialize(spec *common.Spec, w *codec.EncodingWriter) error { + return w.Container( + &lcu.AttestedHeader, + spec.Wrap(&lcu.NextSyncCommittee), + &lcu.NextSyncCommitteeBranch, + &lcu.FinalizedHeader, + &lcu.FinalityBranch, + spec.Wrap(&lcu.SyncAggregate), + &lcu.SignatureSlot, + ) +} + +func (lcu *LightClientUpdate) ByteLength(spec *common.Spec) uint64 { + return codec.ContainerLength( + &lcu.AttestedHeader, + spec.Wrap(&lcu.NextSyncCommittee), + &lcu.NextSyncCommitteeBranch, + &lcu.FinalizedHeader, + &lcu.FinalityBranch, + spec.Wrap(&lcu.SyncAggregate), + &lcu.SignatureSlot, + ) +} + +func (lcu *LightClientUpdate) FixedLength(spec *common.Spec) uint64 { + return 0 +} + +func (lcu *LightClientUpdate) HashTreeRoot(spec *common.Spec, hFn tree.HashFn) common.Root { + return hFn.HashTreeRoot( + &lcu.AttestedHeader, + spec.Wrap(&lcu.NextSyncCommittee), + &lcu.NextSyncCommitteeBranch, + &lcu.FinalizedHeader, + &lcu.FinalityBranch, + spec.Wrap(&lcu.SyncAggregate), + &lcu.SignatureSlot, + ) +} + +type LightClientFinalityUpdate struct { + AttestedHeader LightClientHeader `yaml:"attested_header" json:"attested_header"` + FinalizedHeader LightClientHeader `yaml:"finalized_header" json:"finalized_header"` + FinalityBranch altair.FinalizedRootProofBranch `yaml:"finality_branch" json:"finality_branch"` + SyncAggregate altair.SyncAggregate `yaml:"sync_aggregate" json:"sync_aggregate"` + SignatureSlot common.Slot `yaml:"signature_slot" json:"signature_slot"` +} + +func LightClientFinalityUpdateType(spec *common.Spec) *view.ContainerTypeDef { + return view.ContainerType("SyncCommittee", []view.FieldDef{ + {Name: "attested_header", Type: LightClientHeaderType}, + {Name: "finalized_header", Type: LightClientHeaderType}, + {Name: "finality_branch", Type: altair.FinalizedRootProofBranchType}, + {Name: "sync_aggregate", Type: altair.SyncAggregateType(spec)}, + {Name: "signature_slot", Type: common.SlotType}, + }) +} + +func (lcfu *LightClientFinalityUpdate) FixedLength(spec *common.Spec) uint64 { + return 0 +} + +func (lcfu *LightClientFinalityUpdate) Deserialize(spec *common.Spec, dr *codec.DecodingReader) error { + return dr.Container(&lcfu.AttestedHeader, &lcfu.FinalizedHeader, &lcfu.FinalityBranch, spec.Wrap(&lcfu.SyncAggregate), &lcfu.SignatureSlot) +} + +func (lcfu *LightClientFinalityUpdate) Serialize(spec *common.Spec, w *codec.EncodingWriter) error { + return w.Container(&lcfu.AttestedHeader, &lcfu.FinalizedHeader, &lcfu.FinalityBranch, spec.Wrap(&lcfu.SyncAggregate), &lcfu.SignatureSlot) +} + +func (lcfu *LightClientFinalityUpdate) ByteLength(spec *common.Spec) uint64 { + return codec.ContainerLength(&lcfu.AttestedHeader, &lcfu.FinalizedHeader, &lcfu.FinalityBranch, spec.Wrap(&lcfu.SyncAggregate), &lcfu.SignatureSlot) +} + +func (lcfu *LightClientFinalityUpdate) HashTreeRoot(spec *common.Spec, hFn tree.HashFn) common.Root { + return hFn.HashTreeRoot( + &lcfu.AttestedHeader, + &lcfu.FinalizedHeader, + &lcfu.FinalityBranch, + spec.Wrap(&lcfu.SyncAggregate), + &lcfu.SignatureSlot, + ) +} + +type LightClientOptimisticUpdate struct { + AttestedHeader LightClientHeader `yaml:"attested_header" json:"attested_header"` + SyncAggregate altair.SyncAggregate `yaml:"sync_aggregate" json:"sync_aggregate"` + SignatureSlot common.Slot `yaml:"signature_slot" json:"signature_slot"` +} + +func LightClientOptimisticUpdateType(spec *common.Spec) *view.ContainerTypeDef { + return view.ContainerType("SyncCommittee", []view.FieldDef{ + {Name: "attested_header", Type: LightClientHeaderType}, + {Name: "finalized_header", Type: common.BeaconBlockHeaderType}, + {Name: "finality_branch", Type: altair.FinalizedRootProofBranchType}, + {Name: "sync_aggregate", Type: altair.SyncAggregateType(spec)}, + {Name: "signature_slot", Type: common.SlotType}, + }) +} + +func (lcou *LightClientOptimisticUpdate) FixedLength(spec *common.Spec) uint64 { + return 0 +} + +func (lcou *LightClientOptimisticUpdate) Deserialize(spec *common.Spec, dr *codec.DecodingReader) error { + return dr.Container(&lcou.AttestedHeader, spec.Wrap(&lcou.SyncAggregate), &lcou.SignatureSlot) +} + +func (lcou *LightClientOptimisticUpdate) Serialize(spec *common.Spec, w *codec.EncodingWriter) error { + return w.Container(&lcou.AttestedHeader, spec.Wrap(&lcou.SyncAggregate), &lcou.SignatureSlot) +} + +func (lcou *LightClientOptimisticUpdate) ByteLength(spec *common.Spec) uint64 { + return codec.ContainerLength(&lcou.AttestedHeader, spec.Wrap(&lcou.SyncAggregate), &lcou.SignatureSlot) +} + +func (lcou *LightClientOptimisticUpdate) HashTreeRoot(spec *common.Spec, hFn tree.HashFn) common.Root { + return hFn.HashTreeRoot( + &lcou.AttestedHeader, + spec.Wrap(&lcou.SyncAggregate), + &lcou.SignatureSlot, + ) +} diff --git a/eth2/beacon/deneb/lightclient.go b/eth2/beacon/deneb/lightclient.go new file mode 100644 index 0000000..922d23b --- /dev/null +++ b/eth2/beacon/deneb/lightclient.go @@ -0,0 +1,243 @@ +package deneb + +import ( + "github.com/protolambda/zrnt/eth2/beacon/altair" + "github.com/protolambda/zrnt/eth2/beacon/capella" + "github.com/protolambda/zrnt/eth2/beacon/common" + "github.com/protolambda/ztyp/codec" + "github.com/protolambda/ztyp/tree" + "github.com/protolambda/ztyp/view" +) + +type LightClientHeader struct { + Beacon common.BeaconBlockHeader `yaml:"beacon" json:"beacon"` + Execution ExecutionPayloadHeader `yaml:"execution" json:"execution"` + ExecutionBranch capella.ExecutionBranch `yaml:"execution_branch" json:"execution_branch"` +} + +var LightClientHeaderType = view.ContainerType("LightClientHeader", []view.FieldDef{ + {Name: "beacon", Type: common.BeaconBlockHeaderType}, + {Name: "execution", Type: ExecutionPayloadHeaderType}, + {Name: "execution_branch", Type: capella.ExecutionBranchType}, +}) + +func (l *LightClientHeader) Deserialize(dr *codec.DecodingReader) error { + return dr.Container(&l.Beacon, &l.Execution, &l.ExecutionBranch) +} + +func (l *LightClientHeader) FixedLength() uint64 { + return LightClientHeaderType.TypeByteLength() +} + +func (l *LightClientHeader) Serialize(w *codec.EncodingWriter) error { + return w.Container(&l.Beacon, &l.Execution, &l.ExecutionBranch) +} + +func (l *LightClientHeader) ByteLength() (out uint64) { + return codec.ContainerLength(&l.Beacon, &l.Execution, &l.ExecutionBranch) +} + +func (l *LightClientHeader) HashTreeRoot(h tree.HashFn) common.Root { + return h.HashTreeRoot(&l.Beacon, &l.Execution, &l.ExecutionBranch) +} + +type LightClientBootstrap struct { + Header LightClientHeader `yaml:"header" json:"header"` + CurrentSyncCommittee common.SyncCommittee `yaml:"current_sync_committee" json:"current_sync_committee"` + CurrentSyncCommitteeBranch altair.SyncCommitteeProofBranch `yaml:"current_sync_committee_branch" json:"current_sync_committee_branch"` +} + +func NewLightClientBootstrapType(spec *common.Spec) *view.ContainerTypeDef { + return view.ContainerType("LightClientHeader", []view.FieldDef{ + {Name: "header", Type: LightClientHeaderType}, + {Name: "next_sync_committee", Type: common.SyncCommitteeType(spec)}, + {Name: "next_sync_committee_branch", Type: altair.SyncCommitteeProofBranchType}, + }) +} + +func (lcb *LightClientBootstrap) FixedLength(spec *common.Spec) uint64 { + return 0 +} + +func (lcb *LightClientBootstrap) Deserialize(spec *common.Spec, dr *codec.DecodingReader) error { + return dr.Container(&lcb.Header, spec.Wrap(&lcb.CurrentSyncCommittee), &lcb.CurrentSyncCommitteeBranch) +} + +func (lcb *LightClientBootstrap) Serialize(spec *common.Spec, w *codec.EncodingWriter) error { + return w.Container(&lcb.Header, spec.Wrap(&lcb.CurrentSyncCommittee), &lcb.CurrentSyncCommitteeBranch) +} + +func (lcb *LightClientBootstrap) ByteLength(spec *common.Spec) uint64 { + return codec.ContainerLength(&lcb.Header, spec.Wrap(&lcb.CurrentSyncCommittee), &lcb.CurrentSyncCommitteeBranch) +} + +func (lcb *LightClientBootstrap) HashTreeRoot(spec *common.Spec, hFn tree.HashFn) common.Root { + return hFn.HashTreeRoot( + &lcb.Header, + spec.Wrap(&lcb.CurrentSyncCommittee), + &lcb.CurrentSyncCommitteeBranch, + ) +} + +func LightClientUpdateType(spec *common.Spec) *view.ContainerTypeDef { + return view.ContainerType("SyncCommittee", []view.FieldDef{ + {Name: "attested_header", Type: common.BeaconBlockHeaderType}, + {Name: "next_sync_committee", Type: common.SyncCommitteeType(spec)}, + {Name: "next_sync_committee_branch", Type: altair.SyncCommitteeProofBranchType}, + {Name: "finalized_header", Type: LightClientHeaderType}, + {Name: "finality_branch", Type: altair.FinalizedRootProofBranchType}, + {Name: "sync_aggregate", Type: altair.SyncAggregateType(spec)}, + {Name: "signature_slot", Type: common.SlotType}, + }) +} + +type LightClientUpdate struct { + // Update beacon block header + AttestedHeader LightClientHeader `yaml:"attested_header" json:"attested_header"` + // Next sync committee corresponding to the header + NextSyncCommittee common.SyncCommittee `yaml:"next_sync_committee" json:"next_sync_committee"` + NextSyncCommitteeBranch altair.SyncCommitteeProofBranch `yaml:"next_sync_committee_branch" json:"next_sync_committee_branch"` + // Finality proof for the update header + FinalizedHeader LightClientHeader `yaml:"finalized_header" json:"finalized_header"` + FinalityBranch altair.FinalizedRootProofBranch `yaml:"finality_branch" json:"finality_branch"` + // Sync committee aggregate signature + SyncAggregate altair.SyncAggregate `yaml:"sync_aggregate" json:"sync_aggregate"` + // Slot at which the aggregate signature was created (untrusted) + SignatureSlot common.Slot `yaml:"signature_slot" json:"signature_slot"` +} + +func (lcu *LightClientUpdate) Deserialize(spec *common.Spec, dr *codec.DecodingReader) error { + return dr.Container( + &lcu.AttestedHeader, + spec.Wrap(&lcu.NextSyncCommittee), + &lcu.NextSyncCommitteeBranch, + &lcu.FinalizedHeader, + &lcu.FinalityBranch, + spec.Wrap(&lcu.SyncAggregate), + &lcu.SignatureSlot, + ) +} + +func (lcu *LightClientUpdate) Serialize(spec *common.Spec, w *codec.EncodingWriter) error { + return w.Container( + &lcu.AttestedHeader, + spec.Wrap(&lcu.NextSyncCommittee), + &lcu.NextSyncCommitteeBranch, + &lcu.FinalizedHeader, + &lcu.FinalityBranch, + spec.Wrap(&lcu.SyncAggregate), + &lcu.SignatureSlot, + ) +} + +func (lcu *LightClientUpdate) ByteLength(spec *common.Spec) uint64 { + return codec.ContainerLength( + &lcu.AttestedHeader, + spec.Wrap(&lcu.NextSyncCommittee), + &lcu.NextSyncCommitteeBranch, + &lcu.FinalizedHeader, + &lcu.FinalityBranch, + spec.Wrap(&lcu.SyncAggregate), + &lcu.SignatureSlot, + ) +} + +func (lcu *LightClientUpdate) FixedLength(spec *common.Spec) uint64 { + return 0 +} + +func (lcu *LightClientUpdate) HashTreeRoot(spec *common.Spec, hFn tree.HashFn) common.Root { + return hFn.HashTreeRoot( + &lcu.AttestedHeader, + spec.Wrap(&lcu.NextSyncCommittee), + &lcu.NextSyncCommitteeBranch, + &lcu.FinalizedHeader, + &lcu.FinalityBranch, + spec.Wrap(&lcu.SyncAggregate), + &lcu.SignatureSlot, + ) +} + +type LightClientFinalityUpdate struct { + AttestedHeader LightClientHeader `yaml:"attested_header" json:"attested_header"` + FinalizedHeader LightClientHeader `yaml:"finalized_header" json:"finalized_header"` + FinalityBranch altair.FinalizedRootProofBranch `yaml:"finality_branch" json:"finality_branch"` + SyncAggregate altair.SyncAggregate `yaml:"sync_aggregate" json:"sync_aggregate"` + SignatureSlot common.Slot `yaml:"signature_slot" json:"signature_slot"` +} + +func LightClientFinalityUpdateType(spec *common.Spec) *view.ContainerTypeDef { + return view.ContainerType("SyncCommittee", []view.FieldDef{ + {Name: "attested_header", Type: LightClientHeaderType}, + {Name: "finalized_header", Type: LightClientHeaderType}, + {Name: "finality_branch", Type: altair.FinalizedRootProofBranchType}, + {Name: "sync_aggregate", Type: altair.SyncAggregateType(spec)}, + {Name: "signature_slot", Type: common.SlotType}, + }) +} + +func (lcfu *LightClientFinalityUpdate) FixedLength(spec *common.Spec) uint64 { + return 0 +} + +func (lcfu *LightClientFinalityUpdate) Deserialize(spec *common.Spec, dr *codec.DecodingReader) error { + return dr.Container(&lcfu.AttestedHeader, &lcfu.FinalizedHeader, &lcfu.FinalityBranch, spec.Wrap(&lcfu.SyncAggregate), &lcfu.SignatureSlot) +} + +func (lcfu *LightClientFinalityUpdate) Serialize(spec *common.Spec, w *codec.EncodingWriter) error { + return w.Container(&lcfu.AttestedHeader, &lcfu.FinalizedHeader, &lcfu.FinalityBranch, spec.Wrap(&lcfu.SyncAggregate), &lcfu.SignatureSlot) +} + +func (lcfu *LightClientFinalityUpdate) ByteLength(spec *common.Spec) uint64 { + return codec.ContainerLength(&lcfu.AttestedHeader, &lcfu.FinalizedHeader, &lcfu.FinalityBranch, spec.Wrap(&lcfu.SyncAggregate), &lcfu.SignatureSlot) +} + +func (lcfu *LightClientFinalityUpdate) HashTreeRoot(spec *common.Spec, hFn tree.HashFn) common.Root { + return hFn.HashTreeRoot( + &lcfu.AttestedHeader, + &lcfu.FinalizedHeader, + &lcfu.FinalityBranch, + spec.Wrap(&lcfu.SyncAggregate), + &lcfu.SignatureSlot, + ) +} + +type LightClientOptimisticUpdate struct { + AttestedHeader LightClientHeader `yaml:"attested_header" json:"attested_header"` + SyncAggregate altair.SyncAggregate `yaml:"sync_aggregate" json:"sync_aggregate"` + SignatureSlot common.Slot `yaml:"signature_slot" json:"signature_slot"` +} + +func LightClientOptimisticUpdateType(spec *common.Spec) *view.ContainerTypeDef { + return view.ContainerType("SyncCommittee", []view.FieldDef{ + {Name: "attested_header", Type: LightClientHeaderType}, + {Name: "finalized_header", Type: common.BeaconBlockHeaderType}, + {Name: "finality_branch", Type: altair.FinalizedRootProofBranchType}, + {Name: "sync_aggregate", Type: altair.SyncAggregateType(spec)}, + {Name: "signature_slot", Type: common.SlotType}, + }) +} + +func (lcou *LightClientOptimisticUpdate) FixedLength(spec *common.Spec) uint64 { + return 0 +} + +func (lcou *LightClientOptimisticUpdate) Deserialize(spec *common.Spec, dr *codec.DecodingReader) error { + return dr.Container(&lcou.AttestedHeader, spec.Wrap(&lcou.SyncAggregate), &lcou.SignatureSlot) +} + +func (lcou *LightClientOptimisticUpdate) Serialize(spec *common.Spec, w *codec.EncodingWriter) error { + return w.Container(&lcou.AttestedHeader, spec.Wrap(&lcou.SyncAggregate), &lcou.SignatureSlot) +} + +func (lcou *LightClientOptimisticUpdate) ByteLength(spec *common.Spec) uint64 { + return codec.ContainerLength(&lcou.AttestedHeader, spec.Wrap(&lcou.SyncAggregate), &lcou.SignatureSlot) +} + +func (lcou *LightClientOptimisticUpdate) HashTreeRoot(spec *common.Spec, hFn tree.HashFn) common.Root { + return hFn.HashTreeRoot( + &lcou.AttestedHeader, + spec.Wrap(&lcou.SyncAggregate), + &lcou.SignatureSlot, + ) +} diff --git a/tests/spec/test_runners/ssz_static/ssz_static_test.go b/tests/spec/test_runners/ssz_static/ssz_static_test.go index 6a9819e..cf1bf9c 100644 --- a/tests/spec/test_runners/ssz_static/ssz_static_test.go +++ b/tests/spec/test_runners/ssz_static/ssz_static_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/protolambda/zrnt/eth2/beacon/capella" + "github.com/protolambda/zrnt/eth2/beacon/deneb" "github.com/golang/snappy" "github.com/protolambda/ztyp/codec" @@ -102,6 +103,7 @@ var objs = map[test_util.ForkName]map[string]ObjAllocator{ "altair": {}, "bellatrix": {}, "capella": {}, + "deneb": {}, } func init() { @@ -148,6 +150,10 @@ func init() { objs["altair"]["LightClientSnapshot"] = func() interface{} { return new(altair.LightClientSnapshot) } objs["altair"]["LightClientUpdate"] = func() interface{} { return new(altair.LightClientUpdate) } + objs["altair"]["LightClientHeader"] = func() interface{} { return new(altair.LightClientHeader) } + objs["altair"]["LightClientBootstrap"] = func() interface{} { return new(altair.LightClientBootstrap) } + objs["altair"]["LightClientFinalityUpdate"] = func() interface{} { return new(altair.LightClientFinalityUpdate) } + objs["altair"]["LightClientOptimisticUpdate"] = func() interface{} { return new(altair.LightClientOptimisticUpdate) } objs["altair"]["SyncAggregatorSelectionData"] = func() interface{} { return new(altair.SyncAggregatorSelectionData) } objs["altair"]["SyncCommitteeContribution"] = func() interface{} { return new(altair.SyncCommitteeContribution) } objs["altair"]["ContributionAndProof"] = func() interface{} { return new(altair.ContributionAndProof) } @@ -172,6 +178,20 @@ func init() { objs["capella"]["Withdrawal"] = func() interface{} { return new(common.Withdrawal) } objs["capella"]["BLSToExecutionChange"] = func() interface{} { return new(common.BLSToExecutionChange) } objs["capella"]["SignedBLSToExecutionChange"] = func() interface{} { return new(common.SignedBLSToExecutionChange) } + objs["capella"]["LightClientHeader"] = func() interface{} { return new(capella.LightClientHeader) } + objs["capella"]["LightClientBootstrap"] = func() interface{} { return new(capella.LightClientBootstrap) } + objs["capella"]["LightClientUpdate"] = func() interface{} { return new(capella.LightClientUpdate) } + objs["capella"]["LightClientFinalityUpdate"] = func() interface{} { return new(capella.LightClientFinalityUpdate) } + objs["capella"]["LightClientOptimisticUpdate"] = func() interface{} { return new(capella.LightClientOptimisticUpdate) } + + objs["deneb"]["SignedBeaconBlock"] = func() interface{} { return new(deneb.SignedBeaconBlock) } + objs["deneb"]["ExecutionPayload"] = func() interface{} { return new(deneb.ExecutionPayload) } + objs["deneb"]["ExecutionPayloadHeader"] = func() interface{} { return new(deneb.ExecutionPayloadHeader) } + objs["deneb"]["LightClientHeader"] = func() interface{} { return new(deneb.LightClientHeader) } + objs["deneb"]["LightClientBootstrap"] = func() interface{} { return new(deneb.LightClientBootstrap) } + objs["deneb"]["LightClientUpdate"] = func() interface{} { return new(deneb.LightClientUpdate) } + objs["deneb"]["LightClientFinalityUpdate"] = func() interface{} { return new(deneb.LightClientFinalityUpdate) } + objs["deneb"]["LightClientOptimisticUpdate"] = func() interface{} { return new(deneb.LightClientOptimisticUpdate) } } type RootsYAML struct {