Skip to content

Commit e49f6fc

Browse files
authored
Merge pull request #7648 from guggero/initial-forwarding-policy
funding: fix flake in itest caused by persistent fee param changes
2 parents 4a03074 + 6820b08 commit e49f6fc

File tree

16 files changed

+503
-449
lines changed

16 files changed

+503
-449
lines changed

chainreg/chainregistry.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525
"github.com/lightningnetwork/lnd/chainntnfs/btcdnotify"
2626
"github.com/lightningnetwork/lnd/chainntnfs/neutrinonotify"
2727
"github.com/lightningnetwork/lnd/channeldb"
28-
"github.com/lightningnetwork/lnd/htlcswitch"
28+
"github.com/lightningnetwork/lnd/channeldb/models"
2929
"github.com/lightningnetwork/lnd/input"
3030
"github.com/lightningnetwork/lnd/keychain"
3131
"github.com/lightningnetwork/lnd/kvdb"
@@ -195,7 +195,7 @@ type PartialChainControl struct {
195195
ChainSource chain.Interface
196196

197197
// RoutingPolicy is the routing policy we have decided to use.
198-
RoutingPolicy htlcswitch.ForwardingPolicy
198+
RoutingPolicy models.ForwardingPolicy
199199

200200
// MinHtlcIn is the minimum HTLC we will accept.
201201
MinHtlcIn lnwire.MilliSatoshi
@@ -270,7 +270,7 @@ func NewPartialChainControl(cfg *Config) (*PartialChainControl, func(), error) {
270270

271271
switch cfg.PrimaryChain() {
272272
case BitcoinChain:
273-
cc.RoutingPolicy = htlcswitch.ForwardingPolicy{
273+
cc.RoutingPolicy = models.ForwardingPolicy{
274274
MinHTLCOut: cfg.Bitcoin.MinHTLCOut,
275275
BaseFee: cfg.Bitcoin.BaseFee,
276276
FeeRate: cfg.Bitcoin.FeeRate,
@@ -282,7 +282,7 @@ func NewPartialChainControl(cfg *Config) (*PartialChainControl, func(), error) {
282282
DefaultBitcoinStaticMinRelayFeeRate,
283283
)
284284
case LitecoinChain:
285-
cc.RoutingPolicy = htlcswitch.ForwardingPolicy{
285+
cc.RoutingPolicy = models.ForwardingPolicy{
286286
MinHTLCOut: cfg.Litecoin.MinHTLCOut,
287287
BaseFee: cfg.Litecoin.BaseFee,
288288
FeeRate: cfg.Litecoin.FeeRate,

channeldb/db.go

-63
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,6 @@ var (
312312
// channelOpeningState for each channel that is currently in the process
313313
// of being opened.
314314
channelOpeningStateBucket = []byte("channelOpeningState")
315-
316-
// initialChannelFwdingPolicyBucket is the database bucket used to store
317-
// the forwarding policy for each permanent channel that is currently
318-
// in the process of being opened.
319-
initialChannelFwdingPolicyBucket = []byte("initialChannelFwdingPolicy")
320315
)
321316

322317
// DB is the primary datastore for the lnd daemon. The database stores
@@ -1433,64 +1428,6 @@ func (c *ChannelStateDB) AbandonChannel(chanPoint *wire.OutPoint,
14331428
return dbChan.CloseChannel(summary, ChanStatusLocalCloseInitiator)
14341429
}
14351430

1436-
// SaveInitialFwdingPolicy saves the serialized forwarding policy for the
1437-
// provided permanent channel id to the initialChannelFwdingPolicyBucket.
1438-
func (c *ChannelStateDB) SaveInitialFwdingPolicy(chanID,
1439-
forwardingPolicy []byte) error {
1440-
1441-
return kvdb.Update(c.backend, func(tx kvdb.RwTx) error {
1442-
bucket, err := tx.CreateTopLevelBucket(
1443-
initialChannelFwdingPolicyBucket,
1444-
)
1445-
if err != nil {
1446-
return err
1447-
}
1448-
1449-
return bucket.Put(chanID, forwardingPolicy)
1450-
}, func() {})
1451-
}
1452-
1453-
// GetInitialFwdingPolicy fetches the serialized forwarding policy for the
1454-
// provided channel id from the database, or returns ErrChannelNotFound if
1455-
// a forwarding policy for this channel id is not found.
1456-
func (c *ChannelStateDB) GetInitialFwdingPolicy(chanID []byte) ([]byte, error) {
1457-
var serializedState []byte
1458-
err := kvdb.View(c.backend, func(tx kvdb.RTx) error {
1459-
bucket := tx.ReadBucket(initialChannelFwdingPolicyBucket)
1460-
if bucket == nil {
1461-
// If the bucket does not exist, it means we
1462-
// never added a channel fees to the db, so
1463-
// return ErrChannelNotFound.
1464-
return ErrChannelNotFound
1465-
}
1466-
1467-
stateBytes := bucket.Get(chanID)
1468-
if stateBytes == nil {
1469-
return ErrChannelNotFound
1470-
}
1471-
1472-
serializedState = append(serializedState, stateBytes...)
1473-
1474-
return nil
1475-
}, func() {
1476-
serializedState = nil
1477-
})
1478-
return serializedState, err
1479-
}
1480-
1481-
// DeleteInitialFwdingPolicy removes the forwarding policy for a given channel
1482-
// from the database.
1483-
func (c *ChannelStateDB) DeleteInitialFwdingPolicy(chanID []byte) error {
1484-
return kvdb.Update(c.backend, func(tx kvdb.RwTx) error {
1485-
bucket := tx.ReadWriteBucket(initialChannelFwdingPolicyBucket)
1486-
if bucket == nil {
1487-
return ErrChannelNotFound
1488-
}
1489-
1490-
return bucket.Delete(chanID)
1491-
}, func() {})
1492-
}
1493-
14941431
// SaveChannelOpeningState saves the serialized channel state for the provided
14951432
// chanPoint to the channelOpeningStateBucket.
14961433
func (c *ChannelStateDB) SaveChannelOpeningState(outPoint,

channeldb/forwarding_policy.go

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package channeldb
2+
3+
import (
4+
"github.com/lightningnetwork/lnd/channeldb/models"
5+
"github.com/lightningnetwork/lnd/kvdb"
6+
"github.com/lightningnetwork/lnd/lnwire"
7+
)
8+
9+
var (
10+
// initialChannelForwardingPolicyBucket is the database bucket used to
11+
// store the forwarding policy for each permanent channel that is
12+
// currently in the process of being opened.
13+
initialChannelForwardingPolicyBucket = []byte(
14+
"initialChannelFwdingPolicy",
15+
)
16+
)
17+
18+
// SaveInitialForwardingPolicy saves the serialized forwarding policy for the
19+
// provided permanent channel id to the initialChannelForwardingPolicyBucket.
20+
func (c *ChannelStateDB) SaveInitialForwardingPolicy(chanID lnwire.ChannelID,
21+
forwardingPolicy *models.ForwardingPolicy) error {
22+
23+
chanIDCopy := make([]byte, 32)
24+
copy(chanIDCopy, chanID[:])
25+
26+
scratch := make([]byte, 36)
27+
byteOrder.PutUint64(scratch[:8], uint64(forwardingPolicy.MinHTLCOut))
28+
byteOrder.PutUint64(scratch[8:16], uint64(forwardingPolicy.MaxHTLC))
29+
byteOrder.PutUint64(scratch[16:24], uint64(forwardingPolicy.BaseFee))
30+
byteOrder.PutUint64(scratch[24:32], uint64(forwardingPolicy.FeeRate))
31+
byteOrder.PutUint32(scratch[32:], forwardingPolicy.TimeLockDelta)
32+
33+
return kvdb.Update(c.backend, func(tx kvdb.RwTx) error {
34+
bucket, err := tx.CreateTopLevelBucket(
35+
initialChannelForwardingPolicyBucket,
36+
)
37+
if err != nil {
38+
return err
39+
}
40+
41+
return bucket.Put(chanIDCopy, scratch)
42+
}, func() {})
43+
}
44+
45+
// GetInitialForwardingPolicy fetches the serialized forwarding policy for the
46+
// provided channel id from the database, or returns ErrChannelNotFound if
47+
// a forwarding policy for this channel id is not found.
48+
func (c *ChannelStateDB) GetInitialForwardingPolicy(
49+
chanID lnwire.ChannelID) (*models.ForwardingPolicy, error) {
50+
51+
chanIDCopy := make([]byte, 32)
52+
copy(chanIDCopy, chanID[:])
53+
54+
var forwardingPolicy *models.ForwardingPolicy
55+
err := kvdb.View(c.backend, func(tx kvdb.RTx) error {
56+
bucket := tx.ReadBucket(initialChannelForwardingPolicyBucket)
57+
if bucket == nil {
58+
// If the bucket does not exist, it means we
59+
// never added a channel fees to the db, so
60+
// return ErrChannelNotFound.
61+
return ErrChannelNotFound
62+
}
63+
64+
stateBytes := bucket.Get(chanIDCopy)
65+
if stateBytes == nil {
66+
return ErrChannelNotFound
67+
}
68+
69+
forwardingPolicy = &models.ForwardingPolicy{
70+
MinHTLCOut: lnwire.MilliSatoshi(
71+
byteOrder.Uint64(stateBytes[:8]),
72+
),
73+
MaxHTLC: lnwire.MilliSatoshi(
74+
byteOrder.Uint64(stateBytes[8:16]),
75+
),
76+
BaseFee: lnwire.MilliSatoshi(
77+
byteOrder.Uint64(stateBytes[16:24]),
78+
),
79+
FeeRate: lnwire.MilliSatoshi(
80+
byteOrder.Uint64(stateBytes[24:32]),
81+
),
82+
TimeLockDelta: byteOrder.Uint32(stateBytes[32:36]),
83+
}
84+
85+
return nil
86+
}, func() {
87+
forwardingPolicy = nil
88+
})
89+
90+
return forwardingPolicy, err
91+
}
92+
93+
// DeleteInitialForwardingPolicy removes the forwarding policy for a given
94+
// channel from the database.
95+
func (c *ChannelStateDB) DeleteInitialForwardingPolicy(
96+
chanID lnwire.ChannelID) error {
97+
98+
chanIDCopy := make([]byte, 32)
99+
copy(chanIDCopy, chanID[:])
100+
101+
return kvdb.Update(c.backend, func(tx kvdb.RwTx) error {
102+
bucket := tx.ReadWriteBucket(
103+
initialChannelForwardingPolicyBucket,
104+
)
105+
if bucket == nil {
106+
return ErrChannelNotFound
107+
}
108+
109+
return bucket.Delete(chanIDCopy)
110+
}, func() {})
111+
}

channeldb/models/channel.go

+38
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,41 @@ func (k *CircuitKey) Decode(r io.Reader) error {
9090
func (k CircuitKey) String() string {
9191
return fmt.Sprintf("(Chan ID=%s, HTLC ID=%d)", k.ChanID, k.HtlcID)
9292
}
93+
94+
// ForwardingPolicy describes the set of constraints that a given ChannelLink
95+
// is to adhere to when forwarding HTLC's. For each incoming HTLC, this set of
96+
// constraints will be consulted in order to ensure that adequate fees are
97+
// paid, and our time-lock parameters are respected. In the event that an
98+
// incoming HTLC violates any of these constraints, it is to be _rejected_ with
99+
// the error possibly carrying along a ChannelUpdate message that includes the
100+
// latest policy.
101+
type ForwardingPolicy struct {
102+
// MinHTLCOut is the smallest HTLC that is to be forwarded.
103+
MinHTLCOut lnwire.MilliSatoshi
104+
105+
// MaxHTLC is the largest HTLC that is to be forwarded.
106+
MaxHTLC lnwire.MilliSatoshi
107+
108+
// BaseFee is the base fee, expressed in milli-satoshi that must be
109+
// paid for each incoming HTLC. This field, combined with FeeRate is
110+
// used to compute the required fee for a given HTLC.
111+
BaseFee lnwire.MilliSatoshi
112+
113+
// FeeRate is the fee rate, expressed in milli-satoshi that must be
114+
// paid for each incoming HTLC. This field combined with BaseFee is
115+
// used to compute the required fee for a given HTLC.
116+
FeeRate lnwire.MilliSatoshi
117+
118+
// TimeLockDelta is the absolute time-lock value, expressed in blocks,
119+
// that will be subtracted from an incoming HTLC's timelock value to
120+
// create the time-lock value for the forwarded outgoing HTLC. The
121+
// following constraint MUST hold for an HTLC to be forwarded:
122+
//
123+
// * incomingHtlc.timeLock - timeLockDelta = fwdInfo.OutgoingCTLV
124+
//
125+
// where fwdInfo is the forwarding information extracted from the
126+
// per-hop payload of the incoming HTLC's onion packet.
127+
TimeLockDelta uint32
128+
129+
// TODO(roasbeef): add fee module inside of switch
130+
}

0 commit comments

Comments
 (0)