Skip to content

Commit

Permalink
Add SingleAttestation container
Browse files Browse the repository at this point in the history
  • Loading branch information
Bez625 committed Nov 4, 2024
1 parent 759b0ac commit 33740bb
Show file tree
Hide file tree
Showing 7 changed files with 290 additions and 4 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,8 @@ coverage.html
# Vim
*.sw?

# Intellij and friends
.idea/

# Local TODO
TODO.md
6 changes: 3 additions & 3 deletions spec/electra/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ package electra

//nolint:revive
// Need to `go install github.com/ferranbt/fastssz/sszgen@latest` for this to work.
//go:generate rm -f aggregateandproof_ssz.go attestation_ssz.go attesterslashing_ssz.go beaconblockbody_ssz.go beaconblock_ssz.go beaconstate_ssz.go consolidation_ssz.go consolidationrequest_ssz.go depositrequest_ssz.go withdrawalrequest_ssz.go executionrequests_ssz.go pendingconsolidation_ssz.go pendingdeposit_ssz.go pendingpartialwithdrawal_ssz.go signedaggregateandproof_ssz.go signedbeaconblock_ssz.go
//go:generate sszgen --suffix=ssz --path . --include ../phase0,../altair,../bellatrix,../capella,../deneb --objs AggregateAndProof,Attestation,AttesterSlashing,BeaconBlockBody,BeaconBlock,BeaconState,Consolidation,ConsolidationRequest,DepositRequest,WithdrawalRequest,ExecutionRequests,PendingConsolidation,PendingDeposit,PendingPartialWithdrawal,SignedAggregateAndProof,SignedBeaconBlock
//go:generate goimports -w aggregateandproof_ssz.go attestation_ssz.go attesterslashing_ssz.go beaconblockbody_ssz.go beaconblock_ssz.go beaconstate_ssz.go consolidation_ssz.go consolidationrequest_ssz.go depositrequest_ssz.go withdrawalrequest_ssz.go executionrequests_ssz.go pendingconsolidation_ssz.go pendingdeposit_ssz.go pendingpartialwithdrawal_ssz.go signedaggregateandproof_ssz.go signedbeaconblock_ssz.go
//go:generate rm -f aggregateandproof_ssz.go attestation_ssz.go attesterslashing_ssz.go beaconblockbody_ssz.go beaconblock_ssz.go beaconstate_ssz.go consolidation_ssz.go consolidationrequest_ssz.go depositrequest_ssz.go withdrawalrequest_ssz.go executionrequests_ssz.go pendingconsolidation_ssz.go pendingdeposit_ssz.go pendingpartialwithdrawal_ssz.go signedaggregateandproof_ssz.go signedbeaconblock_ssz.go singleattestation_ssz.go
//go:generate sszgen --suffix=ssz --path . --include ../phase0,../altair,../bellatrix,../capella,../deneb --objs AggregateAndProof,Attestation,AttesterSlashing,BeaconBlockBody,BeaconBlock,BeaconState,Consolidation,ConsolidationRequest,DepositRequest,WithdrawalRequest,ExecutionRequests,PendingConsolidation,PendingDeposit,PendingPartialWithdrawal,SignedAggregateAndProof,SignedBeaconBlock,SingleAttestation
//go:generate goimports -w aggregateandproof_ssz.go attestation_ssz.go attesterslashing_ssz.go beaconblockbody_ssz.go beaconblock_ssz.go beaconstate_ssz.go consolidation_ssz.go consolidationrequest_ssz.go depositrequest_ssz.go withdrawalrequest_ssz.go executionrequests_ssz.go pendingconsolidation_ssz.go pendingdeposit_ssz.go pendingpartialwithdrawal_ssz.go signedaggregateandproof_ssz.go signedbeaconblock_ssz.go singleattestation_ssz.go
40 changes: 40 additions & 0 deletions spec/electra/singleattestation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright © 2024 Attestant Limited.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package electra

import (
"fmt"

"github.com/attestantio/go-eth2-client/spec/phase0"
"github.com/goccy/go-yaml"
)

// SingleAttestation is a new struct in electra for propagating network only Attestations. See:
// https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#singleattestation.
type SingleAttestation struct {
CommitteeIndex phase0.CommitteeIndex
AttesterIndex phase0.ValidatorIndex
Data *phase0.AttestationData
Signature phase0.BLSSignature `ssz-size:"96"`
}

// String returns a string version of the structure.
func (a *SingleAttestation) String() string {
data, err := yaml.Marshal(a)
if err != nil {
return fmt.Sprintf("ERR: %v", err)
}

return string(data)
}
80 changes: 80 additions & 0 deletions spec/electra/singleattestation_json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright © 2024 Attestant Limited.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package electra

import (
"encoding/hex"
"encoding/json"
"fmt"
"strings"

"github.com/attestantio/go-eth2-client/spec/phase0"
"github.com/pkg/errors"
)

// singleAttestationJSON is the spec representation of the struct.
type singleAttestationJSON struct {
CommitteeIndex string `json:"committee_index"`
AttesterIndex string `json:"attester_index"`
Data *phase0.AttestationData `json:"data"`
Signature string `json:"signature"`
}

// MarshalJSON implements json.Marshaler.
func (a *SingleAttestation) MarshalJSON() ([]byte, error) {
return json.Marshal(&singleAttestationJSON{
CommitteeIndex: fmt.Sprintf("%d", a.CommitteeIndex),
AttesterIndex: fmt.Sprintf("%d", a.AttesterIndex),
Data: a.Data,
Signature: fmt.Sprintf("%#x", a.Signature),
})
}

// UnmarshalJSON implements json.Unmarshaler.
func (a *SingleAttestation) UnmarshalJSON(input []byte) error {
var singleAttestationJSON singleAttestationJSON
err := json.Unmarshal(input, &singleAttestationJSON)
if err != nil {
return errors.Wrap(err, "invalid JSON")
}

return a.unpack(&singleAttestationJSON)
}

func (a *SingleAttestation) unpack(singleAttestationJSON *singleAttestationJSON) error {
var err error
if singleAttestationJSON.CommitteeIndex == "" {
return errors.New("committee index missing")
}
if singleAttestationJSON.AttesterIndex == "" {
return errors.New("attester index missing")
}
a.Data = singleAttestationJSON.Data
if a.Data == nil {
return errors.New("data missing")
}
if singleAttestationJSON.Signature == "" {
return errors.New("signature missing")
}
signature, err := hex.DecodeString(strings.TrimPrefix(singleAttestationJSON.Signature, "0x"))
if err != nil {
return errors.Wrap(err, "invalid value for signature")
}
if len(signature) != phase0.SignatureLength {
return errors.New("incorrect length for signature")
}
copy(a.Signature[:], signature)

return nil
}
107 changes: 107 additions & 0 deletions spec/electra/singleattestation_ssz.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 56 additions & 0 deletions spec/electra/singleattestation_yaml.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright © 2024 Attestant Limited.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package electra

import (
"bytes"
"fmt"

"github.com/attestantio/go-eth2-client/spec/phase0"
"github.com/goccy/go-yaml"
)

// singleAttestationYAML is the spec representation of the struct.
type singleAttestationYAML struct {
CommitteeIndex string `yaml:"committee_index"`
AttesterIndex string `yaml:"attester_index"`
Data *phase0.AttestationData `yaml:"data"`
Signature string `yaml:"signature"`
}

// MarshalYAML implements yaml.Marshaller.
func (a *SingleAttestation) MarshalYAML() ([]byte, error) {
yamlBytes, err := yaml.MarshalWithOptions(&singleAttestationYAML{
CommitteeIndex: fmt.Sprintf("%d", a.CommitteeIndex),
AttesterIndex: fmt.Sprintf("%d", a.AttesterIndex),
Data: a.Data,
Signature: fmt.Sprintf("%#x", a.Signature),
}, yaml.Flow(true))
if err != nil {
return nil, err
}

return bytes.ReplaceAll(yamlBytes, []byte(`"`), []byte(`'`)), nil
}

// UnmarshalYAML implements yaml.Unmarshaler.
func (a *SingleAttestation) UnmarshalYAML(input []byte) error {
// We unmarshal to the JSON struct to save on duplicate code.
var singleAttestationJSON singleAttestationJSON
if err := yaml.Unmarshal(input, &singleAttestationJSON); err != nil {
return err
}

return a.unpack(&singleAttestationJSON)
}
2 changes: 1 addition & 1 deletion spec/phase0/attestationdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func (a *AttestationData) UnmarshalYAML(input []byte) error {
return a.unpack(&attestationDataJSON)
}

// String provids a string representation of the struct.
// String provides a string representation of the struct.
func (a *AttestationData) String() string {
data, err := yaml.Marshal(a)
if err != nil {
Expand Down

0 comments on commit 33740bb

Please sign in to comment.