5
5
"context"
6
6
"fmt"
7
7
"sync"
8
+ "time"
8
9
10
+ "github.com/bottlepay/lnmux/common"
9
11
"github.com/bottlepay/lnmux/lnd"
10
12
"github.com/bottlepay/lnmux/types"
11
13
"github.com/btcsuite/btcd/chaincfg"
@@ -30,6 +32,8 @@ type Mux struct {
30
32
routingPolicy RoutingPolicy
31
33
32
34
virtualChannel uint64
35
+ muxKey common.PubKey
36
+ nodeKey common.PubKey
33
37
}
34
38
35
39
type MuxConfig struct {
@@ -52,9 +56,7 @@ type RoutingPolicy struct {
52
56
FeeRatePpm int64
53
57
}
54
58
55
- func New (cfg * MuxConfig ) (* Mux ,
56
- error ) {
57
-
59
+ func New (cfg * MuxConfig ) (* Mux , error ) {
58
60
idKeyDesc , err := cfg .KeyRing .DeriveKey (
59
61
keychain.KeyLocator {
60
62
Family : keychain .KeyFamilyNodeKey ,
@@ -67,6 +69,17 @@ func New(cfg *MuxConfig) (*Mux,
67
69
68
70
nodeKeyECDH := keychain .NewPubKeyECDH (idKeyDesc , cfg .KeyRing )
69
71
72
+ muxKubKey , err := cfg .KeyRing .DeriveKey (keychain.KeyLocator {})
73
+ if err != nil {
74
+ return nil , err
75
+ }
76
+ muxKey , err := common .NewPubKeyFromBytes (
77
+ muxKubKey .PubKey .SerializeCompressed (),
78
+ )
79
+ if err != nil {
80
+ return nil , err
81
+ }
82
+
70
83
replayLog := & replayLog {}
71
84
72
85
sphinxRouter := sphinx .NewRouter (
@@ -88,6 +101,8 @@ func New(cfg *MuxConfig) (*Mux,
88
101
settledHandler : cfg .SettledHandler ,
89
102
routingPolicy : cfg .RoutingPolicy ,
90
103
virtualChannel : virtualChannel ,
104
+ muxKey : muxKey ,
105
+ nodeKey : cfg .Lnd .PubKey (),
91
106
}, nil
92
107
}
93
108
@@ -105,10 +120,11 @@ type interceptedHtlc struct {
105
120
}
106
121
107
122
type interceptedHtlcResponse struct {
108
- action routerrpc.ResolveHoldForwardAction
109
- preimage lntypes.Preimage
110
- failureMessage []byte
111
- failureCode lnrpc.Failure_FailureCode
123
+ action routerrpc.ResolveHoldForwardAction
124
+ preimage lntypes.Preimage
125
+ failureMessage []byte
126
+ failureCode lnrpc.Failure_FailureCode
127
+ failureMessageUnencrypted bool
112
128
}
113
129
114
130
func (p * Mux ) Run (mainCtx context.Context ) error {
@@ -221,6 +237,35 @@ func (p *Mux) ProcessHtlc(
221
237
fail := func (code lnwire.FailCode ) error {
222
238
logger .Debugw ("Failing htlc" , "code" , code )
223
239
240
+ if code == lnwire .CodeFeeInsufficient {
241
+ var channelFlags lnwire.ChanUpdateChanFlags
242
+
243
+ if bytes .Compare (p .muxKey [:], p .nodeKey [:]) == 1 {
244
+ channelFlags |= lnwire .ChanUpdateDirection
245
+ }
246
+
247
+ wireMsg := lnwire .NewFeeInsufficient (0 , lnwire.ChannelUpdate {
248
+ ChainHash : * p .lnd .Network ().GenesisHash ,
249
+ ShortChannelID : lnwire .NewShortChanIDFromInt (p .virtualChannel ),
250
+ Timestamp : uint32 (time .Now ().Unix ()),
251
+ ChannelFlags : channelFlags ,
252
+ TimeLockDelta : uint16 (p .routingPolicy .CltvDelta ),
253
+ BaseFee : uint32 (p .routingPolicy .FeeBaseMsat ),
254
+ FeeRate : uint32 (p .routingPolicy .FeeRatePpm ),
255
+ })
256
+ var w bytes.Buffer
257
+ err := lnwire .EncodeFailureMessage (& w , wireMsg , 0 )
258
+ if err != nil {
259
+ return err
260
+ }
261
+
262
+ return htlc .reply (& interceptedHtlcResponse {
263
+ action : routerrpc .ResolveHoldForwardAction_FAIL ,
264
+ failureMessage : w .Bytes (),
265
+ failureMessageUnencrypted : true ,
266
+ })
267
+ }
268
+
224
269
rpcCode , err := marshallFailureCode (code )
225
270
if err != nil {
226
271
return err
0 commit comments