github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/network/alsp/report.go (about) 1 package alsp 2 3 import ( 4 "fmt" 5 6 "github.com/onflow/flow-go/model/flow" 7 "github.com/onflow/flow-go/network" 8 "github.com/onflow/flow-go/network/alsp/model" 9 ) 10 11 // MisbehaviorReport is a report that is sent to the networking layer to penalize the misbehaving node. 12 // A MisbehaviorReport reports the misbehavior of a node on sending a message to the current node that appears valid 13 // based on the networking layer but is considered invalid by the current node based on the Flow protocol. 14 // 15 // A MisbehaviorReport consists of a reason and a penalty. The reason is a string that describes the misbehavior. 16 // The penalty is a value that is deducted from the overall score of the misbehaving node. The score is 17 // decayed at each decay interval. If the overall penalty of the misbehaving node drops below the disallow-listing 18 // threshold, the node is reported to be disallow-listed by the networking layer, i.e., existing connections to the 19 // node are closed and the node is no longer allowed to connect till its penalty is decayed back to zero. 20 type MisbehaviorReport struct { 21 id flow.Identifier // the ID of the misbehaving node 22 reason network.Misbehavior // the reason of the misbehavior 23 penalty float64 // the penalty value of the misbehavior 24 } 25 26 var _ network.MisbehaviorReport = (*MisbehaviorReport)(nil) 27 28 // MisbehaviorReportOpt is an option that can be used to configure a misbehavior report. 29 type MisbehaviorReportOpt func(r *MisbehaviorReport) error 30 31 // WithPenaltyAmplification returns an option that can be used to amplify the penalty value. 32 // The penalty value is multiplied by the given value. The value should be between 1-100. 33 // If the value is not in the range, an error is returned. 34 // The returned error by this option indicates that the option is not applied. In BFT setup, the returned error 35 // should be treated as a fatal error. 36 func WithPenaltyAmplification(v float64) MisbehaviorReportOpt { 37 return func(r *MisbehaviorReport) error { 38 if v <= 0 || v > 100 { 39 return fmt.Errorf("penalty value should be between 1-100: %v", v) 40 } 41 r.penalty *= v 42 return nil 43 } 44 } 45 46 // OriginId returns the ID of the misbehaving node. 47 func (r MisbehaviorReport) OriginId() flow.Identifier { 48 return r.id 49 } 50 51 // Reason returns the reason of the misbehavior. 52 func (r MisbehaviorReport) Reason() network.Misbehavior { 53 return r.reason 54 } 55 56 // Penalty returns the penalty value of the misbehavior. 57 func (r MisbehaviorReport) Penalty() float64 { 58 return r.penalty 59 } 60 61 // NewMisbehaviorReport creates a new misbehavior report with the given reason and options. 62 // If no options are provided, the default penalty value is used. 63 // The returned error by this function indicates that the report is not created. In BFT setup, the returned error 64 // should be treated as a fatal error. 65 // The default penalty value is 0.01 * misbehaviorDisallowListingThreshold = -86.4 66 func NewMisbehaviorReport(misbehavingId flow.Identifier, reason network.Misbehavior, opts ...MisbehaviorReportOpt) (*MisbehaviorReport, error) { 67 m := &MisbehaviorReport{ 68 id: misbehavingId, 69 reason: reason, 70 penalty: model.DefaultPenaltyValue, 71 } 72 73 for _, opt := range opts { 74 if err := opt(m); err != nil { 75 return nil, fmt.Errorf("failed to apply misbehavior report option: %w", err) 76 } 77 } 78 79 return m, nil 80 }