Skip to content

Commit 84112d8

Browse files
authored
ci: Enable staticcheck lints and fix violations (wormhole-foundation#4424)
* ci: Enable staticcheck lints and fix violations - Ensure `error` types are the final return value - Ensure error messages begin with a lowercase letter (official Go style recommendation) - Enable style rule such that Duration variable names don't end with time units - Remove exception for a file that has since been deleted * fix unit tests errors and apply formatting * improve variable name
1 parent 704b9e9 commit 84112d8

15 files changed

Lines changed: 76 additions & 56 deletions

File tree

.golangci.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ linters:
168168
# All of these lints should eventually be added.
169169
# They occurred during the migration to v2 and were disabled to make the upgrade easier.
170170
# https://golangci-lint.run/usage/linters/#staticcheck
171-
["all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022", "-SA9003", "-QF1003", "-QF1006", "-QF1008", "-QF1011", "-S1009", "-ST1005", "-ST1008", "-ST1011", "-ST1017", "-ST1018", "-ST1019", "-ST1023"]
171+
["all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022", "-SA9003", "-QF1003", "-QF1006", "-QF1008", "-QF1011", "-S1009", "-ST1017", "-ST1018", "-ST1019", "-ST1023"]
172172
unparam:
173173
# Inspect exported functions.
174174
#
@@ -187,10 +187,6 @@ linters:
187187
- legacy
188188
- std-error-handling
189189
rules:
190-
- linters:
191-
- unused
192-
path: pkg/supervisor/supervisor_testhelpers.go
193-
text: ^func.*supervisor.*(waitSettle|waitSettleError).*$
194190
# This file contains hard-coded Sui core contract addresses that are marked as hardcoded credentials.
195191
- path: pkg/txverifier/sui_test.go
196192
text: 'G101: Potential hardcoded credentials'

node/hack/findmissing/findmissing.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,28 @@ var (
1919
onlyChain = flag.String("only", "", "Only check this chain")
2020
)
2121

22-
func getAdminClient(ctx context.Context, addr string) (*grpc.ClientConn, error, nodev1.NodePrivilegedServiceClient) {
22+
func getAdminClient(ctx context.Context, addr string) (*grpc.ClientConn, nodev1.NodePrivilegedServiceClient, error) {
2323
conn, err := grpc.DialContext(ctx, fmt.Sprintf("unix:///%s", addr), grpc.WithTransportCredentials(insecure.NewCredentials()))
2424

2525
if err != nil {
2626
log.Fatalf("failed to connect to %s: %v", addr, err)
2727
}
2828

2929
c := nodev1.NewNodePrivilegedServiceClient(conn)
30-
return conn, err, c
30+
return conn, c, err
3131
}
3232

3333
func main() {
3434
flag.Parse()
3535

3636
ctx := context.Background()
3737

38-
conn, err, admin := getAdminClient(ctx, *adminRPC)
39-
defer conn.Close()
38+
conn, admin, err := getAdminClient(ctx, *adminRPC)
4039
if err != nil {
40+
conn.Close()
4141
log.Fatalf("failed to get admin client: %v", err)
4242
}
43+
defer conn.Close()
4344

4445
var only vaa.ChainID
4546
if *onlyChain != "" {

node/hack/repair_eth/repair_eth.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,15 @@ func usesBlockscout(chainId vaa.ChainID) bool {
9090
return chainId == vaa.ChainIDOasis || chainId == vaa.ChainIDAurora || chainId == vaa.ChainIDKarura || chainId == vaa.ChainIDAcala
9191
}
9292

93-
func getAdminClient(ctx context.Context, addr string) (*grpc.ClientConn, error, nodev1.NodePrivilegedServiceClient) {
93+
func getAdminClient(ctx context.Context, addr string) (*grpc.ClientConn, nodev1.NodePrivilegedServiceClient, error) {
9494
conn, err := grpc.DialContext(ctx, fmt.Sprintf("unix:///%s", addr), grpc.WithTransportCredentials(insecure.NewCredentials()))
9595

9696
if err != nil {
9797
log.Fatalf("failed to connect to %s: %v", addr, err)
9898
}
9999

100100
c := nodev1.NewNodePrivilegedServiceClient(conn)
101-
return conn, err, c
101+
return conn, c, err
102102
}
103103

104104
type logEntry struct {
@@ -284,11 +284,12 @@ func main() {
284284

285285
missingMessages := make(map[eth_common.Address]map[uint64]bool)
286286

287-
conn, err, admin := getAdminClient(ctx, *adminRPC)
288-
defer conn.Close()
287+
conn, admin, err := getAdminClient(ctx, *adminRPC)
289288
if err != nil {
289+
conn.Close()
290290
log.Fatalf("failed to get admin client: %v", err)
291291
}
292+
defer conn.Close()
292293

293294
// A polygon VAA that was not reobserved before the blocks aged out of guardian rpc nodes
294295
ignoreAddress, _ := vaa.StringToAddress("0000000000000000000000005a58505a96d1dbf8df91cb21b54419fc36e93fde")

node/hack/repair_solana/repair.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ const (
3333
postMessageInstructionID = 0x01
3434
)
3535

36-
func getAdminClient(ctx context.Context, addr string) (*grpc.ClientConn, error, nodev1.NodePrivilegedServiceClient) {
36+
func getAdminClient(ctx context.Context, addr string) (*grpc.ClientConn, nodev1.NodePrivilegedServiceClient, error) {
3737
conn, err := grpc.DialContext(ctx, fmt.Sprintf("unix:///%s", addr), grpc.WithTransportCredentials(insecure.NewCredentials()))
3838

3939
if err != nil {
4040
log.Fatalf("failed to connect to %s: %v", addr, err)
4141
}
4242

4343
c := nodev1.NewNodePrivilegedServiceClient(conn)
44-
return conn, err, c
44+
return conn, c, err
4545
}
4646

4747
func main() {
@@ -50,11 +50,12 @@ func main() {
5050
ctx := context.Background()
5151
sr := rpc.New(*solanaRPC)
5252

53-
conn, err, admin := getAdminClient(ctx, *adminRPC)
54-
defer conn.Close()
53+
conn, admin, err := getAdminClient(ctx, *adminRPC)
5554
if err != nil {
55+
conn.Close()
5656
log.Fatalf("failed to get admin client: %v", err)
5757
}
58+
defer conn.Close()
5859

5960
for _, emitter := range sdk.KnownEmitters {
6061
if emitter.ChainID != vaa.ChainIDSolana {

node/hack/repair_terra/repair.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,15 @@ var (
6060
sleepTime = flag.Int("sleepTime", 1, "Time to sleep between http requests")
6161
)
6262

63-
func getAdminClient(ctx context.Context, addr string) (*grpc.ClientConn, error, nodev1.NodePrivilegedServiceClient) {
63+
func getAdminClient(ctx context.Context, addr string) (*grpc.ClientConn, nodev1.NodePrivilegedServiceClient, error) {
6464
conn, err := grpc.DialContext(ctx, fmt.Sprintf("unix:///%s", addr), grpc.WithTransportCredentials(insecure.NewCredentials()))
6565

6666
if err != nil {
6767
log.Fatalf("failed to connect to %s: %v", addr, err)
6868
}
6969

7070
c := nodev1.NewNodePrivilegedServiceClient(conn)
71-
return conn, err, c
71+
return conn, c, err
7272
}
7373

7474
func getSequencesForTxhash(txhash string, fcd string, contractAddressLogKey string, coreContract string, emitter Emitter, chainID vaa.ChainID) ([]uint64, error) {
@@ -286,11 +286,12 @@ func main() {
286286

287287
missingMessages := make(map[uint64]bool)
288288

289-
conn, err, admin := getAdminClient(ctx, *adminRPC)
290-
defer conn.Close()
289+
conn, admin, err := getAdminClient(ctx, *adminRPC)
291290
if err != nil {
291+
conn.Close()
292292
log.Fatalf("failed to get admin client: %v", err)
293293
}
294+
defer conn.Close()
294295

295296
log.Printf("Requesting missing messages for %s", emitter.Emitter)
296297

node/pkg/accountant/submit_obs.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ import (
2121
"go.uber.org/zap"
2222
)
2323

24-
const batchSize = 10
25-
const delayInMS = 100 * time.Millisecond
24+
const (
25+
batchSize = 10
26+
batchTimeout = 100 * time.Millisecond
27+
)
2628

2729
// baseWorker is the entry point for the base accountant worker.
2830
func (acct *Accountant) baseWorker(ctx context.Context) error {
@@ -63,7 +65,7 @@ func (acct *Accountant) worker(ctx context.Context, isNTT bool) error {
6365
// handleBatch reads a batch of events from the channel, either until a timeout occurs or the batch is full,
6466
// and submits them to the smart contract.
6567
func (acct *Accountant) handleBatch(ctx context.Context, subChan chan *common.MessagePublication, wormchainConn AccountantWormchainConn, contract string, prefix []byte, tag string) error {
66-
ctx, cancel := context.WithTimeout(ctx, delayInMS)
68+
ctx, cancel := context.WithTimeout(ctx, batchTimeout)
6769
defer cancel()
6870

6971
msgs, err := common.ReadFromChannelWithTimeout[*common.MessagePublication](ctx, subChan, batchSize)

node/pkg/guardiansigner/amazonkms.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func NewAmazonKmsSigner(ctx context.Context, keyPath string) (*AmazonKms, error)
8484
region := getRegionFromArn(keyPath)
8585

8686
if region == "" {
87-
return nil, errors.New("Invalid KMS ARN")
87+
return nil, errors.New("invalid KMS ARN")
8888
}
8989

9090
amazonKmsSigner := AmazonKms{
@@ -97,7 +97,7 @@ func NewAmazonKmsSigner(ctx context.Context, keyPath string) (*AmazonKms, error)
9797
// an error. This is why the region is first extracted from the keyPath.
9898
cfg, err := config.LoadDefaultConfig(timeoutCtx, config.WithDefaultRegion(amazonKmsSigner.region))
9999
if err != nil {
100-
return nil, errors.New("Failed to load KMS default config")
100+
return nil, errors.New("failed to load KMS default config")
101101
}
102102

103103
amazonKmsSigner.client = kms.NewFromConfig(cfg)
@@ -116,12 +116,12 @@ func NewAmazonKmsSigner(ctx context.Context, keyPath string) (*AmazonKms, error)
116116
_, err = asn1.Unmarshal(pubKeyOutput.PublicKey, &asn1Pubkey)
117117

118118
if err != nil {
119-
return nil, fmt.Errorf("Failed to unmarshal KMS public key: %w", err)
119+
return nil, fmt.Errorf("failed to unmarshal KMS public key: %w", err)
120120
}
121121

122122
// The public key is expected to be at least `MINIMUM_KMS_PUBKEY_LENGTH` bytes long.
123123
if len(asn1Pubkey.PublicKey.Bytes) < MINIMUM_KMS_PUBKEY_LENGTH {
124-
return nil, errors.New("Invalid KMS public key length")
124+
return nil, errors.New("invalid KMS public key length")
125125
}
126126

127127
// It is possible to use `ethcrypto.UnmarshalPubkey(asn1Pubkey.PublicKey.Bytes)`` to get the public key,
@@ -160,7 +160,7 @@ func (a *AmazonKms) Sign(ctx context.Context, hash []byte) (signature []byte, er
160160
r, s, err := derSignatureToRS(res.Signature)
161161

162162
if err != nil {
163-
return nil, fmt.Errorf("Failed to decode signature: %w", err)
163+
return nil, fmt.Errorf("failed to decode signature: %w", err)
164164
}
165165

166166
// if s is greater than secp256k1HalfN, we need to subtract secp256k1N from it
@@ -196,7 +196,7 @@ func (a *AmazonKms) Sign(ctx context.Context, hash []byte) (signature []byte, er
196196

197197
// Reaching this return implies that it wasn't possible to generate a valid signature. This shouldn't
198198
// happen, unless there is something seriously wrong with the KMS service.
199-
return nil, fmt.Errorf("Failed to generate valid signature")
199+
return nil, fmt.Errorf("failed to generate valid signature")
200200
}
201201

202202
func (a *AmazonKms) PublicKey(ctx context.Context) ecdsa.PublicKey {

node/pkg/node/node.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,23 @@ const (
5353
observationRequestPerChainBufferSize = 100
5454
)
5555

56+
type ComponentAlreadyConfiguredError struct {
57+
componentName string
58+
}
59+
60+
func (e ComponentAlreadyConfiguredError) Error() string {
61+
return fmt.Sprintf("component %s is already configured and cannot be configured a second time", e.componentName)
62+
}
63+
64+
type ComponentDependencyError struct {
65+
componentName string
66+
dependencyName string
67+
}
68+
69+
func (e ComponentDependencyError) Error() string {
70+
return fmt.Sprintf("component %s requires %s to be configured first, check the order of your options", e.componentName, e.dependencyName)
71+
}
72+
5673
type PrometheusCtxKey struct{}
5774

5875
type G struct {
@@ -156,20 +173,20 @@ func (g *G) applyOptions(ctx context.Context, logger *zap.Logger, options []*Gua
156173
for _, option := range options {
157174
// check that this component has not been configured yet
158175
if _, ok := configuredComponents[option.name]; ok {
159-
return fmt.Errorf("Component %s is already configured and cannot be configured a second time.", option.name)
176+
return ComponentAlreadyConfiguredError{componentName: option.name}
160177
}
161178

162179
// check that all dependencies have been met
163180
for _, dep := range option.dependencies {
164181
if _, ok := configuredComponents[dep]; !ok {
165-
return fmt.Errorf("Component %s requires %s to be configured first. Check the order of your options.", option.name, dep)
182+
return ComponentDependencyError{componentName: option.name, dependencyName: dep}
166183
}
167184
}
168185

169186
// run the config
170187
err := option.f(ctx, logger, g)
171188
if err != nil {
172-
return fmt.Errorf("Error applying option for component %s: %w", option.name, err)
189+
return fmt.Errorf("error applying option for component %s: %w", option.name, err)
173190
}
174191

175192
// mark the component as configured

node/pkg/node/node_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -927,15 +927,15 @@ func TestGuardianConfigs(t *testing.T) {
927927
nil, // nttWormchainConn
928928
),
929929
},
930-
err: "Check the order of your options.",
930+
err: ComponentDependencyError{componentName: "accountant", dependencyName: "db"}.Error(),
931931
},
932932
{
933933
name: "double-configuration",
934934
opts: []*GuardianOption{
935935
GuardianOptionDatabase(nil),
936936
GuardianOptionDatabase(nil),
937937
},
938-
err: "Component db is already configured and cannot be configured a second time",
938+
err: ComponentAlreadyConfiguredError{componentName: "db"}.Error(),
939939
},
940940
}
941941
runGuardianConfigTests(t, tc)
@@ -989,6 +989,7 @@ func runGuardianConfigTests(t *testing.T, testCases []testCaseGuardianConfig) {
989989
if tc.err == "" {
990990
assert.Equal(t, tc.err, r)
991991
}
992+
// Check that the string logged by the fatal hook contains the error message.
992993
assert.Contains(t, r, tc.err)
993994
rootCtxCancel()
994995
case <-rootCtx.Done():

node/pkg/txverifier/evm.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ func (tv *TransferVerifier[ethClient, Connector]) UpdateReceiptDetails(
173173
invalidErr := receipt.Validate()
174174
if invalidErr != nil {
175175
return errors.Join(
176-
errors.New("ProcessReceipt was called with an invalid Transfer Receipt:"),
176+
errors.New("ProcessReceipt was called with an invalid Transfer Receipt"),
177177
invalidErr,
178178
)
179179
}
@@ -485,7 +485,7 @@ func (tv *TransferVerifier[evmClient, connector]) ProcessReceipt(
485485
invalidErr := receipt.Validate()
486486
if invalidErr != nil {
487487
return nil, errors.Join(
488-
errors.New("ProcessReceipt was called with an invalid Transfer Receipt:"),
488+
errors.New("ProcessReceipt was called with an invalid Transfer Receipt"),
489489
invalidErr,
490490
)
491491
}
@@ -634,7 +634,7 @@ func parseLogMessagePublishedPayload(
634634
// Note: vaa.DecodeTransferPayloadHdr performs validation on data, e.g. length checks.
635635
hdr, err := vaa.DecodeTransferPayloadHdr(data)
636636
if err != nil {
637-
return nil, errors.Join(errors.New("could not parse LogMessagePublished payload:"), err)
637+
return nil, errors.Join(errors.New("could not parse LogMessagePublished payload"), err)
638638
}
639639
return &TransferDetails{
640640
PayloadType: VAAPayloadType(hdr.Type),
@@ -688,7 +688,7 @@ func (tv *TransferVerifier[ethClient, connector]) fetchLogMessageDetails(details
688688
zap.String("originAddressRaw", details.OriginAddress.String()),
689689
zap.String("tokenChain", details.TokenChain.String()),
690690
)
691-
return newDetails, errors.New("unwrap call for foreign asset returned the zero address. Either token has not been registered or there is a bug in the program.")
691+
return newDetails, errors.New("unwrap call for foreign asset returned the zero address, either token has not been registered or there is a bug in the program")
692692
} else {
693693
originAddress = unwrappedAddress
694694
}

0 commit comments

Comments
 (0)