From 95736a6e4821dc2b48d536fe149351cdd8197101 Mon Sep 17 00:00:00 2001 From: ffranr Date: Fri, 23 Feb 2024 13:58:09 +0000 Subject: [PATCH 1/3] lint: enable errorlint This commit enables a linter which checks to ensure that we do not incorrectly use a non-wrapping format verb when trying to wrap an error with `fmt.Errorf`. --- .golangci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.golangci.yml b/.golangci.yml index 981a70642..af57bba3e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -3,6 +3,9 @@ run: deadline: 4m linters-settings: + errorlint: + comparison: false + asserts: false govet: # Don't report about shadowed variables check-shadowing: false @@ -26,6 +29,7 @@ linters-settings: linters: enable: + - errorlint - gofmt - tagliatelle - whitespace From 08c28eedd5594acc2e38ca907edbe58cbd787e04 Mon Sep 17 00:00:00 2001 From: ffranr Date: Fri, 23 Feb 2024 13:59:27 +0000 Subject: [PATCH 2/3] multi: fix `fmt.Errorf` error wrapping misuse --- cmd/tapcli/addrs.go | 4 ++-- cmd/tapcli/cmd_profile.go | 20 ++++++++++---------- cmd/tapcli/macaroon_jar.go | 24 ++++++++++++------------ cmd/tapcli/main.go | 10 +++++----- cmd/tapcli/profile.go | 18 +++++++++--------- cmd/tapd/main.go | 2 +- fn/errors_test.go | 2 +- itest/assertions.go | 2 +- itest/tapd_harness.go | 14 +++++++------- itest/test_harness.go | 4 ++-- itest/universe_test.go | 2 +- mssmt/tree_test.go | 2 +- proof/archive.go | 2 +- proof/courier.go | 2 +- proof/file.go | 2 +- rpcserver.go | 4 ++-- server.go | 20 ++++++++++---------- tapcfg/server.go | 18 +++++++++--------- tapdb/asset_minting.go | 8 ++++---- tapdb/assets_store.go | 4 ++-- tapdb/universe_federation.go | 2 +- tapfreighter/chain_porter.go | 4 ++-- tapgarden/caretaker.go | 6 +++--- tapgarden/custodian.go | 2 +- tapgarden/planter.go | 6 +++--- tapgarden/planter_test.go | 5 +++-- tapgarden/seedling.go | 2 +- tapsend/send.go | 2 +- universe/base.go | 6 +++--- universe/syncer.go | 2 +- universe_rpc_registrar.go | 4 ++-- 31 files changed, 103 insertions(+), 102 deletions(-) diff --git a/cmd/tapcli/addrs.go b/cmd/tapcli/addrs.go index 084267f84..4ffa000d4 100644 --- a/cmd/tapcli/addrs.go +++ b/cmd/tapcli/addrs.go @@ -71,7 +71,7 @@ func newAddr(ctx *cli.Context) error { assetID, err := hex.DecodeString(ctx.String(assetIDName)) if err != nil { - return fmt.Errorf("unable to decode assetID: %v", err) + return fmt.Errorf("unable to decode assetID: %w", err) } ctxc := getContext() @@ -168,7 +168,7 @@ func queryAddr(ctx *cli.Context) error { Offset: int32(ctx.Int64(offsetName)), }) if err != nil { - return fmt.Errorf("unable to make addrs: %v", err) + return fmt.Errorf("unable to make addrs: %w", err) } printRespJSON(addrs) diff --git a/cmd/tapcli/cmd_profile.go b/cmd/tapcli/cmd_profile.go index eb611cb9a..efa204171 100644 --- a/cmd/tapcli/cmd_profile.go +++ b/cmd/tapcli/cmd_profile.go @@ -118,7 +118,7 @@ func profileAdd(ctx *cli.Context) error { // Create a profile struct from all the global options. profile, err := profileFromContext(ctx, true, false) if err != nil { - return fmt.Errorf("could not load global options: %v", err) + return fmt.Errorf("could not load global options: %w", err) } // Finally, all that's left is to get the profile name from either @@ -149,7 +149,7 @@ func profileAdd(ctx *cli.Context) error { // All done, store the updated profile file. f.Profiles = append(f.Profiles, profile) if err = saveProfileFile(defaultProfileFile, f); err != nil { - return fmt.Errorf("error writing profile file %s: %v", + return fmt.Errorf("error writing profile file %s: %w", defaultProfileFile, err) } @@ -180,7 +180,7 @@ func profileRemove(ctx *cli.Context) error { // Load the default profile file. f, err := loadProfileFile(defaultProfileFile) if err != nil { - return fmt.Errorf("could not load profile file: %v", err) + return fmt.Errorf("could not load profile file: %w", err) } // Get the profile name from either positional argument or flag. @@ -255,7 +255,7 @@ func profileSetDefault(ctx *cli.Context) error { // Load the default profile file. f, err := loadProfileFile(defaultProfileFile) if err != nil { - return fmt.Errorf("could not load profile file: %v", err) + return fmt.Errorf("could not load profile file: %w", err) } // Get the profile name from either positional argument or flag. @@ -308,7 +308,7 @@ func profileUnsetDefault(_ *cli.Context) error { // Load the default profile file. f, err := loadProfileFile(defaultProfileFile) if err != nil { - return fmt.Errorf("could not load profile file: %v", err) + return fmt.Errorf("could not load profile file: %w", err) } // Save the file with the flag disabled. @@ -354,7 +354,7 @@ func profileAddMacaroon(ctx *cli.Context) error { // yet. f, err := loadProfileFile(defaultProfileFile) if err != nil { - return fmt.Errorf("could not load profile file: %v", err) + return fmt.Errorf("could not load profile file: %w", err) } // Finally, all that's left is to get the profile name from either @@ -420,17 +420,17 @@ func profileAddMacaroon(ctx *cli.Context) error { macPath := lncfg.CleanAndExpandPath(ctx.GlobalString("macaroonpath")) macBytes, err := os.ReadFile(macPath) if err != nil { - return fmt.Errorf("unable to read macaroon path: %v", err) + return fmt.Errorf("unable to read macaroon path: %w", err) } mac := &macaroon.Macaroon{} if err = mac.UnmarshalBinary(macBytes); err != nil { - return fmt.Errorf("unable to decode macaroon: %v", err) + return fmt.Errorf("unable to decode macaroon: %w", err) } macEntry := &macaroonEntry{ Name: macName, } if err = macEntry.storeMacaroon(mac, nil); err != nil { - return fmt.Errorf("unable to store macaroon: %v", err) + return fmt.Errorf("unable to store macaroon: %w", err) } // All done, store the updated profile file. @@ -438,7 +438,7 @@ func profileAddMacaroon(ctx *cli.Context) error { selectedProfile.Macaroons.Jar, macEntry, ) if err = saveProfileFile(defaultProfileFile, f); err != nil { - return fmt.Errorf("error writing profile file %s: %v", + return fmt.Errorf("error writing profile file %s: %w", defaultProfileFile, err) } diff --git a/cmd/tapcli/macaroon_jar.go b/cmd/tapcli/macaroon_jar.go index 29b364904..85db4a6e8 100644 --- a/cmd/tapcli/macaroon_jar.go +++ b/cmd/tapcli/macaroon_jar.go @@ -62,26 +62,26 @@ func (e *macaroonEntry) loadMacaroon( pw, err := pwCallback("Enter macaroon encryption password: ") if err != nil { return nil, fmt.Errorf("could not read password from "+ - "terminal: %v", err) + "terminal: %w", err) } macBytes, err = decryptMacaroon(parts[1], parts[2], pw) if err != nil { - return nil, fmt.Errorf("unable to decrypt macaroon: %v", + return nil, fmt.Errorf("unable to decrypt macaroon: %w", err) } } else { macBytes, err = hex.DecodeString(e.Data) if err != nil { return nil, fmt.Errorf("unable to hex decode "+ - "macaroon: %v", err) + "macaroon: %w", err) } } // Parse the macaroon data into its native struct. mac := &macaroon.Macaroon{} if err := mac.UnmarshalBinary(macBytes); err != nil { - return nil, fmt.Errorf("unable to decode macaroon: %v", err) + return nil, fmt.Errorf("unable to decode macaroon: %w", err) } return mac, nil } @@ -93,7 +93,7 @@ func (e *macaroonEntry) storeMacaroon(mac *macaroon.Macaroon, pw []byte) error { // First of all, make sure we can serialize the macaroon. macBytes, err := mac.MarshalBinary() if err != nil { - return fmt.Errorf("unable to marshal macaroon: %v", err) + return fmt.Errorf("unable to marshal macaroon: %w", err) } if len(pw) == 0 { @@ -106,14 +106,14 @@ func (e *macaroonEntry) storeMacaroon(mac *macaroon.Macaroon, pw []byte) error { &pw, snacl.DefaultN, snacl.DefaultR, snacl.DefaultP, ) if err != nil { - return fmt.Errorf("unable to create encryption key: %v", err) + return fmt.Errorf("unable to create encryption key: %w", err) } // Encrypt the macaroon data with the derived key and store it in the // human readable format snacl::. encryptedMac, err := key.Encrypt(macBytes) if err != nil { - return fmt.Errorf("unable to encrypt macaroon: %v", err) + return fmt.Errorf("unable to encrypt macaroon: %w", err) } keyB64 := base64.StdEncoding.EncodeToString(key.Marshal()) @@ -130,19 +130,19 @@ func decryptMacaroon(keyB64, dataB64 string, pw []byte) ([]byte, error) { keyData, err := base64.StdEncoding.DecodeString(keyB64) if err != nil { return nil, fmt.Errorf("could not base64 decode encryption "+ - "key: %v", err) + "key: %w", err) } encryptedMac, err := base64.StdEncoding.DecodeString(dataB64) if err != nil { return nil, fmt.Errorf("could not base64 decode macaroon "+ - "data: %v", err) + "data: %w", err) } // Unmarshal the encryption key and ask the user for the password. key := &snacl.SecretKey{} err = key.Unmarshal(keyData) if err != nil { - return nil, fmt.Errorf("could not unmarshal encryption key: %v", + return nil, fmt.Errorf("could not unmarshal encryption key: %w", err) } @@ -151,11 +151,11 @@ func decryptMacaroon(keyB64, dataB64 string, pw []byte) ([]byte, error) { err = key.DeriveKey(&pw) if err != nil { return nil, fmt.Errorf("could not derive encryption key, "+ - "possibly due to incorrect password: %v", err) + "possibly due to incorrect password: %w", err) } macBytes, err := key.Decrypt(encryptedMac) if err != nil { - return nil, fmt.Errorf("could not decrypt macaroon data: %v", + return nil, fmt.Errorf("could not decrypt macaroon data: %w", err) } return macBytes, nil diff --git a/cmd/tapcli/main.go b/cmd/tapcli/main.go index 4afe311a4..d3134ab36 100644 --- a/cmd/tapcli/main.go +++ b/cmd/tapcli/main.go @@ -90,13 +90,13 @@ func getClientConn(ctx *cli.Context, skipMacaroons bool) *grpc.ClientConn { // created from the global options in the CLI context. profile, err := getGlobalOptions(ctx, skipMacaroons) if err != nil { - fatal(fmt.Errorf("could not load global options: %v", err)) + fatal(fmt.Errorf("could not load global options: %w", err)) } // Load the specified TLS certificate. certPool, err := profile.cert() if err != nil { - fatal(fmt.Errorf("could not create cert pool: %v", err)) + fatal(fmt.Errorf("could not create cert pool: %w", err)) } // Build transport credentials from the certificate pool. If there is no @@ -143,7 +143,7 @@ func getClientConn(ctx *cli.Context, skipMacaroons bool) *grpc.ClientConn { // don't need to ask for it every time. mac, err := macEntry.loadMacaroon(readPassword) if err != nil { - fatal(fmt.Errorf("could not load macaroon: %v", err)) + fatal(fmt.Errorf("could not load macaroon: %w", err)) } macConstraints := []macaroons.Constraint{ @@ -174,7 +174,7 @@ func getClientConn(ctx *cli.Context, skipMacaroons bool) *grpc.ClientConn { // Now we append the macaroon credentials to the dial options. cred, err := macaroons.NewMacaroonCredential(constrainedMac) if err != nil { - fatal(fmt.Errorf("error cloning mac: %v", err)) + fatal(fmt.Errorf("error cloning mac: %w", err)) } opts = append(opts, grpc.WithPerRPCCredentials(cred)) } @@ -201,7 +201,7 @@ func getClientConn(ctx *cli.Context, skipMacaroons bool) *grpc.ClientConn { conn, err := grpc.Dial(profile.RPCServer, opts...) if err != nil { - fatal(fmt.Errorf("unable to connect to RPC server: %v", err)) + fatal(fmt.Errorf("unable to connect to RPC server: %w", err)) } return conn diff --git a/cmd/tapcli/profile.go b/cmd/tapcli/profile.go index 8b20e598e..b04c71552 100644 --- a/cmd/tapcli/profile.go +++ b/cmd/tapcli/profile.go @@ -170,7 +170,7 @@ func profileFromContext(ctx *cli.Context, store, skipMacaroons bool) ( var err error tlsCert, err = os.ReadFile(tlsCertPath) if err != nil { - return nil, fmt.Errorf("could not load TLS cert file: %v", err) + return nil, fmt.Errorf("could not load TLS cert file: %w", err) } } @@ -194,11 +194,11 @@ func profileFromContext(ctx *cli.Context, store, skipMacaroons bool) ( macBytes, err := os.ReadFile(macPath) if err != nil { return nil, fmt.Errorf("unable to read macaroon path (check "+ - "the network setting!): %v", err) + "the network setting!): %w", err) } mac := &macaroon.Macaroon{} if err = mac.UnmarshalBinary(macBytes); err != nil { - return nil, fmt.Errorf("unable to decode macaroon: %v", err) + return nil, fmt.Errorf("unable to decode macaroon: %w", err) } var pw []byte @@ -212,12 +212,12 @@ func profileFromContext(ctx *cli.Context, store, skipMacaroons bool) ( ) if err != nil { return nil, fmt.Errorf("unable to get encryption "+ - "password: %v", err) + "password: %w", err) } } macEntry := &macaroonEntry{} if err = macEntry.storeMacaroon(mac, pw); err != nil { - return nil, fmt.Errorf("unable to store macaroon: %v", err) + return nil, fmt.Errorf("unable to store macaroon: %w", err) } // We determine the name of the macaroon from the file itself but cut @@ -248,7 +248,7 @@ func loadProfileFile(file string) (*profileFile, error) { content, err := os.ReadFile(file) if err != nil { - return nil, fmt.Errorf("could not load profile file %s: %v", + return nil, fmt.Errorf("could not load profile file %s: %w", file, err) } f := &profileFile{} @@ -265,7 +265,7 @@ func loadProfileFile(file string) (*profileFile, error) { func saveProfileFile(file string, f *profileFile) error { content, err := f.marshalJSON() if err != nil { - return fmt.Errorf("could not marshal profile: %v", err) + return fmt.Errorf("could not marshal profile: %w", err) } return os.WriteFile(file, content, 0644) } @@ -286,14 +286,14 @@ func (f *profileFile) unmarshalJSON(content []byte) error { func (f *profileFile) marshalJSON() ([]byte, error) { b, err := json.Marshal(f) if err != nil { - return nil, fmt.Errorf("error JSON marshalling profile: %v", + return nil, fmt.Errorf("error JSON marshalling profile: %w", err) } var out bytes.Buffer err = json.Indent(&out, b, "", " ") if err != nil { - return nil, fmt.Errorf("error indenting profile JSON: %v", err) + return nil, fmt.Errorf("error indenting profile JSON: %w", err) } out.WriteString("\n") return out.Bytes(), nil diff --git a/cmd/tapd/main.go b/cmd/tapd/main.go index 6e0666192..67b54036b 100644 --- a/cmd/tapd/main.go +++ b/cmd/tapd/main.go @@ -70,7 +70,7 @@ func main() { cfg, cfgLogger, shutdownInterceptor, errQueue.ChanIn(), ) if err != nil { - err := fmt.Errorf("error creating server: %v", err) + err := fmt.Errorf("error creating server: %w", err) _, _ = fmt.Fprintln(os.Stderr, err) os.Exit(1) } diff --git a/fn/errors_test.go b/fn/errors_test.go index 20884db58..9c7389456 100644 --- a/fn/errors_test.go +++ b/fn/errors_test.go @@ -14,5 +14,5 @@ func TestIsCanceled(t *testing.T) { require.True(t, IsCanceled(context.Canceled)) require.True(t, IsCanceled(errRpcCanceled)) require.True(t, IsCanceled(fmt.Errorf("foo: %w", context.Canceled))) - require.True(t, IsCanceled(fmt.Errorf("foo: %v", errRpcCanceled))) + require.True(t, IsCanceled(fmt.Errorf("foo: %w", errRpcCanceled))) } diff --git a/itest/assertions.go b/itest/assertions.go index 9c770e261..98db80e8a 100644 --- a/itest/assertions.go +++ b/itest/assertions.go @@ -86,7 +86,7 @@ func AssetAnchorCheck(txid, blockHash chainhash.Hash) AssetCheck { out, err := wire.NewOutPointFromString(a.ChainAnchor.AnchorOutpoint) if err != nil { - return fmt.Errorf("unable to parse outpoint: %v", err) + return fmt.Errorf("unable to parse outpoint: %w", err) } anchorTxid := out.Hash.String() diff --git a/itest/tapd_harness.go b/itest/tapd_harness.go index 41890777a..20068d369 100644 --- a/itest/tapd_harness.go +++ b/itest/tapd_harness.go @@ -295,7 +295,7 @@ func (hs *tapdHarness) start(expectErrExit bool) error { hs.clientCfg, cfgLogger, hs.ht.interceptor, mainErrChan, ) if err != nil { - return fmt.Errorf("could not create tapd server: %v", err) + return fmt.Errorf("could not create tapd server: %w", err) } hs.wg.Add(1) @@ -314,7 +314,7 @@ func (hs *tapdHarness) start(expectErrExit bool) error { return err }, defaultTimeout) if err != nil { - return fmt.Errorf("error waiting for server to start: %v", err) + return fmt.Errorf("error waiting for server to start: %w", err) } // Create our client to interact with the tapd RPC server directly. @@ -323,7 +323,7 @@ func (hs *tapdHarness) start(expectErrExit bool) error { hs.clientCfg.RpcConf.MacaroonPath, ) if err != nil { - return fmt.Errorf("could not connect to %v: %v", + return fmt.Errorf("could not connect to %v: %w", listenerAddr, err) } hs.TaprootAssetsClient = taprpc.NewTaprootAssetsClient(rpcConn) @@ -452,7 +452,7 @@ func defaultDialOptions(serverCertPath, macaroonPath string) ([]grpc.DialOption, if macaroonPath != "" { macaroonOptions, err := readMacaroon(macaroonPath) if err != nil { - return nil, fmt.Errorf("unable to load macaroon %s: %v", + return nil, fmt.Errorf("unable to load macaroon %s: %w", macaroonPath, err) } baseOpts = append(baseOpts, macaroonOptions) @@ -467,18 +467,18 @@ func readMacaroon(macaroonPath string) (grpc.DialOption, error) { // Load the specified macaroon file. macBytes, err := os.ReadFile(macaroonPath) if err != nil { - return nil, fmt.Errorf("unable to read macaroon path : %v", err) + return nil, fmt.Errorf("unable to read macaroon path : %w", err) } mac := &macaroon.Macaroon{} if err = mac.UnmarshalBinary(macBytes); err != nil { - return nil, fmt.Errorf("unable to decode macaroon: %v", err) + return nil, fmt.Errorf("unable to decode macaroon: %w", err) } // Now we append the macaroon credentials to the dial options. cred, err := macaroons.NewMacaroonCredential(mac) if err != nil { - return nil, fmt.Errorf("error creating mac cred: %v", err) + return nil, fmt.Errorf("error creating mac cred: %w", err) } return grpc.WithPerRPCCredentials(cred), nil } diff --git a/itest/test_harness.go b/itest/test_harness.go index 91c388e21..654fff447 100644 --- a/itest/test_harness.go +++ b/itest/test_harness.go @@ -184,13 +184,13 @@ func (h *harnessTest) shutdown(_ *testing.T) error { err := h.proofCourier.Stop() if err != nil { return fmt.Errorf("unable to stop proof courier "+ - "harness: %v", err) + "harness: %w", err) } } err = h.tapd.stop(!*noDelete) if err != nil { - return fmt.Errorf("unable to stop tapd: %v", err) + return fmt.Errorf("unable to stop tapd: %w", err) } return nil diff --git a/itest/universe_test.go b/itest/universe_test.go index 8129b54c7..c253432dc 100644 --- a/itest/universe_test.go +++ b/itest/universe_test.go @@ -489,7 +489,7 @@ func getJSON[T proto.Message](url string) (T, error) { err = taprpc.RESTJsonUnmarshalOpts.Unmarshal(body, jsonResp) if err != nil { - return jsonType, fmt.Errorf("failed to unmarshal %s: %v", body, + return jsonType, fmt.Errorf("failed to unmarshal %s: %w", body, err) } diff --git a/mssmt/tree_test.go b/mssmt/tree_test.go index c07a10bfc..2965b47ef 100644 --- a/mssmt/tree_test.go +++ b/mssmt/tree_test.go @@ -50,7 +50,7 @@ func genTestStores(t *testing.T) map[string]makeTestTreeStoreFunc { if err != nil { return nil, fmt.Errorf("unable to "+ "create new sqlite tree "+ - "store: %v", err) + "store: %w", err) } return treeStore, nil diff --git a/proof/archive.go b/proof/archive.go index d4de97bcd..70a0df819 100644 --- a/proof/archive.go +++ b/proof/archive.go @@ -651,7 +651,7 @@ func (f *FileArchiver) ImportProofs(_ context.Context, err = os.WriteFile(proofPath, proof.Blob, 0666) if err != nil { - return fmt.Errorf("unable to store proof: %v", err) + return fmt.Errorf("unable to store proof: %w", err) } f.eventDistributor.NotifySubscribers(proof.Blob) diff --git a/proof/courier.go b/proof/courier.go index 42ff090a5..431e26cef 100644 --- a/proof/courier.go +++ b/proof/courier.go @@ -129,7 +129,7 @@ func (u *URLDispatch) NewCourier(addr *url.URL, hashMailBox, err := NewHashMailBox(addr) if err != nil { - return nil, fmt.Errorf("unable to make mailbox: %v", + return nil, fmt.Errorf("unable to make mailbox: %w", err) } diff --git a/proof/file.go b/proof/file.go index e3c0998d3..c896a8a4b 100644 --- a/proof/file.go +++ b/proof/file.go @@ -308,7 +308,7 @@ func (f *File) ProofAt(index uint32) (*Proof, error) { reader = bytes.NewReader(f.proofs[index].proofBytes) ) if err := proof.Decode(reader); err != nil { - return nil, fmt.Errorf("error decoding proof: %v", err) + return nil, fmt.Errorf("error decoding proof: %w", err) } return proof, nil diff --git a/rpcserver.go b/rpcserver.go index 415655cf4..d46f274aa 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -456,7 +456,7 @@ func (r *rpcServer) MintAsset(ctx context.Context, // If the asset meta field was specified, then the data inside // must be valid. Let's check that now. if err := seedling.Meta.Validate(); err != nil { - return nil, fmt.Errorf("invalid asset meta: %v", err) + return nil, fmt.Errorf("invalid asset meta: %w", err) } } @@ -959,7 +959,7 @@ func (r *rpcServer) ListBalances(ctx context.Context, groupKey, err = btcec.ParsePubKey(req.GroupKeyFilter) if err != nil { return nil, fmt.Errorf("invalid group key "+ - "filter: %v", err) + "filter: %w", err) } } diff --git a/server.go b/server.go index 73d03af5b..341d3afe3 100644 --- a/server.go +++ b/server.go @@ -94,7 +94,7 @@ func (s *Server) initialize(interceptorChain *rpcperms.InterceptorChain) error { ) if err != nil { return fmt.Errorf("unable to create macaroon "+ - "service: %v", err) + "service: %w", err) } rpcsLog.Infof("Validating RPC requests based on macaroon "+ "at: %v", s.cfg.MacaroonPath) @@ -132,44 +132,44 @@ func (s *Server) initialize(interceptorChain *rpcperms.InterceptorChain) error { s.cfg.SignalInterceptor, interceptorChain, s.cfg, ) if err != nil { - return fmt.Errorf("unable to create rpc server: %v", err) + return fmt.Errorf("unable to create rpc server: %w", err) } // First, we'll start the main batched asset minter. if err := s.cfg.AssetMinter.Start(); err != nil { - return fmt.Errorf("unable to start asset minter: %v", err) + return fmt.Errorf("unable to start asset minter: %w", err) } // Next, we'll start the asset custodian. if err := s.cfg.AssetCustodian.Start(); err != nil { - return fmt.Errorf("unable to start asset custodian: %v", err) + return fmt.Errorf("unable to start asset custodian: %w", err) } if err := s.cfg.ReOrgWatcher.Start(); err != nil { - return fmt.Errorf("unable to start re-org watcher: %v", err) + return fmt.Errorf("unable to start re-org watcher: %w", err) } if err := s.cfg.ChainPorter.Start(); err != nil { - return fmt.Errorf("unable to start chain porter: %v", err) + return fmt.Errorf("unable to start chain porter: %w", err) } if err := s.cfg.UniverseFederation.Start(); err != nil { return fmt.Errorf("unable to start universe "+ - "federation: %v", err) + "federation: %w", err) } if s.cfg.UniversePublicAccess { err := s.cfg.UniverseFederation.SetAllowPublicAccess() if err != nil { return fmt.Errorf("unable to set public access "+ - "for universe federation: %v", err) + "for universe federation: %w", err) } } // Now we have created all dependencies necessary to populate and // start the RPC server. if err := s.rpcServer.Start(); err != nil { - return fmt.Errorf("unable to start RPC server: %v", err) + return fmt.Errorf("unable to start RPC server: %w", err) } // This does have no effect if starting the rpc server is the last step @@ -382,7 +382,7 @@ func (s *Server) RunUntilShutdown(mainErrChan <-chan error) error { // register to an existing one. func (s *Server) StartAsSubserver(lndGrpc *lndclient.GrpcLndServices) error { if err := s.initialize(nil); err != nil { - return fmt.Errorf("unable to initialize RPC server: %v", err) + return fmt.Errorf("unable to initialize RPC server: %w", err) } return nil diff --git a/tapcfg/server.go b/tapcfg/server.go index 044b598e5..13117bb3b 100644 --- a/tapcfg/server.go +++ b/tapcfg/server.go @@ -61,7 +61,7 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger, cfg.DatabaseBackend) } if err != nil { - return nil, fmt.Errorf("unable to open database: %v", err) + return nil, fmt.Errorf("unable to open database: %w", err) } defaultClock := clock.NewDefaultClock() @@ -158,7 +158,7 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger, proofFileStore, err := proof.NewFileArchiver(cfg.networkDir) if err != nil { - return nil, fmt.Errorf("unable to open disk archive: %v", err) + return nil, fmt.Errorf("unable to open disk archive: %w", err) } proofArchive := proof.NewMultiArchiver( &proof.BaseVerifier{}, tapdb.DefaultStoreTimeout, @@ -216,7 +216,7 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger, ) if err != nil { return nil, fmt.Errorf("unable to parse fallback proof "+ - "courier address: %v", err) + "courier address: %w", err) } // If default proof courier address is set, use it as the default. @@ -226,7 +226,7 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger, ) if err != nil { return nil, fmt.Errorf("unable to parse default proof "+ - "courier address: %v", err) + "courier address: %w", err) } } @@ -261,7 +261,7 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger, var runtimeIDBytes [8]byte _, err = rand.Read(runtimeIDBytes[:]) if err != nil { - return nil, fmt.Errorf("unable to generate runtime ID: %v", err) + return nil, fmt.Errorf("unable to generate runtime ID: %w", err) } runtimeID := int64(binary.BigEndian.Uint64(runtimeIDBytes[:])) @@ -419,7 +419,7 @@ func CreateServerFromConfig(cfg *Config, cfgLogger btclog.Logger, cfg, cfgLogger, ) if err != nil { - return nil, fmt.Errorf("unable to load TLS credentials: %v", + return nil, fmt.Errorf("unable to load TLS credentials: %w", err) } @@ -429,7 +429,7 @@ func CreateServerFromConfig(cfg *Config, cfgLogger btclog.Logger, cfg.ChainConf.Network, cfg.Lnd, shutdownInterceptor, ) if err != nil { - return nil, fmt.Errorf("unable to connect to lnd node: %v", err) + return nil, fmt.Errorf("unable to connect to lnd node: %w", err) } cfgLogger.Infof("lnd connection initialized") @@ -438,7 +438,7 @@ func CreateServerFromConfig(cfg *Config, cfgLogger btclog.Logger, cfg, cfgLogger, &lndConn.LndServices, mainErrChan, ) if err != nil { - return nil, fmt.Errorf("unable to generate server config: %v", + return nil, fmt.Errorf("unable to generate server config: %w", err) } @@ -477,7 +477,7 @@ func CreateSubServerFromConfig(cfg *Config, cfgLogger btclog.Logger, cfg, cfgLogger, lndServices, mainErrChan, ) if err != nil { - return nil, fmt.Errorf("unable to generate server config: %v", + return nil, fmt.Errorf("unable to generate server config: %w", err) } diff --git a/tapdb/asset_minting.go b/tapdb/asset_minting.go index 967999acf..b2d1efa6d 100644 --- a/tapdb/asset_minting.go +++ b/tapdb/asset_minting.go @@ -434,7 +434,7 @@ func (a *AssetMintingStore) AddSeedlingsToBatch(ctx context.Context, err = q.InsertAssetSeedlingIntoBatch(ctx, dbSeedling) if err != nil { return fmt.Errorf("unable to insert "+ - "seedling into db: %v", err) + "seedling into db: %w", err) } } @@ -647,7 +647,7 @@ func fetchAssetSprouts(ctx context.Context, q PendingAssetStore, ) if err != nil { return nil, fmt.Errorf("unable to create new sprout: "+ - "%v", err) + "%w", err) } // TODO(roasbeef): need to update the above to set the @@ -974,7 +974,7 @@ func (a *AssetMintingStore) AddSproutsToBatch(ctx context.Context, // the genesis packet, and genesis point information. var psbtBuf bytes.Buffer if err := genesisPacket.Pkt.Serialize(&psbtBuf); err != nil { - return fmt.Errorf("unable to encode psbt: %v", err) + return fmt.Errorf("unable to encode psbt: %w", err) } err = q.BindMintingBatchWithTx(ctx, BatchChainUpdate{ RawKey: rawBatchKey, @@ -1096,7 +1096,7 @@ func (a *AssetMintingStore) CommitSignedGenesisTx(ctx context.Context, AnchorUtxoID: sqlInt64(utxoID), }) if err != nil { - return fmt.Errorf("unable to anchor pending assets: %v", err) + return fmt.Errorf("unable to anchor pending assets: %w", err) } // Next, we'll anchor the genesis point to point to the chain diff --git a/tapdb/assets_store.go b/tapdb/assets_store.go index 2ae6e432d..de3c8e21f 100644 --- a/tapdb/assets_store.go +++ b/tapdb/assets_store.go @@ -635,7 +635,7 @@ func (a *AssetStore) dbAssetsToChainAssets(dbAssets []ConfirmedAsset, ) if err != nil { return nil, fmt.Errorf("unable to create new sprout: "+ - "%v", err) + "%w", err) } // We cannot use 0 as the amount when creating a new asset with @@ -1412,7 +1412,7 @@ func (a *AssetStore) insertAssetWitnesses(ctx context.Context, WitnessIndex: int32(idx), }) if err != nil { - return fmt.Errorf("unable to insert witness: %v", err) + return fmt.Errorf("unable to insert witness: %w", err) } } diff --git a/tapdb/universe_federation.go b/tapdb/universe_federation.go index c6bbea8a5..215e5562b 100644 --- a/tapdb/universe_federation.go +++ b/tapdb/universe_federation.go @@ -787,7 +787,7 @@ func (u *UniverseFederationDB) QueryFederationSyncConfigs( pubKey, err = btcec.ParsePubKey(config.GroupKey) if err != nil { return fmt.Errorf("unable to parse "+ - "group key: %v", err) + "group key: %w", err) } } diff --git a/tapfreighter/chain_porter.go b/tapfreighter/chain_porter.go index 64705cb60..85c3e03da 100644 --- a/tapfreighter/chain_porter.go +++ b/tapfreighter/chain_porter.go @@ -961,7 +961,7 @@ func (p *ChainPorter) stateStep(currentPkg sendPackage) (*sendPackage, error) { currentHeight, err := p.cfg.ChainBridge.CurrentHeight(ctx) if err != nil { return nil, fmt.Errorf("unable to get current height: "+ - "%v", err) + "%w", err) } // We need to prepare the parcel for storage. @@ -998,7 +998,7 @@ func (p *ChainPorter) stateStep(currentPkg sendPackage) (*sendPackage, error) { ) if err != nil { return nil, fmt.Errorf("unable to write send pkg to "+ - "disk: %v", err) + "disk: %w", err) } // We've logged the state transition to disk, so now we can diff --git a/tapgarden/caretaker.go b/tapgarden/caretaker.go index 6093af28c..cafa5569e 100644 --- a/tapgarden/caretaker.go +++ b/tapgarden/caretaker.go @@ -674,7 +674,7 @@ func (b *BatchCaretaker) stateStep(currentState BatchState) (BatchState, error) ) if err != nil { return 0, fmt.Errorf("unable to map seedlings to "+ - "sprouts: %v", err) + "sprouts: %w", err) } b.cfg.Batch.RootAssetCommitment = tapCommitment @@ -685,7 +685,7 @@ func (b *BatchCaretaker) stateStep(currentState BatchState) (BatchState, error) genesisScript, err := b.cfg.Batch.genesisScript() if err != nil { return 0, fmt.Errorf("unable to create genesis "+ - "script: %v", err) + "script: %w", err) } genesisTxPkt.Pkt.UnsignedTx.TxOut[b.anchorOutputIndex].PkScript = genesisScript @@ -865,7 +865,7 @@ func (b *BatchCaretaker) stateStep(currentState BatchState) (BatchState, error) ) if err != nil { return 0, fmt.Errorf("unable to register for "+ - "minting tx conf: %v", err) + "minting tx conf: %w", err) } // Launch a goroutine that'll notify us when the transaction diff --git a/tapgarden/custodian.go b/tapgarden/custodian.go index 6f0e9d648..2cf531f47 100644 --- a/tapgarden/custodian.go +++ b/tapgarden/custodian.go @@ -569,7 +569,7 @@ func (c *Custodian) mapToTapAddr(walletTx *lndclient.Transaction, addrStr, err := addr.EncodeAddress() if err != nil { - return nil, fmt.Errorf("unable to encode address: %v", err) + return nil, fmt.Errorf("unable to encode address: %w", err) } // Make sure we have an event registered for the transaction, since it diff --git a/tapgarden/planter.go b/tapgarden/planter.go index 7eed9d5d1..e88d566cf 100644 --- a/tapgarden/planter.go +++ b/tapgarden/planter.go @@ -827,7 +827,7 @@ func (c *ChainPlanter) prepAssetSeedling(ctx context.Context, defer cancel() currentHeight, err := c.cfg.ChainBridge.CurrentHeight(ctx) if err != nil { - return fmt.Errorf("unable to get current height: %v", + return fmt.Errorf("unable to get current height: %w", err) } @@ -934,7 +934,7 @@ func (c *ChainPlanter) updateMintingProofs(proofs []*proof.Proof) error { // here now. var proofBuf bytes.Buffer if err := p.Encode(&proofBuf); err != nil { - return fmt.Errorf("unable to encode proof: %v", err) + return fmt.Errorf("unable to encode proof: %w", err) } // With both of those assembled, we can now update issuance @@ -955,7 +955,7 @@ func (c *ChainPlanter) updateMintingProofs(proofs []*proof.Proof) error { ctx, uniID, leafKey, mintingLeaf, ) if err != nil { - return fmt.Errorf("unable to update issuance: %v", err) + return fmt.Errorf("unable to update issuance: %w", err) } } diff --git a/tapgarden/planter_test.go b/tapgarden/planter_test.go index a2b831251..362a0a30b 100644 --- a/tapgarden/planter_test.go +++ b/tapgarden/planter_test.go @@ -6,12 +6,13 @@ import ( "database/sql" "encoding/hex" "fmt" - "github.com/lightninglabs/taproot-assets/tapsend" "math/rand" "sync" "testing" "time" + "github.com/lightninglabs/taproot-assets/tapsend" + "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" @@ -589,7 +590,7 @@ func (t *mintingTestHarness) assertSeedlingsMatchSprouts( return true }, defaultTimeout) require.NoError( - t, err, fmt.Errorf("unable to read pending batch: %v", err), + t, err, fmt.Errorf("unable to read pending batch: %w", err), ) // The amount of assets committed to in the Taproot Asset commitment diff --git a/tapgarden/seedling.go b/tapgarden/seedling.go index 7bbe521e6..0298d5ba7 100644 --- a/tapgarden/seedling.go +++ b/tapgarden/seedling.go @@ -114,7 +114,7 @@ func (c Seedling) validateFields() error { // // TODO(roasbeef): lift into new constant? case c.AssetType != asset.Normal && c.AssetType != asset.Collectible: - return fmt.Errorf("%v: %v", int(c.AssetType), + return fmt.Errorf("%v: %w", int(c.AssetType), ErrInvalidAssetType) // Creating an asset with zero available supply is not allowed. diff --git a/tapsend/send.go b/tapsend/send.go index ab01159e2..5a3c92e9a 100644 --- a/tapsend/send.go +++ b/tapsend/send.go @@ -180,7 +180,7 @@ func DescribeRecipients(ctx context.Context, vPkt *tappsbt.VPacket, groupPubKey = &groupKey.GroupPubKey case err != nil: - return nil, fmt.Errorf("unable to query asset group: %v", err) + return nil, fmt.Errorf("unable to query asset group: %w", err) } desc := &FundingDescriptor{ diff --git a/universe/base.go b/universe/base.go index 310a709f2..1c33fe919 100644 --- a/universe/base.go +++ b/universe/base.go @@ -306,7 +306,7 @@ func (a *Archive) UpsertProofLeaf(ctx context.Context, id Identifier, ) if err != nil { return nil, fmt.Errorf("unable to register new "+ - "issuance: %v", err) + "issuance: %w", err) } // Log a sync event for the newly inserted leaf in the background as an @@ -335,7 +335,7 @@ func (a *Archive) verifyIssuanceProof(ctx context.Context, id Identifier, a.cfg.GroupVerifier, ) if err != nil { - return nil, fmt.Errorf("unable to verify proof: %v", err) + return nil, fmt.Errorf("unable to verify proof: %w", err) } newAsset := assetSnapshot.Asset @@ -555,7 +555,7 @@ func (a *Archive) getPrevAssetSnapshot(ctx context.Context, ) if err != nil { return nil, fmt.Errorf("unable to parse previous "+ - "script key: %v", err) + "script key: %w", err) } prevScriptKey := asset.NewScriptKey(prevScriptKeyPubKey) diff --git a/universe/syncer.go b/universe/syncer.go index b93539412..77e53f0a7 100644 --- a/universe/syncer.go +++ b/universe/syncer.go @@ -234,7 +234,7 @@ func (s *SimpleSyncer) syncRoot(ctx context.Context, remoteRoot Root, return nil case err != nil: - return fmt.Errorf("unable to fetch local root: %v", err) + return fmt.Errorf("unable to fetch local root: %w", err) } log.Infof("UniverseRoot(%v) diverges, performing leaf diff...", diff --git a/universe_rpc_registrar.go b/universe_rpc_registrar.go index 477e2c49b..c0e20844d 100644 --- a/universe_rpc_registrar.go +++ b/universe_rpc_registrar.go @@ -194,8 +194,8 @@ func ConnectUniverse( rawConn, err := grpc.Dial(uniAddr.String(), opts...) if err != nil { - return nil, fmt.Errorf("unable to connect to RPC "+ - "server: %v", err) + return nil, fmt.Errorf("unable to connect to RPC server: "+ + "%w", err) } return &universeClientConn{ From f00697f19caa3095e0880c4422199fb74274170d Mon Sep 17 00:00:00 2001 From: ffranr Date: Fri, 23 Feb 2024 14:41:38 +0000 Subject: [PATCH 3/3] multi: fix multi error `fmt.Errorf` wrapping misuse --- proof/verifier.go | 2 +- tapgarden/caretaker.go | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/proof/verifier.go b/proof/verifier.go index c7cc6e081..b3f914c80 100644 --- a/proof/verifier.go +++ b/proof/verifier.go @@ -356,7 +356,7 @@ func (p *Proof) verifyGenesisGroupKey(groupVerifier GroupVerifier) error { groupKey := p.Asset.GroupKey.GroupPubKey err := groupVerifier(&groupKey) if err != nil { - return fmt.Errorf("%w: %v", ErrGroupKeyUnknown, err) + return fmt.Errorf("%w: %s", ErrGroupKeyUnknown, err.Error()) } return nil diff --git a/tapgarden/caretaker.go b/tapgarden/caretaker.go index cafa5569e..b9f6d2db9 100644 --- a/tapgarden/caretaker.go +++ b/tapgarden/caretaker.go @@ -1417,8 +1417,9 @@ func GenGroupVerifier(ctx context.Context, // tweaked group key. _, err = mintingStore.FetchGroupByGroupKey(ctx, groupKey) if err != nil { - return fmt.Errorf("%x: group verifier: %v: %w", - assetGroupKey[:], err, ErrGroupKeyUnknown) + return fmt.Errorf("%x: group verifier: %s: %w", + assetGroupKey[:], err.Error(), + ErrGroupKeyUnknown) } _, _ = assetGroups.Put(assetGroupKey, emptyCacheVal{})