mirror of
https://github.com/wealdtech/ethdo.git
synced 2026-01-08 21:48:05 -05:00
Refactor based on review
This commit is contained in:
@@ -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),
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user