github.com/prysmaticlabs/prysm@v1.4.4/validator/db/kv/deprecated_attester_protection.go (about) 1 package kv 2 3 import ( 4 "context" 5 "fmt" 6 7 types "github.com/prysmaticlabs/eth2-types" 8 "github.com/prysmaticlabs/prysm/shared/bytesutil" 9 "github.com/prysmaticlabs/prysm/shared/params" 10 ) 11 12 const ( 13 // The size of each data entry in bytes for the source epoch (8 bytes) and signing root (32 bytes). 14 uint64Size = 8 15 latestEpochWrittenSize = uint64Size 16 targetSize = uint64Size 17 sourceSize = uint64Size 18 signingRootSize = 32 19 historySize = targetSize + sourceSize + signingRootSize 20 minimalSize = latestEpochWrittenSize 21 ) 22 23 // deprecatedHistoryData stores the needed data to confirm if an attestation is slashable 24 // or repeated. 25 type deprecatedHistoryData struct { 26 Source types.Epoch 27 SigningRoot []byte 28 } 29 30 // deprecatedEncodedAttestingHistory encapsulated history data. 31 type deprecatedEncodedAttestingHistory []byte 32 33 func (dh deprecatedEncodedAttestingHistory) assertSize() error { 34 if dh == nil || len(dh) < minimalSize { 35 return fmt.Errorf("encapsulated data size: %d is smaller then minimal size: %d", len(dh), minimalSize) 36 } 37 if (len(dh)-minimalSize)%historySize != 0 { 38 return fmt.Errorf("encapsulated data size: %d is not a multiple of entry size: %d", len(dh), historySize) 39 } 40 return nil 41 } 42 43 func (dhd *deprecatedHistoryData) isEmpty() bool { 44 if dhd == (*deprecatedHistoryData)(nil) { 45 return true 46 } 47 if dhd.Source == params.BeaconConfig().FarFutureEpoch { 48 return true 49 } 50 return false 51 } 52 53 func emptyHistoryData() *deprecatedHistoryData { 54 h := &deprecatedHistoryData{Source: params.BeaconConfig().FarFutureEpoch, SigningRoot: bytesutil.PadTo([]byte{}, 32)} 55 return h 56 } 57 58 // newDeprecatedAttestingHistory creates a new encapsulated attestation history byte array 59 // sized by the latest epoch written. 60 func newDeprecatedAttestingHistory(target types.Epoch) deprecatedEncodedAttestingHistory { 61 relativeTarget := target % params.BeaconConfig().WeakSubjectivityPeriod 62 historyDataSize := (relativeTarget + 1) * historySize 63 arraySize := latestEpochWrittenSize + historyDataSize 64 en := make(deprecatedEncodedAttestingHistory, arraySize) 65 enc := en 66 ctx := context.Background() 67 var err error 68 for i := types.Epoch(0); i <= target%params.BeaconConfig().WeakSubjectivityPeriod; i++ { 69 enc, err = enc.setTargetData(ctx, i, emptyHistoryData()) 70 if err != nil { 71 log.WithError(err).Error("Failed to set empty target data") 72 } 73 } 74 return enc 75 } 76 77 func (dh deprecatedEncodedAttestingHistory) getLatestEpochWritten(ctx context.Context) (types.Epoch, error) { 78 if err := dh.assertSize(); err != nil { 79 return 0, err 80 } 81 return types.Epoch(bytesutil.FromBytes8(dh[:latestEpochWrittenSize])), nil 82 } 83 84 func (dh deprecatedEncodedAttestingHistory) setLatestEpochWritten( 85 ctx context.Context, 86 latestEpochWritten types.Epoch, 87 ) (deprecatedEncodedAttestingHistory, error) { 88 if err := dh.assertSize(); err != nil { 89 return nil, err 90 } 91 copy(dh[:latestEpochWrittenSize], bytesutil.EpochToBytesLittleEndian(latestEpochWritten)) 92 return dh, nil 93 } 94 95 func (dh deprecatedEncodedAttestingHistory) getTargetData(ctx context.Context, target types.Epoch) (*deprecatedHistoryData, error) { 96 if err := dh.assertSize(); err != nil { 97 return nil, err 98 } 99 // Cursor for the location to read target epoch from. 100 // Modulus of target epoch X weak subjectivity period in order to have maximum size to the encapsulated data array. 101 cursor := (target%params.BeaconConfig().WeakSubjectivityPeriod)*historySize + latestEpochWrittenSize 102 if uint64(len(dh)) < uint64(cursor+historySize) { 103 return nil, nil 104 } 105 history := &deprecatedHistoryData{} 106 history.Source = types.Epoch(bytesutil.FromBytes8(dh[cursor : cursor+sourceSize])) 107 sr := make([]byte, 32) 108 copy(sr, dh[cursor+sourceSize:cursor+historySize]) 109 history.SigningRoot = sr 110 return history, nil 111 } 112 113 func (dh deprecatedEncodedAttestingHistory) setTargetData( 114 ctx context.Context, 115 target types.Epoch, 116 historyData *deprecatedHistoryData, 117 ) (deprecatedEncodedAttestingHistory, error) { 118 if err := dh.assertSize(); err != nil { 119 return nil, err 120 } 121 // Cursor for the location to write target epoch to. 122 // Modulus of target epoch X weak subjectivity period in order to have maximum size to the encapsulated data array. 123 cursor := latestEpochWrittenSize + (target%params.BeaconConfig().WeakSubjectivityPeriod)*historySize 124 125 if uint64(len(dh)) < uint64(cursor+historySize) { 126 ext := make([]byte, uint64(cursor+historySize)-uint64(len(dh))) 127 dh = append(dh, ext...) 128 } 129 copy(dh[cursor:cursor+sourceSize], bytesutil.EpochToBytesLittleEndian(historyData.Source)) 130 copy(dh[cursor+sourceSize:cursor+sourceSize+signingRootSize], historyData.SigningRoot) 131 132 return dh, nil 133 }