Skip to content

Commit 3a0bb3a

Browse files
authored
Merge pull request #146 from lightninglabs/rescueclosed
rescueclosed: make number of keys configurable
2 parents 3c04692 + 133cf7b commit 3a0bb3a

File tree

9 files changed

+59
-45
lines changed

9 files changed

+59
-45
lines changed

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@ ifneq ($(sys),)
3535
BUILD_SYSTEM = $(sys)
3636
endif
3737

38-
DOCKER_TOOLS = docker run -v $$(pwd):/build chantools-tools
38+
DOCKER_TOOLS = docker run \
39+
--rm \
40+
-v $(shell bash -c "go env GOCACHE || (mkdir -p /tmp/go-cache; echo /tmp/go-cache)"):/tmp/build/.cache \
41+
-v $(shell bash -c "go env GOMODCACHE || (mkdir -p /tmp/go-modcache; echo /tmp/go-modcache)"):/tmp/build/.modcache \
42+
-v $(shell bash -c "mkdir -p /tmp/go-lint-cache; echo /tmp/go-lint-cache"):/root/.cache/golangci-lint \
43+
-v $$(pwd):/build chantools-tools
3944

4045
TEST_FLAGS = -test.timeout=20m
4146

btc/explorer_api.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,10 @@ func (a *ExplorerAPI) Unspent(addr string) ([]*Vout, error) {
168168
// Now filter those that are really unspent, because above we get all
169169
// outputs that are sent to the address.
170170
var unspent []*Vout
171-
for idx, vout := range outputs {
171+
for _, vout := range outputs {
172172
url := fmt.Sprintf(
173173
"%s/tx/%s/outspend/%d", a.BaseURL, vout.Outspend.Txid,
174-
idx,
174+
vout.Outspend.Vin,
175175
)
176176
outspend := Outspend{}
177177
err := fetchJSON(url, &outspend)

cmd/chantools/fakechanbackup.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import (
55
"encoding/hex"
66
"errors"
77
"fmt"
8-
"io/ioutil"
98
"net"
9+
"os"
1010
"strconv"
1111
"strings"
1212
"time"
@@ -133,7 +133,7 @@ func (c *fakeChanBackupCommand) Execute(_ *cobra.Command, _ []string) error {
133133
}
134134

135135
if c.FromChannelGraph != "" {
136-
graphBytes, err := ioutil.ReadFile(c.FromChannelGraph)
136+
graphBytes, err := os.ReadFile(c.FromChannelGraph)
137137
if err != nil {
138138
return fmt.Errorf("error reading graph JSON file %s: "+
139139
"%v", c.FromChannelGraph, err)

cmd/chantools/forceclose.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"errors"
88
"fmt"
99
"io"
10-
"io/ioutil"
10+
"os"
1111
"time"
1212

1313
"github.com/btcsuite/btcd/btcutil/hdkeychain"
@@ -230,5 +230,5 @@ func forceCloseChannels(apiURL string, extendedKey *hdkeychain.ExtendedKey,
230230
fileName := fmt.Sprintf("results/forceclose-%s.json",
231231
time.Now().Format("2006-01-02-15-04-05"))
232232
log.Infof("Writing result to %s", fileName)
233-
return ioutil.WriteFile(fileName, summaryBytes, 0644)
233+
return os.WriteFile(fileName, summaryBytes, 0644)
234234
}

cmd/chantools/rescueclosed.go

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"encoding/json"
77
"errors"
88
"fmt"
9-
"io/ioutil"
9+
"os"
1010
"regexp"
1111
"time"
1212

@@ -22,8 +22,8 @@ import (
2222
)
2323

2424
var (
25-
cacheSize = 5000
26-
cache []*cacheEntry
25+
defaultNumKeys uint32 = 5000
26+
cache []*cacheEntry
2727

2828
errAddrNotFound = errors.New("addr not found")
2929

@@ -40,6 +40,7 @@ type rescueClosedCommand struct {
4040
Addr string
4141
CommitPoint string
4242
LndLog string
43+
NumKeys uint32
4344

4445
rootKey *rootKey
4546
inputs *inputFlags
@@ -103,7 +104,12 @@ chantools rescueclosed --fromsummary results/summary-xxxxxx.json \
103104
cc.cmd.Flags().StringVar(
104105
&cc.LndLog, "lnd_log", "", "the lnd log file to read to get "+
105106
"the commit_point values when rescuing multiple "+
106-
"channels at the same time")
107+
"channels at the same time",
108+
)
109+
cc.cmd.Flags().Uint32Var(
110+
&cc.NumKeys, "num_keys", defaultNumKeys, "the number of keys "+
111+
"to derive for the brute force attack",
112+
)
107113
cc.rootKey = newRootKey(cc.cmd, "decrypting the backup")
108114
cc.inputs = newInputFlags(cc.cmd)
109115

@@ -136,7 +142,9 @@ func (c *rescueClosedCommand) Execute(_ *cobra.Command, _ []string) error {
136142
return fmt.Errorf("error reading commit points from "+
137143
"db: %w", err)
138144
}
139-
return rescueClosedChannels(extendedKey, entries, commitPoints)
145+
return rescueClosedChannels(
146+
c.NumKeys, extendedKey, entries, commitPoints,
147+
)
140148

141149
case c.Addr != "":
142150
// First parse address to get targetPubKeyHash from it later.
@@ -156,7 +164,9 @@ func (c *rescueClosedCommand) Execute(_ *cobra.Command, _ []string) error {
156164
return fmt.Errorf("error parsing commit point: %w", err)
157165
}
158166

159-
return rescueClosedChannel(extendedKey, targetAddr, commitPoint)
167+
return rescueClosedChannel(
168+
c.NumKeys, extendedKey, targetAddr, commitPoint,
169+
)
160170

161171
case c.LndLog != "":
162172
// Parse channel entries from any of the possible input files.
@@ -170,7 +180,9 @@ func (c *rescueClosedCommand) Execute(_ *cobra.Command, _ []string) error {
170180
return fmt.Errorf("error parsing commit points from "+
171181
"log file: %w", err)
172182
}
173-
return rescueClosedChannels(extendedKey, entries, commitPoints)
183+
return rescueClosedChannels(
184+
c.NumKeys, extendedKey, entries, commitPoints,
185+
)
174186

175187
default:
176188
return errors.New("you either need to specify --channeldb and " +
@@ -204,7 +216,7 @@ func commitPointsFromDB(chanDb *channeldb.ChannelStateDB) ([]*btcec.PublicKey,
204216
}
205217

206218
func commitPointsFromLogFile(lndLog string) ([]*btcec.PublicKey, error) {
207-
logFileBytes, err := ioutil.ReadFile(lndLog)
219+
logFileBytes, err := os.ReadFile(lndLog)
208220
if err != nil {
209221
return nil, fmt.Errorf("error reading log file %s: %w", lndLog,
210222
err)
@@ -241,11 +253,11 @@ func commitPointsFromLogFile(lndLog string) ([]*btcec.PublicKey, error) {
241253
return result, nil
242254
}
243255

244-
func rescueClosedChannels(extendedKey *hdkeychain.ExtendedKey,
256+
func rescueClosedChannels(numKeys uint32, extendedKey *hdkeychain.ExtendedKey,
245257
entries []*dataformat.SummaryEntry,
246258
possibleCommitPoints []*btcec.PublicKey) error {
247259

248-
err := fillCache(extendedKey)
260+
err := fillCache(numKeys, extendedKey)
249261
if err != nil {
250262
return err
251263
}
@@ -279,7 +291,7 @@ outer:
279291
addr = entry.ClosingTX.ToRemoteAddr
280292
}
281293

282-
wif, err := addrInCache(addr, commitPoint)
294+
wif, err := addrInCache(numKeys, addr, commitPoint)
283295
switch {
284296
case err == nil:
285297
entry.ClosingTX.SweepPrivkey = wif
@@ -313,10 +325,10 @@ outer:
313325
fileName := fmt.Sprintf("results/rescueclosed-%s.json",
314326
time.Now().Format("2006-01-02-15-04-05"))
315327
log.Infof("Writing result to %s", fileName)
316-
return ioutil.WriteFile(fileName, summaryBytes, 0644)
328+
return os.WriteFile(fileName, summaryBytes, 0644)
317329
}
318330

319-
func rescueClosedChannel(extendedKey *hdkeychain.ExtendedKey,
331+
func rescueClosedChannel(numKeys uint32, extendedKey *hdkeychain.ExtendedKey,
320332
addr btcutil.Address, commitPoint *btcec.PublicKey) error {
321333

322334
// Make the check on the decoded address according to the active
@@ -336,12 +348,12 @@ func rescueClosedChannel(extendedKey *hdkeychain.ExtendedKey,
336348
return errors.New("address: must be a bech32 P2WPKH address")
337349
}
338350

339-
err := fillCache(extendedKey)
351+
err := fillCache(numKeys, extendedKey)
340352
if err != nil {
341353
return err
342354
}
343355

344-
wif, err := addrInCache(addr.String(), commitPoint)
356+
wif, err := addrInCache(numKeys, addr.String(), commitPoint)
345357
switch {
346358
case err == nil:
347359
log.Infof("Found private key %s for address %v!", wif, addr)
@@ -356,7 +368,7 @@ func rescueClosedChannel(extendedKey *hdkeychain.ExtendedKey,
356368
}
357369

358370
// Try again as a static_remote_key address.
359-
wif, err = addrInCache(addr.String(), nil)
371+
wif, err = addrInCache(numKeys, addr.String(), nil)
360372
switch {
361373
case err == nil:
362374
log.Infof("Found private key %s for address %v!", wif, addr)
@@ -372,7 +384,9 @@ func rescueClosedChannel(extendedKey *hdkeychain.ExtendedKey,
372384
}
373385
}
374386

375-
func addrInCache(addr string, perCommitPoint *btcec.PublicKey) (string, error) {
387+
func addrInCache(numKeys uint32, addr string,
388+
perCommitPoint *btcec.PublicKey) (string, error) {
389+
376390
targetPubKeyHash, scriptHash, err := lnd.DecodeAddressHash(
377391
addr, chainParams,
378392
)
@@ -386,7 +400,7 @@ func addrInCache(addr string, perCommitPoint *btcec.PublicKey) (string, error) {
386400
// If the commit point is nil, we try with plain private keys to match
387401
// static_remote_key outputs.
388402
if perCommitPoint == nil {
389-
for i := range cacheSize {
403+
for i := range numKeys {
390404
cacheEntry := cache[i]
391405
hashedPubKey := btcutil.Hash160(
392406
cacheEntry.pubKey.SerializeCompressed(),
@@ -415,7 +429,7 @@ func addrInCache(addr string, perCommitPoint *btcec.PublicKey) (string, error) {
415429
// Loop through all cached payment base point keys, tweak each of it
416430
// with the per_commit_point and see if the hashed public key
417431
// corresponds to the target pubKeyHash of the given address.
418-
for i := range cacheSize {
432+
for i := range numKeys {
419433
cacheEntry := cache[i]
420434
basePoint := cacheEntry.pubKey
421435
tweakedPubKey := input.TweakPubKey(basePoint, perCommitPoint)
@@ -446,17 +460,16 @@ func addrInCache(addr string, perCommitPoint *btcec.PublicKey) (string, error) {
446460
return "", errAddrNotFound
447461
}
448462

449-
func fillCache(extendedKey *hdkeychain.ExtendedKey) error {
450-
cache = make([]*cacheEntry, cacheSize)
463+
func fillCache(numKeys uint32, extendedKey *hdkeychain.ExtendedKey) error {
464+
cache = make([]*cacheEntry, numKeys)
451465

452-
for i := range cacheSize {
466+
for i := range numKeys {
453467
key, err := lnd.DeriveChildren(extendedKey, []uint32{
454468
lnd.HardenedKeyStart + uint32(keychain.BIP0043Purpose),
455469
lnd.HardenedKeyStart + chainParams.HDCoinType,
456-
lnd.HardenedKeyStart +
457-
uint32(keychain.KeyFamilyPaymentBase),
458-
0,
459-
uint32(i),
470+
lnd.HardenedKeyStart + uint32(
471+
keychain.KeyFamilyPaymentBase,
472+
), 0, i,
460473
})
461474
if err != nil {
462475
return err
@@ -476,7 +489,7 @@ func fillCache(extendedKey *hdkeychain.ExtendedKey) error {
476489

477490
if i > 0 && i%10000 == 0 {
478491
fmt.Printf("Filled cache with %d of %d keys.\n",
479-
i, cacheSize)
492+
i, numKeys)
480493
}
481494
}
482495
return nil

cmd/chantools/root.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8-
"io/ioutil"
8+
"io"
99
"os"
1010
"strings"
1111
"time"
@@ -299,9 +299,9 @@ func (f *inputFlags) parseInputType() ([]*dataformat.SummaryEntry, error) {
299299

300300
func readInput(input string) ([]byte, error) {
301301
if strings.TrimSpace(input) == "-" {
302-
return ioutil.ReadAll(os.Stdin)
302+
return io.ReadAll(os.Stdin)
303303
}
304-
return ioutil.ReadFile(input)
304+
return os.ReadFile(input)
305305
}
306306

307307
func setupLogging() {

cmd/chantools/root_test.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package main
33
import (
44
"bytes"
55
"io"
6-
"io/ioutil"
76
"os"
87
"path"
98
"regexp"
@@ -53,14 +52,12 @@ func newHarness(t *testing.T) *harness {
5352

5453
buf := &bytes.Buffer{}
5554
logBackend := btclog.NewBackend(buf)
56-
tempDir, err := ioutil.TempDir("", "chantools")
57-
require.NoError(t, err)
5855

5956
h := &harness{
6057
t: t,
6158
logBuffer: buf,
6259
logger: logBackend.Logger("CHAN"),
63-
tempDir: tempDir,
60+
tempDir: t.TempDir(),
6461
}
6562

6663
h.logger.SetLevel(btclog.LevelTrace)

cmd/chantools/summary.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package main
33
import (
44
"encoding/json"
55
"fmt"
6-
"io/ioutil"
6+
"os"
77
"time"
88

99
"github.com/lightninglabs/chantools/btc"
@@ -88,5 +88,5 @@ func summarizeChannels(apiURL string,
8888
fileName := fmt.Sprintf("results/summary-%s.json",
8989
time.Now().Format("2006-01-02-15-04-05"))
9090
log.Infof("Writing result to %s", fileName)
91-
return ioutil.WriteFile(fileName, summaryBytes, 0644)
91+
return os.WriteFile(fileName, summaryBytes, 0644)
9292
}

cmd/chantools/zombierecovery_preparekeys.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"encoding/json"
77
"errors"
88
"fmt"
9-
"io/ioutil"
109
"os"
1110
"time"
1211

@@ -76,7 +75,7 @@ func (c *zombieRecoveryPrepareKeysCommand) Execute(_ *cobra.Command,
7675
return errors.New("invalid payout address, must be P2WPKH")
7776
}
7877

79-
matchFileBytes, err := ioutil.ReadFile(c.MatchFile)
78+
matchFileBytes, err := os.ReadFile(c.MatchFile)
8079
if err != nil {
8180
return fmt.Errorf("error reading match file %s: %w",
8281
c.MatchFile, err)

0 commit comments

Comments
 (0)