@@ -207,7 +207,7 @@ func TestAutoLoopEnabled(t *testing.T) {
207
207
Events : []* loopdb.LoopEvent {
208
208
{
209
209
SwapStateData : loopdb.SwapStateData {
210
- State : loopdb .StateInitiated ,
210
+ State : loopdb .StateSuccess ,
211
211
},
212
212
},
213
213
},
@@ -472,7 +472,7 @@ func TestAutoloopAddress(t *testing.T) {
472
472
Events : []* loopdb.LoopEvent {
473
473
{
474
474
SwapStateData : loopdb.SwapStateData {
475
- State : loopdb .StateHtlcPublished ,
475
+ State : loopdb .StateSuccess ,
476
476
},
477
477
},
478
478
},
@@ -647,7 +647,7 @@ func TestCompositeRules(t *testing.T) {
647
647
Events : []* loopdb.LoopEvent {
648
648
{
649
649
SwapStateData : loopdb.SwapStateData {
650
- State : loopdb .StateHtlcPublished ,
650
+ State : loopdb .StateSuccess ,
651
651
},
652
652
},
653
653
},
@@ -984,7 +984,7 @@ func TestAutoloopBothTypes(t *testing.T) {
984
984
Events : []* loopdb.LoopEvent {
985
985
{
986
986
SwapStateData : loopdb.SwapStateData {
987
- State : loopdb .StateHtlcPublished ,
987
+ State : loopdb .SwapState ( loopdb . StateSuccess ) ,
988
988
},
989
989
},
990
990
},
@@ -1162,15 +1162,28 @@ func TestAutoLoopRecurringBudget(t *testing.T) {
1162
1162
},
1163
1163
},
1164
1164
}
1165
+
1166
+ singleLoopOut = & loopdb.LoopOut {
1167
+ Loop : loopdb.Loop {
1168
+ Events : []* loopdb.LoopEvent {
1169
+ {
1170
+ SwapStateData : loopdb.SwapStateData {
1171
+ State : loopdb .SwapState (loopdb .StateSuccess ),
1172
+ },
1173
+ },
1174
+ },
1175
+ },
1176
+ }
1165
1177
)
1166
1178
1167
1179
// Tick our autolooper with no existing swaps, we expect a loop out
1168
1180
// swap to be dispatched on first channel.
1169
1181
step := & autoloopStep {
1170
- minAmt : 1 ,
1171
- maxAmt : amt + 1 ,
1172
- quotesOut : quotes1 ,
1173
- expectedOut : loopOuts1 ,
1182
+ minAmt : 1 ,
1183
+ maxAmt : amt + 1 ,
1184
+ quotesOut : quotes1 ,
1185
+ expectedOut : loopOuts1 ,
1186
+ existingOutSingle : singleLoopOut ,
1174
1187
}
1175
1188
c .autoloop (step )
1176
1189
@@ -1188,11 +1201,12 @@ func TestAutoLoopRecurringBudget(t *testing.T) {
1188
1201
}
1189
1202
1190
1203
step = & autoloopStep {
1191
- minAmt : 1 ,
1192
- maxAmt : amt + 1 ,
1193
- quotesOut : quotes2 ,
1194
- existingOut : existing ,
1195
- expectedOut : nil ,
1204
+ minAmt : 1 ,
1205
+ maxAmt : amt + 1 ,
1206
+ quotesOut : quotes2 ,
1207
+ existingOut : existing ,
1208
+ expectedOut : nil ,
1209
+ existingOutSingle : singleLoopOut ,
1196
1210
}
1197
1211
// Tick again, we should expect no loop outs because our budget would be
1198
1212
// exceeded.
@@ -1222,11 +1236,12 @@ func TestAutoLoopRecurringBudget(t *testing.T) {
1222
1236
c .testClock .SetTime (testTime .Add (time .Hour * 25 ))
1223
1237
1224
1238
step = & autoloopStep {
1225
- minAmt : 1 ,
1226
- maxAmt : amt + 1 ,
1227
- quotesOut : quotes2 ,
1228
- existingOut : existing2 ,
1229
- expectedOut : loopOuts2 ,
1239
+ minAmt : 1 ,
1240
+ maxAmt : amt + 1 ,
1241
+ quotesOut : quotes2 ,
1242
+ existingOut : existing2 ,
1243
+ expectedOut : loopOuts2 ,
1244
+ existingOutSingle : singleLoopOut ,
1230
1245
}
1231
1246
1232
1247
// Tick again, we should expect a loop out to occur on the 2nd channel.
@@ -1235,6 +1250,177 @@ func TestAutoLoopRecurringBudget(t *testing.T) {
1235
1250
c .stop ()
1236
1251
}
1237
1252
1253
+ // TestEasyAutoloop tests that the easy autoloop logic works as expected. This
1254
+ // involves testing that channels are correctly selected and that the balance
1255
+ // target is successfully met.
1256
+ func TestEasyAutoloop (t * testing.T ) {
1257
+ defer test .Guard (t )
1258
+
1259
+ // We need to change the default channels we use for tests so that they
1260
+ // have different local balances in order to know which one is going to
1261
+ // be selected by easy autoloop.
1262
+ easyChannel1 := lndclient.ChannelInfo {
1263
+ Active : true ,
1264
+ ChannelID : chanID1 .ToUint64 (),
1265
+ PubKeyBytes : peer1 ,
1266
+ LocalBalance : 95000 ,
1267
+ RemoteBalance : 0 ,
1268
+ Capacity : 100000 ,
1269
+ }
1270
+
1271
+ easyChannel2 := lndclient.ChannelInfo {
1272
+ Active : true ,
1273
+ ChannelID : chanID1 .ToUint64 (),
1274
+ PubKeyBytes : peer1 ,
1275
+ LocalBalance : 75000 ,
1276
+ RemoteBalance : 0 ,
1277
+ Capacity : 100000 ,
1278
+ }
1279
+
1280
+ var (
1281
+ channels = []lndclient.ChannelInfo {
1282
+ easyChannel1 , easyChannel2 ,
1283
+ }
1284
+
1285
+ params = Parameters {
1286
+ Autoloop : true ,
1287
+ AutoFeeBudget : 36000 ,
1288
+ AutoFeeRefreshPeriod : time .Hour * 3 ,
1289
+ AutoloopBudgetLastRefresh : testBudgetStart ,
1290
+ MaxAutoInFlight : 2 ,
1291
+ FailureBackOff : time .Hour ,
1292
+ SweepConfTarget : 10 ,
1293
+ HtlcConfTarget : defaultHtlcConfTarget ,
1294
+ EasyAutoloop : true ,
1295
+ EasyAutoloopTarget : 75000 ,
1296
+ FeeLimit : defaultFeePortion (),
1297
+ }
1298
+ )
1299
+
1300
+ c := newAutoloopTestCtx (t , params , channels , testRestrictions )
1301
+ c .start ()
1302
+
1303
+ var (
1304
+ maxAmt = 50000
1305
+
1306
+ chan1Swap = & loop.OutRequest {
1307
+ Amount : btcutil .Amount (maxAmt ),
1308
+ OutgoingChanSet : loopdb.ChannelSet {easyChannel1 .ChannelID },
1309
+ Label : labels .AutoloopLabel (swap .TypeOut ),
1310
+ Initiator : autoloopSwapInitiator ,
1311
+ }
1312
+
1313
+ quotesOut1 = []quoteRequestResp {
1314
+ {
1315
+ request : & loop.LoopOutQuoteRequest {
1316
+ Amount : btcutil .Amount (maxAmt ),
1317
+ },
1318
+ quote : & loop.LoopOutQuote {
1319
+ SwapFee : 1 ,
1320
+ PrepayAmount : 1 ,
1321
+ MinerFee : 1 ,
1322
+ },
1323
+ },
1324
+ }
1325
+
1326
+ loopOut1 = []loopOutRequestResp {
1327
+ {
1328
+ request : chan1Swap ,
1329
+ response : & loop.LoopOutSwapInfo {
1330
+ SwapHash : lntypes.Hash {1 },
1331
+ },
1332
+ },
1333
+ }
1334
+ )
1335
+
1336
+ // We expected one max size swap to be dispatched on our channel with
1337
+ // the biggest local balance.
1338
+ step := & easyAutoloopStep {
1339
+ minAmt : 1 ,
1340
+ maxAmt : 50000 ,
1341
+ quotesOut : quotesOut1 ,
1342
+ expectedOut : loopOut1 ,
1343
+ }
1344
+
1345
+ c .easyautoloop (step , false )
1346
+ c .stop ()
1347
+
1348
+ // In order to reflect the change on the channel balances we create a
1349
+ // new context and restart the autolooper.
1350
+ easyChannel1 .LocalBalance -= chan1Swap .Amount
1351
+ channels = []lndclient.ChannelInfo {
1352
+ easyChannel1 , easyChannel2 ,
1353
+ }
1354
+
1355
+ c = newAutoloopTestCtx (t , params , channels , testRestrictions )
1356
+ c .start ()
1357
+
1358
+ var (
1359
+ amt2 = 45_000
1360
+
1361
+ chan2Swap = & loop.OutRequest {
1362
+ Amount : btcutil .Amount (amt2 ),
1363
+ OutgoingChanSet : loopdb.ChannelSet {easyChannel2 .ChannelID },
1364
+ Label : labels .AutoloopLabel (swap .TypeOut ),
1365
+ Initiator : autoloopSwapInitiator ,
1366
+ }
1367
+
1368
+ quotesOut2 = []quoteRequestResp {
1369
+ {
1370
+ request : & loop.LoopOutQuoteRequest {
1371
+ Amount : btcutil .Amount (amt2 ),
1372
+ },
1373
+ quote : & loop.LoopOutQuote {
1374
+ SwapFee : 1 ,
1375
+ PrepayAmount : 1 ,
1376
+ MinerFee : 1 ,
1377
+ },
1378
+ },
1379
+ }
1380
+
1381
+ loopOut2 = []loopOutRequestResp {
1382
+ {
1383
+ request : chan2Swap ,
1384
+ response : & loop.LoopOutSwapInfo {
1385
+ SwapHash : lntypes.Hash {1 },
1386
+ },
1387
+ },
1388
+ }
1389
+ )
1390
+
1391
+ // We expect a swap of size 45_000 to be dispatched in order to meet the
1392
+ // defined target of 75_000.
1393
+ step = & easyAutoloopStep {
1394
+ minAmt : 1 ,
1395
+ maxAmt : 50000 ,
1396
+ quotesOut : quotesOut2 ,
1397
+ expectedOut : loopOut2 ,
1398
+ }
1399
+
1400
+ c .easyautoloop (step , false )
1401
+ c .stop ()
1402
+
1403
+ // In order to reflect the change on the channel balances we create a
1404
+ // new context and restart the autolooper.
1405
+ easyChannel2 .LocalBalance -= btcutil .Amount (amt2 )
1406
+ channels = []lndclient.ChannelInfo {
1407
+ easyChannel1 , easyChannel2 ,
1408
+ }
1409
+
1410
+ c = newAutoloopTestCtx (t , params , channels , testRestrictions )
1411
+ c .start ()
1412
+
1413
+ // We have met the target of 75_000 so we don't expect any action from
1414
+ // easy autoloop. That's why we set noop to true in the call below.
1415
+ step = & easyAutoloopStep {
1416
+ minAmt : 1 ,
1417
+ maxAmt : 50000 ,
1418
+ }
1419
+
1420
+ c .easyautoloop (step , true )
1421
+ c .stop ()
1422
+ }
1423
+
1238
1424
// existingSwapFromRequest is a helper function which returns the db
1239
1425
// representation of a loop out request with the event set provided.
1240
1426
func existingSwapFromRequest (request * loop.OutRequest , initTime time.Time ,
0 commit comments