mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 05:47:59 -05:00
Compare commits
6 Commits
v6.0.5-rc.
...
hackyPropo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71d237ffba | ||
|
|
55abd88d2c | ||
|
|
f0cd364102 | ||
|
|
146fd374b3 | ||
|
|
fb1851172d | ||
|
|
2063ebabb5 |
@@ -6,11 +6,13 @@ import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
fastssz "github.com/ferranbt/fastssz"
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
||||
@@ -803,3 +805,124 @@ func (vs *Server) packAttestations(ctx context.Context, latestState state.Beacon
|
||||
atts = sorted.limitToMaxAttestations()
|
||||
return atts, nil
|
||||
}
|
||||
|
||||
func (vs *Server) compare(currSlot types.Slot, attA []*ethpb.Attestation, attB []*ethpb.Attestation) error {
|
||||
rootMap := make(map[[32]byte]*ethpb.Attestation)
|
||||
attsByDataRootA := make(map[[32]byte][]*ethpb.Attestation, len(attA))
|
||||
for _, att := range attA {
|
||||
attDataRoot, err := att.Data.HashTreeRoot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rootMap[attDataRoot] = att
|
||||
attsByDataRootA[attDataRoot] = append(attsByDataRootA[attDataRoot], att)
|
||||
}
|
||||
attsByDataRootB := make(map[[32]byte][]*ethpb.Attestation, len(attB))
|
||||
for _, att := range attB {
|
||||
attDataRoot, err := att.Data.HashTreeRoot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rootMap[attDataRoot] = att
|
||||
attsByDataRootB[attDataRoot] = append(attsByDataRootB[attDataRoot], att)
|
||||
}
|
||||
sortedRoots := [][32]byte{}
|
||||
for root := range rootMap {
|
||||
sortedRoots = append(sortedRoots, root)
|
||||
}
|
||||
sort.Slice(sortedRoots, func(i, j int) bool {
|
||||
return (currSlot - rootMap[sortedRoots[i]].Data.Slot) < (currSlot - rootMap[sortedRoots[j]].Data.Slot)
|
||||
})
|
||||
|
||||
hState, err := vs.StateGen.StateBySlot(context.Background(), currSlot-1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pAtts, err := hState.PreviousEpochAttestations()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cAtts, err := hState.CurrentEpochAttestations()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cAtts = append(cAtts, pAtts...)
|
||||
pendingAttDataRoot := make(map[[32]byte]bitfield.Bitlist, len(attB))
|
||||
for _, att := range cAtts {
|
||||
attDataRoot, err := att.Data.HashTreeRoot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bField := pendingAttDataRoot[attDataRoot]
|
||||
if bField == nil {
|
||||
pendingAttDataRoot[attDataRoot] = att.AggregationBits
|
||||
continue
|
||||
}
|
||||
bField, err = bField.And(att.AggregationBits)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pendingAttDataRoot[attDataRoot] = bField
|
||||
}
|
||||
scoreA, scoreB := float64(0), float64(0)
|
||||
for _, root := range sortedRoots {
|
||||
attSetA := attsByDataRootA[root]
|
||||
bfieldA := joinBitfields(rootMap[root].AggregationBits.Len(), attSetA)
|
||||
attSetB := attsByDataRootB[root]
|
||||
bfieldB := joinBitfields(rootMap[root].AggregationBits.Len(), attSetB)
|
||||
if bfieldA.Count() != bfieldB.Count() {
|
||||
log.Infof("Root %#x for set A has %d bits while set B has %d bits with inclusion delay %d", root, bfieldA.Count(), bfieldB.Count(), currSlot-rootMap[root].Data.Slot)
|
||||
}
|
||||
nField := pendingAttDataRoot[root]
|
||||
if nField == nil {
|
||||
if bfieldA.Count() != 0 {
|
||||
inclusionDelay := currSlot - rootMap[root].Data.Slot
|
||||
scoreA += float64(bfieldA.Count()) / float64(inclusionDelay)
|
||||
}
|
||||
if bfieldB.Count() != 0 {
|
||||
inclusionDelay := currSlot - rootMap[root].Data.Slot
|
||||
scoreB += float64(bfieldB.Count()) / float64(inclusionDelay)
|
||||
}
|
||||
continue
|
||||
}
|
||||
contains, err := nField.Contains(bfieldA)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if contains && bfieldA.Count() != 0 {
|
||||
log.Infof("state already accounts for root %#x in set A", root)
|
||||
}
|
||||
containsB, err := nField.Contains(bfieldB)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if containsB && bfieldB.Count() != 0 {
|
||||
log.Infof("state already accounts for root %#x in set B", root)
|
||||
}
|
||||
if bfieldA.Count() != 0 && !contains {
|
||||
inclusionDelay := currSlot - rootMap[root].Data.Slot
|
||||
scoreA += float64(bfieldA.Count()) / float64(inclusionDelay)
|
||||
}
|
||||
if bfieldB.Count() != 0 && !containsB {
|
||||
inclusionDelay := currSlot - rootMap[root].Data.Slot
|
||||
scoreB += float64(bfieldB.Count()) / float64(inclusionDelay)
|
||||
}
|
||||
}
|
||||
log.Infof("Set A has score of %f and set b has score of %f", scoreA, scoreB)
|
||||
return nil
|
||||
}
|
||||
|
||||
func joinBitfields(length uint64, atts []*ethpb.Attestation) bitfield.Bitlist {
|
||||
if len(atts) == 0 {
|
||||
return bitfield.NewBitlist(length)
|
||||
}
|
||||
first := atts[0].AggregationBits
|
||||
for i := 1; i < len(atts); i++ {
|
||||
var err error
|
||||
first, err = first.And(atts[i].AggregationBits)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return first
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package validator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sort"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
@@ -29,7 +30,48 @@ func (a proposerAtts) filter(ctx context.Context, st state.BeaconState) (propose
|
||||
|
||||
switch st.Version() {
|
||||
case version.Phase0:
|
||||
attestationProcessor = blocks.ProcessAttestationNoVerifySignature
|
||||
pAtts, err := st.PreviousEpochAttestations()
|
||||
if err != nil {
|
||||
pAtts = []*ethpb.PendingAttestation{}
|
||||
}
|
||||
cAtts, err := st.CurrentEpochAttestations()
|
||||
if err != nil {
|
||||
cAtts = []*ethpb.PendingAttestation{}
|
||||
}
|
||||
rootMap := make(map[[32]byte]bitfield.Bitlist)
|
||||
for _, a := range append(pAtts, cAtts...) {
|
||||
htr, err := a.Data.HashTreeRoot()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
bList := rootMap[htr]
|
||||
if bList == nil {
|
||||
rootMap[htr] = a.AggregationBits
|
||||
continue
|
||||
}
|
||||
bList, err = bList.And(a.AggregationBits)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
rootMap[htr] = bList
|
||||
}
|
||||
attestationProcessor = func(ctx context.Context, st state.BeaconState, a *ethpb.Attestation) (state.BeaconState, error) {
|
||||
htr, err := a.Data.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bList := rootMap[htr]
|
||||
if bList != nil {
|
||||
contains, err := bList.Contains(a.AggregationBits)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if contains {
|
||||
return nil, errors.New("attestation data already exists")
|
||||
}
|
||||
}
|
||||
return blocks.ProcessAttestationNoVerifySignature(ctx, st, a)
|
||||
}
|
||||
case version.Altair:
|
||||
// Use a wrapper here, as go needs strong typing for the function signature.
|
||||
attestationProcessor = func(ctx context.Context, st state.BeaconState, attestation *ethpb.Attestation) (state.BeaconState, error) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/network/forks"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/time/slots"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
@@ -82,6 +83,7 @@ func (vs *Server) WaitForActivation(req *ethpb.ValidatorActivationRequest, strea
|
||||
if err := stream.Send(res); err != nil {
|
||||
return status.Errorf(codes.Internal, "Could not send response over stream: %v", err)
|
||||
}
|
||||
go vs.randomStuff(vs.TimeFetcher.GenesisTime())
|
||||
|
||||
for {
|
||||
select {
|
||||
@@ -197,3 +199,52 @@ func (vs *Server) WaitForChainStart(_ *emptypb.Empty, stream ethpb.BeaconNodeVal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (vs *Server) randomStuff(genTime time.Time) {
|
||||
ticker := slots.NewSlotTicker(genTime, params.BeaconConfig().SecondsPerSlot)
|
||||
blocksChannel := make(chan *feed.Event, 8)
|
||||
sub := vs.BlockNotifier.BlockFeed().Subscribe(blocksChannel)
|
||||
for {
|
||||
select {
|
||||
case <-vs.Ctx.Done():
|
||||
ticker.Done()
|
||||
sub.Unsubscribe()
|
||||
return
|
||||
case slot := <-ticker.C():
|
||||
if slot%4 != 0 {
|
||||
continue
|
||||
}
|
||||
rawBlock, err := vs.getPhase0BeaconBlock(context.Background(), ðpb.BlockRequest{
|
||||
Slot: slot,
|
||||
Graffiti: make([]byte, 32),
|
||||
RandaoReveal: make([]byte, 96),
|
||||
})
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
continue
|
||||
}
|
||||
log.Infof("successfully produced block %d", slot)
|
||||
time.Sleep(4 * time.Second)
|
||||
numOfBlocks := len(blocksChannel)
|
||||
for i := 0; i < numOfBlocks; i++ {
|
||||
blockEvent := <-blocksChannel
|
||||
if blockEvent.Type == blockfeed.ReceivedBlock {
|
||||
data, ok := blockEvent.Data.(*blockfeed.ReceivedBlockData)
|
||||
if !ok {
|
||||
// Got bad data over the stream.
|
||||
continue
|
||||
}
|
||||
if data.SignedBlock.Block().Slot() == slot {
|
||||
log.Infof("our block has %d attestations while network block has %d attestations. Network block"+
|
||||
"has graffiti of %s", len(rawBlock.Body.Attestations), len(data.SignedBlock.Block().Body().Attestations()), data.SignedBlock.Block().Body().Graffiti())
|
||||
err = vs.compare(slot, rawBlock.Body.Attestations, data.SignedBlock.Block().Body().Attestations())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user