Skip to content

Commit

Permalink
Added SSZ support for Phase0 state. (#7065)
Browse files Browse the repository at this point in the history
  • Loading branch information
Giulio2002 committed Mar 9, 2023
1 parent d5fbc50 commit 7f6d1c9
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 168 deletions.
30 changes: 6 additions & 24 deletions cl/cltypes/beacon_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,29 +188,11 @@ func (b *BeaconBody) EncodeSSZ(dst []byte) ([]byte, error) {
}
}
// Write attester slashings as a dynamic list.
subOffset := len(b.AttesterSlashings) * 4
for _, attesterSlashing := range b.AttesterSlashings {
buf = append(buf, ssz_utils.OffsetSSZ(uint32(subOffset))...)
subOffset += attesterSlashing.EncodingSizeSSZ()
}

for _, attesterSlashing := range b.AttesterSlashings {
buf, err = attesterSlashing.EncodeSSZ(buf)
if err != nil {
return nil, err
}
}
// Attestation
subOffset = len(b.Attestations) * 4
for _, attestation := range b.Attestations {
buf = append(buf, ssz_utils.OffsetSSZ(uint32(subOffset))...)
subOffset += attestation.EncodingSizeSSZ()
if buf, err = ssz_utils.EncodeDynamicList(buf, b.AttesterSlashings); err != nil {
return nil, err
}
for _, attestation := range b.Attestations {
buf, err = attestation.EncodeSSZ(buf)
if err != nil {
return nil, err
}
if buf, err = ssz_utils.EncodeDynamicList(buf, b.Attestations); err != nil {
return nil, err
}

for _, deposit := range b.Deposits {
Expand Down Expand Up @@ -323,12 +305,12 @@ func (b *BeaconBody) DecodeSSZWithVersion(buf []byte, version int) error {
return err
}
// Decode attester slashings
b.AttesterSlashings, err = ssz_utils.DecodeDynamicList[*AttesterSlashing](buf, offsetAttesterSlashings, offsetAttestations, uint32(MaxAttesterSlashings))
b.AttesterSlashings, err = ssz_utils.DecodeDynamicList[*AttesterSlashing](buf, offsetAttesterSlashings, offsetAttestations, MaxAttesterSlashings)
if err != nil {
return err
}
// Decode attestations
b.Attestations, err = ssz_utils.DecodeDynamicList[*Attestation](buf, offsetAttestations, offsetDeposits, uint32(MaxAttestations))
b.Attestations, err = ssz_utils.DecodeDynamicList[*Attestation](buf, offsetAttestations, offsetDeposits, MaxAttestations)
if err != nil {
return err
}
Expand Down
21 changes: 19 additions & 2 deletions cl/cltypes/ssz_utils/ssz.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func UnmarshalUint64SSZ(x []byte) uint64 {
return binary.LittleEndian.Uint64(x)
}

func DecodeDynamicList[T Unmarshaler](bytes []byte, start, end, max uint32) ([]T, error) {
func DecodeDynamicList[T Unmarshaler](bytes []byte, start, end uint32, max uint64) ([]T, error) {
if start > end || len(bytes) < int(end) {
return nil, ErrBadOffset
}
Expand All @@ -82,7 +82,7 @@ func DecodeDynamicList[T Unmarshaler](bytes []byte, start, end, max uint32) ([]T
elementsNum = currentOffset / 4
}
inPos := 4
if elementsNum > max {
if uint64(elementsNum) > max {
return nil, ErrTooBigList
}
objs := make([]T, elementsNum)
Expand Down Expand Up @@ -187,3 +187,20 @@ func DecodeString(bytes []byte, start, end, max uint64) ([]byte, error) {
}
return buf, nil
}

func EncodeDynamicList[T Marshaler](buf []byte, objs []T) (dst []byte, err error) {
dst = buf
// Attestation
subOffset := len(objs) * 4
for _, attestation := range objs {
dst = append(dst, OffsetSSZ(uint32(subOffset))...)
subOffset += attestation.EncodingSizeSSZ()
}
for _, obj := range objs {
dst, err = obj.EncodeSSZ(dst)
if err != nil {
return
}
}
return
}
61 changes: 40 additions & 21 deletions cmd/erigon-cl/core/state/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func (b *BeaconState) computeDirtyLeaves() error {

// Field(9): Eth1DataVotes
if b.isLeafDirty(Eth1DataVotesLeafIndex) {
root, err := state_encoding.Eth1DataVectorRoot(b.eth1DataVotes)
root, err := merkle_tree.ListObjectSSZRoot(b.eth1DataVotes, maxEth1Votes)
if err != nil {
return err
}
Expand All @@ -110,7 +110,7 @@ func (b *BeaconState) computeDirtyLeaves() error {

// Field(11): Validators
if b.isLeafDirty(ValidatorsLeafIndex) {
root, err := state_encoding.ValidatorsVectorRoot(b.validators)
root, err := merkle_tree.ListObjectSSZRoot(b.validators, state_encoding.ValidatorRegistryLimit)
if err != nil {
return err
}
Expand Down Expand Up @@ -143,18 +143,34 @@ func (b *BeaconState) computeDirtyLeaves() error {
}
b.updateLeaf(SlashingsLeafIndex, root)
}

// Field(15) and Field(16) are special due to the fact that they have different format in Phase0.

// Field(15): PreviousEpochParticipation
if b.isLeafDirty(PreviousEpochParticipationLeafIndex) {
root, err := merkle_tree.BitlistRootWithLimitForState(b.previousEpochParticipation.Bytes(), state_encoding.ValidatorRegistryLimit)
var root libcommon.Hash
var err error
if b.version == clparams.Phase0Version {
root, err = merkle_tree.ListObjectSSZRoot(b.previousEpochAttestations, b.beaconConfig.SlotsPerEpoch*b.beaconConfig.MaxAttestations)
} else {
root, err = merkle_tree.BitlistRootWithLimitForState(b.previousEpochParticipation.Bytes(), state_encoding.ValidatorRegistryLimit)
}
if err != nil {
return err
}

b.updateLeaf(PreviousEpochParticipationLeafIndex, root)
}

// Field(16): CurrentEpochParticipation
if b.isLeafDirty(CurrentEpochParticipationLeafIndex) {
root, err := merkle_tree.BitlistRootWithLimitForState(b.currentEpochParticipation.Bytes(), state_encoding.ValidatorRegistryLimit)
var root libcommon.Hash
var err error
if b.version == clparams.Phase0Version {
root, err = merkle_tree.ListObjectSSZRoot(b.currentEpochAttestations, b.beaconConfig.SlotsPerEpoch*b.beaconConfig.MaxAttestations)
} else {
root, err = merkle_tree.BitlistRootWithLimitForState(b.currentEpochParticipation.Bytes(), state_encoding.ValidatorRegistryLimit)
}
if err != nil {
return err
}
Expand Down Expand Up @@ -194,7 +210,9 @@ func (b *BeaconState) computeDirtyLeaves() error {
}
b.updateLeaf(FinalizedCheckpointLeafIndex, checkpointRoot)
}

if b.version == clparams.Phase0Version {
return nil
}
// Field(21): Inactivity Scores
if b.isLeafDirty(InactivityScoresLeafIndex) {
root, err := merkle_tree.Uint64ListRootWithLimit(b.inactivityScores, state_encoding.ValidatorLimitForBalancesChunks())
Expand Down Expand Up @@ -234,26 +252,27 @@ func (b *BeaconState) computeDirtyLeaves() error {
b.updateLeaf(LatestExecutionPayloadHeaderLeafIndex, headerRoot)
}

if b.version >= clparams.CapellaVersion {
if b.version < clparams.CapellaVersion {
return nil
}

// Field(25): NextWithdrawalIndex
if b.isLeafDirty(NextWithdrawalIndexLeafIndex) {
b.updateLeaf(NextWithdrawalIndexLeafIndex, merkle_tree.Uint64Root(b.nextWithdrawalIndex))
}
// Field(25): NextWithdrawalIndex
if b.isLeafDirty(NextWithdrawalIndexLeafIndex) {
b.updateLeaf(NextWithdrawalIndexLeafIndex, merkle_tree.Uint64Root(b.nextWithdrawalIndex))
}

// Field(26): NextWithdrawalValidatorIndex
if b.isLeafDirty(NextWithdrawalValidatorIndexLeafIndex) {
b.updateLeaf(NextWithdrawalValidatorIndexLeafIndex, merkle_tree.Uint64Root(b.nextWithdrawalValidatorIndex))
}
// Field(26): NextWithdrawalValidatorIndex
if b.isLeafDirty(NextWithdrawalValidatorIndexLeafIndex) {
b.updateLeaf(NextWithdrawalValidatorIndexLeafIndex, merkle_tree.Uint64Root(b.nextWithdrawalValidatorIndex))
}

// Field(27): HistoricalSummaries
if b.isLeafDirty(HistoricalSummariesLeafIndex) {
root, err := merkle_tree.ListObjectSSZRoot(b.historicalSummaries, state_encoding.HistoricalRootsLength)
if err != nil {
return err
}
b.updateLeaf(HistoricalSummariesLeafIndex, root)
// Field(27): HistoricalSummaries
if b.isLeafDirty(HistoricalSummariesLeafIndex) {
root, err := merkle_tree.ListObjectSSZRoot(b.historicalSummaries, state_encoding.HistoricalRootsLength)
if err != nil {
return err
}
b.updateLeaf(HistoricalSummariesLeafIndex, root)
}

return nil
Expand Down
Loading

0 comments on commit 7f6d1c9

Please sign in to comment.