Skip to content

Commit

Permalink
Align aggregator action with v0.11 (#5146)
Browse files Browse the repository at this point in the history
  • Loading branch information
terencechain authored Mar 21, 2020
1 parent aff5587 commit 4f83b45
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 106 deletions.
2 changes: 1 addition & 1 deletion WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -1304,7 +1304,7 @@ go_repository(

go_repository(
name = "com_github_prysmaticlabs_ethereumapis",
commit = "c0970cf6aa0c0826b73047770e81617bd24a9ffe",
commit = "aae6bf3b3452f7aa4e8f5a88a3ba31c67c0fc7e4",
importpath = "github.com/prysmaticlabs/ethereumapis",
patch_args = ["-p1"],
patches = [
Expand Down
6 changes: 3 additions & 3 deletions beacon-chain/rpc/aggregator/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ func (as *Server) SubmitAggregateAndProof(ctx context.Context, req *pb.Aggregati
defer span.End()
span.AddAttributes(trace.Int64Attribute("slot", int64(req.Slot)))

request := &ethpb.AggregationRequest{
request := &ethpb.AggregateSelectionRequest{
Slot: req.Slot,
CommitteeIndex: req.CommitteeIndex,
PublicKey: req.PublicKey,
SlotSignature: req.SlotSignature,
}

// Passthrough request to non-deprecated method.
res, err := as.ValidatorServer.SubmitAggregateAndProof(ctx, request)
_, err := as.ValidatorServer.SubmitAggregateSelectionProof(ctx, request)
if err != nil {
return nil, err
}
return &pb.AggregationResponse{Root: res.AttestationDataRoot}, nil
return &pb.AggregationResponse{}, nil
}
62 changes: 39 additions & 23 deletions beacon-chain/rpc/validator/aggregator.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import (
"google.golang.org/grpc/status"
)

// SubmitAggregateAndProof is called by a validator when its assigned to be an aggregator.
// The beacon node will broadcast aggregated attestation and proof on the aggregator's behavior.
func (as *Server) SubmitAggregateAndProof(ctx context.Context, req *ethpb.AggregationRequest) (*ethpb.AggregationResponse, error) {
ctx, span := trace.StartSpan(ctx, "AggregatorServer.SubmitAggregation")
// SubmitAggregateSelectionProof is called by a validator when its assigned to be an aggregator.
// The aggregator submits the selection proof to obtain the aggregated attestation
// object to sign over.
func (as *Server) SubmitAggregateSelectionProof(ctx context.Context, req *ethpb.AggregateSelectionRequest) (*ethpb.AggregateSelectionResponse, error) {
ctx, span := trace.StartSpan(ctx, "AggregatorServer.SubmitAggregateSelectionProof")
defer span.End()
span.AddAttributes(trace.Int64Attribute("slot", int64(req.Slot)))

Expand Down Expand Up @@ -56,27 +57,42 @@ func (as *Server) SubmitAggregateAndProof(ctx context.Context, req *ethpb.Aggreg
// Retrieve the unaggregated attestation from pool.
aggregatedAtts := as.AttPool.AggregatedAttestationsBySlotIndex(req.Slot, req.CommitteeIndex)

for _, aggregatedAtt := range aggregatedAtts {
if ctx.Err() != nil {
return nil, ctx.Err()
// Filter out the best aggregated attestation (ie. the one with the most aggregated bits).
if len(aggregatedAtts) == 0 {
return nil, status.Error(codes.Internal, "No aggregated attestation in beacon node")
}
best := aggregatedAtts[0]
for _, aggregatedAtt := range aggregatedAtts[1:] {
if aggregatedAtt.AggregationBits.Count() > best.AggregationBits.Count() {
best = aggregatedAtt
}
if helpers.IsAggregated(aggregatedAtt) {
if err := as.P2P.Broadcast(ctx, &ethpb.AggregateAttestationAndProof{
AggregatorIndex: validatorIndex,
SelectionProof: req.SlotSignature,
Aggregate: aggregatedAtt,
}); err != nil {
return nil, status.Errorf(codes.Internal, "Could not broadcast aggregated attestation: %v", err)
}
}

log.WithFields(logrus.Fields{
"slot": req.Slot,
"committeeIndex": req.CommitteeIndex,
"validatorIndex": validatorIndex,
"aggregatedCount": aggregatedAtt.AggregationBits.Count(),
}).Debug("Broadcasting aggregated attestation and proof")
}
a := &ethpb.AggregateAttestationAndProof{
Aggregate: best,
SelectionProof: req.SlotSignature,
AggregatorIndex: validatorIndex,
}
return &ethpb.AggregateSelectionResponse{AggregateAndProof: a}, nil
}

// SubmitSignedAggregateSelectionProof is called by a validator to broadcast a signed
// aggregated and proof object.
func (as *Server) SubmitSignedAggregateSelectionProof(ctx context.Context, req *ethpb.SignedAggregateSubmitRequest) (*ethpb.SignedAggregateSubmitResponse, error) {
if req.SignedAggregateAndProof == nil {
return nil, status.Error(codes.InvalidArgument, "Signed aggregate request can't be nil")
}

if err := as.P2P.Broadcast(ctx, req.SignedAggregateAndProof); err != nil {
return nil, status.Errorf(codes.Internal, "Could not broadcast signed aggregated attestation: %v", err)
}

log.WithFields(logrus.Fields{
"slot": req.SignedAggregateAndProof.Message.Aggregate.Data.Slot,
"committeeIndex": req.SignedAggregateAndProof.Message.Aggregate.Data.CommitteeIndex,
"validatorIndex": req.SignedAggregateAndProof.Message.AggregatorIndex,
"aggregatedCount": req.SignedAggregateAndProof.Message.Aggregate.AggregationBits.Count(),
}).Debug("Broadcasting aggregated attestation and proof")

return &ethpb.AggregationResponse{}, nil
return &ethpb.SignedAggregateSubmitResponse{}, nil
}
43 changes: 17 additions & 26 deletions beacon-chain/rpc/validator/aggregator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ func TestSubmitAggregateAndProof_Syncing(t *testing.T) {
BeaconDB: db,
}

req := &ethpb.AggregationRequest{CommitteeIndex: 1}
req := &ethpb.AggregateSelectionRequest{CommitteeIndex: 1}
wanted := "Syncing to latest head, not ready to respond"
if _, err := aggregatorServer.SubmitAggregateAndProof(ctx, req); !strings.Contains(err.Error(), wanted) {
if _, err := aggregatorServer.SubmitAggregateSelectionProof(ctx, req); !strings.Contains(err.Error(), wanted) {
t.Error("Did not receive wanted error")
}
}
Expand All @@ -64,14 +64,14 @@ func TestSubmitAggregateAndProof_CantFindValidatorIndex(t *testing.T) {

priv := bls.RandKey()
sig := priv.Sign([]byte{'A'})
req := &ethpb.AggregationRequest{CommitteeIndex: 1, SlotSignature: sig.Marshal(), PublicKey: pubKey(3)}
req := &ethpb.AggregateSelectionRequest{CommitteeIndex: 1, SlotSignature: sig.Marshal(), PublicKey: pubKey(3)}
wanted := "Could not locate validator index in DB"
if _, err := server.SubmitAggregateAndProof(ctx, req); !strings.Contains(err.Error(), wanted) {
if _, err := server.SubmitAggregateSelectionProof(ctx, req); !strings.Contains(err.Error(), wanted) {
t.Errorf("Did not receive wanted error: expected %v, received %v", wanted, err.Error())
}
}

func TestSubmitAggregateAndProof_IsAggregator(t *testing.T) {
func TestSubmitAggregateAndProof_IsAggregatorAndNoAtts(t *testing.T) {
db := dbutil.SetupDB(t)
defer dbutil.TeardownDB(t, db)
ctx := context.Background()
Expand All @@ -90,13 +90,13 @@ func TestSubmitAggregateAndProof_IsAggregator(t *testing.T) {
priv := bls.RandKey()
sig := priv.Sign([]byte{'A'})
pubKey := pubKey(1)
req := &ethpb.AggregationRequest{CommitteeIndex: 1, SlotSignature: sig.Marshal(), PublicKey: pubKey}
req := &ethpb.AggregateSelectionRequest{CommitteeIndex: 1, SlotSignature: sig.Marshal(), PublicKey: pubKey}
if err := db.SaveValidatorIndex(ctx, pubKey, 100); err != nil {
t.Fatal(err)
}

if _, err := server.SubmitAggregateAndProof(ctx, req); err != nil {
t.Fatal(err)
if _, err := server.SubmitAggregateSelectionProof(ctx, req); !strings.Contains(err.Error(), "No aggregated attestation in beacon node") {
t.Error("Did not get wanted error")
}
}

Expand All @@ -116,7 +116,7 @@ func TestSubmitAggregateAndProof_AggregateOk(t *testing.T) {
if err != nil {
t.Fatal(err)
}
att1, err := generateAtt(beaconState, 1, privKeys)
att1, err := generateAtt(beaconState, 2, privKeys)
if err != nil {
t.Fatal(err)
}
Expand All @@ -134,19 +134,19 @@ func TestSubmitAggregateAndProof_AggregateOk(t *testing.T) {
priv := bls.RandKey()
sig := priv.Sign([]byte{'B'})
pubKey := pubKey(2)
req := &ethpb.AggregationRequest{CommitteeIndex: 1, SlotSignature: sig.Marshal(), PublicKey: pubKey}
req := &ethpb.AggregateSelectionRequest{CommitteeIndex: 1, SlotSignature: sig.Marshal(), PublicKey: pubKey}
if err := db.SaveValidatorIndex(ctx, pubKey, 100); err != nil {
t.Fatal(err)
}

if err := aggregatorServer.AttPool.SaveUnaggregatedAttestation(att0); err != nil {
if err := aggregatorServer.AttPool.SaveAggregatedAttestation(att0); err != nil {
t.Fatal(err)
}
if err := aggregatorServer.AttPool.SaveUnaggregatedAttestation(att1); err != nil {
if err := aggregatorServer.AttPool.SaveAggregatedAttestation(att1); err != nil {
t.Fatal(err)
}

if _, err := aggregatorServer.SubmitAggregateAndProof(ctx, req); err != nil {
if _, err := aggregatorServer.SubmitAggregateSelectionProof(ctx, req); err != nil {
t.Fatal(err)
}

Expand All @@ -171,11 +171,7 @@ func TestSubmitAggregateAndProof_AggregateNotOk(t *testing.T) {
defer dbutil.TeardownDB(t, db)
ctx := context.Background()

beaconState, privKeys := testutil.DeterministicGenesisState(t, 32)
att0, err := generateAtt(beaconState, 0, privKeys)
if err != nil {
t.Fatal(err)
}
beaconState, _ := testutil.DeterministicGenesisState(t, 32)
beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)

aggregatorServer := &Server{
Expand All @@ -189,18 +185,12 @@ func TestSubmitAggregateAndProof_AggregateNotOk(t *testing.T) {
priv := bls.RandKey()
sig := priv.Sign([]byte{'B'})
pubKey := pubKey(2)
req := &ethpb.AggregationRequest{CommitteeIndex: 1, SlotSignature: sig.Marshal(), PublicKey: pubKey}
req := &ethpb.AggregateSelectionRequest{CommitteeIndex: 1, SlotSignature: sig.Marshal(), PublicKey: pubKey}
if err := db.SaveValidatorIndex(ctx, pubKey, 100); err != nil {
t.Fatal(err)
}

if err := aggregatorServer.AttPool.SaveUnaggregatedAttestation(att0); err != nil {
t.Fatal(err)
}

if _, err := aggregatorServer.SubmitAggregateAndProof(ctx, req); err != nil {
t.Fatal(err)
}
aggregatorServer.SubmitAggregateSelectionProof(ctx, req)

aggregatedAtts := aggregatorServer.AttPool.AggregatedAttestations()
if len(aggregatedAtts) != 0 {
Expand All @@ -211,6 +201,7 @@ func TestSubmitAggregateAndProof_AggregateNotOk(t *testing.T) {
func generateAtt(state *beaconstate.BeaconState, index uint64, privKeys []*bls.SecretKey) (*ethpb.Attestation, error) {
aggBits := bitfield.NewBitlist(4)
aggBits.SetBitAt(index, true)
aggBits.SetBitAt(index+1, true)
att := &ethpb.Attestation{
Data: &ethpb.AttestationData{
CommitteeIndex: 1,
Expand Down
24 changes: 14 additions & 10 deletions shared/params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,13 @@ type BeaconChainConfig struct {
MaxVoluntaryExits uint64 `yaml:"MAX_VOLUNTARY_EXITS"` // MaxVoluntaryExits defines the maximum number of validator exits in a block.

// BLS domain values.
DomainBeaconProposer [4]byte `yaml:"DOMAIN_BEACON_PROPOSER"` // DomainBeaconProposer defines the BLS signature domain for beacon proposal verification.
DomainRandao [4]byte `yaml:"DOMAIN_RANDAO"` // DomainRandao defines the BLS signature domain for randao verification.
DomainBeaconAttester [4]byte `yaml:"DOMAIN_ATTESTATION"` // DomainBeaconAttester defines the BLS signature domain for attestation verification.
DomainDeposit [4]byte `yaml:"DOMAIN_DEPOSIT"` // DomainDeposit defines the BLS signature domain for deposit verification.
DomainVoluntaryExit [4]byte `yaml:"DOMAIN_VOLUNTARY_EXIT"` // DomainVoluntaryExit defines the BLS signature domain for exit verification.
DomainBeaconProposer [4]byte `yaml:"DOMAIN_BEACON_PROPOSER"` // DomainBeaconProposer defines the BLS signature domain for beacon proposal verification.
DomainRandao [4]byte `yaml:"DOMAIN_RANDAO"` // DomainRandao defines the BLS signature domain for randao verification.
DomainBeaconAttester [4]byte `yaml:"DOMAIN_ATTESTATION"` // DomainBeaconAttester defines the BLS signature domain for attestation verification.
DomainDeposit [4]byte `yaml:"DOMAIN_DEPOSIT"` // DomainDeposit defines the BLS signature domain for deposit verification.
DomainVoluntaryExit [4]byte `yaml:"DOMAIN_VOLUNTARY_EXIT"` // DomainVoluntaryExit defines the BLS signature domain for exit verification.
DomainSelectionProof [4]byte `yaml:"DOMAIN_SELECTION_PROOF"` // DomainVoluntaryExit defines the BLS signature domain for selection proof.
DomainAggregateAndProof [4]byte `yaml:"DOMAIN_AGGREGATE_AND_PROOF"` // DomainVoluntaryExit defines the BLS signature domain for aggregate and proof.

// Prysm constants.
GweiPerEth uint64 // GweiPerEth is the amount of gwei corresponding to 1 eth.
Expand Down Expand Up @@ -171,11 +173,13 @@ var defaultBeaconConfig = &BeaconChainConfig{
MaxVoluntaryExits: 16,

// BLS domain values.
DomainBeaconProposer: bytesutil.ToBytes4(bytesutil.Bytes4(0)),
DomainBeaconAttester: bytesutil.ToBytes4(bytesutil.Bytes4(1)),
DomainRandao: bytesutil.ToBytes4(bytesutil.Bytes4(2)),
DomainDeposit: bytesutil.ToBytes4(bytesutil.Bytes4(3)),
DomainVoluntaryExit: bytesutil.ToBytes4(bytesutil.Bytes4(4)),
DomainBeaconProposer: bytesutil.ToBytes4(bytesutil.Bytes4(0)),
DomainBeaconAttester: bytesutil.ToBytes4(bytesutil.Bytes4(1)),
DomainRandao: bytesutil.ToBytes4(bytesutil.Bytes4(2)),
DomainDeposit: bytesutil.ToBytes4(bytesutil.Bytes4(3)),
DomainVoluntaryExit: bytesutil.ToBytes4(bytesutil.Bytes4(4)),
DomainSelectionProof: bytesutil.ToBytes4(bytesutil.Bytes4(5)),
DomainAggregateAndProof: bytesutil.ToBytes4(bytesutil.Bytes4(6)),

// Prysm constants.
GweiPerEth: 1000000000,
Expand Down
Loading

0 comments on commit 4f83b45

Please sign in to comment.