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

lightningnetwork / lnd / 13035292482

29 Jan 2025 03:59PM UTC coverage: 49.3% (-9.5%) from 58.777%
13035292482

Pull #9456

github

mohamedawnallah
docs: update release-notes-0.19.0.md

In this commit, we warn users about the removal
of RPCs `SendToRoute`, `SendToRouteSync`, `SendPayment`,
and `SendPaymentSync` in the next release 0.20.
Pull Request #9456: lnrpc+docs: deprecate warning `SendToRoute`, `SendToRouteSync`, `SendPayment`, and `SendPaymentSync` in Release 0.19

100634 of 204126 relevant lines covered (49.3%)

1.54 hits per line

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

68.94
/chanbackup/backupfile.go
1
package chanbackup
2

3
import (
4
        "fmt"
5
        "os"
6
        "path/filepath"
7

8
        "github.com/lightningnetwork/lnd/keychain"
9
)
10

11
const (
12
        // DefaultBackupFileName is the default name of the auto updated static
13
        // channel backup fie.
14
        DefaultBackupFileName = "channel.backup"
15

16
        // DefaultTempBackupFileName is the default name of the temporary SCB
17
        // file that we'll use to atomically update the primary back up file
18
        // when new channel are detected.
19
        DefaultTempBackupFileName = "temp-dont-use.backup"
20
)
21

22
var (
23
        // ErrNoBackupFileExists is returned if caller attempts to call
24
        // UpdateAndSwap with the file name not set.
25
        ErrNoBackupFileExists = fmt.Errorf("back up file name not set")
26

27
        // ErrNoTempBackupFile is returned if caller attempts to call
28
        // UpdateAndSwap with the temp back up file name not set.
29
        ErrNoTempBackupFile = fmt.Errorf("temp backup file not set")
30
)
31

32
// MultiFile represents a file on disk that a caller can use to read the packed
33
// multi backup into an unpacked one, and also atomically update the contents
34
// on disk once new channels have been opened, and old ones closed. This struct
35
// relies on an atomic file rename property which most widely use file systems
36
// have.
37
type MultiFile struct {
38
        // fileName is the file name of the main back up file.
39
        fileName string
40

41
        // tempFileName is the name of the file that we'll use to stage a new
42
        // packed multi-chan backup, and the rename to the main back up file.
43
        tempFileName string
44

45
        // tempFile is an open handle to the temp back up file.
46
        tempFile *os.File
47
}
48

49
// NewMultiFile create a new multi-file instance at the target location on the
50
// file system.
51
func NewMultiFile(fileName string) *MultiFile {
52

53
        // We'll our temporary backup file in the very same directory as the
54
        // main backup file.
55
        backupFileDir := filepath.Dir(fileName)
56
        tempFileName := filepath.Join(
57
                backupFileDir, DefaultTempBackupFileName,
58
        )
59

60
        return &MultiFile{
61
                fileName:     fileName,
62
                tempFileName: tempFileName,
63
        }
64
}
65

3✔
66
// UpdateAndSwap will attempt write a new temporary backup file to disk with
3✔
67
// the newBackup encoded, then atomically swap (via rename) the old file for
3✔
68
// the new file by updating the name of the new file to the old.
3✔
69
func (b *MultiFile) UpdateAndSwap(newBackup PackedMulti) error {
3✔
70
        // If the main backup file isn't set, then we can't proceed.
3✔
71
        if b.fileName == "" {
3✔
72
                return ErrNoBackupFileExists
3✔
73
        }
3✔
74

3✔
75
        log.Infof("Updating backup file at %v", b.fileName)
3✔
76

3✔
77
        // If the old back up file still exists, then we'll delete it before
3✔
78
        // proceeding.
3✔
79
        if _, err := os.Stat(b.tempFileName); err == nil {
3✔
80
                log.Infof("Found old temp backup @ %v, removing before swap",
3✔
81
                        b.tempFileName)
3✔
82

3✔
83
                err = os.Remove(b.tempFileName)
84
                if err != nil {
85
                        return fmt.Errorf("unable to remove temp "+
86
                                "backup file: %v", err)
87
                }
88
        }
3✔
89

3✔
90
        // Now that we know the staging area is clear, we'll create the new
3✔
91
        // temporary back up file.
×
92
        var err error
×
93
        b.tempFile, err = os.Create(b.tempFileName)
94
        if err != nil {
3✔
95
                return fmt.Errorf("unable to create temp file: %w", err)
3✔
96
        }
3✔
97

3✔
98
        // With the file created, we'll write the new packed multi backup and
3✔
99
        // remove the temporary file all together once this method exits.
×
100
        _, err = b.tempFile.Write([]byte(newBackup))
×
101
        if err != nil {
×
102
                return fmt.Errorf("unable to write backup to temp file: %w",
×
103
                        err)
×
104
        }
×
105
        if err := b.tempFile.Sync(); err != nil {
×
106
                return fmt.Errorf("unable to sync temp file: %w", err)
×
107
        }
108
        defer os.Remove(b.tempFileName)
109

110
        log.Infof("Swapping old multi backup file from %v to %v",
111
                b.tempFileName, b.fileName)
3✔
112

3✔
113
        // Before we rename the swap (atomic name swap), we'll make
6✔
114
        // sure to close the current file as some OSes don't support
3✔
115
        // renaming a file that's already open (Windows).
3✔
116
        if err := b.tempFile.Close(); err != nil {
117
                return fmt.Errorf("unable to close file: %w", err)
118
        }
119

3✔
120
        // Finally, we'll attempt to atomically rename the temporary file to
3✔
121
        // the main back up file. If this succeeds, then we'll only have a
×
122
        // single file on disk once this method exits.
×
123
        return os.Rename(b.tempFileName, b.fileName)
×
124
}
3✔
125

×
126
// ExtractMulti attempts to extract the packed multi backup we currently point
×
127
// to into an unpacked version. This method will fail if no backup file
3✔
128
// currently exists as the specified location.
3✔
129
func (b *MultiFile) ExtractMulti(keyChain keychain.KeyRing) (*Multi, error) {
3✔
130
        var err error
3✔
131

3✔
132
        // We'll return an error if the main file isn't currently set.
3✔
133
        if b.fileName == "" {
3✔
134
                return nil, ErrNoBackupFileExists
3✔
135
        }
3✔
136

×
137
        // Now that we've confirmed the target file is populated, we'll read
×
138
        // all the contents of the file. This function ensures that file is
139
        // always closed, even if we can't read the contents.
140
        multiBytes, err := os.ReadFile(b.fileName)
3✔
141
        if err != nil {
×
142
                return nil, err
×
143
        }
×
144

145
        // Finally, we'll attempt to unpack the file and return the unpack
146
        // version to the caller.
147
        packedMulti := PackedMulti(multiBytes)
148
        return packedMulti.Unpack(keyChain)
3✔
149
}
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