• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 13211764208

08 Feb 2025 03:08AM UTC coverage: 49.288% (-9.5%) from 58.815%
13211764208

Pull #9489

github

calvinrzachman
itest: verify switchrpc server enforces send then track

We prevent the rpc server from allowing onion dispatches for
attempt IDs which have already been tracked by rpc clients.

This helps protect the client from leaking a duplicate onion
attempt. NOTE: This is not the only method for solving this
issue! The issue could be addressed via careful client side
programming which accounts for the uncertainty and async
nature of dispatching onions to a remote process via RPC.
This would require some lnd ChannelRouter changes for how
we intend to use these RPCs though.
Pull Request #9489: multi: add BuildOnion, SendOnion, and TrackOnion RPCs

474 of 990 new or added lines in 11 files covered. (47.88%)

27321 existing lines in 435 files now uncovered.

101192 of 205306 relevant lines covered (49.29%)

1.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/watchtower/wtdb/migration5/client_db.go
1
package migration5
2

3
import (
4
        "encoding/binary"
5
        "errors"
6

7
        "github.com/lightningnetwork/lnd/kvdb"
8
)
9

10
var (
11
        // cTowerBkt is a top-level bucket storing:
12
        //    tower-id -> encoded Tower.
13
        cTowerBkt = []byte("client-tower-bucket")
14

15
        // cTowerIDToSessionIDIndexBkt is a top-level bucket storing:
16
        //         tower-id -> session-id -> 1
17
        cTowerIDToSessionIDIndexBkt = []byte(
18
                "client-tower-to-session-index-bucket",
19
        )
20

21
        // ErrUninitializedDB signals that top-level buckets for the database
22
        // have not been initialized.
23
        ErrUninitializedDB = errors.New("db not initialized")
24

25
        // byteOrder is the default endianness used when serializing integers.
26
        byteOrder = binary.BigEndian
27
)
28

29
// MigrateCompleteTowerToSessionIndex ensures that the tower-to-session index
30
// contains entries for all towers in the db. This is necessary because
31
// migration1 only created entries in the index for towers that the client had
32
// at least one session with. This migration thus makes sure that there is
33
// always a tower-to-sessions index entry for a tower even if there are no
34
// sessions with that tower.
UNCOV
35
func MigrateCompleteTowerToSessionIndex(tx kvdb.RwTx) error {
×
UNCOV
36
        log.Infof("Migrating the tower client db to ensure that there is an " +
×
UNCOV
37
                "entry in the towerID-to-sessionID index for every tower in " +
×
UNCOV
38
                "the db")
×
UNCOV
39

×
UNCOV
40
        // First, we collect all the towers that we should add an entry for in
×
UNCOV
41
        // the index.
×
UNCOV
42
        towerIDs, err := listTowerIDs(tx)
×
UNCOV
43
        if err != nil {
×
UNCOV
44
                return err
×
UNCOV
45
        }
×
46

47
        // Create a new top-level bucket for the index if it does not yet exist.
UNCOV
48
        indexBkt, err := tx.CreateTopLevelBucket(cTowerIDToSessionIDIndexBkt)
×
UNCOV
49
        if err != nil {
×
50
                return err
×
51
        }
×
52

53
        // Finally, ensure that there is an entry in the tower-to-session index
54
        // for each of our towers.
UNCOV
55
        for _, id := range towerIDs {
×
UNCOV
56
                // Create a sub-bucket using the tower ID.
×
UNCOV
57
                _, err := indexBkt.CreateBucketIfNotExists(id.Bytes())
×
UNCOV
58
                if err != nil {
×
59
                        return err
×
60
                }
×
61
        }
62

UNCOV
63
        return nil
×
64
}
65

66
// listTowerIDs iterates through the cTowerBkt and collects a list of all the
67
// TowerIDs.
UNCOV
68
func listTowerIDs(tx kvdb.RTx) ([]*TowerID, error) {
×
UNCOV
69
        var ids []*TowerID
×
UNCOV
70
        towerBucket := tx.ReadBucket(cTowerBkt)
×
UNCOV
71
        if towerBucket == nil {
×
72
                return nil, ErrUninitializedDB
×
73
        }
×
74

UNCOV
75
        err := towerBucket.ForEach(func(towerIDBytes, _ []byte) error {
×
UNCOV
76
                id, err := TowerIDFromBytes(towerIDBytes)
×
UNCOV
77
                if err != nil {
×
UNCOV
78
                        return err
×
UNCOV
79
                }
×
80

UNCOV
81
                ids = append(ids, &id)
×
UNCOV
82

×
UNCOV
83
                return nil
×
84
        })
UNCOV
85
        if err != nil {
×
UNCOV
86
                return nil, err
×
UNCOV
87
        }
×
88

UNCOV
89
        return ids, nil
×
90
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc