multi: distinguish between htlc in and out constraints

This commit is contained in:
Joost Jager 2019-11-15 10:09:27 +01:00
parent d8fd6fae23
commit ddb98fcc41
No known key found for this signature in database
GPG Key ID: A61B9D4C393C59C7
11 changed files with 48 additions and 39 deletions

@ -130,6 +130,8 @@ type chainControl struct {
wallet *lnwallet.LightningWallet
routingPolicy htlcswitch.ForwardingPolicy
minHtlcIn lnwire.MilliSatoshi
}
// newChainControlFromConfig attempts to create a chainControl instance
@ -157,21 +159,23 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
switch registeredChains.PrimaryChain() {
case bitcoinChain:
cc.routingPolicy = htlcswitch.ForwardingPolicy{
MinHTLC: cfg.Bitcoin.MinHTLC,
MinHTLCOut: cfg.Bitcoin.MinHTLC,
BaseFee: cfg.Bitcoin.BaseFee,
FeeRate: cfg.Bitcoin.FeeRate,
TimeLockDelta: cfg.Bitcoin.TimeLockDelta,
}
cc.minHtlcIn = cfg.Bitcoin.MinHTLC
cc.feeEstimator = chainfee.NewStaticEstimator(
defaultBitcoinStaticFeePerKW, 0,
)
case litecoinChain:
cc.routingPolicy = htlcswitch.ForwardingPolicy{
MinHTLC: cfg.Litecoin.MinHTLC,
MinHTLCOut: cfg.Litecoin.MinHTLC,
BaseFee: cfg.Litecoin.BaseFee,
FeeRate: cfg.Litecoin.FeeRate,
TimeLockDelta: cfg.Litecoin.TimeLockDelta,
}
cc.minHtlcIn = cfg.Litecoin.MinHTLC
cc.feeEstimator = chainfee.NewStaticEstimator(
defaultLitecoinStaticFeePerKW, 0,
)

@ -285,6 +285,10 @@ type fundingConfig struct {
// initially announcing channels.
DefaultRoutingPolicy htlcswitch.ForwardingPolicy
// DefaultMinHtlcIn is the default minimum incoming htlc value that is
// set as a channel parameter.
DefaultMinHtlcIn lnwire.MilliSatoshi
// NumRequiredConfs is a function closure that helps the funding
// manager decide how many confirmations it should require for a
// channel extended to it. The function is able to take into account
@ -1300,7 +1304,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
chanReserve := f.cfg.RequiredRemoteChanReserve(amt, msg.DustLimit)
maxValue := f.cfg.RequiredRemoteMaxValue(amt)
maxHtlcs := f.cfg.RequiredRemoteMaxHTLCs(amt)
minHtlc := f.cfg.DefaultRoutingPolicy.MinHTLC
minHtlc := f.cfg.DefaultMinHtlcIn
// Once the reservation has been created successfully, we add it to
// this peer's map of pending reservations to track this particular
@ -2806,7 +2810,7 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
var (
peerKey = msg.peer.IdentityKey()
localAmt = msg.localFundingAmt
minHtlc = msg.minHtlc
minHtlcIn = msg.minHtlcIn
remoteCsvDelay = msg.remoteCsvDelay
)
@ -2922,8 +2926,8 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
}
// If no minimum HTLC value was specified, use the default one.
if minHtlc == 0 {
minHtlc = f.cfg.DefaultRoutingPolicy.MinHTLC
if minHtlcIn == 0 {
minHtlcIn = f.cfg.DefaultMinHtlcIn
}
// If a pending channel map for this peer isn't already created, then
@ -2938,7 +2942,7 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
resCtx := &reservationWithCtx{
chanAmt: capacity,
remoteCsvDelay: remoteCsvDelay,
remoteMinHtlc: minHtlc,
remoteMinHtlc: minHtlcIn,
reservation: reservation,
peer: msg.peer,
updates: msg.updates,
@ -2972,7 +2976,7 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
DustLimit: ourContribution.DustLimit,
MaxValueInFlight: maxValue,
ChannelReserve: chanReserve,
HtlcMinimum: minHtlc,
HtlcMinimum: minHtlcIn,
FeePerKiloWeight: uint32(commitFeePerKw),
CsvDelay: remoteCsvDelay,
MaxAcceptedHTLCs: maxHtlcs,

@ -336,11 +336,12 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
return nil, fmt.Errorf("unable to find channel")
},
DefaultRoutingPolicy: htlcswitch.ForwardingPolicy{
MinHTLC: 5,
MinHTLCOut: 5,
BaseFee: 100,
FeeRate: 1000,
TimeLockDelta: 10,
},
DefaultMinHtlcIn: 5,
NumRequiredConfs: func(chanAmt btcutil.Amount,
pushAmt lnwire.MilliSatoshi) uint16 {
return 3
@ -464,11 +465,12 @@ func recreateAliceFundingManager(t *testing.T, alice *testNode) {
TempChanIDSeed: oldCfg.TempChanIDSeed,
FindChannel: oldCfg.FindChannel,
DefaultRoutingPolicy: htlcswitch.ForwardingPolicy{
MinHTLC: 5,
MinHTLCOut: 5,
BaseFee: 100,
FeeRate: 1000,
TimeLockDelta: 10,
},
DefaultMinHtlcIn: 5,
RequiredRemoteMaxValue: oldCfg.RequiredRemoteMaxValue,
PublishTransaction: func(txn *wire.MsgTx) error {
publishChan <- txn
@ -926,7 +928,7 @@ func assertChannelAnnouncements(t *testing.T, alice, bob *testNode,
// _other_ node.
other := (j + 1) % 2
minHtlc := nodes[other].fundingMgr.cfg.
DefaultRoutingPolicy.MinHTLC
DefaultMinHtlcIn
// We might expect a custom MinHTLC value.
if len(customMinHtlc) > 0 {
@ -2325,7 +2327,7 @@ func TestFundingManagerCustomChannelParameters(t *testing.T) {
// This is the custom parameters we'll use.
const csvDelay = 67
const minHtlc = 1234
const minHtlcIn = 1234
// We will consume the channel updates as we go, so no buffering is
// needed.
@ -2344,7 +2346,7 @@ func TestFundingManagerCustomChannelParameters(t *testing.T) {
localFundingAmt: localAmt,
pushAmt: lnwire.NewMSatFromSatoshis(pushAmt),
private: false,
minHtlc: minHtlc,
minHtlcIn: minHtlcIn,
remoteCsvDelay: csvDelay,
updates: updateChan,
err: errChan,
@ -2381,9 +2383,9 @@ func TestFundingManagerCustomChannelParameters(t *testing.T) {
}
// Check that the custom minHTLC value is sent.
if openChannelReq.HtlcMinimum != minHtlc {
if openChannelReq.HtlcMinimum != minHtlcIn {
t.Fatalf("expected OpenChannel to have minHtlc %v, got %v",
minHtlc, openChannelReq.HtlcMinimum)
minHtlcIn, openChannelReq.HtlcMinimum)
}
chanID := openChannelReq.PendingChannelID
@ -2468,7 +2470,7 @@ func TestFundingManagerCustomChannelParameters(t *testing.T) {
// The minimum HTLC value Alice can offer should be 5, and the minimum
// Bob can offer should be 1234.
if err := assertMinHtlc(resCtx, 5, minHtlc); err != nil {
if err := assertMinHtlc(resCtx, 5, minHtlcIn); err != nil {
t.Fatal(err)
}
@ -2482,7 +2484,7 @@ func TestFundingManagerCustomChannelParameters(t *testing.T) {
t.Fatal(err)
}
if err := assertMinHtlc(resCtx, minHtlc, 5); err != nil {
if err := assertMinHtlc(resCtx, minHtlcIn, 5); err != nil {
t.Fatal(err)
}
@ -2543,7 +2545,7 @@ func TestFundingManagerCustomChannelParameters(t *testing.T) {
// announcements. Alice should advertise the default MinHTLC value of
// 5, while bob should advertise the value minHtlc, since Alice
// required him to use it.
assertChannelAnnouncements(t, alice, bob, capacity, 5, minHtlc)
assertChannelAnnouncements(t, alice, bob, capacity, 5, minHtlcIn)
// The funding transaction is now confirmed, wait for the
// OpenStatusUpdate_ChanOpen update

@ -71,10 +71,8 @@ const (
// the error possibly carrying along a ChannelUpdate message that includes the
// latest policy.
type ForwardingPolicy struct {
// MinHTLC is the smallest HTLC that is to be forwarded. This is
// set when a channel is first opened, and will be static for the
// lifetime of the channel.
MinHTLC lnwire.MilliSatoshi
// MinHTLC is the smallest HTLC that is to be forwarded.
MinHTLCOut lnwire.MilliSatoshi
// MaxHTLC is the largest HTLC that is to be forwarded.
MaxHTLC lnwire.MilliSatoshi
@ -2218,9 +2216,9 @@ func (l *channelLink) canSendHtlc(policy ForwardingPolicy,
// As our first sanity check, we'll ensure that the passed HTLC isn't
// too small for the next hop. If so, then we'll cancel the HTLC
// directly.
if amt < policy.MinHTLC {
if amt < policy.MinHTLCOut {
l.log.Errorf("outgoing htlc(%x) is too small: min_htlc=%v, "+
"htlc_value=%v", payHash[:], policy.MinHTLC,
"htlc_value=%v", payHash[:], policy.MinHTLCOut,
amt)
// As part of the returned error, we'll send our latest routing

@ -1694,7 +1694,7 @@ func newSingleLinkTestHarness(chanAmt, chanReserve btcutil.Amount) (
quit: make(chan struct{}),
}
globalPolicy = ForwardingPolicy{
MinHTLC: lnwire.NewMSatFromSatoshis(5),
MinHTLCOut: lnwire.NewMSatFromSatoshis(5),
MaxHTLC: lnwire.NewMSatFromSatoshis(chanAmt),
BaseFee: lnwire.NewMSatFromSatoshis(1),
TimeLockDelta: 6,
@ -4253,7 +4253,7 @@ func (h *persistentLinkHarness) restartLink(
}
globalPolicy = ForwardingPolicy{
MinHTLC: lnwire.NewMSatFromSatoshis(5),
MinHTLCOut: lnwire.NewMSatFromSatoshis(5),
BaseFee: lnwire.NewMSatFromSatoshis(1),
TimeLockDelta: 6,
}
@ -5512,7 +5512,7 @@ func TestCheckHtlcForward(t *testing.T) {
cfg: ChannelLinkConfig{
FwrdingPolicy: ForwardingPolicy{
TimeLockDelta: 20,
MinHTLC: 500,
MinHTLCOut: 500,
MaxHTLC: 1000,
BaseFee: 10,
},

@ -1078,7 +1078,7 @@ func newHopNetwork() *hopNetwork {
defaultDelta := uint32(6)
globalPolicy := ForwardingPolicy{
MinHTLC: lnwire.NewMSatFromSatoshis(5),
MinHTLCOut: lnwire.NewMSatFromSatoshis(5),
BaseFee: lnwire.NewMSatFromSatoshis(1),
TimeLockDelta: defaultDelta,
}

@ -531,7 +531,7 @@ func (p *peer) loadActiveChannels(chans []*channeldb.OpenChannel) (
var forwardingPolicy *htlcswitch.ForwardingPolicy
if selfPolicy != nil {
forwardingPolicy = &htlcswitch.ForwardingPolicy{
MinHTLC: selfPolicy.MinHTLC,
MinHTLCOut: selfPolicy.MinHTLC,
MaxHTLC: selfPolicy.MaxHTLC,
BaseFee: selfPolicy.FeeBaseMSat,
FeeRate: selfPolicy.FeeProportionalMillionths,
@ -1862,7 +1862,7 @@ out:
fwdMinHtlc := lnChan.FwdMinHtlc()
defaultPolicy := p.server.cc.routingPolicy
forwardingPolicy := &htlcswitch.ForwardingPolicy{
MinHTLC: fwdMinHtlc,
MinHTLCOut: fwdMinHtlc,
MaxHTLC: newChan.LocalChanCfg.MaxPendingAmount,
BaseFee: defaultPolicy.BaseFee,
FeeRate: defaultPolicy.FeeRate,

@ -92,7 +92,7 @@ func (c *chanController) OpenChannel(target *btcec.PublicKey,
}
// TODO(halseth): make configurable?
minHtlc := lnwire.NewMSatFromSatoshis(1)
minHtlcIn := lnwire.NewMSatFromSatoshis(1)
// Construct the open channel request and send it to the server to begin
// the funding workflow.
@ -102,7 +102,7 @@ func (c *chanController) OpenChannel(target *btcec.PublicKey,
subtractFees: true,
localFundingAmt: amt,
pushAmt: 0,
minHtlc: minHtlc,
minHtlcIn: minHtlcIn,
fundingFeePerKw: feePerKw,
private: c.private,
remoteCsvDelay: 0,

@ -93,7 +93,7 @@ func (r *Manager) UpdatePolicy(newSchema routing.ChannelPolicy,
BaseFee: edge.FeeBaseMSat,
FeeRate: edge.FeeProportionalMillionths,
TimeLockDelta: uint32(edge.TimeLockDelta),
MinHTLC: edge.MinHTLC,
MinHTLCOut: edge.MinHTLC,
MaxHTLC: edge.MaxHTLC,
}

@ -1449,7 +1449,7 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
localFundingAmt := btcutil.Amount(in.LocalFundingAmount)
remoteInitialBalance := btcutil.Amount(in.PushSat)
minHtlc := lnwire.MilliSatoshi(in.MinHtlcMsat)
minHtlcIn := lnwire.MilliSatoshi(in.MinHtlcMsat)
remoteCsvDelay := uint16(in.RemoteCsvDelay)
// Ensure that the initial balance of the remote party (if pushing
@ -1537,7 +1537,7 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
chainHash: *activeNetParams.GenesisHash,
localFundingAmt: localFundingAmt,
pushAmt: lnwire.NewMSatFromSatoshis(remoteInitialBalance),
minHtlc: minHtlc,
minHtlcIn: minHtlcIn,
fundingFeePerKw: feeRate,
private: in.Private,
remoteCsvDelay: remoteCsvDelay,
@ -1631,7 +1631,7 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context,
localFundingAmt := btcutil.Amount(in.LocalFundingAmount)
remoteInitialBalance := btcutil.Amount(in.PushSat)
minHtlc := lnwire.MilliSatoshi(in.MinHtlcMsat)
minHtlcIn := lnwire.MilliSatoshi(in.MinHtlcMsat)
remoteCsvDelay := uint16(in.RemoteCsvDelay)
// Ensure that the initial balance of the remote party (if pushing
@ -1679,7 +1679,7 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context,
chainHash: *activeNetParams.GenesisHash,
localFundingAmt: localFundingAmt,
pushAmt: lnwire.NewMSatFromSatoshis(remoteInitialBalance),
minHtlc: minHtlc,
minHtlcIn: minHtlcIn,
fundingFeePerKw: feeRate,
private: in.Private,
remoteCsvDelay: remoteCsvDelay,

@ -985,6 +985,7 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB,
return nil, fmt.Errorf("unable to find channel")
},
DefaultRoutingPolicy: cc.routingPolicy,
DefaultMinHtlcIn: cc.minHtlcIn,
NumRequiredConfs: func(chanAmt btcutil.Amount,
pushAmt lnwire.MilliSatoshi) uint16 {
// For large channels we increase the number
@ -3084,8 +3085,8 @@ type openChanReq struct {
private bool
// minHtlc is the minimum incoming htlc that we accept.
minHtlc lnwire.MilliSatoshi
// minHtlcIn is the minimum incoming htlc that we accept.
minHtlcIn lnwire.MilliSatoshi
remoteCsvDelay uint16