Refactor based on review

This commit is contained in:
Chris Berry
2025-01-27 10:23:30 +00:00
parent 8322353af5
commit f17fe2f5cb
3 changed files with 58 additions and 58 deletions

View File

@@ -55,7 +55,7 @@ type command struct {
weightDenominator uint64 weightDenominator uint64
// Processing. // Processing.
priorAttestations map[string]*attestationData priorAttestations map[string]*attestationDataInfo
// Head roots provides the root of the head slot at given slots. // Head roots provides the root of the head slot at given slots.
headRoots map[phase0.Slot]phase0.Root headRoots map[phase0.Slot]phase0.Root
// Target roots provides the root of the target epoch at given slots. // Target roots provides the root of the target epoch at given slots.
@@ -77,20 +77,20 @@ type blockAnalysis struct {
} }
type attestationAnalysis struct { type attestationAnalysis struct {
Head phase0.Root `json:"head"` Head phase0.Root `json:"head"`
Target phase0.Root `json:"target"` Target phase0.Root `json:"target"`
Distance int `json:"distance"` Distance int `json:"distance"`
Duplicate *attestationData `json:"duplicate,omitempty"` Duplicate *attestationDataInfo `json:"duplicate,omitempty"`
NewVotes int `json:"new_votes"` NewVotes int `json:"new_votes"`
Votes int `json:"votes"` Votes int `json:"votes"`
PossibleVotes int `json:"possible_votes"` PossibleVotes int `json:"possible_votes"`
HeadCorrect bool `json:"head_correct"` HeadCorrect bool `json:"head_correct"`
HeadTimely bool `json:"head_timely"` HeadTimely bool `json:"head_timely"`
SourceTimely bool `json:"source_timely"` SourceTimely bool `json:"source_timely"`
TargetCorrect bool `json:"target_correct"` TargetCorrect bool `json:"target_correct"`
TargetTimely bool `json:"target_timely"` TargetTimely bool `json:"target_timely"`
Score float64 `json:"score"` Score float64 `json:"score"`
Value float64 `json:"value"` Value float64 `json:"value"`
} }
type syncCommitteeAnalysis struct { type syncCommitteeAnalysis struct {
@@ -100,7 +100,7 @@ type syncCommitteeAnalysis struct {
Value float64 `json:"value"` Value float64 `json:"value"`
} }
type attestationData struct { type attestationDataInfo struct {
Block phase0.Slot `json:"block"` Block phase0.Slot `json:"block"`
Index int `json:"index"` Index int `json:"index"`
} }
@@ -110,7 +110,7 @@ func newCommand(_ context.Context) (*command, error) {
quiet: viper.GetBool("quiet"), quiet: viper.GetBool("quiet"),
verbose: viper.GetBool("verbose"), verbose: viper.GetBool("verbose"),
debug: viper.GetBool("debug"), debug: viper.GetBool("debug"),
priorAttestations: make(map[string]*attestationData), priorAttestations: make(map[string]*attestationDataInfo),
headRoots: make(map[phase0.Slot]phase0.Root), headRoots: make(map[phase0.Slot]phase0.Root),
targetRoots: make(map[phase0.Slot]phase0.Root), targetRoots: make(map[phase0.Slot]phase0.Root),
votes: make(map[phase0.Slot]map[phase0.CommitteeIndex]bitfield.Bitlist), votes: make(map[phase0.Slot]map[phase0.CommitteeIndex]bitfield.Bitlist),

View File

@@ -34,20 +34,20 @@ func (c *command) output(ctx context.Context) (string, error) {
} }
type attestationAnalysisJSON struct { type attestationAnalysisJSON struct {
Head string `json:"head"` Head string `json:"head"`
Target string `json:"target"` Target string `json:"target"`
Distance int `json:"distance"` Distance int `json:"distance"`
Duplicate *attestationData `json:"duplicate,omitempty"` Duplicate *attestationDataInfo `json:"duplicate,omitempty"`
NewVotes int `json:"new_votes"` NewVotes int `json:"new_votes"`
Votes int `json:"votes"` Votes int `json:"votes"`
PossibleVotes int `json:"possible_votes"` PossibleVotes int `json:"possible_votes"`
HeadCorrect bool `json:"head_correct"` HeadCorrect bool `json:"head_correct"`
HeadTimely bool `json:"head_timely"` HeadTimely bool `json:"head_timely"`
SourceTimely bool `json:"source_timely"` SourceTimely bool `json:"source_timely"`
TargetCorrect bool `json:"target_correct"` TargetCorrect bool `json:"target_correct"`
TargetTimely bool `json:"target_timely"` TargetTimely bool `json:"target_timely"`
Score float64 `json:"score"` Score float64 `json:"score"`
Value float64 `json:"value"` Value float64 `json:"value"`
} }
func (a *attestationAnalysis) MarshalJSON() ([]byte, error) { func (a *attestationAnalysis) MarshalJSON() ([]byte, error) {

View File

@@ -63,12 +63,12 @@ func (c *command) process(ctx context.Context) error {
// Calculate how many parents we need to fetch. // Calculate how many parents we need to fetch.
minSlot := slot minSlot := slot
for _, attestation := range attestations { for _, attestation := range attestations {
attestData, err := attestation.Data() attestationData, err := attestation.Data()
if err != nil { if err != nil {
return errors.Wrap(err, "failed to obtain attestation data") return errors.Wrap(err, "failed to obtain attestation data")
} }
if attestData.Slot < minSlot { if attestationData.Slot < minSlot {
minSlot = attestData.Slot minSlot = attestationData.Slot
} }
} }
if c.debug { if c.debug {
@@ -107,14 +107,14 @@ func (c *command) analyzeAttestations(ctx context.Context, block *spec.Versioned
if c.debug { if c.debug {
fmt.Printf("Processing attestation %d\n", i) fmt.Printf("Processing attestation %d\n", i)
} }
attestData, err := attestation.Data() attestationData, err := attestation.Data()
if err != nil { if err != nil {
return errors.Wrap(err, "failed to obtain attestation data") return errors.Wrap(err, "failed to obtain attestation data")
} }
analysis := &attestationAnalysis{ analysis := &attestationAnalysis{
Head: attestData.BeaconBlockRoot, Head: attestationData.BeaconBlockRoot,
Target: attestData.Target.Root, Target: attestationData.Target.Root,
Distance: int(slot - attestData.Slot), Distance: int(slot - attestationData.Slot),
} }
root, err := attestation.HashTreeRoot() root, err := attestation.HashTreeRoot()
@@ -128,13 +128,13 @@ func (c *command) analyzeAttestations(ctx context.Context, block *spec.Versioned
if err != nil { if err != nil {
return err return err
} }
_, exists := blockVotes[attestData.Slot] _, exists := blockVotes[attestationData.Slot]
if !exists { if !exists {
blockVotes[attestData.Slot] = make(map[phase0.CommitteeIndex]bitfield.Bitlist) blockVotes[attestationData.Slot] = make(map[phase0.CommitteeIndex]bitfield.Bitlist)
} }
_, exists = blockVotes[attestData.Slot][attestData.Index] _, exists = blockVotes[attestationData.Slot][attestationData.Index]
if !exists { if !exists {
blockVotes[attestData.Slot][attestData.Index] = bitfield.NewBitlist(aggregationBits.Len()) blockVotes[attestationData.Slot][attestationData.Index] = bitfield.NewBitlist(aggregationBits.Len())
} }
// Count new votes. // Count new votes.
@@ -142,16 +142,16 @@ func (c *command) analyzeAttestations(ctx context.Context, block *spec.Versioned
for j := range aggregationBits.Len() { for j := range aggregationBits.Len() {
if aggregationBits.BitAt(j) { if aggregationBits.BitAt(j) {
analysis.Votes++ analysis.Votes++
if blockVotes[attestData.Slot][attestData.Index].BitAt(j) { if blockVotes[attestationData.Slot][attestationData.Index].BitAt(j) {
// Already attested to in this block; skip. // Already attested to in this block; skip.
continue continue
} }
if c.votes[attestData.Slot][attestData.Index].BitAt(j) { if c.votes[attestationData.Slot][attestationData.Index].BitAt(j) {
// Already attested to in a previous block; skip. // Already attested to in a previous block; skip.
continue continue
} }
analysis.NewVotes++ analysis.NewVotes++
blockVotes[attestData.Slot][attestData.Index].SetBitAt(j, true) blockVotes[attestationData.Slot][attestationData.Index].SetBitAt(j, true)
} }
} }
// Calculate head correct. // Calculate head correct.
@@ -161,10 +161,10 @@ func (c *command) analyzeAttestations(ctx context.Context, block *spec.Versioned
} }
// Calculate head timely. // Calculate head timely.
analysis.HeadTimely = analysis.HeadCorrect && attestData.Slot == slot-1 analysis.HeadTimely = analysis.HeadCorrect && attestationData.Slot == slot-1
// Calculate source timely. // Calculate source timely.
analysis.SourceTimely = attestData.Slot >= slot-5 analysis.SourceTimely = attestationData.Slot >= slot-5
// Calculate target correct. // Calculate target correct.
analysis.TargetCorrect, err = c.calcTargetCorrect(ctx, attestation) analysis.TargetCorrect, err = c.calcTargetCorrect(ctx, attestation)
@@ -174,7 +174,7 @@ func (c *command) analyzeAttestations(ctx context.Context, block *spec.Versioned
// Calculate target timely. // Calculate target timely.
if block.Version < spec.DataVersionDeneb { if block.Version < spec.DataVersionDeneb {
analysis.TargetTimely = attestData.Slot >= slot-32 analysis.TargetTimely = attestationData.Slot >= slot-32
} else { } else {
analysis.TargetTimely = true analysis.TargetTimely = true
} }
@@ -265,7 +265,7 @@ func (c *command) processParentBlock(_ context.Context, block *spec.VersionedSig
if err != nil { if err != nil {
return err return err
} }
c.priorAttestations[fmt.Sprintf("%#x", root)] = &attestationData{ c.priorAttestations[fmt.Sprintf("%#x", root)] = &attestationDataInfo{
Block: slot, Block: slot,
Index: i, Index: i,
} }
@@ -403,11 +403,11 @@ func (c *command) setup(ctx context.Context) error {
} }
func (c *command) calcHeadCorrect(ctx context.Context, attestation *spec.VersionedAttestation) (bool, error) { func (c *command) calcHeadCorrect(ctx context.Context, attestation *spec.VersionedAttestation) (bool, error) {
attestData, err := attestation.Data() attestationData, err := attestation.Data()
if err != nil { if err != nil {
return false, errors.Wrap(err, "failed to obtain attestation data") return false, errors.Wrap(err, "failed to obtain attestation data")
} }
slot := attestData.Slot slot := attestationData.Slot
root, exists := c.headRoots[slot] root, exists := c.headRoots[slot]
if !exists { if !exists {
for { for {
@@ -434,24 +434,24 @@ func (c *command) calcHeadCorrect(ctx context.Context, attestation *spec.Version
slot-- slot--
continue continue
} }
c.headRoots[attestData.Slot] = response.Data.Root c.headRoots[attestationData.Slot] = response.Data.Root
root = response.Data.Root root = response.Data.Root
break break
} }
} }
return bytes.Equal(root[:], attestData.BeaconBlockRoot[:]), nil return bytes.Equal(root[:], attestationData.BeaconBlockRoot[:]), nil
} }
func (c *command) calcTargetCorrect(ctx context.Context, attestation *spec.VersionedAttestation) (bool, error) { func (c *command) calcTargetCorrect(ctx context.Context, attestation *spec.VersionedAttestation) (bool, error) {
attestData, err := attestation.Data() attestationData, err := attestation.Data()
if err != nil { if err != nil {
return false, errors.Wrap(err, "failed to obtain attestation data") return false, errors.Wrap(err, "failed to obtain attestation data")
} }
root, exists := c.targetRoots[attestData.Slot] root, exists := c.targetRoots[attestationData.Slot]
if !exists { if !exists {
// Start with first slot of the target epoch. // Start with first slot of the target epoch.
slot := c.chainTime.FirstSlotOfEpoch(attestData.Target.Epoch) slot := c.chainTime.FirstSlotOfEpoch(attestationData.Target.Epoch)
for { for {
response, err := c.blockHeadersProvider.BeaconBlockHeader(ctx, &api.BeaconBlockHeaderOpts{ response, err := c.blockHeadersProvider.BeaconBlockHeader(ctx, &api.BeaconBlockHeaderOpts{
Block: fmt.Sprintf("%d", slot), Block: fmt.Sprintf("%d", slot),
@@ -475,12 +475,12 @@ func (c *command) calcTargetCorrect(ctx context.Context, attestation *spec.Versi
slot-- slot--
continue continue
} }
c.targetRoots[attestData.Slot] = response.Data.Root c.targetRoots[attestationData.Slot] = response.Data.Root
root = response.Data.Root root = response.Data.Root
break break
} }
} }
return bytes.Equal(root[:], attestData.Target.Root[:]), nil return bytes.Equal(root[:], attestationData.Target.Root[:]), nil
} }
func (c *command) analyzeSyncCommittees(_ context.Context, block *spec.VersionedSignedBeaconBlock) error { func (c *command) analyzeSyncCommittees(_ context.Context, block *spec.VersionedSignedBeaconBlock) error {