Merge pull request #466 from bhandras/routing-plugin-force-mc-import

routing: integrate with the forced MC import to eliminate the "1 sec hack" when importing pair history
This commit is contained in:
András Bánki-Horváth 2022-03-16 15:06:11 +01:00 committed by GitHub
commit a6350905d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 53 additions and 57 deletions

6
go.mod
View file

@ -11,10 +11,10 @@ require (
github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0
github.com/jessevdk/go-flags v1.4.0
github.com/lightninglabs/aperture v0.1.6-beta
github.com/lightninglabs/lndclient v0.14.0-8
github.com/lightninglabs/lndclient v0.14.2-3
github.com/lightninglabs/loop/swapserverrpc v1.0.0
github.com/lightninglabs/protobuf-hex-display v1.4.3-hex-display
github.com/lightningnetwork/lnd v0.14.2-beta.rc1
github.com/lightningnetwork/lnd v0.14.2-beta
github.com/lightningnetwork/lnd/cert v1.1.0
github.com/lightningnetwork/lnd/clock v1.1.0
github.com/lightningnetwork/lnd/queue v1.1.0
@ -32,5 +32,5 @@ go 1.15
replace github.com/lightninglabs/loop/swapserverrpc => ./swapserverrpc
// TODO(bhandras): remove once v0.14.2-beta is tagged.
// TODO(bhandras): remove once v0.14.3-beta or v0.15.0-beta is tagged.
replace github.com/lightningnetwork/lnd => github.com/lightningnetwork/lnd v0.14.1-beta.0.20220131141659-60625b6c1a0b

5
go.sum
View file

@ -548,8 +548,8 @@ github.com/lightninglabs/aperture v0.1.6-beta/go.mod h1:9xl4mx778ZAzrB87nLHMqk+X
github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf h1:HZKvJUHlcXI/f/O0Avg7t8sqkPo78HFzjmeYFl6DPnc=
github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf/go.mod h1:vxmQPeIQxPf6Jf9rM8R+B4rKBqLA2AjttNxkFBL2Plk=
github.com/lightninglabs/lndclient v0.11.0-4/go.mod h1:8/cTKNwgL87NX123gmlv3Xh6p1a7pvzu+40Un3PhHiI=
github.com/lightninglabs/lndclient v0.14.0-8 h1:vdwV6yFU4A7BjG2V8cpI8Kqdl2M0NSfsA+RWR+JGTko=
github.com/lightninglabs/lndclient v0.14.0-8/go.mod h1:YIE/Yac69hIMiq9cm/ZC2sP4F0Llv3tC4hZGfgOhdeY=
github.com/lightninglabs/lndclient v0.14.2-3 h1:19HWiGCUNejCAm9Ffl5Y56A8u6ZDhhfyjPSDbMDmjuw=
github.com/lightninglabs/lndclient v0.14.2-3/go.mod h1:8fu/+OAK1PqUx9oglz5p0WPOSAwKBUwrC3q3D1yi6Oo=
github.com/lightninglabs/neutrino v0.12.1/go.mod h1:GlKninWpRBbL7b8G0oQ36/8downfnFwKsr0hbRA6E/E=
github.com/lightninglabs/neutrino v0.13.0 h1:j3PKWEJCwqwMn/qLASz2j0IuCF6AumS9DaM0i0pM/nY=
github.com/lightninglabs/neutrino v0.13.0/go.mod h1:GlKninWpRBbL7b8G0oQ36/8downfnFwKsr0hbRA6E/E=
@ -568,7 +568,6 @@ github.com/lightningnetwork/lnd/clock v1.1.0/go.mod h1:KnQudQ6w0IAMZi1SgvecLZQZ4
github.com/lightningnetwork/lnd/healthcheck v1.0.0/go.mod h1:u92p1JGFJNMSkMvztKEwmt1P3TRnLeJBXZ3M85xkU1E=
github.com/lightningnetwork/lnd/healthcheck v1.2.0 h1:00bkNn+hGJM9j3Ht+ulf8YNcSx1HEYSDv5pf4HB1/uQ=
github.com/lightningnetwork/lnd/healthcheck v1.2.0/go.mod h1:WSz3lsUjErJQZ3gb+zW32nM3WIHNiZ3A40GVoaQY5wU=
github.com/lightningnetwork/lnd/kvdb v1.2.0/go.mod h1:4DW7zc9AWqqJBvwhSE251VasYikTELItN70hESIt9RU=
github.com/lightningnetwork/lnd/kvdb v1.3.0 h1:0sadTsmfIoorGvd2zf09q/H7sxa/OU48NCpCQUPNN48=
github.com/lightningnetwork/lnd/kvdb v1.3.0/go.mod h1:x+IpsuDynubjokUofavLXroeGfS/WrqUXXTK6vN/gp4=
github.com/lightningnetwork/lnd/queue v1.0.1/go.mod h1:vaQwexir73flPW43Mrm7JOgJHmcEFBWWSl9HlyASoms=

View file

@ -26,8 +26,8 @@ var (
// listed build tags/subservers need to be enabled.
LoopMinRequiredLndVersion = &verrpc.Version{
AppMajor: 0,
AppMinor: 11,
AppPatch: 1,
AppMinor: 14,
AppPatch: 2,
BuildTags: []string{
"signrpc", "walletrpc", "chainrpc", "invoicesrpc",
},

View file

@ -19,6 +19,7 @@ This file tracks release notes for the loop client.
* Loop client now supports optional routing plugins to improve off-chain payment
reliability. One such plugin that the client implemenets will gradually prefer
increasingly more expensive routes in case payments using cheap routes time out.
Note that with this addition the minimum required LND version is LND 0.14.2-beta.
#### Breaking Changes

View file

@ -5,7 +5,6 @@ import (
"fmt"
"sort"
"sync"
"time"
"github.com/btcsuite/btclog"
"github.com/btcsuite/btcutil"
@ -520,13 +519,10 @@ func (r *lowToHighRoutingPlugin) BeforePayment(ctx context.Context,
limit := minFee +
((maxFee-minFee)/int64(maxAttempts))*int64(currAttempt)
// Create a timestamp just slightly in the future as Mission Control
// stores timestamps with sub second precision where as we send a unix
// timestamp it may occur that we can't override the last entries as
// they have the same unix timestamp.
// TODO(bhandras): not very reliable, ideally we'd need a force import
// for MC.
now := r.clock.Now().Add(time.Second)
// With the forced MC import we can safely set the pair history
// timestamps to the current time as import will always just override
// current MC state.
now := r.clock.Now()
allowed := 0
entries := make(
@ -566,7 +562,7 @@ func (r *lowToHighRoutingPlugin) BeforePayment(ctx context.Context,
return ErrRoutingPluginNoMoreRetries
}
err := r.lnd.Router.ImportMissionControl(ctx, entries)
err := r.lnd.Router.ImportMissionControl(ctx, entries, true)
if err != nil {
return err
}
@ -606,10 +602,10 @@ func (r *lowToHighRoutingPlugin) Done(ctx context.Context) error {
return nil
}
// Roll the entry times forward (to be able to override recent updates).
// Use the "time travel" trick which is required to make overrides
// succeed.
now := r.clock.Now().Add(time.Second)
// With the forced import we're safe to just set the pair history
// timestamps to the current time as import will always succeed and
// override current MC state.
now := r.clock.Now()
entries := make(
[]lndclient.MissionControlEntry, 0, len(r.nodesByMaxFee),
)
@ -647,7 +643,7 @@ func (r *lowToHighRoutingPlugin) Done(ctx context.Context) error {
}
}
err := r.lnd.Router.ImportMissionControl(ctx, entries)
err := r.lnd.Router.ImportMissionControl(ctx, entries, true)
if err != nil {
return err
}

View file

@ -81,8 +81,6 @@ func TestLowHighRoutingPlugin(t *testing.T) {
target := loopNode
amt := btcutil.Amount(50)
testTime := time.Now().UTC()
// We expect Mission Control entries to be set to now + 1 sec.
testTimeMc := testTime.Add(time.Second)
tests := []struct {
name string
@ -168,7 +166,7 @@ func TestLowHighRoutingPlugin(t *testing.T) {
NodeTo: dave,
FailTime: time.Time{},
FailAmt: 0,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 10000,
},
},
@ -210,14 +208,14 @@ func TestLowHighRoutingPlugin(t *testing.T) {
{
NodeFrom: bob,
NodeTo: dave,
FailTime: testTimeMc,
FailTime: testTime,
FailAmt: 1,
},
// Encourage Charlie - Dave
{
NodeFrom: charlie,
NodeTo: dave,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 1000000,
},
},
@ -228,15 +226,15 @@ func TestLowHighRoutingPlugin(t *testing.T) {
NodeTo: dave,
FailTime: time.Time{},
FailAmt: 0,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 10000,
},
{
NodeFrom: charlie,
NodeTo: dave,
FailTime: testTimeMc,
FailTime: testTime,
FailAmt: 1000001,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 1000000,
},
},
@ -283,13 +281,13 @@ func TestLowHighRoutingPlugin(t *testing.T) {
{
NodeFrom: bob,
NodeTo: dave,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 999000,
},
{
NodeFrom: charlie,
NodeTo: dave,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 999000,
},
},
@ -304,17 +302,17 @@ func TestLowHighRoutingPlugin(t *testing.T) {
{
NodeFrom: bob,
NodeTo: dave,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 999000,
FailTime: testTimeMc,
FailTime: testTime,
FailAmt: 999001,
},
{
NodeFrom: charlie,
NodeTo: dave,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 999000,
FailTime: testTimeMc,
FailTime: testTime,
FailAmt: 999001,
},
},
@ -375,21 +373,21 @@ func TestLowHighRoutingPlugin(t *testing.T) {
{
NodeFrom: bob,
NodeTo: eugene,
FailTime: testTimeMc,
FailTime: testTime,
FailAmt: 1,
},
// Encourage Charlie - Eugene
{
NodeFrom: charlie,
NodeTo: eugene,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 1000000,
},
// Encourage Dave - Eugene
{
NodeFrom: dave,
NodeTo: eugene,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 1000000,
},
},
@ -399,21 +397,21 @@ func TestLowHighRoutingPlugin(t *testing.T) {
{
NodeFrom: bob,
NodeTo: eugene,
FailTime: testTimeMc,
FailTime: testTime,
FailAmt: 1,
},
// Discourage Charlie - Eugene
{
NodeFrom: charlie,
NodeTo: eugene,
FailTime: testTimeMc,
FailTime: testTime,
FailAmt: 1,
},
// Encourage Dave - Eugene
{
NodeFrom: dave,
NodeTo: eugene,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 1000000,
},
},
@ -422,9 +420,9 @@ func TestLowHighRoutingPlugin(t *testing.T) {
{
NodeFrom: bob,
NodeTo: eugene,
FailTime: testTimeMc,
FailTime: testTime,
FailAmt: 1000001,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 1000000,
},
{
@ -432,15 +430,15 @@ func TestLowHighRoutingPlugin(t *testing.T) {
NodeTo: eugene,
FailTime: time.Time{},
FailAmt: 0,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 10000,
},
{
NodeFrom: dave,
NodeTo: eugene,
FailTime: testTimeMc,
FailTime: testTime,
FailAmt: 1000001,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 1000000,
},
},
@ -500,14 +498,14 @@ func TestLowHighRoutingPlugin(t *testing.T) {
{
NodeFrom: frank,
NodeTo: george,
FailTime: testTimeMc,
FailTime: testTime,
FailAmt: 1,
},
// Encourage Dave - George
{
NodeFrom: dave,
NodeTo: george,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 1000000,
},
},
@ -522,17 +520,17 @@ func TestLowHighRoutingPlugin(t *testing.T) {
{
NodeFrom: frank,
NodeTo: george,
FailTime: testTimeMc,
FailTime: testTime,
FailAmt: 1000001,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 1000000,
},
{
NodeFrom: dave,
NodeTo: george,
FailTime: testTimeMc,
FailTime: testTime,
FailAmt: 1000001,
SuccessTime: testTimeMc,
SuccessTime: testTime,
SuccessAmt: 1000000,
},
},

View file

@ -52,7 +52,7 @@ func (r *mockRouter) QueryMissionControl(ctx context.Context) (
// ImpotMissionControl is a mocked reimplementation of the pair import.
// Reference: lnd/router/missioncontrol_state.go:importSnapshot().
func (r *mockRouter) ImportMissionControl(ctx context.Context,
entries []lndclient.MissionControlEntry) error {
entries []lndclient.MissionControlEntry, force bool) error {
for _, entry := range entries {
found := false
@ -79,12 +79,14 @@ func (r *mockRouter) ImportMissionControl(ctx context.Context,
// Import success result second.
current.SuccessTime = entry.SuccessTime
if entry.SuccessAmt > current.SuccessAmt {
if force ||
entry.SuccessAmt > current.SuccessAmt {
current.SuccessAmt = entry.SuccessAmt
}
if !current.FailTime.IsZero() &&
entry.SuccessAmt >= current.FailAmt {
if !force && (!current.FailTime.IsZero() &&
entry.SuccessAmt >= current.FailAmt) {
current.FailAmt = entry.SuccessAmt + 1
}