mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 22:07:59 -05:00
Compare commits
1 Commits
devnet-2-d
...
move-sig-v
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d60c2a125 |
@@ -317,94 +317,6 @@ type BlindedBeaconBlockBodyDeneb struct {
|
||||
BlobKzgCommitments []string `json:"blob_kzg_commitments"`
|
||||
}
|
||||
|
||||
type SignedBeaconBlockContentsElectra struct {
|
||||
SignedBlock *SignedBeaconBlockElectra `json:"signed_block"`
|
||||
KzgProofs []string `json:"kzg_proofs"`
|
||||
Blobs []string `json:"blobs"`
|
||||
}
|
||||
|
||||
type BeaconBlockContentsElectra struct {
|
||||
Block *BeaconBlockElectra `json:"block"`
|
||||
KzgProofs []string `json:"kzg_proofs"`
|
||||
Blobs []string `json:"blobs"`
|
||||
}
|
||||
|
||||
type SignedBeaconBlockElectra struct {
|
||||
Message *BeaconBlockElectra `json:"message"`
|
||||
Signature string `json:"signature"`
|
||||
}
|
||||
|
||||
var _ SignedMessageJsoner = &SignedBeaconBlockElectra{}
|
||||
|
||||
func (s *SignedBeaconBlockElectra) MessageRawJson() ([]byte, error) {
|
||||
return json.Marshal(s.Message)
|
||||
}
|
||||
|
||||
func (s *SignedBeaconBlockElectra) SigString() string {
|
||||
return s.Signature
|
||||
}
|
||||
|
||||
type BeaconBlockElectra struct {
|
||||
Slot string `json:"slot"`
|
||||
ProposerIndex string `json:"proposer_index"`
|
||||
ParentRoot string `json:"parent_root"`
|
||||
StateRoot string `json:"state_root"`
|
||||
Body *BeaconBlockBodyElectra `json:"body"`
|
||||
}
|
||||
|
||||
type BeaconBlockBodyElectra struct {
|
||||
RandaoReveal string `json:"randao_reveal"`
|
||||
Eth1Data *Eth1Data `json:"eth1_data"`
|
||||
Graffiti string `json:"graffiti"`
|
||||
ProposerSlashings []*ProposerSlashing `json:"proposer_slashings"`
|
||||
AttesterSlashings []*AttesterSlashingElectra `json:"attester_slashings"`
|
||||
Attestations []*AttestationElectra `json:"attestations"`
|
||||
Deposits []*Deposit `json:"deposits"`
|
||||
VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits"`
|
||||
SyncAggregate *SyncAggregate `json:"sync_aggregate"`
|
||||
ExecutionPayload *ExecutionPayloadElectra `json:"execution_payload"`
|
||||
BLSToExecutionChanges []*SignedBLSToExecutionChange `json:"bls_to_execution_changes"`
|
||||
BlobKzgCommitments []string `json:"blob_kzg_commitments"`
|
||||
}
|
||||
|
||||
type BlindedBeaconBlockElectra struct {
|
||||
Slot string `json:"slot"`
|
||||
ProposerIndex string `json:"proposer_index"`
|
||||
ParentRoot string `json:"parent_root"`
|
||||
StateRoot string `json:"state_root"`
|
||||
Body *BlindedBeaconBlockBodyElectra `json:"body"`
|
||||
}
|
||||
|
||||
type SignedBlindedBeaconBlockElectra struct {
|
||||
Message *BlindedBeaconBlockElectra `json:"message"`
|
||||
Signature string `json:"signature"`
|
||||
}
|
||||
|
||||
var _ SignedMessageJsoner = &SignedBlindedBeaconBlockElectra{}
|
||||
|
||||
func (s *SignedBlindedBeaconBlockElectra) MessageRawJson() ([]byte, error) {
|
||||
return json.Marshal(s.Message)
|
||||
}
|
||||
|
||||
func (s *SignedBlindedBeaconBlockElectra) SigString() string {
|
||||
return s.Signature
|
||||
}
|
||||
|
||||
type BlindedBeaconBlockBodyElectra struct {
|
||||
RandaoReveal string `json:"randao_reveal"`
|
||||
Eth1Data *Eth1Data `json:"eth1_data"`
|
||||
Graffiti string `json:"graffiti"`
|
||||
ProposerSlashings []*ProposerSlashing `json:"proposer_slashings"`
|
||||
AttesterSlashings []*AttesterSlashingElectra `json:"attester_slashings"`
|
||||
Attestations []*AttestationElectra `json:"attestations"`
|
||||
Deposits []*Deposit `json:"deposits"`
|
||||
VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits"`
|
||||
SyncAggregate *SyncAggregate `json:"sync_aggregate"`
|
||||
ExecutionPayloadHeader *ExecutionPayloadHeaderElectra `json:"execution_payload_header"`
|
||||
BLSToExecutionChanges []*SignedBLSToExecutionChange `json:"bls_to_execution_changes"`
|
||||
BlobKzgCommitments []string `json:"blob_kzg_commitments"`
|
||||
}
|
||||
|
||||
type SignedBeaconBlockHeaderContainer struct {
|
||||
Header *SignedBeaconBlockHeader `json:"header"`
|
||||
Root string `json:"root"`
|
||||
@@ -533,49 +445,3 @@ type ExecutionPayloadHeaderDeneb struct {
|
||||
BlobGasUsed string `json:"blob_gas_used"`
|
||||
ExcessBlobGas string `json:"excess_blob_gas"`
|
||||
}
|
||||
|
||||
type ExecutionPayloadElectra struct {
|
||||
ParentHash string `json:"parent_hash"`
|
||||
FeeRecipient string `json:"fee_recipient"`
|
||||
StateRoot string `json:"state_root"`
|
||||
ReceiptsRoot string `json:"receipts_root"`
|
||||
LogsBloom string `json:"logs_bloom"`
|
||||
PrevRandao string `json:"prev_randao"`
|
||||
BlockNumber string `json:"block_number"`
|
||||
GasLimit string `json:"gas_limit"`
|
||||
GasUsed string `json:"gas_used"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
ExtraData string `json:"extra_data"`
|
||||
BaseFeePerGas string `json:"base_fee_per_gas"`
|
||||
BlockHash string `json:"block_hash"`
|
||||
Transactions []string `json:"transactions"`
|
||||
Withdrawals []*Withdrawal `json:"withdrawals"`
|
||||
BlobGasUsed string `json:"blob_gas_used"`
|
||||
ExcessBlobGas string `json:"excess_blob_gas"`
|
||||
DepositRequests []*DepositRequest `json:"deposit_requests"`
|
||||
WithdrawalRequests []*WithdrawalRequest `json:"withdrawal_requests"`
|
||||
ConsolidationRequests []*ConsolidationRequest `json:"consolidation_requests"`
|
||||
}
|
||||
|
||||
type ExecutionPayloadHeaderElectra struct {
|
||||
ParentHash string `json:"parent_hash"`
|
||||
FeeRecipient string `json:"fee_recipient"`
|
||||
StateRoot string `json:"state_root"`
|
||||
ReceiptsRoot string `json:"receipts_root"`
|
||||
LogsBloom string `json:"logs_bloom"`
|
||||
PrevRandao string `json:"prev_randao"`
|
||||
BlockNumber string `json:"block_number"`
|
||||
GasLimit string `json:"gas_limit"`
|
||||
GasUsed string `json:"gas_used"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
ExtraData string `json:"extra_data"`
|
||||
BaseFeePerGas string `json:"base_fee_per_gas"`
|
||||
BlockHash string `json:"block_hash"`
|
||||
TransactionsRoot string `json:"transactions_root"`
|
||||
WithdrawalsRoot string `json:"withdrawals_root"`
|
||||
BlobGasUsed string `json:"blob_gas_used"`
|
||||
ExcessBlobGas string `json:"excess_blob_gas"`
|
||||
DepositRequestsRoot string `json:"deposit_requests_root"`
|
||||
WithdrawalRequestsRoot string `json:"withdrawal_requests_root"`
|
||||
ConsolidationRequestsRoot string `json:"consolidation_requests_root"`
|
||||
}
|
||||
|
||||
@@ -340,42 +340,6 @@ func (a *AggregateAttestationAndProof) ToConsensus() (*eth.AggregateAttestationA
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *SignedAggregateAttestationAndProofElectra) ToConsensus() (*eth.SignedAggregateAttestationAndProofElectra, error) {
|
||||
msg, err := s.Message.ToConsensus()
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "Message")
|
||||
}
|
||||
sig, err := bytesutil.DecodeHexWithLength(s.Signature, fieldparams.BLSSignatureLength)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "Signature")
|
||||
}
|
||||
|
||||
return ð.SignedAggregateAttestationAndProofElectra{
|
||||
Message: msg,
|
||||
Signature: sig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *AggregateAttestationAndProofElectra) ToConsensus() (*eth.AggregateAttestationAndProofElectra, error) {
|
||||
aggIndex, err := strconv.ParseUint(a.AggregatorIndex, 10, 64)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "AggregatorIndex")
|
||||
}
|
||||
agg, err := a.Aggregate.ToConsensus()
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "Aggregate")
|
||||
}
|
||||
proof, err := bytesutil.DecodeHexWithLength(a.SelectionProof, 96)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "SelectionProof")
|
||||
}
|
||||
return ð.AggregateAttestationAndProofElectra{
|
||||
AggregatorIndex: primitives.ValidatorIndex(aggIndex),
|
||||
Aggregate: agg,
|
||||
SelectionProof: proof,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *Attestation) ToConsensus() (*eth.Attestation, error) {
|
||||
aggBits, err := hexutil.Decode(a.AggregationBits)
|
||||
if err != nil {
|
||||
@@ -405,41 +369,6 @@ func AttFromConsensus(a *eth.Attestation) *Attestation {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AttestationElectra) ToConsensus() (*eth.AttestationElectra, error) {
|
||||
aggBits, err := hexutil.Decode(a.AggregationBits)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "AggregationBits")
|
||||
}
|
||||
data, err := a.Data.ToConsensus()
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "Data")
|
||||
}
|
||||
sig, err := bytesutil.DecodeHexWithLength(a.Signature, fieldparams.BLSSignatureLength)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "Signature")
|
||||
}
|
||||
committeeBits, err := hexutil.Decode(a.CommitteeBits)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "CommitteeBits")
|
||||
}
|
||||
|
||||
return ð.AttestationElectra{
|
||||
AggregationBits: aggBits,
|
||||
Data: data,
|
||||
Signature: sig,
|
||||
CommitteeBits: committeeBits,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func AttElectraFromConsensus(a *eth.AttestationElectra) *AttestationElectra {
|
||||
return &AttestationElectra{
|
||||
AggregationBits: hexutil.Encode(a.AggregationBits),
|
||||
Data: AttDataFromConsensus(a.Data),
|
||||
Signature: hexutil.Encode(a.Signature),
|
||||
CommitteeBits: hexutil.Encode(a.CommitteeBits),
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AttestationData) ToConsensus() (*eth.AttestationData, error) {
|
||||
slot, err := strconv.ParseUint(a.Slot, 10, 64)
|
||||
if err != nil {
|
||||
@@ -694,18 +623,6 @@ func (s *AttesterSlashing) ToConsensus() (*eth.AttesterSlashing, error) {
|
||||
return ð.AttesterSlashing{Attestation_1: att1, Attestation_2: att2}, nil
|
||||
}
|
||||
|
||||
func (s *AttesterSlashingElectra) ToConsensus() (*eth.AttesterSlashingElectra, error) {
|
||||
att1, err := s.Attestation1.ToConsensus()
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "Attestation1")
|
||||
}
|
||||
att2, err := s.Attestation2.ToConsensus()
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "Attestation2")
|
||||
}
|
||||
return ð.AttesterSlashingElectra{Attestation_1: att1, Attestation_2: att2}, nil
|
||||
}
|
||||
|
||||
func (a *IndexedAttestation) ToConsensus() (*eth.IndexedAttestation, error) {
|
||||
indices := make([]uint64, len(a.AttestingIndices))
|
||||
var err error
|
||||
@@ -731,31 +648,6 @@ func (a *IndexedAttestation) ToConsensus() (*eth.IndexedAttestation, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *IndexedAttestationElectra) ToConsensus() (*eth.IndexedAttestationElectra, error) {
|
||||
indices := make([]uint64, len(a.AttestingIndices))
|
||||
var err error
|
||||
for i, ix := range a.AttestingIndices {
|
||||
indices[i], err = strconv.ParseUint(ix, 10, 64)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, fmt.Sprintf("AttestingIndices[%d]", i))
|
||||
}
|
||||
}
|
||||
data, err := a.Data.ToConsensus()
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "Data")
|
||||
}
|
||||
sig, err := bytesutil.DecodeHexWithLength(a.Signature, fieldparams.BLSSignatureLength)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "Signature")
|
||||
}
|
||||
|
||||
return ð.IndexedAttestationElectra{
|
||||
AttestingIndices: indices,
|
||||
Data: data,
|
||||
Signature: sig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func WithdrawalsFromConsensus(ws []*enginev1.Withdrawal) []*Withdrawal {
|
||||
result := make([]*Withdrawal, len(ws))
|
||||
for i, w := range ws {
|
||||
@@ -773,126 +665,6 @@ func WithdrawalFromConsensus(w *enginev1.Withdrawal) *Withdrawal {
|
||||
}
|
||||
}
|
||||
|
||||
func WithdrawalRequestsFromConsensus(ws []*enginev1.WithdrawalRequest) []*WithdrawalRequest {
|
||||
result := make([]*WithdrawalRequest, len(ws))
|
||||
for i, w := range ws {
|
||||
result[i] = WithdrawalRequestFromConsensus(w)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func WithdrawalRequestFromConsensus(w *enginev1.WithdrawalRequest) *WithdrawalRequest {
|
||||
return &WithdrawalRequest{
|
||||
SourceAddress: hexutil.Encode(w.SourceAddress),
|
||||
ValidatorPubkey: hexutil.Encode(w.ValidatorPubkey),
|
||||
Amount: fmt.Sprintf("%d", w.Amount),
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WithdrawalRequest) ToConsensus() (*enginev1.WithdrawalRequest, error) {
|
||||
src, err := bytesutil.DecodeHexWithLength(w.SourceAddress, common.AddressLength)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "SourceAddress")
|
||||
}
|
||||
pubkey, err := bytesutil.DecodeHexWithLength(w.ValidatorPubkey, fieldparams.BLSPubkeyLength)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "ValidatorPubkey")
|
||||
}
|
||||
amount, err := strconv.ParseUint(w.Amount, 10, 64)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "Amount")
|
||||
}
|
||||
return &enginev1.WithdrawalRequest{
|
||||
SourceAddress: src,
|
||||
ValidatorPubkey: pubkey,
|
||||
Amount: amount,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ConsolidationRequestsFromConsensus(cs []*enginev1.ConsolidationRequest) []*ConsolidationRequest {
|
||||
result := make([]*ConsolidationRequest, len(cs))
|
||||
for i, c := range cs {
|
||||
result[i] = ConsolidationRequestFromConsensus(c)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func ConsolidationRequestFromConsensus(c *enginev1.ConsolidationRequest) *ConsolidationRequest {
|
||||
return &ConsolidationRequest{
|
||||
SourceAddress: hexutil.Encode(c.SourceAddress),
|
||||
SourcePubkey: hexutil.Encode(c.SourcePubkey),
|
||||
TargetPubkey: hexutil.Encode(c.TargetPubkey),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ConsolidationRequest) ToConsensus() (*enginev1.ConsolidationRequest, error) {
|
||||
srcAddress, err := bytesutil.DecodeHexWithLength(c.SourceAddress, common.AddressLength)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "SourceAddress")
|
||||
}
|
||||
srcPubkey, err := bytesutil.DecodeHexWithLength(c.SourcePubkey, fieldparams.BLSPubkeyLength)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "SourcePubkey")
|
||||
}
|
||||
targetPubkey, err := bytesutil.DecodeHexWithLength(c.TargetPubkey, fieldparams.BLSPubkeyLength)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "TargetPubkey")
|
||||
}
|
||||
return &enginev1.ConsolidationRequest{
|
||||
SourceAddress: srcAddress,
|
||||
SourcePubkey: srcPubkey,
|
||||
TargetPubkey: targetPubkey,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func DepositRequestsFromConsensus(ds []*enginev1.DepositRequest) []*DepositRequest {
|
||||
result := make([]*DepositRequest, len(ds))
|
||||
for i, d := range ds {
|
||||
result[i] = DepositRequestFromConsensus(d)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func DepositRequestFromConsensus(d *enginev1.DepositRequest) *DepositRequest {
|
||||
return &DepositRequest{
|
||||
Pubkey: hexutil.Encode(d.Pubkey),
|
||||
WithdrawalCredentials: hexutil.Encode(d.WithdrawalCredentials),
|
||||
Amount: fmt.Sprintf("%d", d.Amount),
|
||||
Signature: hexutil.Encode(d.Signature),
|
||||
Index: fmt.Sprintf("%d", d.Index),
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DepositRequest) ToConsensus() (*enginev1.DepositRequest, error) {
|
||||
pubkey, err := bytesutil.DecodeHexWithLength(d.Pubkey, fieldparams.BLSPubkeyLength)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "Pubkey")
|
||||
}
|
||||
withdrawalCredentials, err := bytesutil.DecodeHexWithLength(d.WithdrawalCredentials, fieldparams.RootLength)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "WithdrawalCredentials")
|
||||
}
|
||||
amount, err := strconv.ParseUint(d.Amount, 10, 64)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "Amount")
|
||||
}
|
||||
sig, err := bytesutil.DecodeHexWithLength(d.Signature, fieldparams.BLSSignatureLength)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "Signature")
|
||||
}
|
||||
index, err := strconv.ParseUint(d.Index, 10, 64)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, "Index")
|
||||
}
|
||||
return &enginev1.DepositRequest{
|
||||
Pubkey: pubkey,
|
||||
WithdrawalCredentials: withdrawalCredentials,
|
||||
Amount: amount,
|
||||
Signature: sig,
|
||||
Index: index,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ProposerSlashingsToConsensus(src []*ProposerSlashing) ([]*eth.ProposerSlashing, error) {
|
||||
if src == nil {
|
||||
return nil, errNilValue
|
||||
@@ -1158,138 +930,6 @@ func AttesterSlashingFromConsensus(src *eth.AttesterSlashing) *AttesterSlashing
|
||||
}
|
||||
}
|
||||
|
||||
func AttesterSlashingsElectraToConsensus(src []*AttesterSlashingElectra) ([]*eth.AttesterSlashingElectra, error) {
|
||||
if src == nil {
|
||||
return nil, errNilValue
|
||||
}
|
||||
err := slice.VerifyMaxLength(src, 2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
attesterSlashings := make([]*eth.AttesterSlashingElectra, len(src))
|
||||
for i, s := range src {
|
||||
if s == nil {
|
||||
return nil, server.NewDecodeError(errNilValue, fmt.Sprintf("[%d]", i))
|
||||
}
|
||||
if s.Attestation1 == nil {
|
||||
return nil, server.NewDecodeError(errNilValue, fmt.Sprintf("[%d].Attestation1", i))
|
||||
}
|
||||
if s.Attestation2 == nil {
|
||||
return nil, server.NewDecodeError(errNilValue, fmt.Sprintf("[%d].Attestation2", i))
|
||||
}
|
||||
|
||||
a1Sig, err := bytesutil.DecodeHexWithLength(s.Attestation1.Signature, fieldparams.BLSSignatureLength)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, fmt.Sprintf("[%d].Attestation1.Signature", i))
|
||||
}
|
||||
err = slice.VerifyMaxLength(s.Attestation1.AttestingIndices, 2048)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, fmt.Sprintf("[%d].Attestation1.AttestingIndices", i))
|
||||
}
|
||||
a1AttestingIndices := make([]uint64, len(s.Attestation1.AttestingIndices))
|
||||
for j, ix := range s.Attestation1.AttestingIndices {
|
||||
attestingIndex, err := strconv.ParseUint(ix, 10, 64)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, fmt.Sprintf("[%d].Attestation1.AttestingIndices[%d]", i, j))
|
||||
}
|
||||
a1AttestingIndices[j] = attestingIndex
|
||||
}
|
||||
a1Data, err := s.Attestation1.Data.ToConsensus()
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, fmt.Sprintf("[%d].Attestation1.Data", i))
|
||||
}
|
||||
a2Sig, err := bytesutil.DecodeHexWithLength(s.Attestation2.Signature, fieldparams.BLSSignatureLength)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, fmt.Sprintf("[%d].Attestation2.Signature", i))
|
||||
}
|
||||
err = slice.VerifyMaxLength(s.Attestation2.AttestingIndices, 2048)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, fmt.Sprintf("[%d].Attestation2.AttestingIndices", i))
|
||||
}
|
||||
a2AttestingIndices := make([]uint64, len(s.Attestation2.AttestingIndices))
|
||||
for j, ix := range s.Attestation2.AttestingIndices {
|
||||
attestingIndex, err := strconv.ParseUint(ix, 10, 64)
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, fmt.Sprintf("[%d].Attestation2.AttestingIndices[%d]", i, j))
|
||||
}
|
||||
a2AttestingIndices[j] = attestingIndex
|
||||
}
|
||||
a2Data, err := s.Attestation2.Data.ToConsensus()
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, fmt.Sprintf("[%d].Attestation2.Data", i))
|
||||
}
|
||||
attesterSlashings[i] = ð.AttesterSlashingElectra{
|
||||
Attestation_1: ð.IndexedAttestationElectra{
|
||||
AttestingIndices: a1AttestingIndices,
|
||||
Data: a1Data,
|
||||
Signature: a1Sig,
|
||||
},
|
||||
Attestation_2: ð.IndexedAttestationElectra{
|
||||
AttestingIndices: a2AttestingIndices,
|
||||
Data: a2Data,
|
||||
Signature: a2Sig,
|
||||
},
|
||||
}
|
||||
}
|
||||
return attesterSlashings, nil
|
||||
}
|
||||
|
||||
func AttesterSlashingsElectraFromConsensus(src []*eth.AttesterSlashingElectra) []*AttesterSlashingElectra {
|
||||
attesterSlashings := make([]*AttesterSlashingElectra, len(src))
|
||||
for i, s := range src {
|
||||
attesterSlashings[i] = AttesterSlashingElectraFromConsensus(s)
|
||||
}
|
||||
return attesterSlashings
|
||||
}
|
||||
|
||||
func AttesterSlashingElectraFromConsensus(src *eth.AttesterSlashingElectra) *AttesterSlashingElectra {
|
||||
a1AttestingIndices := make([]string, len(src.Attestation_1.AttestingIndices))
|
||||
for j, ix := range src.Attestation_1.AttestingIndices {
|
||||
a1AttestingIndices[j] = fmt.Sprintf("%d", ix)
|
||||
}
|
||||
a2AttestingIndices := make([]string, len(src.Attestation_2.AttestingIndices))
|
||||
for j, ix := range src.Attestation_2.AttestingIndices {
|
||||
a2AttestingIndices[j] = fmt.Sprintf("%d", ix)
|
||||
}
|
||||
return &AttesterSlashingElectra{
|
||||
Attestation1: &IndexedAttestationElectra{
|
||||
AttestingIndices: a1AttestingIndices,
|
||||
Data: &AttestationData{
|
||||
Slot: fmt.Sprintf("%d", src.Attestation_1.Data.Slot),
|
||||
CommitteeIndex: fmt.Sprintf("%d", src.Attestation_1.Data.CommitteeIndex),
|
||||
BeaconBlockRoot: hexutil.Encode(src.Attestation_1.Data.BeaconBlockRoot),
|
||||
Source: &Checkpoint{
|
||||
Epoch: fmt.Sprintf("%d", src.Attestation_1.Data.Source.Epoch),
|
||||
Root: hexutil.Encode(src.Attestation_1.Data.Source.Root),
|
||||
},
|
||||
Target: &Checkpoint{
|
||||
Epoch: fmt.Sprintf("%d", src.Attestation_1.Data.Target.Epoch),
|
||||
Root: hexutil.Encode(src.Attestation_1.Data.Target.Root),
|
||||
},
|
||||
},
|
||||
Signature: hexutil.Encode(src.Attestation_1.Signature),
|
||||
},
|
||||
Attestation2: &IndexedAttestationElectra{
|
||||
AttestingIndices: a2AttestingIndices,
|
||||
Data: &AttestationData{
|
||||
Slot: fmt.Sprintf("%d", src.Attestation_2.Data.Slot),
|
||||
CommitteeIndex: fmt.Sprintf("%d", src.Attestation_2.Data.CommitteeIndex),
|
||||
BeaconBlockRoot: hexutil.Encode(src.Attestation_2.Data.BeaconBlockRoot),
|
||||
Source: &Checkpoint{
|
||||
Epoch: fmt.Sprintf("%d", src.Attestation_2.Data.Source.Epoch),
|
||||
Root: hexutil.Encode(src.Attestation_2.Data.Source.Root),
|
||||
},
|
||||
Target: &Checkpoint{
|
||||
Epoch: fmt.Sprintf("%d", src.Attestation_2.Data.Target.Epoch),
|
||||
Root: hexutil.Encode(src.Attestation_2.Data.Target.Root),
|
||||
},
|
||||
},
|
||||
Signature: hexutil.Encode(src.Attestation_2.Signature),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func AttsToConsensus(src []*Attestation) ([]*eth.Attestation, error) {
|
||||
if src == nil {
|
||||
return nil, errNilValue
|
||||
@@ -1317,33 +957,6 @@ func AttsFromConsensus(src []*eth.Attestation) []*Attestation {
|
||||
return atts
|
||||
}
|
||||
|
||||
func AttsElectraToConsensus(src []*AttestationElectra) ([]*eth.AttestationElectra, error) {
|
||||
if src == nil {
|
||||
return nil, errNilValue
|
||||
}
|
||||
err := slice.VerifyMaxLength(src, 8)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
atts := make([]*eth.AttestationElectra, len(src))
|
||||
for i, a := range src {
|
||||
atts[i], err = a.ToConsensus()
|
||||
if err != nil {
|
||||
return nil, server.NewDecodeError(err, fmt.Sprintf("[%d]", i))
|
||||
}
|
||||
}
|
||||
return atts, nil
|
||||
}
|
||||
|
||||
func AttsElectraFromConsensus(src []*eth.AttestationElectra) []*AttestationElectra {
|
||||
atts := make([]*AttestationElectra, len(src))
|
||||
for i, a := range src {
|
||||
atts[i] = AttElectraFromConsensus(a)
|
||||
}
|
||||
return atts
|
||||
}
|
||||
|
||||
func DepositsToConsensus(src []*Deposit) ([]*eth.Deposit, error) {
|
||||
if src == nil {
|
||||
return nil, errNilValue
|
||||
@@ -1474,37 +1087,3 @@ func DepositSnapshotFromConsensus(ds *eth.DepositSnapshot) *DepositSnapshot {
|
||||
ExecutionBlockHeight: fmt.Sprintf("%d", ds.ExecutionDepth),
|
||||
}
|
||||
}
|
||||
|
||||
func PendingBalanceDepositsFromConsensus(ds []*eth.PendingBalanceDeposit) []*PendingBalanceDeposit {
|
||||
deposits := make([]*PendingBalanceDeposit, len(ds))
|
||||
for i, d := range ds {
|
||||
deposits[i] = &PendingBalanceDeposit{
|
||||
Index: fmt.Sprintf("%d", d.Index),
|
||||
Amount: fmt.Sprintf("%d", d.Amount),
|
||||
}
|
||||
}
|
||||
return deposits
|
||||
}
|
||||
|
||||
func PendingPartialWithdrawalsFromConsensus(ws []*eth.PendingPartialWithdrawal) []*PendingPartialWithdrawal {
|
||||
withdrawals := make([]*PendingPartialWithdrawal, len(ws))
|
||||
for i, w := range ws {
|
||||
withdrawals[i] = &PendingPartialWithdrawal{
|
||||
Index: fmt.Sprintf("%d", w.Index),
|
||||
Amount: fmt.Sprintf("%d", w.Amount),
|
||||
WithdrawableEpoch: fmt.Sprintf("%d", w.WithdrawableEpoch),
|
||||
}
|
||||
}
|
||||
return withdrawals
|
||||
}
|
||||
|
||||
func PendingConsolidationsFromConsensus(cs []*eth.PendingConsolidation) []*PendingConsolidation {
|
||||
consolidations := make([]*PendingConsolidation, len(cs))
|
||||
for i, c := range cs {
|
||||
consolidations[i] = &PendingConsolidation{
|
||||
SourceIndex: fmt.Sprintf("%d", c.SourceIndex),
|
||||
TargetIndex: fmt.Sprintf("%d", c.TargetIndex),
|
||||
}
|
||||
}
|
||||
return consolidations
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -593,185 +593,3 @@ func BeaconStateDenebFromConsensus(st beaconState.BeaconState) (*BeaconStateDene
|
||||
HistoricalSummaries: hs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func BeaconStateElectraFromConsensus(st beaconState.BeaconState) (*BeaconStateElectra, error) {
|
||||
srcBr := st.BlockRoots()
|
||||
br := make([]string, len(srcBr))
|
||||
for i, r := range srcBr {
|
||||
br[i] = hexutil.Encode(r)
|
||||
}
|
||||
srcSr := st.StateRoots()
|
||||
sr := make([]string, len(srcSr))
|
||||
for i, r := range srcSr {
|
||||
sr[i] = hexutil.Encode(r)
|
||||
}
|
||||
srcHr, err := st.HistoricalRoots()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hr := make([]string, len(srcHr))
|
||||
for i, r := range srcHr {
|
||||
hr[i] = hexutil.Encode(r)
|
||||
}
|
||||
srcVotes := st.Eth1DataVotes()
|
||||
votes := make([]*Eth1Data, len(srcVotes))
|
||||
for i, e := range srcVotes {
|
||||
votes[i] = Eth1DataFromConsensus(e)
|
||||
}
|
||||
srcVals := st.Validators()
|
||||
vals := make([]*Validator, len(srcVals))
|
||||
for i, v := range srcVals {
|
||||
vals[i] = ValidatorFromConsensus(v)
|
||||
}
|
||||
srcBals := st.Balances()
|
||||
bals := make([]string, len(srcBals))
|
||||
for i, b := range srcBals {
|
||||
bals[i] = fmt.Sprintf("%d", b)
|
||||
}
|
||||
srcRm := st.RandaoMixes()
|
||||
rm := make([]string, len(srcRm))
|
||||
for i, m := range srcRm {
|
||||
rm[i] = hexutil.Encode(m)
|
||||
}
|
||||
srcSlashings := st.Slashings()
|
||||
slashings := make([]string, len(srcSlashings))
|
||||
for i, s := range srcSlashings {
|
||||
slashings[i] = fmt.Sprintf("%d", s)
|
||||
}
|
||||
srcPrevPart, err := st.PreviousEpochParticipation()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
prevPart := make([]string, len(srcPrevPart))
|
||||
for i, p := range srcPrevPart {
|
||||
prevPart[i] = fmt.Sprintf("%d", p)
|
||||
}
|
||||
srcCurrPart, err := st.CurrentEpochParticipation()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currPart := make([]string, len(srcCurrPart))
|
||||
for i, p := range srcCurrPart {
|
||||
currPart[i] = fmt.Sprintf("%d", p)
|
||||
}
|
||||
srcIs, err := st.InactivityScores()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
is := make([]string, len(srcIs))
|
||||
for i, s := range srcIs {
|
||||
is[i] = fmt.Sprintf("%d", s)
|
||||
}
|
||||
currSc, err := st.CurrentSyncCommittee()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nextSc, err := st.NextSyncCommittee()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
execData, err := st.LatestExecutionPayloadHeader()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
srcPayload, ok := execData.Proto().(*enginev1.ExecutionPayloadHeaderElectra)
|
||||
if !ok {
|
||||
return nil, errPayloadHeaderNotFound
|
||||
}
|
||||
payload, err := ExecutionPayloadHeaderElectraFromConsensus(srcPayload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
srcHs, err := st.HistoricalSummaries()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hs := make([]*HistoricalSummary, len(srcHs))
|
||||
for i, s := range srcHs {
|
||||
hs[i] = HistoricalSummaryFromConsensus(s)
|
||||
}
|
||||
nwi, err := st.NextWithdrawalIndex()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nwvi, err := st.NextWithdrawalValidatorIndex()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
drsi, err := st.DepositRequestsStartIndex()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dbtc, err := st.DepositBalanceToConsume()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ebtc, err := st.ExitBalanceToConsume()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
eee, err := st.EarliestExitEpoch()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cbtc, err := st.ConsolidationBalanceToConsume()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ece, err := st.EarliestConsolidationEpoch()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pbd, err := st.PendingBalanceDeposits()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ppw, err := st.PendingPartialWithdrawals()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pc, err := st.PendingConsolidations()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &BeaconStateElectra{
|
||||
GenesisTime: fmt.Sprintf("%d", st.GenesisTime()),
|
||||
GenesisValidatorsRoot: hexutil.Encode(st.GenesisValidatorsRoot()),
|
||||
Slot: fmt.Sprintf("%d", st.Slot()),
|
||||
Fork: ForkFromConsensus(st.Fork()),
|
||||
LatestBlockHeader: BeaconBlockHeaderFromConsensus(st.LatestBlockHeader()),
|
||||
BlockRoots: br,
|
||||
StateRoots: sr,
|
||||
HistoricalRoots: hr,
|
||||
Eth1Data: Eth1DataFromConsensus(st.Eth1Data()),
|
||||
Eth1DataVotes: votes,
|
||||
Eth1DepositIndex: fmt.Sprintf("%d", st.Eth1DepositIndex()),
|
||||
Validators: vals,
|
||||
Balances: bals,
|
||||
RandaoMixes: rm,
|
||||
Slashings: slashings,
|
||||
PreviousEpochParticipation: prevPart,
|
||||
CurrentEpochParticipation: currPart,
|
||||
JustificationBits: hexutil.Encode(st.JustificationBits()),
|
||||
PreviousJustifiedCheckpoint: CheckpointFromConsensus(st.PreviousJustifiedCheckpoint()),
|
||||
CurrentJustifiedCheckpoint: CheckpointFromConsensus(st.CurrentJustifiedCheckpoint()),
|
||||
FinalizedCheckpoint: CheckpointFromConsensus(st.FinalizedCheckpoint()),
|
||||
InactivityScores: is,
|
||||
CurrentSyncCommittee: SyncCommitteeFromConsensus(currSc),
|
||||
NextSyncCommittee: SyncCommitteeFromConsensus(nextSc),
|
||||
LatestExecutionPayloadHeader: payload,
|
||||
NextWithdrawalIndex: fmt.Sprintf("%d", nwi),
|
||||
NextWithdrawalValidatorIndex: fmt.Sprintf("%d", nwvi),
|
||||
HistoricalSummaries: hs,
|
||||
DepositRequestsStartIndex: fmt.Sprintf("%d", drsi),
|
||||
DepositBalanceToConsume: fmt.Sprintf("%d", dbtc),
|
||||
ExitBalanceToConsume: fmt.Sprintf("%d", ebtc),
|
||||
EarliestExitEpoch: fmt.Sprintf("%d", eee),
|
||||
ConsolidationBalanceToConsume: fmt.Sprintf("%d", cbtc),
|
||||
EarliestConsolidationEpoch: fmt.Sprintf("%d", ece),
|
||||
PendingBalanceDeposits: PendingBalanceDepositsFromConsensus(pbd),
|
||||
PendingPartialWithdrawals: PendingPartialWithdrawalsFromConsensus(ppw),
|
||||
PendingConsolidations: PendingConsolidationsFromConsensus(pc),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -29,13 +29,6 @@ type Attestation struct {
|
||||
Signature string `json:"signature"`
|
||||
}
|
||||
|
||||
type AttestationElectra struct {
|
||||
AggregationBits string `json:"aggregation_bits"`
|
||||
Data *AttestationData `json:"data"`
|
||||
Signature string `json:"signature"`
|
||||
CommitteeBits string `json:"committee_bits"`
|
||||
}
|
||||
|
||||
type AttestationData struct {
|
||||
Slot string `json:"slot"`
|
||||
CommitteeIndex string `json:"index"`
|
||||
@@ -85,17 +78,6 @@ type AggregateAttestationAndProof struct {
|
||||
SelectionProof string `json:"selection_proof"`
|
||||
}
|
||||
|
||||
type SignedAggregateAttestationAndProofElectra struct {
|
||||
Message *AggregateAttestationAndProofElectra `json:"message"`
|
||||
Signature string `json:"signature"`
|
||||
}
|
||||
|
||||
type AggregateAttestationAndProofElectra struct {
|
||||
AggregatorIndex string `json:"aggregator_index"`
|
||||
Aggregate *AttestationElectra `json:"aggregate"`
|
||||
SelectionProof string `json:"selection_proof"`
|
||||
}
|
||||
|
||||
type SyncCommitteeSubscription struct {
|
||||
ValidatorIndex string `json:"validator_index"`
|
||||
SyncCommitteeIndices []string `json:"sync_committee_indices"`
|
||||
@@ -196,11 +178,6 @@ type AttesterSlashing struct {
|
||||
Attestation2 *IndexedAttestation `json:"attestation_2"`
|
||||
}
|
||||
|
||||
type AttesterSlashingElectra struct {
|
||||
Attestation1 *IndexedAttestationElectra `json:"attestation_1"`
|
||||
Attestation2 *IndexedAttestationElectra `json:"attestation_2"`
|
||||
}
|
||||
|
||||
type Deposit struct {
|
||||
Proof []string `json:"proof"`
|
||||
Data *DepositData `json:"data"`
|
||||
@@ -219,12 +196,6 @@ type IndexedAttestation struct {
|
||||
Signature string `json:"signature"`
|
||||
}
|
||||
|
||||
type IndexedAttestationElectra struct {
|
||||
AttestingIndices []string `json:"attesting_indices"`
|
||||
Data *AttestationData `json:"data"`
|
||||
Signature string `json:"signature"`
|
||||
}
|
||||
|
||||
type SyncAggregate struct {
|
||||
SyncCommitteeBits string `json:"sync_committee_bits"`
|
||||
SyncCommitteeSignature string `json:"sync_committee_signature"`
|
||||
@@ -236,39 +207,3 @@ type Withdrawal struct {
|
||||
ExecutionAddress string `json:"address"`
|
||||
Amount string `json:"amount"`
|
||||
}
|
||||
|
||||
type DepositRequest struct {
|
||||
Pubkey string `json:"pubkey"`
|
||||
WithdrawalCredentials string `json:"withdrawal_credentials"`
|
||||
Amount string `json:"amount"`
|
||||
Signature string `json:"signature"`
|
||||
Index string `json:"index"`
|
||||
}
|
||||
|
||||
type WithdrawalRequest struct {
|
||||
SourceAddress string `json:"source_address"`
|
||||
ValidatorPubkey string `json:"validator_pubkey"`
|
||||
Amount string `json:"amount"`
|
||||
}
|
||||
|
||||
type ConsolidationRequest struct {
|
||||
SourceAddress string `json:"source_address"`
|
||||
SourcePubkey string `json:"source_pubkey"`
|
||||
TargetPubkey string `json:"target_pubkey"`
|
||||
}
|
||||
|
||||
type PendingBalanceDeposit struct {
|
||||
Index string `json:"index"`
|
||||
Amount string `json:"amount"`
|
||||
}
|
||||
|
||||
type PendingPartialWithdrawal struct {
|
||||
Index string `json:"index"`
|
||||
Amount string `json:"amount"`
|
||||
WithdrawableEpoch string `json:"withdrawable_epoch"`
|
||||
}
|
||||
|
||||
type PendingConsolidation struct {
|
||||
SourceIndex string `json:"source_index"`
|
||||
TargetIndex string `json:"target_index"`
|
||||
}
|
||||
|
||||
@@ -140,43 +140,3 @@ type BeaconStateDeneb struct {
|
||||
NextWithdrawalValidatorIndex string `json:"next_withdrawal_validator_index"`
|
||||
HistoricalSummaries []*HistoricalSummary `json:"historical_summaries"`
|
||||
}
|
||||
|
||||
type BeaconStateElectra struct {
|
||||
GenesisTime string `json:"genesis_time"`
|
||||
GenesisValidatorsRoot string `json:"genesis_validators_root"`
|
||||
Slot string `json:"slot"`
|
||||
Fork *Fork `json:"fork"`
|
||||
LatestBlockHeader *BeaconBlockHeader `json:"latest_block_header"`
|
||||
BlockRoots []string `json:"block_roots"`
|
||||
StateRoots []string `json:"state_roots"`
|
||||
HistoricalRoots []string `json:"historical_roots"`
|
||||
Eth1Data *Eth1Data `json:"eth1_data"`
|
||||
Eth1DataVotes []*Eth1Data `json:"eth1_data_votes"`
|
||||
Eth1DepositIndex string `json:"eth1_deposit_index"`
|
||||
Validators []*Validator `json:"validators"`
|
||||
Balances []string `json:"balances"`
|
||||
RandaoMixes []string `json:"randao_mixes"`
|
||||
Slashings []string `json:"slashings"`
|
||||
PreviousEpochParticipation []string `json:"previous_epoch_participation"`
|
||||
CurrentEpochParticipation []string `json:"current_epoch_participation"`
|
||||
JustificationBits string `json:"justification_bits"`
|
||||
PreviousJustifiedCheckpoint *Checkpoint `json:"previous_justified_checkpoint"`
|
||||
CurrentJustifiedCheckpoint *Checkpoint `json:"current_justified_checkpoint"`
|
||||
FinalizedCheckpoint *Checkpoint `json:"finalized_checkpoint"`
|
||||
InactivityScores []string `json:"inactivity_scores"`
|
||||
CurrentSyncCommittee *SyncCommittee `json:"current_sync_committee"`
|
||||
NextSyncCommittee *SyncCommittee `json:"next_sync_committee"`
|
||||
LatestExecutionPayloadHeader *ExecutionPayloadHeaderElectra `json:"latest_execution_payload_header"`
|
||||
NextWithdrawalIndex string `json:"next_withdrawal_index"`
|
||||
NextWithdrawalValidatorIndex string `json:"next_withdrawal_validator_index"`
|
||||
HistoricalSummaries []*HistoricalSummary `json:"historical_summaries"`
|
||||
DepositRequestsStartIndex string `json:"deposit_requests_start_index"`
|
||||
DepositBalanceToConsume string `json:"deposit_balance_to_consume"`
|
||||
ExitBalanceToConsume string `json:"exit_balance_to_consume"`
|
||||
EarliestExitEpoch string `json:"earliest_exit_epoch"`
|
||||
ConsolidationBalanceToConsume string `json:"consolidation_balance_to_consume"`
|
||||
EarliestConsolidationEpoch string `json:"earliest_consolidation_epoch"`
|
||||
PendingBalanceDeposits []*PendingBalanceDeposit `json:"pending_balance_deposits"`
|
||||
PendingPartialWithdrawals []*PendingPartialWithdrawal `json:"pending_partial_withdrawals"`
|
||||
PendingConsolidations []*PendingConsolidation `json:"pending_consolidations"`
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@ func (s *Service) GetProposerHead() [32]byte {
|
||||
return s.cfg.ForkChoiceStore.GetProposerHead()
|
||||
}
|
||||
|
||||
// ShouldOverrideFCU returns the corresponding value from forkchoice
|
||||
func (s *Service) ShouldOverrideFCU() bool {
|
||||
s.cfg.ForkChoiceStore.RLock()
|
||||
defer s.cfg.ForkChoiceStore.RUnlock()
|
||||
return s.cfg.ForkChoiceStore.ShouldOverrideFCU()
|
||||
}
|
||||
|
||||
// SetForkChoiceGenesisTime sets the genesis time in Forkchoice
|
||||
func (s *Service) SetForkChoiceGenesisTime(timestamp uint64) {
|
||||
s.cfg.ForkChoiceStore.Lock()
|
||||
|
||||
@@ -2044,11 +2044,7 @@ func TestOnBlock_HandleBlockAttestations(t *testing.T) {
|
||||
|
||||
st, err = service.HeadState(ctx)
|
||||
require.NoError(t, err)
|
||||
defaultConfig := util.DefaultBlockGenConfig()
|
||||
defaultConfig.NumWithdrawalRequests = 1
|
||||
defaultConfig.NumDepositRequests = 2
|
||||
defaultConfig.NumConsolidationRequests = 1
|
||||
b, err := util.GenerateFullBlockElectra(st, keys, defaultConfig, 1)
|
||||
b, err := util.GenerateFullBlockElectra(st, keys, util.DefaultBlockGenConfig(), 1)
|
||||
require.NoError(t, err)
|
||||
wsb, err := consensusblocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
@@ -2063,7 +2059,7 @@ func TestOnBlock_HandleBlockAttestations(t *testing.T) {
|
||||
|
||||
st, err = service.HeadState(ctx)
|
||||
require.NoError(t, err)
|
||||
b, err = util.GenerateFullBlockElectra(st, keys, defaultConfig, 2)
|
||||
b, err = util.GenerateFullBlockElectra(st, keys, util.DefaultBlockGenConfig(), 2)
|
||||
require.NoError(t, err)
|
||||
wsb, err = consensusblocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
@@ -2071,7 +2067,7 @@ func TestOnBlock_HandleBlockAttestations(t *testing.T) {
|
||||
// prepare another block that is not inserted
|
||||
st3, err := transition.ExecuteStateTransition(ctx, st, wsb)
|
||||
require.NoError(t, err)
|
||||
b3, err := util.GenerateFullBlockElectra(st3, keys, defaultConfig, 3)
|
||||
b3, err := util.GenerateFullBlockElectra(st3, keys, util.DefaultBlockGenConfig(), 3)
|
||||
require.NoError(t, err)
|
||||
wsb3, err := consensusblocks.NewSignedBeaconBlock(b3)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/trace"
|
||||
@@ -191,26 +190,13 @@ func (s *Service) processAttestations(ctx context.Context, disparity time.Durati
|
||||
}
|
||||
|
||||
if err := s.receiveAttestationNoPubsub(ctx, a, disparity); err != nil {
|
||||
var fields logrus.Fields
|
||||
if a.Version() >= version.Electra {
|
||||
fields = logrus.Fields{
|
||||
"slot": a.GetData().Slot,
|
||||
"committeeCount": a.CommitteeBitsVal().Count(),
|
||||
"committeeIndices": a.CommitteeBitsVal().BitIndices(),
|
||||
"beaconBlockRoot": fmt.Sprintf("%#x", bytesutil.Trunc(a.GetData().BeaconBlockRoot)),
|
||||
"targetRoot": fmt.Sprintf("%#x", bytesutil.Trunc(a.GetData().Target.Root)),
|
||||
"aggregatedCount": a.GetAggregationBits().Count(),
|
||||
}
|
||||
} else {
|
||||
fields = logrus.Fields{
|
||||
"slot": a.GetData().Slot,
|
||||
"committeeIndex": a.GetData().CommitteeIndex,
|
||||
"beaconBlockRoot": fmt.Sprintf("%#x", bytesutil.Trunc(a.GetData().BeaconBlockRoot)),
|
||||
"targetRoot": fmt.Sprintf("%#x", bytesutil.Trunc(a.GetData().Target.Root)),
|
||||
"aggregatedCount": a.GetAggregationBits().Count(),
|
||||
}
|
||||
}
|
||||
log.WithFields(fields).WithError(err).Warn("Could not process attestation for fork choice")
|
||||
log.WithFields(logrus.Fields{
|
||||
"slot": a.GetData().Slot,
|
||||
"committeeIndex": a.GetData().CommitteeIndex,
|
||||
"beaconBlockRoot": fmt.Sprintf("%#x", bytesutil.Trunc(a.GetData().BeaconBlockRoot)),
|
||||
"targetRoot": fmt.Sprintf("%#x", bytesutil.Trunc(a.GetData().Target.Root)),
|
||||
"aggregationCount": a.GetAggregationBits().Count(),
|
||||
}).WithError(err).Warn("Could not process attestation for fork choice")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,25 @@ func VerifyAttestationNoVerifySignature(
|
||||
|
||||
var indexedAtt ethpb.IndexedAtt
|
||||
|
||||
if att.Version() >= version.Electra {
|
||||
if att.Version() < version.Electra {
|
||||
if uint64(att.GetData().CommitteeIndex) >= c {
|
||||
return fmt.Errorf("committee index %d >= committee count %d", att.GetData().CommitteeIndex, c)
|
||||
}
|
||||
|
||||
if err = helpers.VerifyAttestationBitfieldLengths(ctx, beaconState, att); err != nil {
|
||||
return errors.Wrap(err, "could not verify attestation bitfields")
|
||||
}
|
||||
|
||||
// Verify attesting indices are correct.
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, beaconState, att.GetData().Slot, att.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
indexedAtt, err = attestation.ConvertToIndexed(ctx, att, committee)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if att.GetData().CommitteeIndex != 0 {
|
||||
return errors.New("committee index must be 0 post-Electra")
|
||||
}
|
||||
@@ -136,29 +154,6 @@ func VerifyAttestationNoVerifySignature(
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if uint64(att.GetData().CommitteeIndex) >= c {
|
||||
return fmt.Errorf("committee index %d >= committee count %d", att.GetData().CommitteeIndex, c)
|
||||
}
|
||||
|
||||
// Verify attesting indices are correct.
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, beaconState, att.GetData().Slot, att.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if committee == nil {
|
||||
return errors.New("no committee exist for this attestation")
|
||||
}
|
||||
|
||||
if err := helpers.VerifyBitfieldLength(att.GetAggregationBits(), uint64(len(committee))); err != nil {
|
||||
return errors.Wrap(err, "failed to verify aggregation bitfield")
|
||||
}
|
||||
|
||||
indexedAtt, err = attestation.ConvertToIndexed(ctx, att, committee)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return attestation.IsValidAttestationIndices(ctx, indexedAtt)
|
||||
|
||||
@@ -40,7 +40,6 @@ import (
|
||||
// excess_blob_gas=pre.latest_execution_payload_header.excess_blob_gas,
|
||||
// deposit_requests_root=Root(), # [New in Electra:EIP6110]
|
||||
// withdrawal_requests_root=Root(), # [New in Electra:EIP7002],
|
||||
// consolidation_requests_root=Root(), # [New in Electra:EIP7251]
|
||||
// )
|
||||
//
|
||||
// exit_epochs = [v.exit_epoch for v in pre.validators if v.exit_epoch != FAR_FUTURE_EPOCH]
|
||||
|
||||
@@ -22,6 +22,7 @@ go_library(
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//math:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/prysm/v1alpha1/attestation:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
],
|
||||
@@ -52,6 +53,7 @@ go_test(
|
||||
"//testing/util:go_default_library",
|
||||
"@com_github_google_go_cmp//cmp:go_default_library",
|
||||
"@com_github_google_gofuzz//:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -20,9 +20,32 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/math"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/attestation"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
)
|
||||
|
||||
// AttestingBalance returns the total balance from all the attesting indices.
|
||||
//
|
||||
// WARNING: This method allocates a new copy of the attesting validator indices set and is
|
||||
// considered to be very memory expensive. Avoid using this unless you really
|
||||
// need to get attesting balance from attestations.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
//
|
||||
// def get_attesting_balance(state: BeaconState, attestations: Sequence[PendingAttestation]) -> Gwei:
|
||||
// """
|
||||
// Return the combined effective balance of the set of unslashed validators participating in ``attestations``.
|
||||
// Note: ``get_total_balance`` returns ``EFFECTIVE_BALANCE_INCREMENT`` Gwei minimum to avoid divisions by zero.
|
||||
// """
|
||||
// return get_total_balance(state, get_unslashed_attesting_indices(state, attestations))
|
||||
func AttestingBalance(ctx context.Context, state state.ReadOnlyBeaconState, atts []*ethpb.PendingAttestation) (uint64, error) {
|
||||
indices, err := UnslashedAttestingIndices(ctx, state, atts)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "could not get attesting indices")
|
||||
}
|
||||
return helpers.TotalBalance(state, indices), nil
|
||||
}
|
||||
|
||||
// ProcessRegistryUpdates rotates validators in and out of active pool.
|
||||
// the amount to rotate is determined churn limit.
|
||||
//
|
||||
@@ -432,3 +455,51 @@ func ProcessFinalUpdates(state state.BeaconState) (state.BeaconState, error) {
|
||||
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// UnslashedAttestingIndices returns all the attesting indices from a list of attestations,
|
||||
// it sorts the indices and filters out the slashed ones.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
//
|
||||
// def get_unslashed_attesting_indices(state: BeaconState,
|
||||
// attestations: Sequence[PendingAttestation]) -> Set[ValidatorIndex]:
|
||||
// output = set() # type: Set[ValidatorIndex]
|
||||
// for a in attestations:
|
||||
// output = output.union(get_attesting_indices(state, a.data, a.aggregation_bits))
|
||||
// return set(filter(lambda index: not state.validators[index].slashed, output))
|
||||
func UnslashedAttestingIndices(ctx context.Context, state state.ReadOnlyBeaconState, atts []*ethpb.PendingAttestation) ([]primitives.ValidatorIndex, error) {
|
||||
var setIndices []primitives.ValidatorIndex
|
||||
seen := make(map[uint64]bool)
|
||||
|
||||
for _, att := range atts {
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, state, att.GetData().Slot, att.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
attestingIndices, err := attestation.AttestingIndices(att, committee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Create a set for attesting indices
|
||||
for _, index := range attestingIndices {
|
||||
if !seen[index] {
|
||||
setIndices = append(setIndices, primitives.ValidatorIndex(index))
|
||||
}
|
||||
seen[index] = true
|
||||
}
|
||||
}
|
||||
// Sort the attesting set indices by increasing order.
|
||||
sort.Slice(setIndices, func(i, j int) bool { return setIndices[i] < setIndices[j] })
|
||||
// Remove the slashed validator indices.
|
||||
for i := 0; i < len(setIndices); i++ {
|
||||
v, err := state.ValidatorAtIndexReadOnly(setIndices[i])
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to look up validator")
|
||||
}
|
||||
if !v.IsNil() && v.Slashed() {
|
||||
setIndices = append(setIndices[:i], setIndices[i+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
return setIndices, nil
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/epoch"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time"
|
||||
@@ -23,6 +24,131 @@ import (
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func TestUnslashedAttestingIndices_CanSortAndFilter(t *testing.T) {
|
||||
// Generate 2 attestations.
|
||||
atts := make([]*ethpb.PendingAttestation, 2)
|
||||
for i := 0; i < len(atts); i++ {
|
||||
atts[i] = ðpb.PendingAttestation{
|
||||
Data: ðpb.AttestationData{Source: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
||||
Target: ðpb.Checkpoint{Epoch: 0, Root: make([]byte, fieldparams.RootLength)},
|
||||
},
|
||||
AggregationBits: bitfield.Bitlist{0x00, 0xFF, 0xFF, 0xFF},
|
||||
}
|
||||
}
|
||||
|
||||
// Generate validators and state for the 2 attestations.
|
||||
validatorCount := 1000
|
||||
validators := make([]*ethpb.Validator, validatorCount)
|
||||
for i := 0; i < len(validators); i++ {
|
||||
validators[i] = ðpb.Validator{
|
||||
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
}
|
||||
}
|
||||
base := ðpb.BeaconState{
|
||||
Validators: validators,
|
||||
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
|
||||
}
|
||||
beaconState, err := state_native.InitializeFromProtoPhase0(base)
|
||||
require.NoError(t, err)
|
||||
|
||||
indices, err := epoch.UnslashedAttestingIndices(context.Background(), beaconState, atts)
|
||||
require.NoError(t, err)
|
||||
for i := 0; i < len(indices)-1; i++ {
|
||||
if indices[i] >= indices[i+1] {
|
||||
t.Error("sorted indices not sorted or duplicated")
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the slashed validator is filtered.
|
||||
slashedValidator := indices[0]
|
||||
validators = beaconState.Validators()
|
||||
validators[slashedValidator].Slashed = true
|
||||
require.NoError(t, beaconState.SetValidators(validators))
|
||||
indices, err = epoch.UnslashedAttestingIndices(context.Background(), beaconState, atts)
|
||||
require.NoError(t, err)
|
||||
for i := 0; i < len(indices); i++ {
|
||||
assert.NotEqual(t, slashedValidator, indices[i], "Slashed validator %d is not filtered", slashedValidator)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnslashedAttestingIndices_DuplicatedAttestations(t *testing.T) {
|
||||
// Generate 5 of the same attestations.
|
||||
atts := make([]*ethpb.PendingAttestation, 5)
|
||||
for i := 0; i < len(atts); i++ {
|
||||
atts[i] = ðpb.PendingAttestation{
|
||||
Data: ðpb.AttestationData{Source: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
||||
Target: ðpb.Checkpoint{Epoch: 0}},
|
||||
AggregationBits: bitfield.Bitlist{0x00, 0xFF, 0xFF, 0xFF},
|
||||
}
|
||||
}
|
||||
|
||||
// Generate validators and state for the 5 attestations.
|
||||
validatorCount := 1000
|
||||
validators := make([]*ethpb.Validator, validatorCount)
|
||||
for i := 0; i < len(validators); i++ {
|
||||
validators[i] = ðpb.Validator{
|
||||
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
}
|
||||
}
|
||||
base := ðpb.BeaconState{
|
||||
Validators: validators,
|
||||
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
|
||||
}
|
||||
beaconState, err := state_native.InitializeFromProtoPhase0(base)
|
||||
require.NoError(t, err)
|
||||
|
||||
indices, err := epoch.UnslashedAttestingIndices(context.Background(), beaconState, atts)
|
||||
require.NoError(t, err)
|
||||
|
||||
for i := 0; i < len(indices)-1; i++ {
|
||||
if indices[i] >= indices[i+1] {
|
||||
t.Error("sorted indices not sorted or duplicated")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttestingBalance_CorrectBalance(t *testing.T) {
|
||||
helpers.ClearCache()
|
||||
// Generate 2 attestations.
|
||||
atts := make([]*ethpb.PendingAttestation, 2)
|
||||
for i := 0; i < len(atts); i++ {
|
||||
atts[i] = ðpb.PendingAttestation{
|
||||
Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
||||
Source: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
||||
Slot: primitives.Slot(i),
|
||||
},
|
||||
AggregationBits: bitfield.Bitlist{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01},
|
||||
}
|
||||
}
|
||||
|
||||
// Generate validators with balances and state for the 2 attestations.
|
||||
validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount)
|
||||
balances := make([]uint64, params.BeaconConfig().MinGenesisActiveValidatorCount)
|
||||
for i := 0; i < len(validators); i++ {
|
||||
validators[i] = ðpb.Validator{
|
||||
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
|
||||
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
||||
}
|
||||
balances[i] = params.BeaconConfig().MaxEffectiveBalance
|
||||
}
|
||||
base := ðpb.BeaconState{
|
||||
Slot: 2,
|
||||
RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
|
||||
|
||||
Validators: validators,
|
||||
Balances: balances,
|
||||
}
|
||||
beaconState, err := state_native.InitializeFromProtoPhase0(base)
|
||||
require.NoError(t, err)
|
||||
|
||||
balance, err := epoch.AttestingBalance(context.Background(), beaconState, atts)
|
||||
require.NoError(t, err)
|
||||
wanted := 256 * params.BeaconConfig().MaxEffectiveBalance
|
||||
assert.Equal(t, wanted, balance)
|
||||
}
|
||||
|
||||
func TestProcessSlashings_NotSlashed(t *testing.T) {
|
||||
base := ðpb.BeaconState{
|
||||
Slot: 0,
|
||||
|
||||
@@ -47,6 +47,7 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//beacon-chain/core/altair:go_default_library",
|
||||
"//beacon-chain/core/epoch:go_default_library",
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/core/time:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/epoch"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
@@ -58,6 +59,90 @@ func TestProcessRewardsAndPenaltiesPrecompute(t *testing.T) {
|
||||
assert.Equal(t, wanted, beaconState.Balances()[0], "Unexpected balance")
|
||||
}
|
||||
|
||||
func TestAttestationDeltaPrecompute(t *testing.T) {
|
||||
e := params.BeaconConfig().SlotsPerEpoch
|
||||
validatorCount := uint64(2048)
|
||||
base := buildState(e+2, validatorCount)
|
||||
atts := make([]*ethpb.PendingAttestation, 3)
|
||||
var emptyRoot [32]byte
|
||||
for i := 0; i < len(atts); i++ {
|
||||
atts[i] = ðpb.PendingAttestation{
|
||||
Data: ðpb.AttestationData{
|
||||
Target: ðpb.Checkpoint{
|
||||
Root: emptyRoot[:],
|
||||
},
|
||||
Source: ðpb.Checkpoint{
|
||||
Root: emptyRoot[:],
|
||||
},
|
||||
BeaconBlockRoot: emptyRoot[:],
|
||||
},
|
||||
AggregationBits: bitfield.Bitlist{0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01},
|
||||
InclusionDelay: 1,
|
||||
}
|
||||
}
|
||||
base.PreviousEpochAttestations = atts
|
||||
beaconState, err := state_native.InitializeFromProtoPhase0(base)
|
||||
require.NoError(t, err)
|
||||
slashedAttestedIndices := []primitives.ValidatorIndex{1413}
|
||||
for _, i := range slashedAttestedIndices {
|
||||
vs := beaconState.Validators()
|
||||
vs[i].Slashed = true
|
||||
require.Equal(t, nil, beaconState.SetValidators(vs))
|
||||
}
|
||||
|
||||
vp, bp, err := New(context.Background(), beaconState)
|
||||
require.NoError(t, err)
|
||||
vp, bp, err = ProcessAttestations(context.Background(), beaconState, vp, bp)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Add some variances to target and head balances.
|
||||
// See: https://github.com/prysmaticlabs/prysm/issues/5593
|
||||
bp.PrevEpochTargetAttested /= 2
|
||||
bp.PrevEpochHeadAttested = bp.PrevEpochHeadAttested * 2 / 3
|
||||
rewards, penalties, err := AttestationsDelta(beaconState, bp, vp)
|
||||
require.NoError(t, err)
|
||||
attestedBalance, err := epoch.AttestingBalance(context.Background(), beaconState, atts)
|
||||
require.NoError(t, err)
|
||||
totalBalance, err := helpers.TotalActiveBalance(beaconState)
|
||||
require.NoError(t, err)
|
||||
|
||||
attestedIndices := []primitives.ValidatorIndex{55, 1339, 1746, 1811, 1569}
|
||||
for _, i := range attestedIndices {
|
||||
base, err := baseReward(beaconState, i)
|
||||
require.NoError(t, err, "Could not get base reward")
|
||||
|
||||
// Base rewards for getting source right
|
||||
wanted := attestedBalance*base/totalBalance +
|
||||
bp.PrevEpochTargetAttested*base/totalBalance +
|
||||
bp.PrevEpochHeadAttested*base/totalBalance
|
||||
// Base rewards for proposer and attesters working together getting attestation
|
||||
// on chain in the fatest manner
|
||||
proposerReward := base / params.BeaconConfig().ProposerRewardQuotient
|
||||
wanted += (base-proposerReward)*uint64(params.BeaconConfig().MinAttestationInclusionDelay) - 1
|
||||
assert.Equal(t, wanted, rewards[i], "Unexpected reward balance for validator with index %d", i)
|
||||
// Since all these validators attested, they shouldn't get penalized.
|
||||
assert.Equal(t, uint64(0), penalties[i], "Unexpected penalty balance")
|
||||
}
|
||||
|
||||
for _, i := range slashedAttestedIndices {
|
||||
base, err := baseReward(beaconState, i)
|
||||
assert.NoError(t, err, "Could not get base reward")
|
||||
assert.Equal(t, uint64(0), rewards[i], "Unexpected slashed indices reward balance")
|
||||
assert.Equal(t, 3*base, penalties[i], "Unexpected slashed indices penalty balance")
|
||||
}
|
||||
|
||||
nonAttestedIndices := []primitives.ValidatorIndex{434, 677, 872, 791}
|
||||
for _, i := range nonAttestedIndices {
|
||||
base, err := baseReward(beaconState, i)
|
||||
assert.NoError(t, err, "Could not get base reward")
|
||||
wanted := 3 * base
|
||||
// Since all these validators did not attest, they shouldn't get rewarded.
|
||||
assert.Equal(t, uint64(0), rewards[i], "Unexpected reward balance")
|
||||
// Base penalties for not attesting.
|
||||
assert.Equal(t, wanted, penalties[i], "Unexpected penalty balance")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttestationDeltas_ZeroEpoch(t *testing.T) {
|
||||
e := params.BeaconConfig().SlotsPerEpoch
|
||||
validatorCount := uint64(2048)
|
||||
|
||||
@@ -337,6 +337,24 @@ func VerifyBitfieldLength(bf bitfield.Bitfield, committeeSize uint64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// VerifyAttestationBitfieldLengths verifies that an attestations aggregation bitfields is
|
||||
// a valid length matching the size of the committee.
|
||||
func VerifyAttestationBitfieldLengths(ctx context.Context, state state.ReadOnlyBeaconState, att ethpb.Att) error {
|
||||
committee, err := BeaconCommitteeFromState(ctx, state, att.GetData().Slot, att.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not retrieve beacon committees")
|
||||
}
|
||||
|
||||
if committee == nil {
|
||||
return errors.New("no committee exist for this attestation")
|
||||
}
|
||||
|
||||
if err := VerifyBitfieldLength(att.GetAggregationBits(), uint64(len(committee))); err != nil {
|
||||
return errors.Wrap(err, "failed to verify aggregation bitfield")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ShuffledIndices uses input beacon state and returns the shuffled indices of the input epoch,
|
||||
// the shuffled indices then can be used to break up into committees.
|
||||
func ShuffledIndices(s state.ReadOnlyBeaconState, epoch primitives.Epoch) ([]primitives.ValidatorIndex, error) {
|
||||
|
||||
@@ -403,12 +403,7 @@ func TestVerifyAttestationBitfieldLengths_OK(t *testing.T) {
|
||||
helpers.ClearCache()
|
||||
|
||||
require.NoError(t, state.SetSlot(tt.stateSlot))
|
||||
att := tt.attestation
|
||||
// Verify attesting indices are correct.
|
||||
committee, err := helpers.BeaconCommitteeFromState(context.Background(), state, att.GetData().Slot, att.GetData().CommitteeIndex)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, committee)
|
||||
err = helpers.VerifyBitfieldLength(att.GetAggregationBits(), uint64(len(committee)))
|
||||
err := helpers.VerifyAttestationBitfieldLengths(context.Background(), state, tt.attestation)
|
||||
if tt.verificationFailure {
|
||||
assert.NotNil(t, err, "Verification succeeded when it was supposed to fail")
|
||||
} else {
|
||||
|
||||
@@ -16,11 +16,6 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
MockRawPeerId0 = "16Uiu2HAkyWZ4Ni1TpvDS8dPxsozmHY85KaiFjodQuV6Tz5tkHVeR"
|
||||
MockRawPeerId1 = "16Uiu2HAm4HgJ9N1o222xK61o7LSgToYWoAy1wNTJRkh9gLZapVAy"
|
||||
)
|
||||
|
||||
// MockPeersProvider implements PeersProvider for testing.
|
||||
type MockPeersProvider struct {
|
||||
lock sync.Mutex
|
||||
@@ -55,7 +50,7 @@ func (m *MockPeersProvider) Peers() *peers.Status {
|
||||
},
|
||||
})
|
||||
// Pretend we are connected to two peers
|
||||
id0, err := peer.Decode(MockRawPeerId0)
|
||||
id0, err := peer.Decode("16Uiu2HAkyWZ4Ni1TpvDS8dPxsozmHY85KaiFjodQuV6Tz5tkHVeR")
|
||||
if err != nil {
|
||||
log.WithError(err).Debug("Cannot decode")
|
||||
}
|
||||
@@ -66,7 +61,7 @@ func (m *MockPeersProvider) Peers() *peers.Status {
|
||||
m.peers.Add(createENR(), id0, ma0, network.DirInbound)
|
||||
m.peers.SetConnectionState(id0, peers.PeerConnected)
|
||||
m.peers.SetChainState(id0, &pb.Status{FinalizedEpoch: 10})
|
||||
id1, err := peer.Decode(MockRawPeerId1)
|
||||
id1, err := peer.Decode("16Uiu2HAm4HgJ9N1o222xK61o7LSgToYWoAy1wNTJRkh9gLZapVAy")
|
||||
if err != nil {
|
||||
log.WithError(err).Debug("Cannot decode")
|
||||
}
|
||||
|
||||
@@ -128,12 +128,13 @@ func TestNodeServer_GetPeer(t *testing.T) {
|
||||
}
|
||||
ethpb.RegisterNodeServer(server, ns)
|
||||
reflection.Register(server)
|
||||
firstPeer := peersProvider.Peers().All()[0]
|
||||
|
||||
res, err := ns.GetPeer(context.Background(), ðpb.PeerRequest{PeerId: mockP2p.MockRawPeerId0})
|
||||
res, err := ns.GetPeer(context.Background(), ðpb.PeerRequest{PeerId: firstPeer.String()})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "16Uiu2HAkyWZ4Ni1TpvDS8dPxsozmHY85KaiFjodQuV6Tz5tkHVeR" /* first peer's raw id */, res.PeerId, "Unexpected peer ID")
|
||||
assert.Equal(t, firstPeer.String(), res.PeerId, "Unexpected peer ID")
|
||||
assert.Equal(t, int(ethpb.PeerDirection_INBOUND), int(res.Direction), "Expected 1st peer to be an inbound connection")
|
||||
assert.Equal(t, int(ethpb.ConnectionState_CONNECTED), int(res.ConnectionState), "Expected peer to be connected")
|
||||
assert.Equal(t, ethpb.ConnectionState_CONNECTED, res.ConnectionState, "Expected peer to be connected")
|
||||
}
|
||||
|
||||
func TestNodeServer_ListPeers(t *testing.T) {
|
||||
@@ -148,25 +149,8 @@ func TestNodeServer_ListPeers(t *testing.T) {
|
||||
res, err := ns.ListPeers(context.Background(), &emptypb.Empty{})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 2, len(res.Peers))
|
||||
|
||||
var (
|
||||
firstPeer *ethpb.Peer
|
||||
secondPeer *ethpb.Peer
|
||||
)
|
||||
|
||||
for _, p := range res.Peers {
|
||||
if p.PeerId == mockP2p.MockRawPeerId0 {
|
||||
firstPeer = p
|
||||
}
|
||||
if p.PeerId == mockP2p.MockRawPeerId1 {
|
||||
secondPeer = p
|
||||
}
|
||||
}
|
||||
|
||||
assert.NotNil(t, firstPeer)
|
||||
assert.NotNil(t, secondPeer)
|
||||
assert.Equal(t, int(ethpb.PeerDirection_INBOUND), int(firstPeer.Direction))
|
||||
assert.Equal(t, int(ethpb.PeerDirection_OUTBOUND), int(secondPeer.Direction))
|
||||
assert.Equal(t, int(ethpb.PeerDirection_INBOUND), int(res.Peers[0].Direction))
|
||||
assert.Equal(t, ethpb.PeerDirection_OUTBOUND, res.Peers[1].Direction)
|
||||
}
|
||||
|
||||
func TestNodeServer_GetETH1ConnectionStatus(t *testing.T) {
|
||||
|
||||
@@ -66,12 +66,18 @@ func (vs *Server) ProposeAttestationElectra(ctx context.Context, att *ethpb.Atte
|
||||
ctx, span := trace.StartSpan(ctx, "AttesterServer.ProposeAttestationElectra")
|
||||
defer span.End()
|
||||
|
||||
committeeIndex, err := att.GetCommitteeIndex()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if att.GetData().CommitteeIndex != 0 {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Committee index must be set to 0")
|
||||
}
|
||||
committeeIndices := helpers.CommitteeIndices(att.CommitteeBits)
|
||||
if len(committeeIndices) == 0 {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Committee bits has no bit set")
|
||||
}
|
||||
if len(committeeIndices) > 1 {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Committee bits has more than one bit set")
|
||||
}
|
||||
|
||||
resp, err := vs.proposeAtt(ctx, att, committeeIndex)
|
||||
resp, err := vs.proposeAtt(ctx, att, committeeIndices[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ func TestProposeAttestation(t *testing.T) {
|
||||
CommitteeBits: cb,
|
||||
}
|
||||
_, err = attesterServer.ProposeAttestationElectra(context.Background(), req)
|
||||
assert.ErrorContains(t, "attestation data's committee index must be 0 but was 1", err)
|
||||
assert.ErrorContains(t, "Committee index must be set to 0", err)
|
||||
})
|
||||
t.Run("Electra - no committee bit set", func(t *testing.T) {
|
||||
state, err := util.NewBeaconStateElectra()
|
||||
@@ -131,7 +131,7 @@ func TestProposeAttestation(t *testing.T) {
|
||||
CommitteeBits: primitives.NewAttestationCommitteeBits(),
|
||||
}
|
||||
_, err = attesterServer.ProposeAttestationElectra(context.Background(), req)
|
||||
assert.ErrorContains(t, "exactly 1 committee index must be set but 0 were set", err)
|
||||
assert.ErrorContains(t, "Committee bits has no bit set", err)
|
||||
})
|
||||
t.Run("Electra - multiple committee bits set", func(t *testing.T) {
|
||||
state, err := util.NewBeaconStateElectra()
|
||||
@@ -152,7 +152,7 @@ func TestProposeAttestation(t *testing.T) {
|
||||
CommitteeBits: cb,
|
||||
}
|
||||
_, err = attesterServer.ProposeAttestationElectra(context.Background(), req)
|
||||
assert.ErrorContains(t, "exactly 1 committee index must be set but 2 were set", err)
|
||||
assert.ErrorContains(t, "Committee bits has more than one bit set", err)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -277,8 +277,8 @@ func (vs *Server) ProposeBeaconBlock(ctx context.Context, req *ethpb.GenericSign
|
||||
var sidecars []*ethpb.BlobSidecar
|
||||
if block.IsBlinded() {
|
||||
block, sidecars, err = vs.handleBlindedBlock(ctx, block)
|
||||
} else if block.Version() >= version.Deneb {
|
||||
sidecars, err = vs.blobSidecarsFromUnblindedBlock(block, req)
|
||||
} else {
|
||||
sidecars, err = vs.handleUnblindedBlock(block, req)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "%s: %v", "handle block failed", err)
|
||||
@@ -345,12 +345,13 @@ func (vs *Server) handleBlindedBlock(ctx context.Context, block interfaces.Signe
|
||||
return copiedBlock, sidecars, nil
|
||||
}
|
||||
|
||||
func (vs *Server) blobSidecarsFromUnblindedBlock(block interfaces.SignedBeaconBlock, req *ethpb.GenericSignedBeaconBlock) ([]*ethpb.BlobSidecar, error) {
|
||||
rawBlobs, proofs, err := blobsAndProofs(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// handleUnblindedBlock processes unblinded beacon blocks.
|
||||
func (vs *Server) handleUnblindedBlock(block interfaces.SignedBeaconBlock, req *ethpb.GenericSignedBeaconBlock) ([]*ethpb.BlobSidecar, error) {
|
||||
dbBlockContents := req.GetDeneb()
|
||||
if dbBlockContents == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return BuildBlobSidecars(block, rawBlobs, proofs)
|
||||
return BuildBlobSidecars(block, dbBlockContents.Blobs, dbBlockContents.KzgProofs)
|
||||
}
|
||||
|
||||
// broadcastReceiveBlock broadcasts a block and handles its reception.
|
||||
@@ -501,16 +502,3 @@ func (vs *Server) SubmitValidatorRegistrations(ctx context.Context, reg *ethpb.S
|
||||
|
||||
return &emptypb.Empty{}, nil
|
||||
}
|
||||
|
||||
func blobsAndProofs(req *ethpb.GenericSignedBeaconBlock) ([][]byte, [][]byte, error) {
|
||||
switch {
|
||||
case req.GetDeneb() != nil:
|
||||
dbBlockContents := req.GetDeneb()
|
||||
return dbBlockContents.Blobs, dbBlockContents.KzgProofs, nil
|
||||
case req.GetElectra() != nil:
|
||||
dbBlockContents := req.GetElectra()
|
||||
return dbBlockContents.Blobs, dbBlockContents.KzgProofs, nil
|
||||
default:
|
||||
return nil, nil, errors.Errorf("unknown request type provided: %T", req)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,15 +242,6 @@ func (vs *Server) getPayloadHeaderFromBuilder(ctx context.Context, slot primitiv
|
||||
return nil, fmt.Errorf("incorrect parent hash %#x != %#x", header.ParentHash(), h.BlockHash())
|
||||
}
|
||||
|
||||
reg, err := vs.BlockBuilder.RegistrationByValidatorID(ctx, idx)
|
||||
if err != nil {
|
||||
log.WithError(err).Warn("Proposer: failed to get registration by validator ID, could not check gas limit")
|
||||
} else {
|
||||
if reg.GasLimit != header.GasLimit() {
|
||||
return nil, fmt.Errorf("incorrect header gas limit %d != %d", reg.GasLimit, header.GasLimit())
|
||||
}
|
||||
}
|
||||
|
||||
t, err := slots.ToTime(uint64(vs.TimeFetcher.GenesisTime().Unix()), slot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -720,29 +720,6 @@ func TestServer_getPayloadHeader(t *testing.T) {
|
||||
Signature: sk.Sign(srCapella[:]).Marshal(),
|
||||
}
|
||||
|
||||
incorrectGasLimitBid := ðpb.BuilderBid{
|
||||
Header: &v1.ExecutionPayloadHeader{
|
||||
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
|
||||
StateRoot: make([]byte, fieldparams.RootLength),
|
||||
ReceiptsRoot: make([]byte, fieldparams.RootLength),
|
||||
LogsBloom: make([]byte, fieldparams.LogsBloomLength),
|
||||
PrevRandao: make([]byte, fieldparams.RootLength),
|
||||
BaseFeePerGas: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
TransactionsRoot: bytesutil.PadTo([]byte{1}, fieldparams.RootLength),
|
||||
ParentHash: params.BeaconConfig().ZeroHash[:],
|
||||
Timestamp: uint64(tiCapella.Unix()),
|
||||
GasLimit: 100,
|
||||
},
|
||||
Pubkey: sk.PublicKey().Marshal(),
|
||||
Value: bytesutil.PadTo([]byte{1, 2, 3}, 32),
|
||||
}
|
||||
signedIncorrectGasLimitBid :=
|
||||
ðpb.SignedBuilderBid{
|
||||
Message: incorrectGasLimitBid,
|
||||
Signature: sk.Sign(srCapella[:]).Marshal(),
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -855,21 +832,6 @@ func TestServer_getPayloadHeader(t *testing.T) {
|
||||
},
|
||||
err: "is different from head block version",
|
||||
},
|
||||
{
|
||||
name: "incorrect gas limit",
|
||||
mock: &builderTest.MockBuilderService{
|
||||
Bid: signedIncorrectGasLimitBid,
|
||||
},
|
||||
fetcher: &blockchainTest.ChainService{
|
||||
Block: func() interfaces.ReadOnlySignedBeaconBlock {
|
||||
wb, err := blocks.NewSignedBeaconBlock(util.NewBeaconBlockBellatrix())
|
||||
require.NoError(t, err)
|
||||
wb.SetSlot(primitives.Slot(params.BeaconConfig().BellatrixForkEpoch) * params.BeaconConfig().SlotsPerEpoch)
|
||||
return wb
|
||||
}(),
|
||||
},
|
||||
err: "incorrect header gas limit 0 != 100",
|
||||
},
|
||||
{
|
||||
name: "different bid version during hard fork",
|
||||
mock: &builderTest.MockBuilderService{
|
||||
@@ -888,18 +850,9 @@ func TestServer_getPayloadHeader(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
vs := &Server{BeaconDB: dbTest.SetupDB(t), BlockBuilder: tc.mock, HeadFetcher: tc.fetcher, TimeFetcher: &blockchainTest.ChainService{
|
||||
vs := &Server{BlockBuilder: tc.mock, HeadFetcher: tc.fetcher, TimeFetcher: &blockchainTest.ChainService{
|
||||
Genesis: genesis,
|
||||
}}
|
||||
regCache := cache.NewRegistrationCache()
|
||||
regCache.UpdateIndexToRegisteredMap(context.Background(), map[primitives.ValidatorIndex]*ethpb.ValidatorRegistrationV1{
|
||||
0: {
|
||||
GasLimit: 0,
|
||||
FeeRecipient: make([]byte, 20),
|
||||
Pubkey: make([]byte, 48),
|
||||
},
|
||||
})
|
||||
tc.mock.RegistrationCache = regCache
|
||||
hb, err := vs.HeadFetcher.HeadBlock(context.Background())
|
||||
require.NoError(t, err)
|
||||
bid, err := vs.getPayloadHeaderFromBuilder(context.Background(), hb.Block().Slot(), 0)
|
||||
|
||||
@@ -59,26 +59,14 @@ func (vs *Server) getLocalPayload(ctx context.Context, blk interfaces.ReadOnlyBe
|
||||
slot := blk.Slot()
|
||||
vIdx := blk.ProposerIndex()
|
||||
headRoot := blk.ParentRoot()
|
||||
|
||||
return vs.getLocalPayloadFromEngine(ctx, st, headRoot, slot, vIdx)
|
||||
}
|
||||
|
||||
// This returns the local execution payload of a slot, proposer ID, and parent root assuming payload Is cached.
|
||||
// If the payload ID is not cached, the function will prepare a new payload through local EL engine and return it by using the head state.
|
||||
func (vs *Server) getLocalPayloadFromEngine(
|
||||
ctx context.Context,
|
||||
st state.BeaconState,
|
||||
parentRoot [32]byte,
|
||||
slot primitives.Slot,
|
||||
proposerId primitives.ValidatorIndex) (*consensusblocks.GetPayloadResponse, error) {
|
||||
logFields := logrus.Fields{
|
||||
"validatorIndex": proposerId,
|
||||
"validatorIndex": vIdx,
|
||||
"slot": slot,
|
||||
"headRoot": fmt.Sprintf("%#x", parentRoot),
|
||||
"headRoot": fmt.Sprintf("%#x", headRoot),
|
||||
}
|
||||
payloadId, ok := vs.PayloadIDCache.PayloadID(slot, parentRoot)
|
||||
payloadId, ok := vs.PayloadIDCache.PayloadID(slot, headRoot)
|
||||
|
||||
val, tracked := vs.TrackedValidatorsCache.Validator(proposerId)
|
||||
val, tracked := vs.TrackedValidatorsCache.Validator(vIdx)
|
||||
if !tracked {
|
||||
logrus.WithFields(logFields).Warn("could not find tracked proposer index")
|
||||
}
|
||||
@@ -147,7 +135,7 @@ func (vs *Server) getLocalPayloadFromEngine(
|
||||
PrevRandao: random,
|
||||
SuggestedFeeRecipient: val.FeeRecipient[:],
|
||||
Withdrawals: withdrawals,
|
||||
ParentBeaconBlockRoot: parentRoot[:],
|
||||
ParentBeaconBlockRoot: headRoot[:],
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -879,6 +879,33 @@ func TestProposer_ProposeBlock_OK(t *testing.T) {
|
||||
},
|
||||
err: "blob KZG commitments don't match number of blobs or KZG proofs",
|
||||
},
|
||||
{
|
||||
name: "electra block no blob",
|
||||
block: func(parent [32]byte) *ethpb.GenericSignedBeaconBlock {
|
||||
sb := ðpb.SignedBeaconBlockContentsElectra{
|
||||
Block: ðpb.SignedBeaconBlockElectra{
|
||||
Block: ðpb.BeaconBlockElectra{Slot: 5, ParentRoot: parent[:], Body: util.HydrateBeaconBlockBodyElectra(ðpb.BeaconBlockBodyElectra{})},
|
||||
},
|
||||
}
|
||||
blk := ðpb.GenericSignedBeaconBlock_Electra{Electra: sb}
|
||||
return ðpb.GenericSignedBeaconBlock{Block: blk, IsBlinded: false}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "electra block some blob",
|
||||
block: func(parent [32]byte) *ethpb.GenericSignedBeaconBlock {
|
||||
|
||||
sb := ðpb.SignedBeaconBlockContentsElectra{
|
||||
Block: ðpb.SignedBeaconBlockElectra{
|
||||
Block: ðpb.BeaconBlockElectra{Slot: 5, ParentRoot: parent[:], Body: util.HydrateBeaconBlockBodyElectra(ðpb.BeaconBlockBodyElectra{})},
|
||||
},
|
||||
KzgProofs: [][]byte{{0x01}, {0x02}, {0x03}},
|
||||
Blobs: [][]byte{{0x01}, {0x02}, {0x03}},
|
||||
}
|
||||
blk := ðpb.GenericSignedBeaconBlock_Electra{Electra: sb}
|
||||
return ðpb.GenericSignedBeaconBlock{Block: blk, IsBlinded: false}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "blind deneb block some blobs",
|
||||
block: func(parent [32]byte) *ethpb.GenericSignedBeaconBlock {
|
||||
@@ -916,57 +943,6 @@ func TestProposer_ProposeBlock_OK(t *testing.T) {
|
||||
useBuilder: true,
|
||||
err: "unblind sidecars failed: commitment value doesn't match block",
|
||||
},
|
||||
{
|
||||
name: "electra block no blob",
|
||||
block: func(parent [32]byte) *ethpb.GenericSignedBeaconBlock {
|
||||
sb := ðpb.SignedBeaconBlockContentsElectra{
|
||||
Block: ðpb.SignedBeaconBlockElectra{
|
||||
Block: ðpb.BeaconBlockElectra{Slot: 5, ParentRoot: parent[:], Body: util.HydrateBeaconBlockBodyElectra(ðpb.BeaconBlockBodyElectra{})},
|
||||
},
|
||||
}
|
||||
blk := ðpb.GenericSignedBeaconBlock_Electra{Electra: sb}
|
||||
return ðpb.GenericSignedBeaconBlock{Block: blk, IsBlinded: false}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "electra block some blob",
|
||||
block: func(parent [32]byte) *ethpb.GenericSignedBeaconBlock {
|
||||
sb := ðpb.SignedBeaconBlockContentsElectra{
|
||||
Block: ðpb.SignedBeaconBlockElectra{
|
||||
Block: ðpb.BeaconBlockElectra{
|
||||
Slot: 5, ParentRoot: parent[:],
|
||||
Body: util.HydrateBeaconBlockBodyElectra(ðpb.BeaconBlockBodyElectra{
|
||||
BlobKzgCommitments: [][]byte{bytesutil.PadTo([]byte("kc"), 48), bytesutil.PadTo([]byte("kc1"), 48), bytesutil.PadTo([]byte("kc2"), 48)},
|
||||
}),
|
||||
},
|
||||
},
|
||||
KzgProofs: [][]byte{{0x01}, {0x02}, {0x03}},
|
||||
Blobs: [][]byte{{0x01}, {0x02}, {0x03}},
|
||||
}
|
||||
blk := ðpb.GenericSignedBeaconBlock_Electra{Electra: sb}
|
||||
return ðpb.GenericSignedBeaconBlock{Block: blk, IsBlinded: false}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "electra block some blob (kzg and blob count mismatch)",
|
||||
block: func(parent [32]byte) *ethpb.GenericSignedBeaconBlock {
|
||||
sb := ðpb.SignedBeaconBlockContentsElectra{
|
||||
Block: ðpb.SignedBeaconBlockElectra{
|
||||
Block: ðpb.BeaconBlockElectra{
|
||||
Slot: 5, ParentRoot: parent[:],
|
||||
Body: util.HydrateBeaconBlockBodyElectra(ðpb.BeaconBlockBodyElectra{
|
||||
BlobKzgCommitments: [][]byte{bytesutil.PadTo([]byte("kc"), 48), bytesutil.PadTo([]byte("kc1"), 48)},
|
||||
}),
|
||||
},
|
||||
},
|
||||
KzgProofs: [][]byte{{0x01}, {0x02}, {0x03}},
|
||||
Blobs: [][]byte{{0x01}, {0x02}, {0x03}},
|
||||
}
|
||||
blk := ðpb.GenericSignedBeaconBlock_Electra{Electra: sb}
|
||||
return ðpb.GenericSignedBeaconBlock{Block: blk, IsBlinded: false}
|
||||
},
|
||||
err: "blob KZG commitments don't match number of blobs or KZG proofs",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
@@ -3116,15 +3092,3 @@ func TestProposer_GetParentHeadState(t *testing.T) {
|
||||
require.LogsContain(t, hook, "late block attempted reorg failed")
|
||||
})
|
||||
}
|
||||
|
||||
func TestProposer_ElectraBlobsAndProofs(t *testing.T) {
|
||||
electraContents := ðpb.SignedBeaconBlockContentsElectra{Block: ðpb.SignedBeaconBlockElectra{}}
|
||||
electraContents.KzgProofs = make([][]byte, 10)
|
||||
electraContents.Blobs = make([][]byte, 10)
|
||||
|
||||
genBlock := ðpb.GenericSignedBeaconBlock{Block: ðpb.GenericSignedBeaconBlock_Electra{Electra: electraContents}}
|
||||
blobs, proofs, err := blobsAndProofs(genBlock)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 10, len(blobs))
|
||||
require.Equal(t, 10, len(proofs))
|
||||
}
|
||||
|
||||
@@ -30,6 +30,10 @@ func (s *Service) receiveAttestations(ctx context.Context, indexedAttsChan chan
|
||||
for {
|
||||
select {
|
||||
case att := <-indexedAttsChan:
|
||||
if att == nil || att.SignatureValidationSet == nil {
|
||||
log.Error("Received nil attestation or attestation with nil signature validation set")
|
||||
continue
|
||||
}
|
||||
if !validateAttestationIntegrity(att) {
|
||||
continue
|
||||
}
|
||||
@@ -38,6 +42,16 @@ func (s *Service) receiveAttestations(ctx context.Context, indexedAttsChan chan
|
||||
log.WithError(err).Error("Could not get hash tree root of attestation")
|
||||
continue
|
||||
}
|
||||
verified, err := att.SignatureValidationSet.Verify()
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not verify attestation signature")
|
||||
continue
|
||||
}
|
||||
if !verified {
|
||||
log.Error("Attestation signature did not verify")
|
||||
continue
|
||||
}
|
||||
// Verify the attestation signature using the signature batch.
|
||||
attWrapper := &slashertypes.IndexedAttestationWrapper{
|
||||
IndexedAttestation: att.IndexedAtt,
|
||||
DataRoot: dataRoot,
|
||||
|
||||
@@ -2,6 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
@@ -31,6 +32,7 @@ func (c ChunkKind) String() string {
|
||||
// which doesn't work well with interface types.
|
||||
type WrappedIndexedAtt struct {
|
||||
ethpb.IndexedAtt
|
||||
SignatureValidationSet *bls.SignatureBatch
|
||||
}
|
||||
|
||||
// IndexedAttestationWrapper contains an indexed attestation with its
|
||||
|
||||
@@ -199,7 +199,6 @@ type ReadOnlyWithdrawals interface {
|
||||
NextWithdrawalValidatorIndex() (primitives.ValidatorIndex, error)
|
||||
NextWithdrawalIndex() (uint64, error)
|
||||
PendingBalanceToWithdraw(idx primitives.ValidatorIndex) (uint64, error)
|
||||
PendingPartialWithdrawals() ([]*ethpb.PendingPartialWithdrawal, error)
|
||||
NumPendingPartialWithdrawals() (uint64, error)
|
||||
HasPendingBalanceToWithdraw(idx primitives.ValidatorIndex) (bool, error)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"beacon_state.go",
|
||||
"beacon_state_mainnet.go",
|
||||
"beacon_state_minimal.go", # keep
|
||||
"doc.go",
|
||||
"error.go",
|
||||
"getters_attestation.go",
|
||||
|
||||
203
beacon-chain/state/state-native/beacon_state_mainnet.go
Normal file
203
beacon-chain/state/state-native/beacon_state_mainnet.go
Normal file
@@ -0,0 +1,203 @@
|
||||
//go:build !minimal
|
||||
|
||||
package state_native
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sync"
|
||||
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/fieldtrie"
|
||||
customtypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native/custom-types"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native/types"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stateutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
// BeaconState defines a struct containing utilities for the Ethereum Beacon Chain state, defining
|
||||
// getters and setters for its respective values and helpful functions such as HashTreeRoot().
|
||||
type BeaconState struct {
|
||||
version int
|
||||
genesisTime uint64
|
||||
genesisValidatorsRoot [32]byte
|
||||
slot primitives.Slot
|
||||
fork *ethpb.Fork
|
||||
latestBlockHeader *ethpb.BeaconBlockHeader
|
||||
blockRoots customtypes.BlockRoots
|
||||
blockRootsMultiValue *MultiValueBlockRoots
|
||||
stateRoots customtypes.StateRoots
|
||||
stateRootsMultiValue *MultiValueStateRoots
|
||||
historicalRoots customtypes.HistoricalRoots
|
||||
historicalSummaries []*ethpb.HistoricalSummary
|
||||
eth1Data *ethpb.Eth1Data
|
||||
eth1DataVotes []*ethpb.Eth1Data
|
||||
eth1DepositIndex uint64
|
||||
validators []*ethpb.Validator
|
||||
validatorsMultiValue *MultiValueValidators
|
||||
balances []uint64
|
||||
balancesMultiValue *MultiValueBalances
|
||||
randaoMixes customtypes.RandaoMixes
|
||||
randaoMixesMultiValue *MultiValueRandaoMixes
|
||||
slashings []uint64
|
||||
previousEpochAttestations []*ethpb.PendingAttestation
|
||||
currentEpochAttestations []*ethpb.PendingAttestation
|
||||
previousEpochParticipation []byte
|
||||
currentEpochParticipation []byte
|
||||
justificationBits bitfield.Bitvector4
|
||||
previousJustifiedCheckpoint *ethpb.Checkpoint
|
||||
currentJustifiedCheckpoint *ethpb.Checkpoint
|
||||
finalizedCheckpoint *ethpb.Checkpoint
|
||||
inactivityScores []uint64
|
||||
inactivityScoresMultiValue *MultiValueInactivityScores
|
||||
currentSyncCommittee *ethpb.SyncCommittee
|
||||
nextSyncCommittee *ethpb.SyncCommittee
|
||||
latestExecutionPayloadHeader *enginev1.ExecutionPayloadHeader
|
||||
latestExecutionPayloadHeaderCapella *enginev1.ExecutionPayloadHeaderCapella
|
||||
latestExecutionPayloadHeaderDeneb *enginev1.ExecutionPayloadHeaderDeneb
|
||||
latestExecutionPayloadHeaderElectra *enginev1.ExecutionPayloadHeaderElectra
|
||||
nextWithdrawalIndex uint64
|
||||
nextWithdrawalValidatorIndex primitives.ValidatorIndex
|
||||
|
||||
// Electra fields
|
||||
depositRequestsStartIndex uint64
|
||||
depositBalanceToConsume primitives.Gwei
|
||||
exitBalanceToConsume primitives.Gwei
|
||||
earliestExitEpoch primitives.Epoch
|
||||
consolidationBalanceToConsume primitives.Gwei
|
||||
earliestConsolidationEpoch primitives.Epoch
|
||||
pendingBalanceDeposits []*ethpb.PendingBalanceDeposit // pending_balance_deposits: List[PendingBalanceDeposit, PENDING_BALANCE_DEPOSITS_LIMIT]
|
||||
pendingPartialWithdrawals []*ethpb.PendingPartialWithdrawal // pending_partial_withdrawals: List[PartialWithdrawal, PENDING_PARTIAL_WITHDRAWALS_LIMIT]
|
||||
pendingConsolidations []*ethpb.PendingConsolidation // pending_consolidations: List[PendingConsolidation, PENDING_CONSOLIDATIONS_LIMIT]
|
||||
|
||||
id uint64
|
||||
lock sync.RWMutex
|
||||
dirtyFields map[types.FieldIndex]bool
|
||||
dirtyIndices map[types.FieldIndex][]uint64
|
||||
stateFieldLeaves map[types.FieldIndex]*fieldtrie.FieldTrie
|
||||
rebuildTrie map[types.FieldIndex]bool
|
||||
valMapHandler *stateutil.ValidatorMapHandler
|
||||
validatorIndexCache *finalizedValidatorIndexCache
|
||||
merkleLayers [][][]byte
|
||||
sharedFieldReferences map[types.FieldIndex]*stateutil.Reference
|
||||
}
|
||||
|
||||
type beaconStateMarshalable struct {
|
||||
Version int `json:"version" yaml:"version"`
|
||||
GenesisTime uint64 `json:"genesis_time" yaml:"genesis_time"`
|
||||
GenesisValidatorsRoot [32]byte `json:"genesis_validators_root" yaml:"genesis_validators_root"`
|
||||
Slot primitives.Slot `json:"slot" yaml:"slot"`
|
||||
Fork *ethpb.Fork `json:"fork" yaml:"fork"`
|
||||
LatestBlockHeader *ethpb.BeaconBlockHeader `json:"latest_block_header" yaml:"latest_block_header"`
|
||||
BlockRoots customtypes.BlockRoots `json:"block_roots" yaml:"block_roots"`
|
||||
StateRoots customtypes.StateRoots `json:"state_roots" yaml:"state_roots"`
|
||||
HistoricalRoots customtypes.HistoricalRoots `json:"historical_roots" yaml:"historical_roots"`
|
||||
HistoricalSummaries []*ethpb.HistoricalSummary `json:"historical_summaries" yaml:"historical_summaries"`
|
||||
Eth1Data *ethpb.Eth1Data `json:"eth_1_data" yaml:"eth_1_data"`
|
||||
Eth1DataVotes []*ethpb.Eth1Data `json:"eth_1_data_votes" yaml:"eth_1_data_votes"`
|
||||
Eth1DepositIndex uint64 `json:"eth_1_deposit_index" yaml:"eth_1_deposit_index"`
|
||||
Validators []*ethpb.Validator `json:"validators" yaml:"validators"`
|
||||
Balances []uint64 `json:"balances" yaml:"balances"`
|
||||
RandaoMixes customtypes.RandaoMixes `json:"randao_mixes" yaml:"randao_mixes"`
|
||||
Slashings []uint64 `json:"slashings" yaml:"slashings"`
|
||||
PreviousEpochAttestations []*ethpb.PendingAttestation `json:"previous_epoch_attestations" yaml:"previous_epoch_attestations"`
|
||||
CurrentEpochAttestations []*ethpb.PendingAttestation `json:"current_epoch_attestations" yaml:"current_epoch_attestations"`
|
||||
PreviousEpochParticipation []byte `json:"previous_epoch_participation" yaml:"previous_epoch_participation"`
|
||||
CurrentEpochParticipation []byte `json:"current_epoch_participation" yaml:"current_epoch_participation"`
|
||||
JustificationBits bitfield.Bitvector4 `json:"justification_bits" yaml:"justification_bits"`
|
||||
PreviousJustifiedCheckpoint *ethpb.Checkpoint `json:"previous_justified_checkpoint" yaml:"previous_justified_checkpoint"`
|
||||
CurrentJustifiedCheckpoint *ethpb.Checkpoint `json:"current_justified_checkpoint" yaml:"current_justified_checkpoint"`
|
||||
FinalizedCheckpoint *ethpb.Checkpoint `json:"finalized_checkpoint" yaml:"finalized_checkpoint"`
|
||||
InactivityScores []uint64 `json:"inactivity_scores" yaml:"inactivity_scores"`
|
||||
CurrentSyncCommittee *ethpb.SyncCommittee `json:"current_sync_committee" yaml:"current_sync_committee"`
|
||||
NextSyncCommittee *ethpb.SyncCommittee `json:"next_sync_committee" yaml:"next_sync_committee"`
|
||||
LatestExecutionPayloadHeader *enginev1.ExecutionPayloadHeader `json:"latest_execution_payload_header" yaml:"latest_execution_payload_header"`
|
||||
LatestExecutionPayloadHeaderCapella *enginev1.ExecutionPayloadHeaderCapella `json:"latest_execution_payload_header_capella" yaml:"latest_execution_payload_header_capella"`
|
||||
LatestExecutionPayloadHeaderDeneb *enginev1.ExecutionPayloadHeaderDeneb `json:"latest_execution_payload_header_deneb" yaml:"latest_execution_payload_header_deneb"`
|
||||
LatestExecutionPayloadHeaderElectra *enginev1.ExecutionPayloadHeaderElectra `json:"latest_execution_payload_header_electra" yaml:"latest_execution_payload_header_electra"`
|
||||
NextWithdrawalIndex uint64 `json:"next_withdrawal_index" yaml:"next_withdrawal_index"`
|
||||
NextWithdrawalValidatorIndex primitives.ValidatorIndex `json:"next_withdrawal_validator_index" yaml:"next_withdrawal_validator_index"`
|
||||
DepositRequestsStartIndex uint64 `json:"deposit_requests_start_index" yaml:"deposit_requests_start_index"`
|
||||
DepositBalanceToConsume primitives.Gwei `json:"deposit_balance_to_consume" yaml:"deposit_balance_to_consume"`
|
||||
ExitBalanceToConsume primitives.Gwei `json:"exit_balance_to_consume" yaml:"exit_balance_to_consume"`
|
||||
EarliestExitEpoch primitives.Epoch `json:"earliest_exit_epoch" yaml:"earliest_exit_epoch"`
|
||||
ConsolidationBalanceToConsume primitives.Gwei `json:"consolidation_balance_to_consume" yaml:"consolidation_balance_to_consume"`
|
||||
EarliestConsolidationEpoch primitives.Epoch `json:"earliest_consolidation_epoch" yaml:"earliest_consolidation_epoch"`
|
||||
PendingBalanceDeposits []*ethpb.PendingBalanceDeposit `json:"pending_balance_deposits" yaml:"pending_balance_deposits"`
|
||||
PendingPartialWithdrawals []*ethpb.PendingPartialWithdrawal `json:"pending_partial_withdrawals" yaml:"pending_partial_withdrawals"`
|
||||
PendingConsolidations []*ethpb.PendingConsolidation `json:"pending_consolidations" yaml:"pending_consolidations"`
|
||||
}
|
||||
|
||||
func (b *BeaconState) MarshalJSON() ([]byte, error) {
|
||||
var bRoots customtypes.BlockRoots
|
||||
var sRoots customtypes.StateRoots
|
||||
var mixes customtypes.RandaoMixes
|
||||
var balances []uint64
|
||||
var inactivityScores []uint64
|
||||
var vals []*ethpb.Validator
|
||||
|
||||
if features.Get().EnableExperimentalState {
|
||||
bRoots = b.blockRootsMultiValue.Value(b)
|
||||
sRoots = b.stateRootsMultiValue.Value(b)
|
||||
mixes = b.randaoMixesMultiValue.Value(b)
|
||||
balances = b.balancesMultiValue.Value(b)
|
||||
inactivityScores = b.inactivityScoresMultiValue.Value(b)
|
||||
vals = b.validatorsMultiValue.Value(b)
|
||||
} else {
|
||||
bRoots = b.blockRoots
|
||||
sRoots = b.stateRoots
|
||||
mixes = b.randaoMixes
|
||||
balances = b.balances
|
||||
inactivityScores = b.inactivityScores
|
||||
vals = b.validators
|
||||
}
|
||||
|
||||
marshalable := &beaconStateMarshalable{
|
||||
Version: b.version,
|
||||
GenesisTime: b.genesisTime,
|
||||
GenesisValidatorsRoot: b.genesisValidatorsRoot,
|
||||
Slot: b.slot,
|
||||
Fork: b.fork,
|
||||
LatestBlockHeader: b.latestBlockHeader,
|
||||
BlockRoots: bRoots,
|
||||
StateRoots: sRoots,
|
||||
HistoricalRoots: b.historicalRoots,
|
||||
HistoricalSummaries: b.historicalSummaries,
|
||||
Eth1Data: b.eth1Data,
|
||||
Eth1DataVotes: b.eth1DataVotes,
|
||||
Eth1DepositIndex: b.eth1DepositIndex,
|
||||
Validators: vals,
|
||||
Balances: balances,
|
||||
RandaoMixes: mixes,
|
||||
Slashings: b.slashings,
|
||||
PreviousEpochAttestations: b.previousEpochAttestations,
|
||||
CurrentEpochAttestations: b.currentEpochAttestations,
|
||||
PreviousEpochParticipation: b.previousEpochParticipation,
|
||||
CurrentEpochParticipation: b.currentEpochParticipation,
|
||||
JustificationBits: b.justificationBits,
|
||||
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint,
|
||||
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint,
|
||||
FinalizedCheckpoint: b.finalizedCheckpoint,
|
||||
InactivityScores: inactivityScores,
|
||||
CurrentSyncCommittee: b.currentSyncCommittee,
|
||||
NextSyncCommittee: b.nextSyncCommittee,
|
||||
LatestExecutionPayloadHeader: b.latestExecutionPayloadHeader,
|
||||
LatestExecutionPayloadHeaderCapella: b.latestExecutionPayloadHeaderCapella,
|
||||
LatestExecutionPayloadHeaderDeneb: b.latestExecutionPayloadHeaderDeneb,
|
||||
LatestExecutionPayloadHeaderElectra: b.latestExecutionPayloadHeaderElectra,
|
||||
NextWithdrawalIndex: b.nextWithdrawalIndex,
|
||||
NextWithdrawalValidatorIndex: b.nextWithdrawalValidatorIndex,
|
||||
DepositRequestsStartIndex: b.depositRequestsStartIndex,
|
||||
DepositBalanceToConsume: b.depositBalanceToConsume,
|
||||
ExitBalanceToConsume: b.exitBalanceToConsume,
|
||||
EarliestExitEpoch: b.earliestExitEpoch,
|
||||
ConsolidationBalanceToConsume: b.consolidationBalanceToConsume,
|
||||
EarliestConsolidationEpoch: b.earliestConsolidationEpoch,
|
||||
PendingBalanceDeposits: b.pendingBalanceDeposits,
|
||||
PendingPartialWithdrawals: b.pendingPartialWithdrawals,
|
||||
PendingConsolidations: b.pendingConsolidations,
|
||||
}
|
||||
return json.Marshal(marshalable)
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
//go:build minimal
|
||||
|
||||
package state_native
|
||||
|
||||
import (
|
||||
@@ -183,15 +183,6 @@ func (b *BeaconState) ExpectedWithdrawals() ([]*enginev1.Withdrawal, uint64, err
|
||||
return withdrawals, partialWithdrawalsCount, nil
|
||||
}
|
||||
|
||||
func (b *BeaconState) PendingPartialWithdrawals() ([]*ethpb.PendingPartialWithdrawal, error) {
|
||||
if b.version < version.Electra {
|
||||
return nil, errNotSupported("PendingPartialWithdrawals", b.version)
|
||||
}
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
return b.pendingPartialWithdrawalsVal(), nil
|
||||
}
|
||||
|
||||
func (b *BeaconState) pendingPartialWithdrawalsVal() []*ethpb.PendingPartialWithdrawal {
|
||||
return ethpb.CopySlice(b.pendingPartialWithdrawals)
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ func newFinalizedValidatorIndexCache() *finalizedValidatorIndexCache {
|
||||
// If the public key is not found in the cache, it searches through the state starting from the last finalized index.
|
||||
func (b *BeaconState) getValidatorIndex(pubKey [fieldparams.BLSPubkeyLength]byte) (primitives.ValidatorIndex, bool) {
|
||||
b.validatorIndexCache.RLock()
|
||||
defer b.validatorIndexCache.RUnlock()
|
||||
index, found := b.validatorIndexCache.indexMap[pubKey]
|
||||
b.validatorIndexCache.RUnlock()
|
||||
if found {
|
||||
return index, true
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
@@ -307,35 +306,8 @@ func (s *State) latestAncestor(ctx context.Context, blockRoot [32]byte) (state.B
|
||||
|
||||
// Does the state exists in DB.
|
||||
if s.beaconDB.HasState(ctx, parentRoot) {
|
||||
st, err := s.beaconDB.State(ctx, parentRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blk, err := s.beaconDB.Block(ctx, parentRoot)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get block from db!")
|
||||
}
|
||||
|
||||
if st.Slot() != blk.Block().Slot() {
|
||||
return nil, errors.New("slot mismatch!")
|
||||
}
|
||||
|
||||
stateRoot1, err := st.HashTreeRoot(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not hash tree root of state!")
|
||||
}
|
||||
stateRoot2 := blk.Block().StateRoot()
|
||||
if stateRoot1 != stateRoot2 {
|
||||
log.WithFields(logrus.Fields{
|
||||
"StateRoot": stateRoot1,
|
||||
"BlockStateRoot": stateRoot2,
|
||||
"ParentBlockRoot": parentRoot,
|
||||
"BlockSlot": blk.Block().Slot(),
|
||||
"StateSlot": st.Slot(),
|
||||
}).Warn("State root missmatch between block and state")
|
||||
}
|
||||
|
||||
return st, nil
|
||||
s, err := s.beaconDB.State(ctx, parentRoot)
|
||||
return s, errors.Wrap(err, "failed to retrieve state from db")
|
||||
}
|
||||
|
||||
b, err = s.beaconDB.Block(ctx, parentRoot)
|
||||
|
||||
@@ -132,7 +132,7 @@ func (s *Service) processAttestations(ctx context.Context, attestations []ethpb.
|
||||
continue
|
||||
}
|
||||
|
||||
valid, err := s.validateUnaggregatedAttWithState(ctx, aggregate, preState)
|
||||
valid, _, err := s.validateUnaggregatedAttWithState(ctx, aggregate, preState)
|
||||
if err != nil {
|
||||
log.WithError(err).Debug("Pending unaggregated attestation failed validation")
|
||||
continue
|
||||
|
||||
@@ -25,11 +25,7 @@ func (s *Service) committeeIndexBeaconAttestationSubscriber(_ context.Context, m
|
||||
if data == nil {
|
||||
return errors.New("nil attestation")
|
||||
}
|
||||
committeeIndex, err := a.GetCommitteeIndex()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "committeeIndexBeaconAttestationSubscriber failed to get committee index")
|
||||
}
|
||||
s.setSeenCommitteeIndicesSlot(data.Slot, committeeIndex, a.GetAggregationBits())
|
||||
s.setSeenCommitteeIndicesSlot(data.Slot, data.CommitteeIndex, a.GetAggregationBits())
|
||||
|
||||
exists, err := s.cfg.attPool.HasAggregatedAttestation(a)
|
||||
if err != nil {
|
||||
|
||||
@@ -167,32 +167,39 @@ func (s *Service) validateAggregatedAtt(ctx context.Context, signed ethpb.Signed
|
||||
return pubsub.ValidationIgnore, err
|
||||
}
|
||||
|
||||
committeeIndex, _, result, err := s.validateCommitteeIndexAndCount(ctx, aggregate, bs)
|
||||
if result != pubsub.ValidationAccept {
|
||||
wrappedErr := errors.Wrapf(err, "could not validate committee index")
|
||||
tracing.AnnotateError(span, wrappedErr)
|
||||
return result, err
|
||||
}
|
||||
|
||||
committee, result, err := s.validateBitLength(ctx, bs, aggregate.GetData().Slot, committeeIndex, aggregate.GetAggregationBits())
|
||||
if result != pubsub.ValidationAccept {
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Verify validator index is within the beacon committee.
|
||||
result, err = s.validateIndexInCommittee(ctx, aggregate, aggregatorIndex, committee)
|
||||
result, err := s.validateIndexInCommittee(ctx, bs, aggregate, aggregatorIndex)
|
||||
if result != pubsub.ValidationAccept {
|
||||
wrappedErr := errors.Wrapf(err, "could not validate index in committee")
|
||||
tracing.AnnotateError(span, wrappedErr)
|
||||
return result, wrappedErr
|
||||
}
|
||||
|
||||
var committeeIndex primitives.CommitteeIndex
|
||||
if signed.Version() >= version.Electra {
|
||||
a, ok := aggregate.(*ethpb.AttestationElectra)
|
||||
// This will never fail in practice because we asserted the version
|
||||
if !ok {
|
||||
err := fmt.Errorf("aggregate attestation has wrong type (expected %T, got %T)", ðpb.AttestationElectra{}, aggregate)
|
||||
tracing.AnnotateError(span, err)
|
||||
return pubsub.ValidationIgnore, err
|
||||
}
|
||||
committeeIndex, result, err = validateCommitteeIndexElectra(ctx, a)
|
||||
if result != pubsub.ValidationAccept {
|
||||
wrappedErr := errors.Wrapf(err, "could not validate committee index for Electra version")
|
||||
tracing.AnnotateError(span, wrappedErr)
|
||||
return result, wrappedErr
|
||||
}
|
||||
} else {
|
||||
committeeIndex = data.CommitteeIndex
|
||||
}
|
||||
|
||||
// Verify selection proof reflects to the right validator.
|
||||
selectionSigSet, err := validateSelectionIndex(
|
||||
ctx,
|
||||
bs,
|
||||
data.Slot,
|
||||
committee,
|
||||
committeeIndex,
|
||||
aggregatorIndex,
|
||||
aggregateAndProof.GetSelectionProof(),
|
||||
)
|
||||
@@ -259,10 +266,24 @@ func (s *Service) setAggregatorIndexEpochSeen(epoch primitives.Epoch, aggregator
|
||||
// - [REJECT] The aggregate attestation has participants -- that is, len(get_attesting_indices(state, aggregate.data, aggregate.aggregation_bits)) >= 1.
|
||||
// - [REJECT] The aggregator's validator index is within the committee --
|
||||
// i.e. `aggregate_and_proof.aggregator_index in get_beacon_committee(state, aggregate.data.slot, aggregate.data.index)`.
|
||||
func (s *Service) validateIndexInCommittee(ctx context.Context, a ethpb.Att, validatorIndex primitives.ValidatorIndex, committee []primitives.ValidatorIndex) (pubsub.ValidationResult, error) {
|
||||
_, span := trace.StartSpan(ctx, "sync.validateIndexInCommittee")
|
||||
//
|
||||
// Post-Electra:
|
||||
// - [REJECT] len(committee_indices) == 1, where committee_indices = get_committee_indices(aggregate).
|
||||
// - [REJECT] aggregate.data.index == 0
|
||||
func (s *Service) validateIndexInCommittee(ctx context.Context, bs state.ReadOnlyBeaconState, a ethpb.Att, validatorIndex primitives.ValidatorIndex) (pubsub.ValidationResult, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "sync.validateIndexInCommittee")
|
||||
defer span.End()
|
||||
|
||||
committeeIndex, _, result, err := s.validateCommitteeIndex(ctx, a, bs)
|
||||
if result != pubsub.ValidationAccept {
|
||||
return result, err
|
||||
}
|
||||
|
||||
committee, result, err := s.validateBitLength(ctx, bs, a.GetData().Slot, committeeIndex, a.GetAggregationBits())
|
||||
if result != pubsub.ValidationAccept {
|
||||
return result, err
|
||||
}
|
||||
|
||||
if a.GetAggregationBits().Count() == 0 {
|
||||
return pubsub.ValidationReject, errors.New("no attesting indices")
|
||||
}
|
||||
@@ -287,13 +308,17 @@ func validateSelectionIndex(
|
||||
ctx context.Context,
|
||||
bs state.ReadOnlyBeaconState,
|
||||
slot primitives.Slot,
|
||||
committee []primitives.ValidatorIndex,
|
||||
committeeIndex primitives.CommitteeIndex,
|
||||
validatorIndex primitives.ValidatorIndex,
|
||||
proof []byte,
|
||||
) (*bls.SignatureBatch, error) {
|
||||
_, span := trace.StartSpan(ctx, "sync.validateSelectionIndex")
|
||||
ctx, span := trace.StartSpan(ctx, "sync.validateSelectionIndex")
|
||||
defer span.End()
|
||||
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, bs, slot, committeeIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aggregator, err := helpers.IsAggregator(uint64(len(committee)), proof)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -50,13 +50,12 @@ func TestVerifyIndexInCommittee_CanVerify(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
indices, err := attestation.AttestingIndices(att, committee)
|
||||
require.NoError(t, err)
|
||||
|
||||
result, err := service.validateIndexInCommittee(ctx, att, primitives.ValidatorIndex(indices[0]), committee)
|
||||
result, err := service.validateIndexInCommittee(ctx, s, att, primitives.ValidatorIndex(indices[0]))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, pubsub.ValidationAccept, result)
|
||||
|
||||
wanted := "validator index 1000 is not within the committee"
|
||||
result, err = service.validateIndexInCommittee(ctx, att, 1000, committee)
|
||||
result, err = service.validateIndexInCommittee(ctx, s, att, 1000)
|
||||
assert.ErrorContains(t, wanted, err)
|
||||
assert.Equal(t, pubsub.ValidationReject, result)
|
||||
}
|
||||
@@ -79,30 +78,28 @@ func TestVerifyIndexInCommittee_ExistsInBeaconCommittee(t *testing.T) {
|
||||
att.AggregationBits = bl
|
||||
|
||||
service := &Service{}
|
||||
result, err := service.validateIndexInCommittee(ctx, att, committee[0], committee)
|
||||
result, err := service.validateIndexInCommittee(ctx, s, att, committee[0])
|
||||
require.ErrorContains(t, "no attesting indices", err)
|
||||
assert.Equal(t, pubsub.ValidationReject, result)
|
||||
|
||||
att.AggregationBits.SetBitAt(0, true)
|
||||
|
||||
result, err = service.validateIndexInCommittee(ctx, att, committee[0], committee)
|
||||
result, err = service.validateIndexInCommittee(ctx, s, att, committee[0])
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, pubsub.ValidationAccept, result)
|
||||
|
||||
wanted := "validator index 1000 is not within the committee"
|
||||
result, err = service.validateIndexInCommittee(ctx, att, 1000, committee)
|
||||
result, err = service.validateIndexInCommittee(ctx, s, att, 1000)
|
||||
assert.ErrorContains(t, wanted, err)
|
||||
assert.Equal(t, pubsub.ValidationReject, result)
|
||||
|
||||
att.AggregationBits = bitfield.NewBitlist(1)
|
||||
committeeIndex, err := att.GetCommitteeIndex()
|
||||
require.NoError(t, err)
|
||||
_, result, err = service.validateBitLength(ctx, s, att.Data.Slot, committeeIndex, att.AggregationBits)
|
||||
result, err = service.validateIndexInCommittee(ctx, s, att, committee[0])
|
||||
require.ErrorContains(t, "wanted participants bitfield length 4, got: 1", err)
|
||||
assert.Equal(t, pubsub.ValidationReject, result)
|
||||
|
||||
att.Data.CommitteeIndex = 10000
|
||||
_, _, result, err = service.validateCommitteeIndexAndCount(ctx, att, s)
|
||||
result, err = service.validateIndexInCommittee(ctx, s, att, committee[0])
|
||||
require.ErrorContains(t, "committee index 10000 > 2", err)
|
||||
assert.Equal(t, pubsub.ValidationReject, result)
|
||||
}
|
||||
@@ -120,7 +117,7 @@ func TestVerifyIndexInCommittee_Electra(t *testing.T) {
|
||||
bl.SetBitAt(0, true)
|
||||
att.AggregationBits = bl
|
||||
|
||||
result, err := service.validateIndexInCommittee(ctx, att, committee[0], committee)
|
||||
result, err := service.validateIndexInCommittee(ctx, s, att, committee[0])
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, pubsub.ValidationAccept, result)
|
||||
}
|
||||
@@ -134,9 +131,8 @@ func TestVerifySelection_NotAnAggregator(t *testing.T) {
|
||||
|
||||
sig := privKeys[0].Sign([]byte{'A'})
|
||||
data := util.HydrateAttestationData(ðpb.AttestationData{})
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, beaconState, data.Slot, data.CommitteeIndex)
|
||||
require.NoError(t, err)
|
||||
_, err = validateSelectionIndex(ctx, beaconState, data.Slot, committee, 0, sig.Marshal())
|
||||
|
||||
_, err := validateSelectionIndex(ctx, beaconState, data.Slot, data.CommitteeIndex, 0, sig.Marshal())
|
||||
wanted := "validator is not an aggregator for slot"
|
||||
assert.ErrorContains(t, wanted, err)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing"
|
||||
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -94,26 +95,36 @@ func (s *Service) validateCommitteeIndexBeaconAttestation(ctx context.Context, p
|
||||
|
||||
var validationRes pubsub.ValidationResult
|
||||
|
||||
committeeIndex, result, err := s.validateCommitteeIndex(ctx, att)
|
||||
if result != pubsub.ValidationAccept {
|
||||
wrappedErr := errors.Wrapf(err, "could not validate committee index for %s version", version.String(att.Version()))
|
||||
tracing.AnnotateError(span, wrappedErr)
|
||||
return result, wrappedErr
|
||||
var committeeIndex primitives.CommitteeIndex
|
||||
if att.Version() >= version.Electra {
|
||||
a, ok := att.(*eth.AttestationElectra)
|
||||
// This will never fail in practice because we asserted the version
|
||||
if !ok {
|
||||
err := fmt.Errorf("attestation has wrong type (expected %T, got %T)", ð.AttestationElectra{}, att)
|
||||
tracing.AnnotateError(span, err)
|
||||
return pubsub.ValidationIgnore, err
|
||||
}
|
||||
committeeIndex, validationRes, err = validateCommitteeIndexElectra(ctx, a)
|
||||
if validationRes != pubsub.ValidationAccept {
|
||||
wrappedErr := errors.Wrapf(err, "could not validate committee index for Electra version")
|
||||
tracing.AnnotateError(span, wrappedErr)
|
||||
return validationRes, wrappedErr
|
||||
}
|
||||
} else {
|
||||
committeeIndex = data.CommitteeIndex
|
||||
}
|
||||
|
||||
if !features.Get().EnableSlasher {
|
||||
// Verify this the first attestation received for the participating validator for the slot.
|
||||
if s.hasSeenCommitteeIndicesSlot(data.Slot, committeeIndex, att.GetAggregationBits()) {
|
||||
return pubsub.ValidationIgnore, nil
|
||||
}
|
||||
// Verify this the first attestation received for the participating validator for the slot.
|
||||
if s.hasSeenCommitteeIndicesSlot(data.Slot, data.CommitteeIndex, att.GetAggregationBits()) {
|
||||
return pubsub.ValidationIgnore, nil
|
||||
}
|
||||
|
||||
// Reject an attestation if it references an invalid block.
|
||||
if s.hasBadBlock(bytesutil.ToBytes32(data.BeaconBlockRoot)) ||
|
||||
s.hasBadBlock(bytesutil.ToBytes32(data.Target.Root)) ||
|
||||
s.hasBadBlock(bytesutil.ToBytes32(data.Source.Root)) {
|
||||
attBadBlockCount.Inc()
|
||||
return pubsub.ValidationReject, errors.New("attestation data references bad block root")
|
||||
}
|
||||
// Reject an attestation if it references an invalid block.
|
||||
if s.hasBadBlock(bytesutil.ToBytes32(data.BeaconBlockRoot)) ||
|
||||
s.hasBadBlock(bytesutil.ToBytes32(data.Target.Root)) ||
|
||||
s.hasBadBlock(bytesutil.ToBytes32(data.Source.Root)) {
|
||||
attBadBlockCount.Inc()
|
||||
return pubsub.ValidationReject, errors.New("attestation data references bad block root")
|
||||
}
|
||||
|
||||
// Verify the block being voted and the processed state is in beaconDB and the block has passed validation if it's in the beaconDB.
|
||||
@@ -159,7 +170,7 @@ func (s *Service) validateCommitteeIndexBeaconAttestation(ctx context.Context, p
|
||||
return validationRes, err
|
||||
}
|
||||
|
||||
validationRes, err = s.validateUnaggregatedAttWithState(ctx, att, preState)
|
||||
validationRes, signatureValidationSet, err := s.validateUnaggregatedAttWithState(ctx, att, preState)
|
||||
if validationRes != pubsub.ValidationAccept {
|
||||
return validationRes, err
|
||||
}
|
||||
@@ -189,11 +200,13 @@ func (s *Service) validateCommitteeIndexBeaconAttestation(ctx context.Context, p
|
||||
tracing.AnnotateError(span, err)
|
||||
return
|
||||
}
|
||||
s.cfg.slasherAttestationsFeed.Send(&types.WrappedIndexedAtt{IndexedAtt: indexedAtt})
|
||||
s.cfg.slasherAttestationsFeed.Send(&types.WrappedIndexedAtt{
|
||||
IndexedAtt: indexedAtt, SignatureValidationSet: signatureValidationSet,
|
||||
})
|
||||
}()
|
||||
}
|
||||
|
||||
s.setSeenCommitteeIndicesSlot(data.Slot, committeeIndex, att.GetAggregationBits())
|
||||
s.setSeenCommitteeIndicesSlot(data.Slot, data.CommitteeIndex, att.GetAggregationBits())
|
||||
|
||||
msg.ValidatorData = att
|
||||
|
||||
@@ -205,7 +218,7 @@ func (s *Service) validateUnaggregatedAttTopic(ctx context.Context, a eth.Att, b
|
||||
ctx, span := trace.StartSpan(ctx, "sync.validateUnaggregatedAttTopic")
|
||||
defer span.End()
|
||||
|
||||
_, valCount, result, err := s.validateCommitteeIndexAndCount(ctx, a, bs)
|
||||
_, valCount, result, err := s.validateCommitteeIndex(ctx, a, bs)
|
||||
if result != pubsub.ValidationAccept {
|
||||
return result, err
|
||||
}
|
||||
@@ -223,63 +236,63 @@ func (s *Service) validateUnaggregatedAttTopic(ctx context.Context, a eth.Att, b
|
||||
return pubsub.ValidationAccept, nil
|
||||
}
|
||||
|
||||
func (s *Service) validateCommitteeIndexAndCount(
|
||||
func (s *Service) validateCommitteeIndex(
|
||||
ctx context.Context,
|
||||
a eth.Att,
|
||||
bs state.ReadOnlyBeaconState,
|
||||
) (primitives.CommitteeIndex, uint64, pubsub.ValidationResult, error) {
|
||||
ci, result, err := s.validateCommitteeIndex(ctx, a)
|
||||
if result != pubsub.ValidationAccept {
|
||||
return 0, 0, result, err
|
||||
}
|
||||
valCount, err := helpers.ActiveValidatorCount(ctx, bs, slots.ToEpoch(a.GetData().Slot))
|
||||
if err != nil {
|
||||
return 0, 0, pubsub.ValidationIgnore, err
|
||||
}
|
||||
count := helpers.SlotCommitteeCount(valCount)
|
||||
if uint64(ci) > count {
|
||||
return 0, 0, pubsub.ValidationReject, fmt.Errorf("committee index %d > %d", a.GetData().CommitteeIndex, count)
|
||||
if uint64(a.GetData().CommitteeIndex) > count {
|
||||
return 0, 0, pubsub.ValidationReject, errors.Errorf("committee index %d > %d", a.GetData().CommitteeIndex, count)
|
||||
}
|
||||
|
||||
var ci primitives.CommitteeIndex
|
||||
if a.Version() >= version.Electra {
|
||||
dataCi := a.GetData().CommitteeIndex
|
||||
if dataCi != 0 {
|
||||
return 0, 0, pubsub.ValidationReject, fmt.Errorf("committee index must be 0 but was %d", dataCi)
|
||||
}
|
||||
indices := helpers.CommitteeIndices(a.CommitteeBitsVal())
|
||||
if len(indices) != 1 {
|
||||
return 0, 0, pubsub.ValidationReject, fmt.Errorf("exactly 1 committee index must be set but %d were set", len(indices))
|
||||
}
|
||||
ci = indices[0]
|
||||
} else {
|
||||
ci = a.GetData().CommitteeIndex
|
||||
}
|
||||
return ci, valCount, pubsub.ValidationAccept, nil
|
||||
}
|
||||
|
||||
func (s *Service) validateCommitteeIndex(ctx context.Context, a eth.Att) (primitives.CommitteeIndex, pubsub.ValidationResult, error) {
|
||||
if a.Version() >= version.Electra {
|
||||
return validateCommitteeIndexElectra(ctx, a)
|
||||
}
|
||||
return a.GetData().CommitteeIndex, pubsub.ValidationAccept, nil
|
||||
}
|
||||
|
||||
// This validates beacon unaggregated attestation using the given state, the validation consists of bitfield length and count consistency
|
||||
// and signature verification.
|
||||
func (s *Service) validateUnaggregatedAttWithState(ctx context.Context, a eth.Att, bs state.ReadOnlyBeaconState) (pubsub.ValidationResult, error) {
|
||||
func (s *Service) validateUnaggregatedAttWithState(ctx context.Context, a eth.Att, bs state.ReadOnlyBeaconState) (pubsub.ValidationResult, *bls.SignatureBatch, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "sync.validateUnaggregatedAttWithState")
|
||||
defer span.End()
|
||||
|
||||
committeeIndex, err := a.GetCommitteeIndex()
|
||||
if err != nil {
|
||||
return pubsub.ValidationIgnore, err
|
||||
}
|
||||
|
||||
committee, result, err := s.validateBitLength(ctx, bs, a.GetData().Slot, committeeIndex, a.GetAggregationBits())
|
||||
committee, result, err := s.validateBitLength(ctx, bs, a.GetData().Slot, a.GetData().CommitteeIndex, a.GetAggregationBits())
|
||||
if result != pubsub.ValidationAccept {
|
||||
return result, err
|
||||
return result, nil, err
|
||||
}
|
||||
|
||||
// Attestation must be unaggregated and the bit index must exist in the range of committee indices.
|
||||
// Note: The Ethereum Beacon chain spec suggests (len(get_attesting_indices(state, attestation.data, attestation.aggregation_bits)) == 1)
|
||||
// however this validation can be achieved without use of get_attesting_indices which is an O(n) lookup.
|
||||
if a.GetAggregationBits().Count() != 1 || a.GetAggregationBits().BitIndices()[0] >= len(committee) {
|
||||
return pubsub.ValidationReject, errors.New("attestation bitfield is invalid")
|
||||
return pubsub.ValidationReject, nil, errors.New("attestation bitfield is invalid")
|
||||
}
|
||||
|
||||
set, err := blocks.AttestationSignatureBatch(ctx, bs, []eth.Att{a})
|
||||
if err != nil {
|
||||
tracing.AnnotateError(span, err)
|
||||
attBadSignatureBatchCount.Inc()
|
||||
return pubsub.ValidationReject, err
|
||||
return pubsub.ValidationReject, nil, err
|
||||
}
|
||||
return s.validateWithBatchVerifier(ctx, "attestation", set)
|
||||
res, err := s.validateWithBatchVerifier(ctx, "attestation", set)
|
||||
return res, set, err
|
||||
}
|
||||
|
||||
func (s *Service) validateBitLength(
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"go.opencensus.io/trace"
|
||||
@@ -13,16 +14,17 @@ import (
|
||||
// validateCommitteeIndexElectra implements the following checks from the spec:
|
||||
// - [REJECT] len(committee_indices) == 1, where committee_indices = get_committee_indices(attestation).
|
||||
// - [REJECT] attestation.data.index == 0
|
||||
func validateCommitteeIndexElectra(ctx context.Context, a ethpb.Att) (primitives.CommitteeIndex, pubsub.ValidationResult, error) {
|
||||
func validateCommitteeIndexElectra(ctx context.Context, a *ethpb.AttestationElectra) (primitives.CommitteeIndex, pubsub.ValidationResult, error) {
|
||||
_, span := trace.StartSpan(ctx, "sync.validateCommitteeIndexElectra")
|
||||
defer span.End()
|
||||
_, ok := a.(*ethpb.AttestationElectra)
|
||||
if !ok {
|
||||
return 0, pubsub.ValidationIgnore, fmt.Errorf("attestation has wrong type (expected %T, got %T)", ðpb.AttestationElectra{}, a)
|
||||
|
||||
ci := a.Data.CommitteeIndex
|
||||
if ci != 0 {
|
||||
return 0, pubsub.ValidationReject, fmt.Errorf("committee index must be 0 but was %d", ci)
|
||||
}
|
||||
committeeIndex, err := a.GetCommitteeIndex()
|
||||
if err != nil {
|
||||
return 0, pubsub.ValidationReject, err
|
||||
committeeIndices := helpers.CommitteeIndices(a.CommitteeBits)
|
||||
if len(committeeIndices) != 1 {
|
||||
return 0, pubsub.ValidationReject, fmt.Errorf("exactly 1 committee index must be set but %d were set", len(committeeIndices))
|
||||
}
|
||||
return committeeIndex, pubsub.ValidationAccept, nil
|
||||
return committeeIndices[0], pubsub.ValidationAccept, nil
|
||||
}
|
||||
|
||||
@@ -39,12 +39,4 @@ const (
|
||||
MaxDepositRequestsPerPayload = 8192 // Maximum number of deposit requests in an execution payload.
|
||||
MaxWithdrawalRequestsPerPayload = 16 // Maximum number of execution layer withdrawal requests in an execution payload.
|
||||
MaxConsolidationRequestsPerPayload = 1 // Maximum number of consolidation requests in an execution payload.
|
||||
MaxProposerSlashings = 16 // Maximum number of proposer slashings in a block.
|
||||
MaxAttesterSlashings = 2 // Maximum number of attester slashings in a block.
|
||||
MaxAttesterSlashingsElectra = 1 // Maximum number of attester slashings in a block.
|
||||
MaxAttestations = 128 // Maximum number of attestations in a block.
|
||||
MaxAttestationsElectra = 8 // Maximum number of attestations in a block.
|
||||
MaxDeposits = 16 // Maximum number of deposits in a block.
|
||||
MaxVoluntaryExits = 16 // Maximum number of voluntary exits in a block.
|
||||
MaxBlsToExecutionChanges = 16 // Maximum number of bls to execution changes in a block.
|
||||
)
|
||||
|
||||
@@ -39,12 +39,4 @@ const (
|
||||
MaxDepositRequestsPerPayload = 4 // Maximum number of deposit requests in an execution payload.
|
||||
MaxWithdrawalRequestsPerPayload = 2 // Maximum number of execution layer withdrawal requests in an execution payload.
|
||||
MaxConsolidationRequestsPerPayload = 1 // Maximum number of consolidation requests in an execution payload.
|
||||
MaxProposerSlashings = 16 // Maximum number of proposer slashings in a block.
|
||||
MaxAttesterSlashings = 2 // Maximum number of attester slashings in a block.
|
||||
MaxAttesterSlashingsElectra = 1 // Maximum number of attester slashings in a block.
|
||||
MaxAttestations = 128 // Maximum number of attestations in a block.
|
||||
MaxAttestationsElectra = 8 // Maximum number of attestations in a block.
|
||||
MaxDeposits = 16 // Maximum number of deposits in a block.
|
||||
MaxVoluntaryExits = 16 // Maximum number of voluntary exits in a block.
|
||||
MaxBlsToExecutionChanges = 16 // Maximum number of bls to execution changes in a block.
|
||||
)
|
||||
|
||||
@@ -242,7 +242,7 @@ var mainnetBeaconConfig = &BeaconChainConfig{
|
||||
EpochsPerSyncCommitteePeriod: 256,
|
||||
|
||||
// Updated penalty values.
|
||||
InactivityPenaltyQuotientAltair: 3 * 1 << 24, // 50331648
|
||||
InactivityPenaltyQuotientAltair: 3 * 1 << 24, //50331648
|
||||
MinSlashingPenaltyQuotientAltair: 64,
|
||||
ProportionalSlashingMultiplierAltair: 2,
|
||||
MinSlashingPenaltyQuotientBellatrix: 32,
|
||||
|
||||
@@ -70,7 +70,6 @@ func MinimalSpecConfig() *BeaconChainConfig {
|
||||
minimalConfig.MaxDeposits = 16
|
||||
minimalConfig.MaxVoluntaryExits = 16
|
||||
minimalConfig.MaxWithdrawalsPerPayload = 4
|
||||
minimalConfig.MaxBlsToExecutionChanges = 16
|
||||
minimalConfig.MaxValidatorsPerWithdrawalsSweep = 16
|
||||
|
||||
// Signature domains
|
||||
|
||||
@@ -8,7 +8,6 @@ go_library(
|
||||
"get_payload.go",
|
||||
"getters.go",
|
||||
"kzg.go",
|
||||
"proofs.go",
|
||||
"proto.go",
|
||||
"roblob.go",
|
||||
"roblock.go",
|
||||
@@ -24,7 +23,6 @@ go_library(
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//container/trie:go_default_library",
|
||||
"//crypto/hash/htr:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//encoding/ssz:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
@@ -34,7 +32,6 @@ go_library(
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_fastssz//:go_default_library",
|
||||
"@com_github_prysmaticlabs_gohashtree//:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
],
|
||||
)
|
||||
@@ -46,7 +43,6 @@ go_test(
|
||||
"factory_test.go",
|
||||
"getters_test.go",
|
||||
"kzg_test.go",
|
||||
"proofs_test.go",
|
||||
"proto_test.go",
|
||||
"roblob_test.go",
|
||||
"roblock_test.go",
|
||||
|
||||
@@ -503,135 +503,6 @@ func hydrateBeaconBlockBody() *eth.BeaconBlockBody {
|
||||
}
|
||||
}
|
||||
|
||||
func hydrateBeaconBlockBodyAltair() *eth.BeaconBlockBodyAltair {
|
||||
return ð.BeaconBlockBodyAltair{
|
||||
RandaoReveal: make([]byte, fieldparams.BLSSignatureLength),
|
||||
Graffiti: make([]byte, fieldparams.RootLength),
|
||||
Eth1Data: ð.Eth1Data{
|
||||
DepositRoot: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
},
|
||||
SyncAggregate: ð.SyncAggregate{
|
||||
SyncCommitteeBits: make([]byte, 64),
|
||||
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func hydrateBeaconBlockBodyBellatrix() *eth.BeaconBlockBodyBellatrix {
|
||||
return ð.BeaconBlockBodyBellatrix{
|
||||
RandaoReveal: make([]byte, fieldparams.BLSSignatureLength),
|
||||
Graffiti: make([]byte, fieldparams.RootLength),
|
||||
Eth1Data: ð.Eth1Data{
|
||||
DepositRoot: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
},
|
||||
SyncAggregate: ð.SyncAggregate{
|
||||
SyncCommitteeBits: make([]byte, 64),
|
||||
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
|
||||
},
|
||||
ExecutionPayload: &pb.ExecutionPayload{
|
||||
ParentHash: make([]byte, fieldparams.RootLength),
|
||||
FeeRecipient: make([]byte, 20),
|
||||
StateRoot: make([]byte, fieldparams.RootLength),
|
||||
ReceiptsRoot: make([]byte, fieldparams.RootLength),
|
||||
LogsBloom: make([]byte, 256),
|
||||
PrevRandao: make([]byte, fieldparams.RootLength),
|
||||
ExtraData: make([]byte, 0),
|
||||
BaseFeePerGas: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
Transactions: make([][]byte, 0),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func hydrateBeaconBlockBodyCapella() *eth.BeaconBlockBodyCapella {
|
||||
return ð.BeaconBlockBodyCapella{
|
||||
RandaoReveal: make([]byte, fieldparams.BLSSignatureLength),
|
||||
Graffiti: make([]byte, fieldparams.RootLength),
|
||||
Eth1Data: ð.Eth1Data{
|
||||
DepositRoot: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
},
|
||||
SyncAggregate: ð.SyncAggregate{
|
||||
SyncCommitteeBits: make([]byte, fieldparams.SyncAggregateSyncCommitteeBytesLength),
|
||||
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
|
||||
},
|
||||
ExecutionPayload: &pb.ExecutionPayloadCapella{
|
||||
ParentHash: make([]byte, fieldparams.RootLength),
|
||||
FeeRecipient: make([]byte, 20),
|
||||
StateRoot: make([]byte, fieldparams.RootLength),
|
||||
ReceiptsRoot: make([]byte, fieldparams.RootLength),
|
||||
LogsBloom: make([]byte, 256),
|
||||
PrevRandao: make([]byte, fieldparams.RootLength),
|
||||
ExtraData: make([]byte, 0),
|
||||
BaseFeePerGas: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
Transactions: make([][]byte, 0),
|
||||
Withdrawals: make([]*pb.Withdrawal, 0),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func hydrateBeaconBlockBodyDeneb() *eth.BeaconBlockBodyDeneb {
|
||||
return ð.BeaconBlockBodyDeneb{
|
||||
RandaoReveal: make([]byte, fieldparams.BLSSignatureLength),
|
||||
Graffiti: make([]byte, fieldparams.RootLength),
|
||||
Eth1Data: ð.Eth1Data{
|
||||
DepositRoot: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
},
|
||||
SyncAggregate: ð.SyncAggregate{
|
||||
SyncCommitteeBits: make([]byte, fieldparams.SyncAggregateSyncCommitteeBytesLength),
|
||||
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
|
||||
},
|
||||
ExecutionPayload: &pb.ExecutionPayloadDeneb{
|
||||
ParentHash: make([]byte, fieldparams.RootLength),
|
||||
FeeRecipient: make([]byte, 20),
|
||||
StateRoot: make([]byte, fieldparams.RootLength),
|
||||
ReceiptsRoot: make([]byte, fieldparams.RootLength),
|
||||
LogsBloom: make([]byte, 256),
|
||||
PrevRandao: make([]byte, fieldparams.RootLength),
|
||||
ExtraData: make([]byte, 0),
|
||||
BaseFeePerGas: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
Transactions: make([][]byte, 0),
|
||||
Withdrawals: make([]*pb.Withdrawal, 0),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func hydrateBeaconBlockBodyElectra() *eth.BeaconBlockBodyElectra {
|
||||
return ð.BeaconBlockBodyElectra{
|
||||
RandaoReveal: make([]byte, fieldparams.BLSSignatureLength),
|
||||
Graffiti: make([]byte, fieldparams.RootLength),
|
||||
Eth1Data: ð.Eth1Data{
|
||||
DepositRoot: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
},
|
||||
SyncAggregate: ð.SyncAggregate{
|
||||
SyncCommitteeBits: make([]byte, fieldparams.SyncAggregateSyncCommitteeBytesLength),
|
||||
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
|
||||
},
|
||||
ExecutionPayload: &pb.ExecutionPayloadElectra{
|
||||
ParentHash: make([]byte, fieldparams.RootLength),
|
||||
FeeRecipient: make([]byte, 20),
|
||||
StateRoot: make([]byte, fieldparams.RootLength),
|
||||
ReceiptsRoot: make([]byte, fieldparams.RootLength),
|
||||
LogsBloom: make([]byte, 256),
|
||||
PrevRandao: make([]byte, fieldparams.RootLength),
|
||||
ExtraData: make([]byte, 0),
|
||||
BaseFeePerGas: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
Transactions: make([][]byte, 0),
|
||||
Withdrawals: make([]*pb.Withdrawal, 0),
|
||||
DepositRequests: make([]*pb.DepositRequest, 0),
|
||||
WithdrawalRequests: make([]*pb.WithdrawalRequest, 0),
|
||||
ConsolidationRequests: make([]*pb.ConsolidationRequest, 0),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestPreElectraFailsInterfaceAssertion(t *testing.T) {
|
||||
var epd interfaces.ExecutionData = &executionPayloadDeneb{}
|
||||
_, ok := epd.(interfaces.ExecutionDataElectra)
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
package blocks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/hash/htr"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/ssz"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
func ComputeBlockBodyFieldRoots(ctx context.Context, blockBody *BeaconBlockBody) ([][]byte, error) {
|
||||
_, span := trace.StartSpan(ctx, "blocks.ComputeBlockBodyFieldRoots")
|
||||
defer span.End()
|
||||
|
||||
if blockBody == nil {
|
||||
return nil, errNilBlockBody
|
||||
}
|
||||
|
||||
var fieldRoots [][]byte
|
||||
switch blockBody.version {
|
||||
case version.Phase0:
|
||||
fieldRoots = make([][]byte, 8)
|
||||
case version.Altair:
|
||||
fieldRoots = make([][]byte, 9)
|
||||
case version.Bellatrix:
|
||||
fieldRoots = make([][]byte, 10)
|
||||
case version.Capella:
|
||||
fieldRoots = make([][]byte, 11)
|
||||
case version.Deneb:
|
||||
fieldRoots = make([][]byte, 12)
|
||||
case version.Electra:
|
||||
fieldRoots = make([][]byte, 12)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown block body version %s", version.String(blockBody.version))
|
||||
}
|
||||
|
||||
for i := range fieldRoots {
|
||||
fieldRoots[i] = make([]byte, 32)
|
||||
}
|
||||
|
||||
// Randao Reveal
|
||||
randao := blockBody.RandaoReveal()
|
||||
root, err := ssz.MerkleizeByteSliceSSZ(randao[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
copy(fieldRoots[0], root[:])
|
||||
|
||||
// eth1_data
|
||||
eth1 := blockBody.Eth1Data()
|
||||
root, err = eth1.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
copy(fieldRoots[1], root[:])
|
||||
|
||||
// graffiti
|
||||
root = blockBody.Graffiti()
|
||||
copy(fieldRoots[2], root[:])
|
||||
|
||||
// Proposer slashings
|
||||
ps := blockBody.ProposerSlashings()
|
||||
root, err = ssz.MerkleizeListSSZ(ps, params.BeaconConfig().MaxProposerSlashings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
copy(fieldRoots[3], root[:])
|
||||
|
||||
// Attester slashings
|
||||
as := blockBody.AttesterSlashings()
|
||||
bodyVersion := blockBody.Version()
|
||||
if bodyVersion < version.Electra {
|
||||
root, err = ssz.MerkleizeListSSZ(as, params.BeaconConfig().MaxAttesterSlashings)
|
||||
} else {
|
||||
root, err = ssz.MerkleizeListSSZ(as, params.BeaconConfig().MaxAttesterSlashingsElectra)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
copy(fieldRoots[4], root[:])
|
||||
|
||||
// Attestations
|
||||
att := blockBody.Attestations()
|
||||
if bodyVersion < version.Electra {
|
||||
root, err = ssz.MerkleizeListSSZ(att, params.BeaconConfig().MaxAttestations)
|
||||
} else {
|
||||
root, err = ssz.MerkleizeListSSZ(att, params.BeaconConfig().MaxAttestationsElectra)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
copy(fieldRoots[5], root[:])
|
||||
|
||||
// Deposits
|
||||
dep := blockBody.Deposits()
|
||||
root, err = ssz.MerkleizeListSSZ(dep, params.BeaconConfig().MaxDeposits)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
copy(fieldRoots[6], root[:])
|
||||
|
||||
// Voluntary Exits
|
||||
ve := blockBody.VoluntaryExits()
|
||||
root, err = ssz.MerkleizeListSSZ(ve, params.BeaconConfig().MaxVoluntaryExits)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
copy(fieldRoots[7], root[:])
|
||||
|
||||
if blockBody.version >= version.Altair {
|
||||
// Sync Aggregate
|
||||
sa, err := blockBody.SyncAggregate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
root, err = sa.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
copy(fieldRoots[8], root[:])
|
||||
}
|
||||
|
||||
if blockBody.version >= version.Bellatrix {
|
||||
// Execution Payload
|
||||
ep, err := blockBody.Execution()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
root, err = ep.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
copy(fieldRoots[9], root[:])
|
||||
}
|
||||
|
||||
if blockBody.version >= version.Capella {
|
||||
// BLS Changes
|
||||
bls, err := blockBody.BLSToExecutionChanges()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
root, err = ssz.MerkleizeListSSZ(bls, params.BeaconConfig().MaxBlsToExecutionChanges)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
copy(fieldRoots[10], root[:])
|
||||
}
|
||||
|
||||
if blockBody.version >= version.Deneb {
|
||||
// KZG commitments
|
||||
roots := make([][32]byte, len(blockBody.blobKzgCommitments))
|
||||
for i, commitment := range blockBody.blobKzgCommitments {
|
||||
chunks, err := ssz.PackByChunk([][]byte{commitment})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
roots[i] = htr.VectorizedSha256(chunks)[0]
|
||||
}
|
||||
commitmentsRoot, err := ssz.BitwiseMerkleize(roots, uint64(len(roots)), 4096)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
length := make([]byte, 32)
|
||||
binary.LittleEndian.PutUint64(length[:8], uint64(len(roots)))
|
||||
root = ssz.MixInLength(commitmentsRoot, length)
|
||||
copy(fieldRoots[11], root[:])
|
||||
}
|
||||
|
||||
return fieldRoots, nil
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
package blocks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/container/trie"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
)
|
||||
|
||||
func TestComputeBlockBodyFieldRoots_Phase0(t *testing.T) {
|
||||
blockBodyPhase0 := hydrateBeaconBlockBody()
|
||||
i, err := NewBeaconBlockBody(blockBodyPhase0)
|
||||
require.NoError(t, err)
|
||||
|
||||
b, ok := i.(*BeaconBlockBody)
|
||||
require.Equal(t, true, ok)
|
||||
|
||||
fieldRoots, err := ComputeBlockBodyFieldRoots(context.Background(), b)
|
||||
require.NoError(t, err)
|
||||
trie, err := trie.GenerateTrieFromItems(fieldRoots, 3)
|
||||
require.NoError(t, err)
|
||||
layers := trie.ToProto().GetLayers()
|
||||
|
||||
hash := layers[len(layers)-1].Layer[0]
|
||||
require.NoError(t, err)
|
||||
|
||||
correctHash, err := b.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.DeepEqual(t, correctHash[:], hash)
|
||||
}
|
||||
|
||||
func TestComputeBlockBodyFieldRoots_Altair(t *testing.T) {
|
||||
blockBodyAltair := hydrateBeaconBlockBodyAltair()
|
||||
i, err := NewBeaconBlockBody(blockBodyAltair)
|
||||
require.NoError(t, err)
|
||||
|
||||
b, ok := i.(*BeaconBlockBody)
|
||||
require.Equal(t, true, ok)
|
||||
|
||||
fieldRoots, err := ComputeBlockBodyFieldRoots(context.Background(), b)
|
||||
require.NoError(t, err)
|
||||
trie, err := trie.GenerateTrieFromItems(fieldRoots, 4)
|
||||
require.NoError(t, err)
|
||||
layers := trie.ToProto().GetLayers()
|
||||
|
||||
hash := layers[len(layers)-1].Layer[0]
|
||||
require.NoError(t, err)
|
||||
|
||||
correctHash, err := b.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.DeepEqual(t, correctHash[:], hash)
|
||||
}
|
||||
|
||||
func TestComputeBlockBodyFieldRoots_Bellatrix(t *testing.T) {
|
||||
blockBodyBellatrix := hydrateBeaconBlockBodyBellatrix()
|
||||
i, err := NewBeaconBlockBody(blockBodyBellatrix)
|
||||
require.NoError(t, err)
|
||||
|
||||
b, ok := i.(*BeaconBlockBody)
|
||||
require.Equal(t, true, ok)
|
||||
|
||||
fieldRoots, err := ComputeBlockBodyFieldRoots(context.Background(), b)
|
||||
require.NoError(t, err)
|
||||
trie, err := trie.GenerateTrieFromItems(fieldRoots, 4)
|
||||
require.NoError(t, err)
|
||||
layers := trie.ToProto().GetLayers()
|
||||
|
||||
hash := layers[len(layers)-1].Layer[0]
|
||||
require.NoError(t, err)
|
||||
|
||||
correctHash, err := b.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.DeepEqual(t, correctHash[:], hash)
|
||||
}
|
||||
|
||||
func TestComputeBlockBodyFieldRoots_Capella(t *testing.T) {
|
||||
blockBodyCapella := hydrateBeaconBlockBodyCapella()
|
||||
i, err := NewBeaconBlockBody(blockBodyCapella)
|
||||
require.NoError(t, err)
|
||||
|
||||
b, ok := i.(*BeaconBlockBody)
|
||||
require.Equal(t, true, ok)
|
||||
|
||||
fieldRoots, err := ComputeBlockBodyFieldRoots(context.Background(), b)
|
||||
require.NoError(t, err)
|
||||
trie, err := trie.GenerateTrieFromItems(fieldRoots, 4)
|
||||
require.NoError(t, err)
|
||||
layers := trie.ToProto().GetLayers()
|
||||
|
||||
hash := layers[len(layers)-1].Layer[0]
|
||||
require.NoError(t, err)
|
||||
|
||||
correctHash, err := b.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.DeepEqual(t, correctHash[:], hash)
|
||||
}
|
||||
|
||||
func TestComputeBlockBodyFieldRoots_Deneb(t *testing.T) {
|
||||
blockBodyDeneb := hydrateBeaconBlockBodyDeneb()
|
||||
i, err := NewBeaconBlockBody(blockBodyDeneb)
|
||||
require.NoError(t, err)
|
||||
|
||||
b, ok := i.(*BeaconBlockBody)
|
||||
require.Equal(t, true, ok)
|
||||
|
||||
fieldRoots, err := ComputeBlockBodyFieldRoots(context.Background(), b)
|
||||
require.NoError(t, err)
|
||||
trie, err := trie.GenerateTrieFromItems(fieldRoots, 4)
|
||||
require.NoError(t, err)
|
||||
layers := trie.ToProto().GetLayers()
|
||||
|
||||
hash := layers[len(layers)-1].Layer[0]
|
||||
require.NoError(t, err)
|
||||
|
||||
correctHash, err := b.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.DeepEqual(t, correctHash[:], hash)
|
||||
}
|
||||
|
||||
func TestComputeBlockBodyFieldRoots_Electra(t *testing.T) {
|
||||
blockBodyElectra := hydrateBeaconBlockBodyElectra()
|
||||
i, err := NewBeaconBlockBody(blockBodyElectra)
|
||||
require.NoError(t, err)
|
||||
|
||||
b, ok := i.(*BeaconBlockBody)
|
||||
require.Equal(t, true, ok)
|
||||
|
||||
fieldRoots, err := ComputeBlockBodyFieldRoots(context.Background(), b)
|
||||
require.NoError(t, err)
|
||||
trie, err := trie.GenerateTrieFromItems(fieldRoots, 4)
|
||||
require.NoError(t, err)
|
||||
layers := trie.ToProto().GetLayers()
|
||||
|
||||
hash := layers[len(layers)-1].Layer[0]
|
||||
require.NoError(t, err)
|
||||
|
||||
correctHash, err := b.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.DeepEqual(t, correctHash[:], hash)
|
||||
}
|
||||
@@ -332,7 +332,6 @@ go_library(
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/eth/ext:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_golang_protobuf//proto:go_default_library",
|
||||
"@com_github_grpc_ecosystem_grpc_gateway_v2//protoc-gen-openapiv2/options:options_go_proto",
|
||||
"@com_github_grpc_ecosystem_grpc_gateway_v2//runtime:go_default_library",
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package eth
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
ssz "github.com/prysmaticlabs/fastssz"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
@@ -24,7 +21,6 @@ type Att interface {
|
||||
GetData() *AttestationData
|
||||
CommitteeBitsVal() bitfield.Bitfield
|
||||
GetSignature() []byte
|
||||
GetCommitteeIndex() (primitives.CommitteeIndex, error)
|
||||
}
|
||||
|
||||
// IndexedAtt defines common functionality for all indexed attestation types.
|
||||
@@ -127,14 +123,6 @@ func (a *Attestation) CommitteeBitsVal() bitfield.Bitfield {
|
||||
return cb
|
||||
}
|
||||
|
||||
// GetCommitteeIndex --
|
||||
func (a *Attestation) GetCommitteeIndex() (primitives.CommitteeIndex, error) {
|
||||
if a == nil || a.Data == nil {
|
||||
return 0, errors.New("nil attestation data")
|
||||
}
|
||||
return a.Data.CommitteeIndex, nil
|
||||
}
|
||||
|
||||
// Version --
|
||||
func (a *PendingAttestation) Version() int {
|
||||
return version.Phase0
|
||||
@@ -168,14 +156,6 @@ func (a *PendingAttestation) GetSignature() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetCommitteeIndex --
|
||||
func (a *PendingAttestation) GetCommitteeIndex() (primitives.CommitteeIndex, error) {
|
||||
if a == nil || a.Data == nil {
|
||||
return 0, errors.New("nil attestation data")
|
||||
}
|
||||
return a.Data.CommitteeIndex, nil
|
||||
}
|
||||
|
||||
// Version --
|
||||
func (a *AttestationElectra) Version() int {
|
||||
return version.Electra
|
||||
@@ -204,24 +184,6 @@ func (a *AttestationElectra) CommitteeBitsVal() bitfield.Bitfield {
|
||||
return a.CommitteeBits
|
||||
}
|
||||
|
||||
// GetCommitteeIndex --
|
||||
func (a *AttestationElectra) GetCommitteeIndex() (primitives.CommitteeIndex, error) {
|
||||
if a == nil || a.Data == nil {
|
||||
return 0, errors.New("nil attestation data")
|
||||
}
|
||||
if len(a.CommitteeBits) == 0 {
|
||||
return 0, errors.New("no committee bits found in attestation")
|
||||
}
|
||||
if a.Data.CommitteeIndex != 0 {
|
||||
return 0, fmt.Errorf("attestation data's committee index must be 0 but was %d", a.Data.CommitteeIndex)
|
||||
}
|
||||
indices := a.CommitteeBits.BitIndices()
|
||||
if len(indices) != 1 {
|
||||
return 0, fmt.Errorf("exactly 1 committee index must be set but %d were set", len(indices))
|
||||
}
|
||||
return primitives.CommitteeIndex(uint64(indices[0])), nil
|
||||
}
|
||||
|
||||
// Version --
|
||||
func (a *IndexedAttestation) Version() int {
|
||||
return version.Phase0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by fastssz. DO NOT EDIT.
|
||||
// Hash: ecf364fe5acf3bed144e2e2d74edecf4b9bb2a8433927332e95d28a80b5f733a
|
||||
// Hash: 84572d8fa233c45a41477bced891ee355cc1745ae0fad290f110b7f6b5ed12e1
|
||||
package eth
|
||||
|
||||
import (
|
||||
@@ -30,20 +30,20 @@ func (a *AttestationElectra) MarshalSSZTo(buf []byte) (dst []byte, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Field (2) 'Signature'
|
||||
if size := len(a.Signature); size != 96 {
|
||||
err = ssz.ErrBytesLengthFn("--.Signature", size, 96)
|
||||
return
|
||||
}
|
||||
dst = append(dst, a.Signature...)
|
||||
|
||||
// Field (3) 'CommitteeBits'
|
||||
// Field (2) 'CommitteeBits'
|
||||
if size := len(a.CommitteeBits); size != 8 {
|
||||
err = ssz.ErrBytesLengthFn("--.CommitteeBits", size, 8)
|
||||
return
|
||||
}
|
||||
dst = append(dst, a.CommitteeBits...)
|
||||
|
||||
// Field (3) 'Signature'
|
||||
if size := len(a.Signature); size != 96 {
|
||||
err = ssz.ErrBytesLengthFn("--.Signature", size, 96)
|
||||
return
|
||||
}
|
||||
dst = append(dst, a.Signature...)
|
||||
|
||||
// Field (0) 'AggregationBits'
|
||||
if size := len(a.AggregationBits); size > 131072 {
|
||||
err = ssz.ErrBytesLengthFn("--.AggregationBits", size, 131072)
|
||||
@@ -82,17 +82,17 @@ func (a *AttestationElectra) UnmarshalSSZ(buf []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Field (2) 'Signature'
|
||||
if cap(a.Signature) == 0 {
|
||||
a.Signature = make([]byte, 0, len(buf[132:228]))
|
||||
}
|
||||
a.Signature = append(a.Signature, buf[132:228]...)
|
||||
|
||||
// Field (3) 'CommitteeBits'
|
||||
// Field (2) 'CommitteeBits'
|
||||
if cap(a.CommitteeBits) == 0 {
|
||||
a.CommitteeBits = make([]byte, 0, len(buf[228:236]))
|
||||
a.CommitteeBits = make([]byte, 0, len(buf[132:140]))
|
||||
}
|
||||
a.CommitteeBits = append(a.CommitteeBits, buf[228:236]...)
|
||||
a.CommitteeBits = append(a.CommitteeBits, buf[132:140]...)
|
||||
|
||||
// Field (3) 'Signature'
|
||||
if cap(a.Signature) == 0 {
|
||||
a.Signature = make([]byte, 0, len(buf[140:236]))
|
||||
}
|
||||
a.Signature = append(a.Signature, buf[140:236]...)
|
||||
|
||||
// Field (0) 'AggregationBits'
|
||||
{
|
||||
@@ -139,20 +139,20 @@ func (a *AttestationElectra) HashTreeRootWith(hh *ssz.Hasher) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Field (2) 'Signature'
|
||||
if size := len(a.Signature); size != 96 {
|
||||
err = ssz.ErrBytesLengthFn("--.Signature", size, 96)
|
||||
return
|
||||
}
|
||||
hh.PutBytes(a.Signature)
|
||||
|
||||
// Field (3) 'CommitteeBits'
|
||||
// Field (2) 'CommitteeBits'
|
||||
if size := len(a.CommitteeBits); size != 8 {
|
||||
err = ssz.ErrBytesLengthFn("--.CommitteeBits", size, 8)
|
||||
return
|
||||
}
|
||||
hh.PutBytes(a.CommitteeBits)
|
||||
|
||||
// Field (3) 'Signature'
|
||||
if size := len(a.Signature); size != 96 {
|
||||
err = ssz.ErrBytesLengthFn("--.Signature", size, 96)
|
||||
return
|
||||
}
|
||||
hh.PutBytes(a.Signature)
|
||||
|
||||
hh.Merkleize(indx)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ func GethTestnetGenesis(genesisTime uint64, cfg *clparams.BeaconChainConfig) *co
|
||||
Nonce: 0, // overridden for authorized signer votes in clique, so we should leave it empty?
|
||||
Timestamp: genesisTime,
|
||||
ExtraData: extra,
|
||||
GasLimit: cfg.DefaultBuilderGasLimit,
|
||||
GasLimit: math.MaxUint64 >> 1, // shift 1 back from the max, just in case
|
||||
Difficulty: common.HexToHash(defaultDifficulty).Big(),
|
||||
Mixhash: common.HexToHash(defaultMixhash),
|
||||
Coinbase: common.HexToAddress(defaultCoinbase),
|
||||
|
||||
@@ -8,5 +8,6 @@ import (
|
||||
)
|
||||
|
||||
func RunExecutionPayloadTest(t *testing.T, config string) {
|
||||
t.Skip("TODO: Electra uses a different execution payload")
|
||||
common.RunExecutionPayloadTest(t, config, version.String(version.Electra), sszToBlockBody, sszToState)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,8 @@ package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
rd "crypto/rand"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/signing"
|
||||
@@ -33,35 +30,27 @@ import (
|
||||
// BlockGenConfig is used to define the requested conditions
|
||||
// for block generation.
|
||||
type BlockGenConfig struct {
|
||||
NumProposerSlashings uint64
|
||||
NumAttesterSlashings uint64
|
||||
NumAttestations uint64
|
||||
NumDeposits uint64
|
||||
NumVoluntaryExits uint64
|
||||
NumTransactions uint64 // Only for post Bellatrix blocks
|
||||
FullSyncAggregate bool
|
||||
NumBLSChanges uint64 // Only for post Capella blocks
|
||||
NumWithdrawals uint64
|
||||
NumDepositRequests uint64 // Only for post Electra blocks
|
||||
NumWithdrawalRequests uint64 // Only for post Electra blocks
|
||||
NumConsolidationRequests uint64 // Only for post Electra blocks
|
||||
NumProposerSlashings uint64
|
||||
NumAttesterSlashings uint64
|
||||
NumAttestations uint64
|
||||
NumDeposits uint64
|
||||
NumVoluntaryExits uint64
|
||||
NumTransactions uint64 // Only for post Bellatrix blocks
|
||||
FullSyncAggregate bool
|
||||
NumBLSChanges uint64 // Only for post Capella blocks
|
||||
}
|
||||
|
||||
// DefaultBlockGenConfig returns the block config that utilizes the
|
||||
// current params in the beacon config.
|
||||
func DefaultBlockGenConfig() *BlockGenConfig {
|
||||
return &BlockGenConfig{
|
||||
NumProposerSlashings: 0,
|
||||
NumAttesterSlashings: 0,
|
||||
NumAttestations: 1,
|
||||
NumDeposits: 0,
|
||||
NumVoluntaryExits: 0,
|
||||
NumTransactions: 0,
|
||||
NumBLSChanges: 0,
|
||||
NumWithdrawals: 0,
|
||||
NumConsolidationRequests: 0,
|
||||
NumWithdrawalRequests: 0,
|
||||
NumDepositRequests: 0,
|
||||
NumProposerSlashings: 0,
|
||||
NumAttesterSlashings: 0,
|
||||
NumAttestations: 1,
|
||||
NumDeposits: 0,
|
||||
NumVoluntaryExits: 0,
|
||||
NumTransactions: 0,
|
||||
NumBLSChanges: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,41 +487,6 @@ func randValIndex(bState state.BeaconState) (primitives.ValidatorIndex, error) {
|
||||
return primitives.ValidatorIndex(rand.NewGenerator().Uint64() % activeCount), nil
|
||||
}
|
||||
|
||||
func generateWithdrawals(
|
||||
bState state.BeaconState,
|
||||
privs []bls.SecretKey,
|
||||
numWithdrawals uint64,
|
||||
) ([]*enginev1.Withdrawal, error) {
|
||||
withdrawalRequests := make([]*enginev1.Withdrawal, numWithdrawals)
|
||||
for i := uint64(0); i < numWithdrawals; i++ {
|
||||
valIndex, err := randValIndex(bState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
amount := uint64(10000)
|
||||
bal, err := bState.BalanceAtIndex(valIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
amounts := []uint64{
|
||||
amount, // some smaller amount
|
||||
bal, // the entire balance
|
||||
}
|
||||
// Get a random index
|
||||
nBig, err := rd.Int(rd.Reader, big.NewInt(int64(len(amounts))))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
randomIndex := nBig.Uint64()
|
||||
withdrawalRequests[i] = &enginev1.Withdrawal{
|
||||
ValidatorIndex: valIndex,
|
||||
Address: make([]byte, common.AddressLength),
|
||||
Amount: amounts[randomIndex],
|
||||
}
|
||||
}
|
||||
return withdrawalRequests, nil
|
||||
}
|
||||
|
||||
// HydrateSignedBeaconHeader hydrates a signed beacon block header with correct field length sizes
|
||||
// to comply with fssz marshalling and unmarshalling rules.
|
||||
func HydrateSignedBeaconHeader(h *ethpb.SignedBeaconBlockHeader) *ethpb.SignedBeaconBlockHeader {
|
||||
|
||||
@@ -2,15 +2,11 @@ package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/signing"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/transition"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
@@ -112,6 +108,7 @@ func GenerateFullBlockElectra(
|
||||
for i := uint64(0); i < numToGen; i++ {
|
||||
newTransactions[i] = bytesutil.Uint64ToBytesLittleEndian(i)
|
||||
}
|
||||
newWithdrawals := make([]*v1.Withdrawal, 0)
|
||||
|
||||
random, err := helpers.RandaoMix(bState, time.CurrentEpoch(bState))
|
||||
if err != nil {
|
||||
@@ -129,59 +126,25 @@ func GenerateFullBlockElectra(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newWithdrawals := make([]*v1.Withdrawal, 0)
|
||||
if conf.NumWithdrawals > 0 {
|
||||
newWithdrawals, err = generateWithdrawals(bState, privs, numToGen)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed generating %d withdrawals:", numToGen)
|
||||
}
|
||||
}
|
||||
|
||||
depositRequests := make([]*v1.DepositRequest, 0)
|
||||
if conf.NumDepositRequests > 0 {
|
||||
depositRequests, err = generateDepositRequests(bState, privs, conf.NumDepositRequests)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed generating %d deposit requests:", conf.NumDepositRequests)
|
||||
}
|
||||
}
|
||||
|
||||
withdrawalRequests := make([]*v1.WithdrawalRequest, 0)
|
||||
if conf.NumWithdrawalRequests > 0 {
|
||||
withdrawalRequests, err = generateWithdrawalRequests(bState, privs, conf.NumWithdrawalRequests)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed generating %d withdrawal requests:", conf.NumWithdrawalRequests)
|
||||
}
|
||||
}
|
||||
|
||||
consolidationRequests := make([]*v1.ConsolidationRequest, 0)
|
||||
if conf.NumConsolidationRequests > 0 {
|
||||
consolidationRequests, err = generateConsolidationRequests(bState, privs, conf.NumConsolidationRequests)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed generating %d consolidation requests:", conf.NumConsolidationRequests)
|
||||
}
|
||||
}
|
||||
parentExecution, err := stCopy.LatestExecutionPayloadHeader()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockHash := indexToHash(uint64(slot))
|
||||
newExecutionPayloadElectra := &v1.ExecutionPayloadElectra{
|
||||
ParentHash: parentExecution.BlockHash(),
|
||||
FeeRecipient: make([]byte, 20),
|
||||
StateRoot: params.BeaconConfig().ZeroHash[:],
|
||||
ReceiptsRoot: params.BeaconConfig().ZeroHash[:],
|
||||
LogsBloom: make([]byte, 256),
|
||||
PrevRandao: random,
|
||||
BlockNumber: uint64(slot),
|
||||
ExtraData: params.BeaconConfig().ZeroHash[:],
|
||||
BaseFeePerGas: params.BeaconConfig().ZeroHash[:],
|
||||
BlockHash: blockHash[:],
|
||||
Timestamp: uint64(timestamp.Unix()),
|
||||
Transactions: newTransactions,
|
||||
Withdrawals: newWithdrawals,
|
||||
DepositRequests: depositRequests,
|
||||
WithdrawalRequests: withdrawalRequests,
|
||||
ConsolidationRequests: consolidationRequests,
|
||||
newExecutionPayloadCapella := &v1.ExecutionPayloadElectra{
|
||||
ParentHash: parentExecution.BlockHash(),
|
||||
FeeRecipient: make([]byte, 20),
|
||||
StateRoot: params.BeaconConfig().ZeroHash[:],
|
||||
ReceiptsRoot: params.BeaconConfig().ZeroHash[:],
|
||||
LogsBloom: make([]byte, 256),
|
||||
PrevRandao: random,
|
||||
BlockNumber: uint64(slot),
|
||||
ExtraData: params.BeaconConfig().ZeroHash[:],
|
||||
BaseFeePerGas: params.BeaconConfig().ZeroHash[:],
|
||||
BlockHash: blockHash[:],
|
||||
Timestamp: uint64(timestamp.Unix()),
|
||||
Transactions: newTransactions,
|
||||
Withdrawals: newWithdrawals,
|
||||
}
|
||||
var syncCommitteeBits []byte
|
||||
currSize := new(ethpb.SyncAggregate).SyncCommitteeBits.Len()
|
||||
@@ -245,7 +208,7 @@ func GenerateFullBlockElectra(
|
||||
Deposits: newDeposits,
|
||||
Graffiti: make([]byte, fieldparams.RootLength),
|
||||
SyncAggregate: newSyncAggregate,
|
||||
ExecutionPayload: newExecutionPayloadElectra,
|
||||
ExecutionPayload: newExecutionPayloadCapella,
|
||||
BlsToExecutionChanges: changes,
|
||||
},
|
||||
}
|
||||
@@ -258,132 +221,3 @@ func GenerateFullBlockElectra(
|
||||
|
||||
return ðpb.SignedBeaconBlockElectra{Block: block, Signature: signature.Marshal()}, nil
|
||||
}
|
||||
|
||||
func generateWithdrawalRequests(
|
||||
bState state.BeaconState,
|
||||
privs []bls.SecretKey,
|
||||
numRequests uint64,
|
||||
) ([]*v1.WithdrawalRequest, error) {
|
||||
withdrawalRequests := make([]*v1.WithdrawalRequest, numRequests)
|
||||
for i := uint64(0); i < numRequests; i++ {
|
||||
valIndex, err := randValIndex(bState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Get a random index
|
||||
nBig, err := rand.Int(rand.Reader, big.NewInt(60000))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
amount := nBig.Uint64() // random amount created
|
||||
bal, err := bState.BalanceAtIndex(valIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
amounts := []uint64{
|
||||
amount, // some smaller amount
|
||||
bal, // the entire balance
|
||||
}
|
||||
// Get a random index
|
||||
nBig, err = rand.Int(rand.Reader, big.NewInt(int64(len(amounts))))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
randomIndex := nBig.Uint64()
|
||||
withdrawalRequests[i] = &v1.WithdrawalRequest{
|
||||
ValidatorPubkey: privs[valIndex].PublicKey().Marshal(),
|
||||
SourceAddress: make([]byte, common.AddressLength),
|
||||
Amount: amounts[randomIndex],
|
||||
}
|
||||
}
|
||||
return withdrawalRequests, nil
|
||||
}
|
||||
|
||||
func generateDepositRequests(
|
||||
bState state.BeaconState,
|
||||
privs []bls.SecretKey,
|
||||
numRequests uint64,
|
||||
) ([]*v1.DepositRequest, error) {
|
||||
depositRequests := make([]*v1.DepositRequest, numRequests)
|
||||
for i := uint64(0); i < numRequests; i++ {
|
||||
valIndex, err := randValIndex(bState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Get a random index
|
||||
nBig, err := rand.Int(rand.Reader, big.NewInt(60000))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
amount := nBig.Uint64() // random amount created
|
||||
prefixes := []byte{params.BeaconConfig().CompoundingWithdrawalPrefixByte, 0, params.BeaconConfig().BLSWithdrawalPrefixByte}
|
||||
withdrawalCred := make([]byte, 32)
|
||||
// Get a random index
|
||||
nBig, err = rand.Int(rand.Reader, big.NewInt(int64(len(prefixes))))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
randPrefixIndex := nBig.Uint64()
|
||||
withdrawalCred[0] = prefixes[randPrefixIndex]
|
||||
|
||||
depositMessage := ðpb.DepositMessage{
|
||||
PublicKey: privs[valIndex].PublicKey().Marshal(),
|
||||
Amount: amount,
|
||||
WithdrawalCredentials: withdrawalCred,
|
||||
}
|
||||
domain, err := signing.ComputeDomain(params.BeaconConfig().DomainDeposit, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sr, err := signing.ComputeSigningRoot(depositMessage, domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sig := privs[i].Sign(sr[:])
|
||||
depositRequests[i] = &v1.DepositRequest{
|
||||
Pubkey: depositMessage.PublicKey,
|
||||
Index: uint64(valIndex),
|
||||
WithdrawalCredentials: depositMessage.WithdrawalCredentials,
|
||||
Amount: depositMessage.Amount,
|
||||
Signature: sig.Marshal(),
|
||||
}
|
||||
}
|
||||
return depositRequests, nil
|
||||
}
|
||||
|
||||
func generateConsolidationRequests(
|
||||
bState state.BeaconState,
|
||||
privs []bls.SecretKey,
|
||||
numRequests uint64,
|
||||
) ([]*v1.ConsolidationRequest, error) {
|
||||
consolidationRequests := make([]*v1.ConsolidationRequest, numRequests)
|
||||
for i := uint64(0); i < numRequests; i++ {
|
||||
valIndex, err := randValIndex(bState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
valIndex2, err := randValIndex(bState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
source, err := randomAddress()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
consolidationRequests[i] = &v1.ConsolidationRequest{
|
||||
TargetPubkey: privs[valIndex2].PublicKey().Marshal(),
|
||||
SourceAddress: source.Bytes(),
|
||||
SourcePubkey: privs[valIndex].PublicKey().Marshal(),
|
||||
}
|
||||
}
|
||||
return consolidationRequests, nil
|
||||
}
|
||||
|
||||
func randomAddress() (common.Address, error) {
|
||||
b := make([]byte, 20)
|
||||
_, err := rand.Read(b)
|
||||
if err != nil {
|
||||
return common.Address{}, err
|
||||
}
|
||||
return common.BytesToAddress(b), nil
|
||||
}
|
||||
|
||||
@@ -119,7 +119,9 @@ func IsValid(walletDir string) (bool, error) {
|
||||
}
|
||||
f, err := os.Open(expanded) // #nosec G304
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
if strings.Contains(err.Error(), "no such file") ||
|
||||
strings.Contains(err.Error(), "cannot find the file") ||
|
||||
strings.Contains(err.Error(), "cannot find the path") {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
|
||||
Reference in New Issue
Block a user