diff --git a/.golangci.yml b/.golangci.yml index e3e2a03..d640b34 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -17,8 +17,13 @@ linters-settings: linters: enable-all: true disable: - # Init functions are used by loggers throughout the codebase. - - gochecknoinits - - # Global variables are used by loggers. - gochecknoglobals + - gosec + - funlen + - maligned + +issues: + exclude-rules: + - path: cmd/chantools + linters: + - lll \ No newline at end of file diff --git a/btc/explorer_api.go b/btc/explorer_api.go index 8076a80..7cb0f05 100644 --- a/btc/explorer_api.go +++ b/btc/explorer_api.go @@ -13,8 +13,8 @@ var ( ErrTxNotFound = errors.New("transaction not found") ) -type ExplorerApi struct { - BaseUrl string +type ExplorerAPI struct { + BaseURL string } type TX struct { @@ -51,15 +51,15 @@ type Status struct { BlockHash string `json:"block_hash"` } -func (a *ExplorerApi) Transaction(txid string) (*TX, error) { +func (a *ExplorerAPI) Transaction(txid string) (*TX, error) { tx := &TX{} - err := fetchJSON(fmt.Sprintf("%s/tx/%s", a.BaseUrl, txid), tx) + err := fetchJSON(fmt.Sprintf("%s/tx/%s", a.BaseURL, txid), tx) if err != nil { return nil, err } for idx, vout := range tx.Vout { url := fmt.Sprintf( - "%s/tx/%s/outspend/%d", a.BaseUrl, txid, idx, + "%s/tx/%s/outspend/%d", a.BaseURL, txid, idx, ) outspend := Outspend{} err := fetchJSON(url, &outspend) @@ -71,12 +71,13 @@ func (a *ExplorerApi) Transaction(txid string) (*TX, error) { return tx, nil } -func (a *ExplorerApi) PublishTx(rawTxHex string) (string, error) { - url := fmt.Sprintf("%s/tx", a.BaseUrl) +func (a *ExplorerAPI) PublishTx(rawTxHex string) (string, error) { + url := fmt.Sprintf("%s/tx", a.BaseURL) resp, err := http.Post(url, "text/plain", strings.NewReader(rawTxHex)) if err != nil { return "", err } + defer resp.Body.Close() body := new(bytes.Buffer) _, err = body.ReadFrom(resp.Body) if err != nil { @@ -99,7 +100,7 @@ func fetchJSON(url string, target interface{}) error { } err = json.Unmarshal(body.Bytes(), target) if err != nil { - if string(body.Bytes()) == "Transaction not found" { + if body.String() == "Transaction not found" { return ErrTxNotFound } } diff --git a/cmd/chantools/derivekey.go b/cmd/chantools/derivekey.go index 1df66d2..7a2d063 100644 --- a/cmd/chantools/derivekey.go +++ b/cmd/chantools/derivekey.go @@ -19,9 +19,9 @@ func (c *deriveKeyCommand) Execute(_ []string) error { var ( extendedKey *hdkeychain.ExtendedKey - err error + err error ) - + // Check that root key is valid or fall back to console input. switch { case c.RootKey != "": diff --git a/cmd/chantools/dumpbackup.go b/cmd/chantools/dumpbackup.go index ac5d142..ea505c7 100644 --- a/cmd/chantools/dumpbackup.go +++ b/cmd/chantools/dumpbackup.go @@ -20,7 +20,7 @@ func (c *dumpBackupCommand) Execute(_ []string) error { var ( extendedKey *hdkeychain.ExtendedKey - err error + err error ) // Check that root key is valid or fall back to console input. diff --git a/cmd/chantools/forceclose.go b/cmd/chantools/forceclose.go index 2179fec..5204de9 100644 --- a/cmd/chantools/forceclose.go +++ b/cmd/chantools/forceclose.go @@ -27,7 +27,7 @@ type forceCloseCommand struct { func (c *forceCloseCommand) Execute(_ []string) error { var ( extendedKey *hdkeychain.ExtendedKey - err error + err error ) // Check that root key is valid or fall back to console input. @@ -67,7 +67,7 @@ func forceCloseChannels(extendedKey *hdkeychain.ExtendedKey, if err != nil { return err } - chainApi := &btc.ExplorerApi{BaseUrl: cfg.ApiUrl} + api := &btc.ExplorerAPI{BaseURL: cfg.APIURL} signer := &btc.Signer{ExtendedKey: extendedKey} // Go through all channels in the DB, find the still open ones and @@ -170,7 +170,7 @@ func forceCloseChannels(extendedKey *hdkeychain.ExtendedKey, // Publish TX. if publish { - response, err := chainApi.PublishTx(serialized) + response, err := api.PublishTx(serialized) if err != nil { return err } diff --git a/cmd/chantools/main.go b/cmd/chantools/main.go index 82773c3..6466b8b 100644 --- a/cmd/chantools/main.go +++ b/cmd/chantools/main.go @@ -5,28 +5,28 @@ import ( "bytes" "encoding/json" "fmt" - "github.com/btcsuite/btcutil/hdkeychain" - "github.com/lightningnetwork/lnd/aezeed" - "golang.org/x/crypto/ssh/terminal" "io/ioutil" "os" "strings" "syscall" "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcutil/hdkeychain" "github.com/guggero/chantools/dataformat" "github.com/jessevdk/go-flags" + "github.com/lightningnetwork/lnd/aezeed" "github.com/lightningnetwork/lnd/build" "github.com/lightningnetwork/lnd/channeldb" + "golang.org/x/crypto/ssh/terminal" ) const ( - defaultApiUrl = "https://blockstream.info/api" + defaultAPIURL = "https://blockstream.info/api" ) type config struct { Testnet bool `long:"testnet" description:"Set to true if testnet parameters should be used."` - ApiUrl string `long:"apiurl" description:"API URL to use (must be esplora compatible)."` + APIURL string `long:"apiurl" description:"API URL to use (must be esplora compatible)."` ListChannels string `long:"listchannels" description:"The channel input is in the format of lncli's listchannels format. Specify '-' to read from stdin."` PendingChannels string `long:"pendingchannels" description:"The channel input is in the format of lncli's pendingchannels format. Specify '-' to read from stdin."` FromSummary string `long:"fromsummary" description:"The channel input is in the format of this tool's channel summary. Specify '-' to read from stdin."` @@ -37,7 +37,7 @@ var ( logWriter = build.NewRotatingLogWriter() log = build.NewSubLogger("CHAN", logWriter.GenSubLogger) cfg = &config{ - ApiUrl: defaultApiUrl, + APIURL: defaultAPIURL, } chainParams = &chaincfg.MainNetParams ) @@ -184,7 +184,7 @@ func rootKeyFromConsole() (*hdkeychain.ExtendedKey, error) { } var mnemonic aezeed.Mnemonic - copy(mnemonic[:], cipherSeedMnemonic[:]) + copy(mnemonic[:], cipherSeedMnemonic) // If we're unable to map it back into the ciphertext, then either the // mnemonic is wrong, or the passphrase is wrong. diff --git a/cmd/chantools/rescueclosed.go b/cmd/chantools/rescueclosed.go index 43e881a..7b50d56 100644 --- a/cmd/chantools/rescueclosed.go +++ b/cmd/chantools/rescueclosed.go @@ -39,7 +39,7 @@ type rescueClosedCommand struct { func (c *rescueClosedCommand) Execute(_ []string) error { var ( extendedKey *hdkeychain.ExtendedKey - err error + err error ) // Check that root key is valid or fall back to console input. @@ -169,7 +169,7 @@ func addrInCache(addr string, perCommitPoint *btcec.PublicKey) (string, error) { tweakedPubKey.SerializeCompressed(), ) equal := subtle.ConstantTimeCompare( - targetPubKeyHash[:], hashedPubKey[:], + targetPubKeyHash, hashedPubKey, ) if equal == 1 { wif, err := btcutil.NewWIF( diff --git a/cmd/chantools/summary.go b/cmd/chantools/summary.go index 556e0c7..55c4a51 100644 --- a/cmd/chantools/summary.go +++ b/cmd/chantools/summary.go @@ -18,19 +18,19 @@ func (c *summaryCommand) Execute(_ []string) error { if err != nil { return err } - return summarizeChannels(cfg.ApiUrl, entries) + return summarizeChannels(cfg.APIURL, entries) } -func summarizeChannels(apiUrl string, +func summarizeChannels(apiURL string, channels []*dataformat.SummaryEntry) error { summaryFile := &dataformat.SummaryEntryFile{ Channels: channels, } - chainApi := &btc.ExplorerApi{BaseUrl: apiUrl} + api := &btc.ExplorerAPI{BaseURL: apiURL} for idx, channel := range channels { - tx, err := chainApi.Transaction(channel.FundingTXID) + tx, err := api.Transaction(channel.FundingTXID) if err == btc.ErrTxNotFound { log.Errorf("Funding TX %s not found. Ignoring.", channel.FundingTXID) @@ -52,7 +52,7 @@ func summarizeChannels(apiUrl string, } err := reportOutspend( - chainApi, summaryFile, channel, outspend, + api, summaryFile, channel, outspend, ) if err != nil { log.Errorf("Problem with channel %d (%s): %v.", @@ -104,7 +104,7 @@ func summarizeChannels(apiUrl string, return ioutil.WriteFile(fileName, summaryBytes, 0644) } -func reportOutspend(api *btc.ExplorerApi, +func reportOutspend(api *btc.ExplorerAPI, summaryFile *dataformat.SummaryEntryFile, entry *dataformat.SummaryEntry, os *btc.Outspend) error { @@ -150,7 +150,7 @@ func reportOutspend(api *btc.ExplorerApi, // Could maybe be brute forced. if len(utxo) == 1 && utxo[0].ScriptPubkeyType == "v0_p2wpkh" && - utxo[0].Outspend.Spent == false { + !utxo[0].Outspend.Spent { entry.ClosingTX.OurAddr = utxo[0].ScriptPubkeyAddr } diff --git a/cmd/chantools/sweeptimelock.go b/cmd/chantools/sweeptimelock.go index 28bfaaa..aa4ab88 100644 --- a/cmd/chantools/sweeptimelock.go +++ b/cmd/chantools/sweeptimelock.go @@ -29,7 +29,7 @@ type sweepTimeLockCommand struct { func (c *sweepTimeLockCommand) Execute(_ []string) error { var ( extendedKey *hdkeychain.ExtendedKey - err error + err error ) // Check that root key is valid or fall back to console input. @@ -60,12 +60,12 @@ func (c *sweepTimeLockCommand) Execute(_ []string) error { c.MaxCsvLimit = 2000 } return sweepTimeLock( - extendedKey, cfg.ApiUrl, entries, c.SweepAddr, c.MaxCsvLimit, + extendedKey, cfg.APIURL, entries, c.SweepAddr, c.MaxCsvLimit, c.Publish, ) } -func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiUrl string, +func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiURL string, entries []*dataformat.SummaryEntry, sweepAddr string, maxCsvTimeout int, publish bool) error { @@ -74,7 +74,7 @@ func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiUrl string, ExtendedKey: extendedKey, ChainParams: chainParams, } - chainApi := &btc.ExplorerApi{BaseUrl: apiUrl} + api := &btc.ExplorerAPI{BaseURL: apiURL} sweepTx := wire.NewMsgTx(2) totalOutputValue := int64(0) @@ -230,7 +230,7 @@ func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiUrl string, // Publish TX. if publish { - response, err := chainApi.PublishTx( + response, err := api.PublishTx( hex.EncodeToString(buf.Bytes()), ) if err != nil { diff --git a/dataformat/input.go b/dataformat/input.go index fa9fc6b..05adfd3 100644 --- a/dataformat/input.go +++ b/dataformat/input.go @@ -171,7 +171,7 @@ func fundingTXID(chanPoint string) string { func fundingTXIndex(chanPoint string) uint32 { parts := strings.Split(chanPoint, ":") if len(parts) != 2 { - panic(fmt.Errorf("channel point not in format :", + panic(fmt.Errorf("channel point %s not in format :", chanPoint)) } return uint32(parseInt(parts[1]))