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

lightningnetwork / lnd / 12199391122

06 Dec 2024 01:10PM UTC coverage: 49.807% (-9.1%) from 58.933%
12199391122

push

github

web-flow
Merge pull request #9337 from Guayaba221/patch-1

chore: fix typo in ruby.md

100137 of 201051 relevant lines covered (49.81%)

2.07 hits per line

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

66.32
/watchtower/wtserver/state_update.go
1
package wtserver
2

3
import (
4
        "fmt"
5

6
        "github.com/lightningnetwork/lnd/watchtower/wtdb"
7
        "github.com/lightningnetwork/lnd/watchtower/wtwire"
8
)
9

10
// handleStateUpdates processes a stream of StateUpdate requests from the
11
// client. The provided update should be the first such update read, subsequent
12
// updates will be consumed if the peer does not signal IsComplete on a
13
// particular update.
14
func (s *Server) handleStateUpdates(peer Peer, id *wtdb.SessionID,
15
        update *wtwire.StateUpdate) error {
4✔
16

4✔
17
        // Set the current update to the first update read off the wire.
4✔
18
        // Additional updates will be read if this value is set to nil after
4✔
19
        // processing the first.
4✔
20
        var curUpdate = update
4✔
21
        for {
8✔
22
                // If this is not the first update, read the next state update
4✔
23
                // from the peer.
4✔
24
                if curUpdate == nil {
8✔
25
                        nextMsg, err := s.readMessage(peer)
4✔
26
                        if err != nil {
4✔
27
                                return err
×
28
                        }
×
29

30
                        var ok bool
4✔
31
                        curUpdate, ok = nextMsg.(*wtwire.StateUpdate)
4✔
32
                        if !ok {
4✔
33
                                return fmt.Errorf("client sent %T after "+
×
34
                                        "StateUpdate", nextMsg)
×
35
                        }
×
36
                }
37

38
                // Try to accept the state update from the client.
39
                err := s.handleStateUpdate(peer, id, curUpdate)
4✔
40
                if err != nil {
4✔
41
                        return err
×
42
                }
×
43

44
                // If the client signals that this is last StateUpdate
45
                // message, we can disconnect the client.
46
                if curUpdate.IsComplete == 1 {
8✔
47
                        return nil
4✔
48
                }
4✔
49

50
                // Reset the current update to read subsequent updates in the
51
                // stream.
52
                curUpdate = nil
4✔
53

4✔
54
                select {
4✔
55
                case <-s.quit:
×
56
                        return ErrServerExiting
×
57
                default:
4✔
58
                }
59
        }
60
}
61

62
// handleStateUpdate processes a StateUpdate message request from a client. An
63
// attempt will be made to insert the update into the db, where it is validated
64
// against the client's session. The possible errors are then mapped back to
65
// StateUpdateCodes specified by the watchtower wire protocol, and sent back
66
// using a StateUpdateReply message.
67
func (s *Server) handleStateUpdate(peer Peer, id *wtdb.SessionID,
68
        update *wtwire.StateUpdate) error {
4✔
69

4✔
70
        var (
4✔
71
                lastApplied uint16
4✔
72
                failCode    wtwire.ErrorCode
4✔
73
                err         error
4✔
74
        )
4✔
75

4✔
76
        sessionUpdate := wtdb.SessionStateUpdate{
4✔
77
                ID:            *id,
4✔
78
                Hint:          update.Hint,
4✔
79
                SeqNum:        update.SeqNum,
4✔
80
                LastApplied:   update.LastApplied,
4✔
81
                EncryptedBlob: update.EncryptedBlob,
4✔
82
        }
4✔
83

4✔
84
        lastApplied, err = s.cfg.DB.InsertStateUpdate(&sessionUpdate)
4✔
85
        switch {
4✔
86
        case err == nil:
4✔
87
                log.Debugf("State update %d accepted for %s",
4✔
88
                        update.SeqNum, id)
4✔
89

4✔
90
                failCode = wtwire.CodeOK
4✔
91

92
        // Return a permanent failure if a client tries to send an update for
93
        // which we have no session.
94
        case err == wtdb.ErrSessionNotFound:
×
95
                failCode = wtwire.CodePermanentFailure
×
96

97
        case err == wtdb.ErrSeqNumAlreadyApplied:
×
98
                failCode = wtwire.CodePermanentFailure
×
99

100
                // TODO(conner): remove session state for protocol
101
                // violation. Could also double as clean up method for
102
                // session-related state.
103

104
        case err == wtdb.ErrLastAppliedReversion:
×
105
                failCode = wtwire.StateUpdateCodeClientBehind
×
106

107
        case err == wtdb.ErrSessionConsumed:
×
108
                failCode = wtwire.StateUpdateCodeMaxUpdatesExceeded
×
109

110
        case err == wtdb.ErrUpdateOutOfOrder:
×
111
                failCode = wtwire.StateUpdateCodeSeqNumOutOfOrder
×
112

113
        default:
×
114
                failCode = wtwire.CodeTemporaryFailure
×
115
        }
116

117
        if s.cfg.NoAckUpdates {
4✔
118
                return &connFailure{
×
119
                        ID:   *id,
×
120
                        Code: failCode,
×
121
                }
×
122
        }
×
123

124
        return s.replyStateUpdate(
4✔
125
                peer, id, failCode, lastApplied,
4✔
126
        )
4✔
127
}
128

129
// replyStateUpdate sends a response to a StateUpdate from a client. If the
130
// status code in the reply is OK, the error from the write will be bubbled up.
131
// Otherwise, this method returns a connection error to ensure we don't continue
132
// communication with the client.
133
func (s *Server) replyStateUpdate(peer Peer, id *wtdb.SessionID,
134
        code wtwire.StateUpdateCode, lastApplied uint16) error {
4✔
135

4✔
136
        msg := &wtwire.StateUpdateReply{
4✔
137
                Code:        code,
4✔
138
                LastApplied: lastApplied,
4✔
139
        }
4✔
140

4✔
141
        err := s.sendMessage(peer, msg)
4✔
142
        if err != nil {
4✔
143
                log.Errorf("unable to send StateUpdateReply to %s", id)
×
144
        }
×
145

146
        // Return the write error if the request succeeded.
147
        if code == wtwire.CodeOK {
8✔
148
                return err
4✔
149
        }
4✔
150

151
        // Otherwise the request failed, return a connection failure to
152
        // disconnect the client.
153
        return &connFailure{
×
154
                ID:   *id,
×
155
                Code: code,
×
156
        }
×
157
}
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