func Proto
has a cyclomatic complexity of 24 with "high" risk 308}
309
310// Proto converts the beacon block body to a protobuf object.
311func (b *BeaconBlockBody) Proto() (proto.Message, error) { 312 if b == nil {
313 return nil, nil
314 }
func Proto
has a cyclomatic complexity of 30 with "very-high" risk 147}
148
149// Proto converts the beacon block to a protobuf object.
150func (b *BeaconBlock) Proto() (proto.Message, error) { 151 if b == nil {
152 return nil, nil
153 }
func Proto
has a cyclomatic complexity of 30 with "very-high" risk 13)
14
15// Proto converts the signed beacon block to a protobuf object.
16func (b *SignedBeaconBlock) Proto() (proto.Message, error) { 17 if b == nil {
18 return nil, errNilBlock
19 }
func UnmarshalSSZ
has a cyclomatic complexity of 29 with "very-high" risk 884}
885
886// UnmarshalSSZ unmarshals the beacon block from its relevant ssz form.
887func (b *BeaconBlock) UnmarshalSSZ(buf []byte) error { 888 var newBlock *BeaconBlock
889 switch b.version {
890 case version.Phase0:
func UnmarshalSSZ
has a cyclomatic complexity of 29 with "very-high" risk 564}
565
566// UnmarshalSSZ unmarshals the signed beacon block from its relevant ssz form.
567func (b *SignedBeaconBlock) UnmarshalSSZ(buf []byte) error { 568 var newBlock *SignedBeaconBlock
569 switch b.version {
570 case version.Phase0:
func BuildSignedBeaconBlockFromExecutionPayload
has a cyclomatic complexity of 23 with "high" risk224
225// BuildSignedBeaconBlockFromExecutionPayload takes a signed, blinded beacon block and converts into
226// a full, signed beacon block by specifying an execution payload.
227func BuildSignedBeaconBlockFromExecutionPayload(228 blk interfaces.ReadOnlySignedBeaconBlock, payload interface{},
229) (interfaces.SignedBeaconBlock, error) {
230 if err := BeaconBlockIsNil(blk); err != nil {
func BuildSignedBeaconBlock
has a cyclomatic complexity of 21 with "high" risk153// BuildSignedBeaconBlock assembles a block.ReadOnlySignedBeaconBlock interface compatible struct from a
154// given beacon block and the appropriate signature. This method may be used to easily create a
155// signed beacon block.
156func BuildSignedBeaconBlock(blk interfaces.ReadOnlyBeaconBlock, signature []byte) (interfaces.SignedBeaconBlock, error) {157 pb, err := blk.Proto()
158 if err != nil {
159 return nil, err
func NewBeaconBlock
has a cyclomatic complexity of 21 with "high" risk 77}
78
79// NewBeaconBlock creates a beacon block from a protobuf beacon block.
80func NewBeaconBlock(i interface{}) (interfaces.ReadOnlyBeaconBlock, error) { 81 switch b := i.(type) {
82 case nil:
83 return nil, ErrNilObject
func NewSignedBeaconBlock
has a cyclomatic complexity of 21 with "high" risk 31)
32
33// NewSignedBeaconBlock creates a signed beacon block from a protobuf signed beacon block.
34func NewSignedBeaconBlock(i interface{}) (interfaces.SignedBeaconBlock, error) { 35 switch b := i.(type) {
36 case nil:
37 return nil, ErrNilObject
func TestGetSpec
has a cyclomatic complexity of 152 with "critical" risk 44 assert.Equal(t, "0x4242424242424242424242424242424242424242", response.Data.Address)
45}
46
47func TestGetSpec(t *testing.T) { 48 params.SetupTestConfigCleanup(t)
49 config := params.BeaconConfig().Copy()
50
A function with high cyclomatic complexity can be hard to understand and maintain. Cyclomatic complexity is a software metric that measures the number of independent paths through a function. A higher cyclomatic complexity indicates that the function has more decision points and is more complex.
Functions with high cyclomatic complexity are more likely to have bugs and be harder to test. They may lead to reduced code maintainability and increased development time.
To reduce the cyclomatic complexity of a function, you can:
- Break the function into smaller, more manageable functions.
- Refactor complex logic into separate functions or classes.
- Avoid multiple return paths and deeply nested control expressions.
Bad practice
package main
import "log"
func fizzbuzzfuzz(x int) { // cc = 1
if x == 0 || x < 0 { // cc = 3 (if, ||)
return
}
for i := 1; i <= x; i++ { // cc = 4 (for)
switch i % 15 * 2 {
case 0: // cc = 5 (case)
countDiv3 += 1
countDiv5 += 1
log.Println("fizzbuzz")
break
case 3:
case 6:
case 9:
case 12: // cc = 9 (case)
countDiv3 += 1
log.Println("fizz")
break
case 5:
case 10: // cc = 11 (case)
countDiv5 += 1
log.Println("buzz")
break
default:
log.Printf("%d\n", x)
}
}
} // CC == 11; raises issues
Recommended
package main
import "log"
func fizzbuzz(x int) { // cc = 1
for i := 1; i <= x; i++ { // cc = 2 (for)
y := i%3 == 0
z := i%5 == 0
if y == z { // 3
if y == false { // 4
log.Printf("%d\n", i)
} else {
log.Println("fizzbuzz")
}
} else {
if y { // 5
log.Println("fizz")
} else {
log.Println("buzz")
}
}
}
} // CC == 5
Issue configuration
Cyclomatic complexity threshold can be configured using the
cyclomatic_complexity_threshold
(docs) in the
.deepsource.toml
config file.
Configuring this is optional. If you don't provide a value, the Analyzer will
raise issues for functions with complexity higher than the default threshold,
which is medium
(only raise issues for >15) for the Go Analyzer.
Here's the mapping of the risk category to the cyclomatic complexity score to help you configure this better:
Risk category | Cyclomatic complexity range | Recommended action |
---|---|---|
low | 1-5 | No action needed. |
medium | 6-15 | Review and monitor. |
high | 16-25 | Review and refactor. Recommended to add comments if the function is absolutely needed to be kept as it is. |
very-high. | 26-50 | Refactor to reduce the complexity. |
critical | >50 | Must refactor this. This can make the code untestable and very difficult to understand. |