mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-02-01 08:35:24 -05:00
Compare commits
6 Commits
e2e-debugg
...
hackyPropo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71d237ffba | ||
|
|
55abd88d2c | ||
|
|
f0cd364102 | ||
|
|
146fd374b3 | ||
|
|
fb1851172d | ||
|
|
2063ebabb5 |
@@ -6,11 +6,13 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
fastssz "github.com/ferranbt/fastssz"
|
fastssz "github.com/ferranbt/fastssz"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
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"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
|
"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()
|
atts = sorted.limitToMaxAttestations()
|
||||||
return atts, nil
|
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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
types "github.com/prysmaticlabs/eth2-types"
|
||||||
@@ -29,7 +30,48 @@ func (a proposerAtts) filter(ctx context.Context, st state.BeaconState) (propose
|
|||||||
|
|
||||||
switch st.Version() {
|
switch st.Version() {
|
||||||
case version.Phase0:
|
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:
|
case version.Altair:
|
||||||
// Use a wrapper here, as go needs strong typing for the function signature.
|
// 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) {
|
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/encoding/bytesutil"
|
||||||
"github.com/prysmaticlabs/prysm/network/forks"
|
"github.com/prysmaticlabs/prysm/network/forks"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/time/slots"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
"google.golang.org/protobuf/types/known/emptypb"
|
"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 {
|
if err := stream.Send(res); err != nil {
|
||||||
return status.Errorf(codes.Internal, "Could not send response over stream: %v", err)
|
return status.Errorf(codes.Internal, "Could not send response over stream: %v", err)
|
||||||
}
|
}
|
||||||
|
go vs.randomStuff(vs.TimeFetcher.GenesisTime())
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
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