Merge pull request #551 from GeorgeTsagk/recurring-budget

multi: add recurring autoloop budget
pull/553/head
Konstantin Nick 1 year ago committed by GitHub
commit e188763d3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -298,11 +298,10 @@ var setParamsCommand = cli.Command{
"automatically dispatched loop out swaps may " + "automatically dispatched loop out swaps may " +
"spend", "spend",
}, },
cli.Uint64Flag{ cli.DurationFlag{
Name: "budgetstart", Name: "autobudgetrefreshperiod",
Usage: "the start time for the automated loop " + Usage: "the time period over which the automated " +
"out budget, expressed as a unix timestamp " + "loop budget is refreshed",
"in seconds",
}, },
cli.Uint64Flag{ cli.Uint64Flag{
Name: "autoinflight", Name: "autoinflight",
@ -440,8 +439,9 @@ func setParams(ctx *cli.Context) error {
flagSet = true flagSet = true
} }
if ctx.IsSet("budgetstart") { if ctx.IsSet("autobudgetrefreshperiod") {
params.AutoloopBudgetStartSec = ctx.Uint64("budgetstart") params.AutoloopBudgetRefreshPeriodSec =
uint64(ctx.Duration("autobudgetrefreshperiod").Seconds())
flagSet = true flagSet = true
} }

@ -157,7 +157,7 @@ The autolooper operates within a set budget, and will stop executing swaps when
this budget is reached. This budget includes the fees paid to the swap server, this budget is reached. This budget includes the fees paid to the swap server,
on-chain sweep costs and off-chain routing fees. Note that the budget does not on-chain sweep costs and off-chain routing fees. Note that the budget does not
include the actual swap amount, as this balance is simply shifted from off-chain include the actual swap amount, as this balance is simply shifted from off-chain
to on-chain, rather than used up. to on-chain, rather than used up.
The budget value is expressed in satoshis, and can be set using the `setparams` The budget value is expressed in satoshis, and can be set using the `setparams`
loop command: loop command:
@ -165,23 +165,20 @@ loop command:
loop setparams --autobudget={budget in satoshis} loop setparams --autobudget={budget in satoshis}
``` ```
Your autoloop budget can optionally be paired with a start time, which Your autoloop budget is refreshed based on a configurable interval. You can
determines the time from which we will count autoloop swaps as being part of specify how often the budget is going to refresh by using the `setparams` loop
the budget. If this value is zero, it will consider all automatically command:
dispatched swaps as being part of the budget.
The start time is expressed as a unix timestamp, and can be set using the
`setparams` loop command:
``` ```
loop setparams --budgetstart={start time in seconds} loop setparams --autobudgetrefreshperiod={duration in seconds}
``` ```
If your autolooper has used up its budget, and you would like to top it up, you If your autolooper has used up its budget, and you would like to top it up, you
can do so by either increasing the overall budget amount, or by increasing the can do so by either increasing the overall budget amount, or by decreasing the
start time to the present. For example, if you want to set your autolooper to refresh interval. For example, if you want to set your autolooper to
have a budget of 100k sats for the month, you could set the following: have a budget of 100k sats per 7 days (or 604800 seconds), you could set the following:
``` ```
loop setparams --autobudget=100000 --autostart={beginning of month ts} loop setparams --autobudget=100000 --autobudgetrefreshperiod=604800
``` ```
## Dispatch Control ## Dispatch Control

@ -95,12 +95,12 @@ func TestAutoLoopEnabled(t *testing.T) {
// autoloop budget is set to allow exactly 2 swaps at the prices // autoloop budget is set to allow exactly 2 swaps at the prices
// that we set in our test quotes. // that we set in our test quotes.
params = Parameters{ params = Parameters{
Autoloop: true, Autoloop: true,
AutoFeeBudget: 40066, AutoFeeBudget: 40066,
AutoFeeStartDate: testTime, AutoFeeRefreshPeriod: testBudgetRefresh,
MaxAutoInFlight: 2, MaxAutoInFlight: 2,
FailureBackOff: time.Hour, FailureBackOff: time.Hour,
SweepConfTarget: 10, SweepConfTarget: 10,
FeeLimit: NewFeeCategoryLimit( FeeLimit: NewFeeCategoryLimit(
swapFeePPM, routeFeePPM, prepayFeePPM, maxMiner, swapFeePPM, routeFeePPM, prepayFeePPM, maxMiner,
prepayAmount, 20000, prepayAmount, 20000,
@ -112,6 +112,7 @@ func TestAutoLoopEnabled(t *testing.T) {
HtlcConfTarget: defaultHtlcConfTarget, HtlcConfTarget: defaultHtlcConfTarget,
} }
) )
c := newAutoloopTestCtx(t, params, channels, testRestrictions) c := newAutoloopTestCtx(t, params, channels, testRestrictions)
c.start() c.start()
@ -335,13 +336,13 @@ func TestAutoloopAddress(t *testing.T) {
// Create some dummy parameters for autoloop and also specify an // Create some dummy parameters for autoloop and also specify an
// destination address. // destination address.
params = Parameters{ params = Parameters{
Autoloop: true, Autoloop: true,
AutoFeeBudget: 40066, AutoFeeBudget: 40066,
DestAddr: addr, DestAddr: addr,
AutoFeeStartDate: testTime, AutoFeeRefreshPeriod: testBudgetRefresh,
MaxAutoInFlight: 2, MaxAutoInFlight: 2,
FailureBackOff: time.Hour, FailureBackOff: time.Hour,
SweepConfTarget: 10, SweepConfTarget: 10,
FeeLimit: NewFeeCategoryLimit( FeeLimit: NewFeeCategoryLimit(
swapFeePPM, routeFeePPM, prepayFeePPM, maxMiner, swapFeePPM, routeFeePPM, prepayFeePPM, maxMiner,
prepayAmount, 20000, prepayAmount, 20000,
@ -491,12 +492,12 @@ func TestCompositeRules(t *testing.T) {
swapFeePPM, routeFeePPM, prepayFeePPM, maxMiner, swapFeePPM, routeFeePPM, prepayFeePPM, maxMiner,
prepayAmount, 20000, prepayAmount, 20000,
), ),
Autoloop: true, Autoloop: true,
AutoFeeBudget: 100000, AutoFeeBudget: 100000,
AutoFeeStartDate: testTime, AutoFeeRefreshPeriod: testBudgetRefresh,
MaxAutoInFlight: 2, MaxAutoInFlight: 2,
FailureBackOff: time.Hour, FailureBackOff: time.Hour,
SweepConfTarget: 10, SweepConfTarget: 10,
ChannelRules: map[lnwire.ShortChannelID]*SwapRule{ ChannelRules: map[lnwire.ShortChannelID]*SwapRule{
chanID1: chanRule, chanID1: chanRule,
}, },
@ -670,13 +671,13 @@ func TestAutoLoopInEnabled(t *testing.T) {
peer2MaxFee = ppmToSat(peer2ExpectedAmt, swapFeePPM) peer2MaxFee = ppmToSat(peer2ExpectedAmt, swapFeePPM)
params = Parameters{ params = Parameters{
Autoloop: true, Autoloop: true,
AutoFeeBudget: peer1MaxFee + peer2MaxFee + 1, AutoFeeBudget: peer1MaxFee + peer2MaxFee + 1,
AutoFeeStartDate: testTime, AutoFeeRefreshPeriod: testBudgetRefresh,
MaxAutoInFlight: 2, MaxAutoInFlight: 2,
FailureBackOff: time.Hour, FailureBackOff: time.Hour,
FeeLimit: NewFeePortion(swapFeePPM), FeeLimit: NewFeePortion(swapFeePPM),
ChannelRules: make(map[lnwire.ShortChannelID]*SwapRule), ChannelRules: make(map[lnwire.ShortChannelID]*SwapRule),
PeerRules: map[route.Vertex]*SwapRule{ PeerRules: map[route.Vertex]*SwapRule{
peer1: rule, peer1: rule,
peer2: rule, peer2: rule,
@ -853,12 +854,12 @@ func TestAutoloopBothTypes(t *testing.T) {
loopInMaxFee = ppmToSat(loopInAmount, swapFeePPM) loopInMaxFee = ppmToSat(loopInAmount, swapFeePPM)
params = Parameters{ params = Parameters{
Autoloop: true, Autoloop: true,
AutoFeeBudget: loopOutMaxFee + loopInMaxFee + 1, AutoFeeBudget: loopOutMaxFee + loopInMaxFee + 1,
AutoFeeStartDate: testTime, AutoFeeRefreshPeriod: testBudgetRefresh,
MaxAutoInFlight: 2, MaxAutoInFlight: 2,
FailureBackOff: time.Hour, FailureBackOff: time.Hour,
FeeLimit: NewFeePortion(swapFeePPM), FeeLimit: NewFeePortion(swapFeePPM),
ChannelRules: map[lnwire.ShortChannelID]*SwapRule{ ChannelRules: map[lnwire.ShortChannelID]*SwapRule{
chanID1: outRule, chanID1: outRule,
}, },
@ -965,6 +966,211 @@ func TestAutoloopBothTypes(t *testing.T) {
c.stop() c.stop()
} }
// TestAutoLoopRecurringBudget tests that the autolooper will perform swaps that
// respect the fee budget, and that it will refresh the budget based on the
// defined refresh period.
func TestAutoLoopRecurringBudget(t *testing.T) {
defer test.Guard(t)()
var (
channels = []lndclient.ChannelInfo{
channel1, channel2,
}
swapFeePPM uint64 = 1000
routeFeePPM uint64 = 1000
prepayFeePPM uint64 = 1000
prepayAmount = btcutil.Amount(20000)
maxMiner = btcutil.Amount(20000)
params = Parameters{
Autoloop: true,
AutoFeeBudget: 36000,
AutoFeeRefreshPeriod: time.Hour * 3,
MaxAutoInFlight: 2,
FailureBackOff: time.Hour,
SweepConfTarget: 10,
FeeLimit: NewFeeCategoryLimit(
swapFeePPM, routeFeePPM, prepayFeePPM, maxMiner,
prepayAmount, 20000,
),
ChannelRules: map[lnwire.ShortChannelID]*SwapRule{
chanID1: chanRule,
chanID2: chanRule,
},
HtlcConfTarget: defaultHtlcConfTarget,
}
)
c := newAutoloopTestCtx(t, params, channels, testRestrictions)
c.start()
// Calculate our maximum allowed fees and create quotes that fall within
// our budget.
var (
amt = chan1Rec.Amount
maxSwapFee = ppmToSat(amt, swapFeePPM)
// Create a quote that is within our limits. We do not set miner
// fee because this value is not actually set by the server.
quote1 = &loop.LoopOutQuote{
SwapFee: maxSwapFee,
PrepayAmount: prepayAmount - 10,
MinerFee: maxMiner - 10,
}
quote2 = &loop.LoopOutQuote{
SwapFee: maxSwapFee,
PrepayAmount: prepayAmount - 20,
MinerFee: maxMiner - 10,
}
quoteRequest = &loop.LoopOutQuoteRequest{
Amount: amt,
SweepConfTarget: params.SweepConfTarget,
}
quotes1 = []quoteRequestResp{
{
request: quoteRequest,
quote: quote1,
},
{
request: quoteRequest,
quote: quote2,
},
}
quotes2 = []quoteRequestResp{
{
request: quoteRequest,
quote: quote2,
},
}
maxRouteFee = ppmToSat(amt, routeFeePPM)
chan1Swap = &loop.OutRequest{
Amount: amt,
MaxSwapRoutingFee: maxRouteFee,
MaxPrepayRoutingFee: ppmToSat(
quote1.PrepayAmount, prepayFeePPM,
),
MaxSwapFee: quote1.SwapFee,
MaxPrepayAmount: quote1.PrepayAmount,
MaxMinerFee: maxMiner,
SweepConfTarget: params.SweepConfTarget,
OutgoingChanSet: loopdb.ChannelSet{chanID1.ToUint64()},
Label: labels.AutoloopLabel(swap.TypeOut),
Initiator: autoloopSwapInitiator,
}
chan2Swap = &loop.OutRequest{
Amount: amt,
MaxSwapRoutingFee: maxRouteFee,
MaxPrepayRoutingFee: ppmToSat(
quote2.PrepayAmount, routeFeePPM,
),
MaxSwapFee: quote2.SwapFee,
MaxPrepayAmount: quote2.PrepayAmount,
MaxMinerFee: maxMiner,
SweepConfTarget: params.SweepConfTarget,
OutgoingChanSet: loopdb.ChannelSet{chanID2.ToUint64()},
Label: labels.AutoloopLabel(swap.TypeOut),
Initiator: autoloopSwapInitiator,
}
loopOuts1 = []loopOutRequestResp{
{
request: chan1Swap,
response: &loop.LoopOutSwapInfo{
SwapHash: lntypes.Hash{1},
},
},
}
loopOuts2 = []loopOutRequestResp{
{
request: chan2Swap,
response: &loop.LoopOutSwapInfo{
SwapHash: lntypes.Hash{1},
},
},
}
)
// Tick our autolooper with no existing swaps, we expect a loop out
// swap to be dispatched on first channel.
step := &autoloopStep{
minAmt: 1,
maxAmt: amt + 1,
quotesOut: quotes1,
expectedOut: loopOuts1,
}
c.autoloop(step)
existing := []*loopdb.LoopOut{
existingSwapFromRequest(
chan1Swap, testTime, []*loopdb.LoopEvent{
{
SwapStateData: loopdb.SwapStateData{
State: loopdb.StateInitiated,
},
Time: testTime,
},
},
),
}
step = &autoloopStep{
minAmt: 1,
maxAmt: amt + 1,
quotesOut: quotes2,
existingOut: existing,
expectedOut: nil,
}
// Tick again, we should expect no loop outs because our budget would be
// exceeded.
c.autoloop(step)
// Create the existing entry for the first swap, marking its last update
// with success and a specific timestamp.
existing2 := []*loopdb.LoopOut{
existingSwapFromRequest(
chan1Swap, testTime, []*loopdb.LoopEvent{
{
SwapStateData: loopdb.SwapStateData{
State: loopdb.StateSuccess,
},
Time: testTime,
},
},
),
}
// Apply the balance shifts on the channels in order to get the correct
// recommendations on next tick.
c.lnd.Channels[0].LocalBalance = 2500
c.lnd.Channels[0].RemoteBalance = 7500
// Advance time to the future, causing a budget refresh.
c.testClock.SetTime(testTime.Add(time.Hour * 25))
step = &autoloopStep{
minAmt: 1,
maxAmt: amt + 1,
quotesOut: quotes2,
existingOut: existing2,
expectedOut: loopOuts2,
}
// Tick again, we should expect a loop out to occur on the 2nd channel.
c.autoloop(step)
c.stop()
}
// existingSwapFromRequest is a helper function which returns the db // existingSwapFromRequest is a helper function which returns the db
// representation of a loop out request with the event set provided. // representation of a loop out request with the event set provided.
func existingSwapFromRequest(request *loop.OutRequest, initTime time.Time, func existingSwapFromRequest(request *loop.OutRequest, initTime time.Time,

@ -117,7 +117,8 @@ func newAutoloopTestCtx(t *testing.T, parameters Parameters,
testCtx.lnd.Channels = channels testCtx.lnd.Channels = channels
cfg := &Config{ cfg := &Config{
AutoloopTicker: ticker.NewForce(DefaultAutoloopTicker), AutoloopTicker: ticker.NewForce(DefaultAutoloopTicker),
AutoloopBudgetLastRefresh: testBudgetStart,
Restrictions: func(_ context.Context, swapType swap.Type) (*Restrictions, Restrictions: func(_ context.Context, swapType swap.Type) (*Restrictions,
error) { error) {

@ -104,6 +104,10 @@ var (
// funding amount. // funding amount.
defaultBudget = ppmToSat(funding.MaxBtcFundingAmount, defaultFeePPM) defaultBudget = ppmToSat(funding.MaxBtcFundingAmount, defaultFeePPM)
// defaultBudgetRefreshPeriod is the default amount of time we wait for
// the autoloop budget to be refreshed.
defaultBudgetRefreshPeriod = time.Hour * 24 * 7
// ErrZeroChannelID is returned if we get a rule for a 0 channel ID. // ErrZeroChannelID is returned if we get a rule for a 0 channel ID.
ErrZeroChannelID = fmt.Errorf("zero channel ID not allowed") ErrZeroChannelID = fmt.Errorf("zero channel ID not allowed")
@ -145,6 +149,10 @@ type Config struct {
// trigger autoloop in itests. // trigger autoloop in itests.
AutoloopTicker *ticker.Force AutoloopTicker *ticker.Force
// AutoloopBudgetLastRefresh is the last time at which we refreshed
// our budget.
AutoloopBudgetLastRefresh time.Time
// Restrictions returns the restrictions that the server applies to // Restrictions returns the restrictions that the server applies to
// swaps. // swaps.
Restrictions func(ctx context.Context, swapType swap.Type) ( Restrictions func(ctx context.Context, swapType swap.Type) (
@ -363,6 +371,10 @@ func (m *Manager) loadParams() (*clientrpc.LiquidityParameters, error) {
// autoloop gets a set of suggested swaps and dispatches them automatically if // autoloop gets a set of suggested swaps and dispatches them automatically if
// we have automated looping enabled. // we have automated looping enabled.
func (m *Manager) autoloop(ctx context.Context) error { func (m *Manager) autoloop(ctx context.Context) error {
// First check if we should refresh our budget before calculating any
// swaps for autoloop.
m.refreshAutoloopBudget(ctx)
suggestion, err := m.SuggestSwaps(ctx, true) suggestion, err := m.SuggestSwaps(ctx, true)
if err != nil { if err != nil {
return err return err
@ -506,16 +518,6 @@ func (m *Manager) SuggestSwaps(ctx context.Context, autoloop bool) (
return nil, ErrNoRules return nil, ErrNoRules
} }
// If our start date is in the future, we interpret this as meaning that
// we should start using our budget at this date. This means that we
// have no budget for the present, so we just return.
if m.params.AutoFeeStartDate.After(m.cfg.Clock.Now()) {
log.Debugf("autoloop fee budget start time: %v is in "+
"the future", m.params.AutoFeeStartDate)
return m.singleReasonSuggestion(ReasonBudgetNotStarted), nil
}
// Get restrictions placed on swaps by the server. // Get restrictions placed on swaps by the server.
outRestrictions, err := m.getSwapRestrictions(ctx, swap.TypeOut) outRestrictions, err := m.getSwapRestrictions(ctx, swap.TypeOut)
if err != nil { if err != nil {
@ -722,6 +724,12 @@ func (m *Manager) SuggestSwaps(ctx context.Context, autoloop bool) (
return nil, err return nil, err
} }
} else { } else {
refreshTime := m.params.AutoFeeRefreshPeriod -
time.Since(m.cfg.AutoloopBudgetLastRefresh)
log.Infof("Swap fee exceeds budget, remaining budget: "+
"%v, swap fee %v, next budget refresh: %v",
available, fees, refreshTime)
setReason(ReasonBudgetInsufficient, swap) setReason(ReasonBudgetInsufficient, swap)
} }
} }
@ -902,7 +910,10 @@ func (m *Manager) checkExistingAutoLoops(ctx context.Context,
out.Contract.MaxMinerFee, out.Contract.MaxMinerFee,
mSatToSatoshis(prepay.Value), mSatToSatoshis(prepay.Value),
) )
} else if !out.LastUpdateTime().Before(m.params.AutoFeeStartDate) { } else if out.LastUpdateTime().After(
m.cfg.AutoloopBudgetLastRefresh,
) {
summary.spentFees += out.State().Cost.Total() summary.spentFees += out.State().Cost.Total()
} }
} }
@ -913,7 +924,8 @@ func (m *Manager) checkExistingAutoLoops(ctx context.Context,
} }
pending := in.State().State.Type() == loopdb.StateTypePending pending := in.State().State.Type() == loopdb.StateTypePending
inBudget := !in.LastUpdateTime().Before(m.params.AutoFeeStartDate) inBudget := !in.LastUpdateTime().
Before(m.cfg.AutoloopBudgetLastRefresh)
// If an autoloop is in a pending state, we always count it in // If an autoloop is in a pending state, we always count it in
// our current budget, and record the worst-case fees for it, // our current budget, and record the worst-case fees for it,
@ -1020,6 +1032,18 @@ func (m *Manager) currentSwapTraffic(loopOut []*loopdb.LoopOut,
return traffic return traffic
} }
// refreshAutoloopBudget checks whether the elapsed time since our last autoloop
// budget refresh is greater than our configured refresh period. If so, the last
// refresh timestamp.
func (m *Manager) refreshAutoloopBudget(ctx context.Context) {
if time.Since(m.cfg.AutoloopBudgetLastRefresh) >
m.params.AutoFeeRefreshPeriod {
log.Debug("Refreshing autoloop budget")
m.cfg.AutoloopBudgetLastRefresh = m.cfg.Clock.Now()
}
}
// swapTraffic contains a summary of our current and previously failed swaps. // swapTraffic contains a summary of our current and previously failed swaps.
type swapTraffic struct { type swapTraffic struct {
ongoingLoopOut map[lnwire.ShortChannelID]bool ongoingLoopOut map[lnwire.ShortChannelID]bool

@ -24,6 +24,11 @@ import (
var ( var (
testTime = time.Date(2020, 02, 13, 0, 0, 0, 0, time.UTC) testTime = time.Date(2020, 02, 13, 0, 0, 0, 0, time.UTC)
testBudgetStart = testTime.Add(time.Hour * -1) testBudgetStart = testTime.Add(time.Hour * -1)
// In order to not influence existing tests we set the budget refresh
// period to 10 years so that it will never be refreshed. This way the
// behavior of autoloop remains identical to before recurring budget was
// introduced.
testBudgetRefresh = time.Hour * 24 * 365 * 10
chanID1 = lnwire.NewShortChanIDFromInt(1) chanID1 = lnwire.NewShortChanIDFromInt(1)
chanID2 = lnwire.NewShortChanIDFromInt(2) chanID2 = lnwire.NewShortChanIDFromInt(2)
@ -143,8 +148,9 @@ func newTestConfig() (*Config, *test.LndMockServices) {
return testRestrictions, nil return testRestrictions, nil
}, },
Lnd: &lnd.LndServices, Lnd: &lnd.LndServices,
Clock: clock.NewTestClock(testTime), Clock: clock.NewTestClock(testTime),
AutoloopBudgetLastRefresh: testBudgetStart,
ListLoopOut: func() ([]*loopdb.LoopOut, error) { ListLoopOut: func() ([]*loopdb.LoopOut, error) {
return nil, nil return nil, nil
}, },
@ -1100,8 +1106,8 @@ func TestFeeBudget(t *testing.T) {
chanID1: chanRule, chanID1: chanRule,
chanID2: chanRule, chanID2: chanRule,
} }
params.AutoFeeStartDate = testBudgetStart
params.AutoFeeBudget = testCase.budget params.AutoFeeBudget = testCase.budget
params.AutoFeeRefreshPeriod = testBudgetRefresh
params.MaxAutoInFlight = 2 params.MaxAutoInFlight = 2
params.FeeLimit = NewFeeCategoryLimit( params.FeeLimit = NewFeeCategoryLimit(
defaultSwapFeePPM, defaultRoutingFeePPM, defaultSwapFeePPM, defaultRoutingFeePPM,
@ -1758,7 +1764,7 @@ func TestBudgetWithLoopin(t *testing.T) {
params := defaultParameters params := defaultParameters
params.AutoFeeBudget = budget params.AutoFeeBudget = budget
params.AutoFeeStartDate = testBudgetStart params.AutoFeeRefreshPeriod = testBudgetRefresh
params.FeeLimit = NewFeePortion(testPPM) params.FeeLimit = NewFeePortion(testPPM)
params.ChannelRules = map[lnwire.ShortChannelID]*SwapRule{ params.ChannelRules = map[lnwire.ShortChannelID]*SwapRule{

@ -20,15 +20,16 @@ var (
// defaultParameters contains the default parameters that we start our // defaultParameters contains the default parameters that we start our
// liquidity manager with. // liquidity manager with.
defaultParameters = Parameters{ defaultParameters = Parameters{
AutoFeeBudget: defaultBudget, AutoFeeBudget: defaultBudget,
DestAddr: nil, AutoFeeRefreshPeriod: defaultBudgetRefreshPeriod,
MaxAutoInFlight: defaultMaxInFlight, DestAddr: nil,
ChannelRules: make(map[lnwire.ShortChannelID]*SwapRule), MaxAutoInFlight: defaultMaxInFlight,
PeerRules: make(map[route.Vertex]*SwapRule), ChannelRules: make(map[lnwire.ShortChannelID]*SwapRule),
FailureBackOff: defaultFailureBackoff, PeerRules: make(map[route.Vertex]*SwapRule),
SweepConfTarget: defaultConfTarget, FailureBackOff: defaultFailureBackoff,
HtlcConfTarget: defaultHtlcConfTarget, SweepConfTarget: defaultConfTarget,
FeeLimit: defaultFeePortion(), HtlcConfTarget: defaultHtlcConfTarget,
FeeLimit: defaultFeePortion(),
} }
) )
@ -44,13 +45,12 @@ type Parameters struct {
// AutoFeeBudget is the total amount we allow to be spent on // AutoFeeBudget is the total amount we allow to be spent on
// automatically dispatched swaps. Once this budget has been used, we // automatically dispatched swaps. Once this budget has been used, we
// will stop dispatching swaps until the budget is increased or the // will stop dispatching swaps until the budget is refreshed.
// start date is moved.
AutoFeeBudget btcutil.Amount AutoFeeBudget btcutil.Amount
// AutoFeeStartDate is the date from which we will include automatically // AutoFeeRefreshPeriod is the amount of time that must pass before the
// dispatched swaps in our current budget, inclusive. // auto fee budget is refreshed.
AutoFeeStartDate time.Time AutoFeeRefreshPeriod time.Duration
// MaxAutoInFlight is the maximum number of in-flight automatically // MaxAutoInFlight is the maximum number of in-flight automatically
// dispatched swaps we allow. // dispatched swaps we allow.
@ -107,11 +107,11 @@ func (p Parameters) String() string {
return fmt.Sprintf("rules: %v, failure backoff: %v, sweep "+ return fmt.Sprintf("rules: %v, failure backoff: %v, sweep "+
"sweep conf target: %v, htlc conf target: %v,fees: %v, "+ "sweep conf target: %v, htlc conf target: %v,fees: %v, "+
"auto budget: %v, budget start: %v, max auto in flight: %v, "+ "auto budget: %v, budget refresh: %v, max auto in flight: %v, "+
"minimum swap size=%v, maximum swap size=%v", "minimum swap size=%v, maximum swap size=%v",
strings.Join(ruleList, ","), p.FailureBackOff, strings.Join(ruleList, ","), p.FailureBackOff,
p.SweepConfTarget, p.HtlcConfTarget, p.FeeLimit, p.SweepConfTarget, p.HtlcConfTarget, p.FeeLimit,
p.AutoFeeBudget, p.AutoFeeStartDate, p.MaxAutoInFlight, p.AutoFeeBudget, p.AutoFeeRefreshPeriod, p.MaxAutoInFlight,
p.ClientRestrictions.Minimum, p.ClientRestrictions.Maximum) p.ClientRestrictions.Minimum, p.ClientRestrictions.Maximum)
} }
@ -386,11 +386,10 @@ func rpcToParameters(req *clientrpc.LiquidityParameters) (*Parameters,
HtlcConfTarget: req.HtlcConfTarget, HtlcConfTarget: req.HtlcConfTarget,
} }
// Zero unix time is different to zero golang time. if req.AutoloopBudgetRefreshPeriodSec != 0 {
if req.AutoloopBudgetStartSec != 0 { params.AutoFeeRefreshPeriod =
params.AutoFeeStartDate = time.Unix( time.Duration(req.AutoloopBudgetRefreshPeriodSec) *
int64(req.AutoloopBudgetStartSec), 0, time.Second
)
} }
for _, rule := range req.Rules { for _, rule := range req.Rules {

@ -753,10 +753,13 @@ func (s *swapClientServer) GetLiquidityParams(_ context.Context,
} }
rpcCfg := &clientrpc.LiquidityParameters{ rpcCfg := &clientrpc.LiquidityParameters{
SweepConfTarget: cfg.SweepConfTarget, SweepConfTarget: cfg.SweepConfTarget,
FailureBackoffSec: uint64(cfg.FailureBackOff.Seconds()), FailureBackoffSec: uint64(cfg.FailureBackOff.Seconds()),
Autoloop: cfg.Autoloop, Autoloop: cfg.Autoloop,
AutoloopBudgetSat: uint64(cfg.AutoFeeBudget), AutoloopBudgetSat: uint64(cfg.AutoFeeBudget),
AutoloopBudgetRefreshPeriodSec: uint64(
cfg.AutoFeeRefreshPeriod.Seconds(),
),
AutoMaxInFlight: uint64(cfg.MaxAutoInFlight), AutoMaxInFlight: uint64(cfg.MaxAutoInFlight),
AutoloopDestAddress: destaddr, AutoloopDestAddress: destaddr,
Rules: make( Rules: make(
@ -786,14 +789,6 @@ func (s *swapClientServer) GetLiquidityParams(_ context.Context,
return nil, fmt.Errorf("unknown fee limit: %T", cfg.FeeLimit) return nil, fmt.Errorf("unknown fee limit: %T", cfg.FeeLimit)
} }
// Zero golang time is different to a zero unix time, so we only set
// our start date if it is non-zero.
if !cfg.AutoFeeStartDate.IsZero() {
rpcCfg.AutoloopBudgetStartSec = uint64(
cfg.AutoFeeStartDate.Unix(),
)
}
for channel, rule := range cfg.ChannelRules { for channel, rule := range cfg.ChannelRules {
rpcRule := newRPCRule(channel.ToUint64(), nil, rule) rpcRule := newRPCRule(channel.ToUint64(), nil, rule)
rpcCfg.Rules = append(rpcCfg.Rules, rpcRule) rpcCfg.Rules = append(rpcCfg.Rules, rpcRule)

@ -2,6 +2,7 @@ package loopd
import ( import (
"context" "context"
"time"
"github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/btcutil"
"github.com/lightninglabs/lndclient" "github.com/lightninglabs/lndclient"
@ -39,9 +40,10 @@ func getClient(config *Config, lnd *lndclient.LndServices) (*loop.Client,
func getLiquidityManager(client *loop.Client) *liquidity.Manager { func getLiquidityManager(client *loop.Client) *liquidity.Manager {
mngrCfg := &liquidity.Config{ mngrCfg := &liquidity.Config{
AutoloopTicker: ticker.NewForce(liquidity.DefaultAutoloopTicker), AutoloopTicker: ticker.NewForce(liquidity.DefaultAutoloopTicker),
LoopOut: client.LoopOut, AutoloopBudgetLastRefresh: time.Now(),
LoopIn: client.LoopIn, LoopOut: client.LoopOut,
LoopIn: client.LoopIn,
Restrictions: func(ctx context.Context, Restrictions: func(ctx context.Context,
swapType swap.Type) (*liquidity.Restrictions, error) { swapType swap.Type) (*liquidity.Restrictions, error) {

@ -2172,12 +2172,6 @@ type LiquidityParameters struct {
//time, expressed in satoshis. //time, expressed in satoshis.
AutoloopBudgetSat uint64 `protobuf:"varint,11,opt,name=autoloop_budget_sat,json=autoloopBudgetSat,proto3" json:"autoloop_budget_sat,omitempty"` AutoloopBudgetSat uint64 `protobuf:"varint,11,opt,name=autoloop_budget_sat,json=autoloopBudgetSat,proto3" json:"autoloop_budget_sat,omitempty"`
// //
//The start time for autoloop budget, expressed as a unix timestamp in
//seconds. If this value is 0, the budget will be applied for all
//automatically dispatched swaps. Swaps that were completed before this date
//will not be included in budget calculations.
AutoloopBudgetStartSec uint64 `protobuf:"varint,12,opt,name=autoloop_budget_start_sec,json=autoloopBudgetStartSec,proto3" json:"autoloop_budget_start_sec,omitempty"`
//
//The maximum number of automatically dispatched swaps that we allow to be in //The maximum number of automatically dispatched swaps that we allow to be in
//flight at any point in time. //flight at any point in time.
AutoMaxInFlight uint64 `protobuf:"varint,13,opt,name=auto_max_in_flight,json=autoMaxInFlight,proto3" json:"auto_max_in_flight,omitempty"` AutoMaxInFlight uint64 `protobuf:"varint,13,opt,name=auto_max_in_flight,json=autoMaxInFlight,proto3" json:"auto_max_in_flight,omitempty"`
@ -2198,6 +2192,10 @@ type LiquidityParameters struct {
//The destination address to use for autoloop loop outs. Set to "default" in //The destination address to use for autoloop loop outs. Set to "default" in
//order to revert to default behavior. //order to revert to default behavior.
AutoloopDestAddress string `protobuf:"bytes,18,opt,name=autoloop_dest_address,json=autoloopDestAddress,proto3" json:"autoloop_dest_address,omitempty"` AutoloopDestAddress string `protobuf:"bytes,18,opt,name=autoloop_dest_address,json=autoloopDestAddress,proto3" json:"autoloop_dest_address,omitempty"`
//
//The period over which the autoloop budget is refreshed, expressed in
//seconds.
AutoloopBudgetRefreshPeriodSec uint64 `protobuf:"varint,19,opt,name=autoloop_budget_refresh_period_sec,json=autoloopBudgetRefreshPeriodSec,proto3" json:"autoloop_budget_refresh_period_sec,omitempty"`
} }
func (x *LiquidityParameters) Reset() { func (x *LiquidityParameters) Reset() {
@ -2316,13 +2314,6 @@ func (x *LiquidityParameters) GetAutoloopBudgetSat() uint64 {
return 0 return 0
} }
func (x *LiquidityParameters) GetAutoloopBudgetStartSec() uint64 {
if x != nil {
return x.AutoloopBudgetStartSec
}
return 0
}
func (x *LiquidityParameters) GetAutoMaxInFlight() uint64 { func (x *LiquidityParameters) GetAutoMaxInFlight() uint64 {
if x != nil { if x != nil {
return x.AutoMaxInFlight return x.AutoMaxInFlight
@ -2358,6 +2349,13 @@ func (x *LiquidityParameters) GetAutoloopDestAddress() string {
return "" return ""
} }
func (x *LiquidityParameters) GetAutoloopBudgetRefreshPeriodSec() uint64 {
if x != nil {
return x.AutoloopBudgetRefreshPeriodSec
}
return 0
}
type LiquidityRule struct { type LiquidityRule struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -2957,7 +2955,7 @@ var file_client_proto_rawDesc = []byte{
0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22,
0x1b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x1b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50,
0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xbe, 0x06, 0x0a, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xcf, 0x06, 0x0a,
0x13, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x13, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65,
0x74, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69,
@ -2992,186 +2990,187 @@ var file_client_proto_rawDesc = []byte{
0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x75, 0x74, 0x6f, 0x6c,
0x6f, 0x6f, 0x70, 0x5f, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x0b, 0x6f, 0x6f, 0x70, 0x5f, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x61, 0x74, 0x18, 0x0b,
0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x42, 0x75, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x42, 0x75,
0x64, 0x67, 0x65, 0x74, 0x53, 0x61, 0x74, 0x12, 0x39, 0x0a, 0x19, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x64, 0x67, 0x65, 0x74, 0x53, 0x61, 0x74, 0x12, 0x2b, 0x0a, 0x12, 0x61, 0x75, 0x74, 0x6f, 0x5f,
0x6f, 0x6f, 0x70, 0x5f, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x6e, 0x5f, 0x66, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x18, 0x0d, 0x20,
0x5f, 0x73, 0x65, 0x63, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x61, 0x75, 0x74, 0x6f, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x61, 0x75, 0x74, 0x6f, 0x4d, 0x61, 0x78, 0x49, 0x6e, 0x46, 0x6c,
0x6c, 0x6f, 0x6f, 0x70, 0x42, 0x75, 0x64, 0x67, 0x65, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x69, 0x67, 0x68, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x77, 0x61, 0x70,
0x65, 0x63, 0x12, 0x2b, 0x0a, 0x12, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6d,
0x6e, 0x5f, 0x66, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x69, 0x6e, 0x53, 0x77, 0x61, 0x70, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f,
0x61, 0x75, 0x74, 0x6f, 0x4d, 0x61, 0x78, 0x49, 0x6e, 0x46, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18,
0x26, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x0f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x53, 0x77, 0x61, 0x70, 0x41, 0x6d,
0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x53, 0x77, 0x61, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x63, 0x6f, 0x6e,
0x70, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x66, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e,
0x77, 0x61, 0x70, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x04, 0x68, 0x74, 0x6c, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x32,
0x52, 0x0d, 0x6d, 0x61, 0x78, 0x53, 0x77, 0x61, 0x70, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0a, 0x15, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x5f,
0x28, 0x0a, 0x10, 0x68, 0x74, 0x6c, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x74, 0x61, 0x72, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x61,
0x67, 0x65, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x68, 0x74, 0x6c, 0x63, 0x43, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x44, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65,
0x6f, 0x6e, 0x66, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x61, 0x75, 0x74, 0x73, 0x73, 0x12, 0x4a, 0x0a, 0x22, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x62,
0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x75, 0x64, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x70, 0x65,
0x73, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x73, 0x65, 0x63, 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1e,
0x6f, 0x70, 0x44, 0x65, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x84, 0x02, 0x61, 0x75, 0x74, 0x6f, 0x6c, 0x6f, 0x6f, 0x70, 0x42, 0x75, 0x64, 0x67, 0x65, 0x74, 0x52, 0x65,
0x0a, 0x0d, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x66, 0x72, 0x65, 0x73, 0x68, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x53, 0x65, 0x63, 0x22, 0x84,
0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x02, 0x0a, 0x0d, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65,
0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x2e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01,
0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12,
0x0e, 0x32, 0x11, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x2e, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01,
0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61,
0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12,
0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18,
0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e,
0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70,
0x6e, 0x67, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x69, 0x6e, 0x63, 0x6f, 0x6d,
0x28, 0x0d, 0x52, 0x11, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x54, 0x68, 0x72, 0x65, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20,
0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x2d, 0x0a, 0x12, 0x6f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x54, 0x68, 0x72,
0x67, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x2d, 0x0a, 0x12, 0x6f, 0x75, 0x74, 0x67, 0x6f, 0x69,
0x0d, 0x52, 0x11, 0x6f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x54, 0x68, 0x72, 0x65, 0x73, 0x6e, 0x67, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x04, 0x20, 0x01,
0x68, 0x6f, 0x6c, 0x64, 0x22, 0x59, 0x0a, 0x19, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x28, 0x0d, 0x52, 0x11, 0x6f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x54, 0x68, 0x72, 0x65,
0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x22, 0x59, 0x0a, 0x19, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75,
0x74, 0x12, 0x3c, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e,
0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
0x65, 0x72, 0x73, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22,
0x1c, 0x0a, 0x1a, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50,
0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x0a,
0x13, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x22, 0x72, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x71, 0x75, 0x61, 0x6c, 0x69,
0x66, 0x69, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f,
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
0x6c, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x06, 0x72,
0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x6c, 0x6f,
0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e,
0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0xb6, 0x01, 0x0a, 0x14, 0x53, 0x75, 0x67,
0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x32, 0x0a, 0x08, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f,
0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x6c, 0x6f,
0x6f, 0x70, 0x4f, 0x75, 0x74, 0x12, 0x2f, 0x0a, 0x07, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x69, 0x6e,
0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63,
0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x06,
0x6c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, 0x39, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x71, 0x75, 0x61,
0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6c,
0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66,
0x69, 0x65, 0x64, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69, 0x65,
0x64, 0x2a, 0x25, 0x0a, 0x08, 0x53, 0x77, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a,
0x08, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x4c,
0x4f, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x10, 0x01, 0x2a, 0x73, 0x0a, 0x09, 0x53, 0x77, 0x61, 0x70,
0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x54,
0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x52, 0x45, 0x49, 0x4d, 0x41, 0x47, 0x45,
0x5f, 0x52, 0x45, 0x56, 0x45, 0x41, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x48,
0x54, 0x4c, 0x43, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x02, 0x12,
0x0b, 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06,
0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x4e, 0x56, 0x4f,
0x49, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x2a, 0xed, 0x01,
0x0a, 0x0d, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12,
0x17, 0x0a, 0x13, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f,
0x4e, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x41, 0x49, 0x4c,
0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4f, 0x46, 0x46, 0x43, 0x48,
0x41, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45,
0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10,
0x02, 0x12, 0x20, 0x0a, 0x1c, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41,
0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55,
0x54, 0x10, 0x03, 0x12, 0x25, 0x0a, 0x21, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52,
0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45,
0x4e, 0x54, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x04, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x41,
0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x45, 0x4d,
0x50, 0x4f, 0x52, 0x41, 0x52, 0x59, 0x10, 0x05, 0x12, 0x23, 0x0a, 0x1f, 0x46, 0x41, 0x49, 0x4c,
0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x52,
0x52, 0x45, 0x43, 0x54, 0x5f, 0x41, 0x4d, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x06, 0x2a, 0x2f, 0x0a,
0x11, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79,
0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12,
0x0d, 0x0a, 0x09, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x01, 0x2a, 0xa6,
0x03, 0x0a, 0x0a, 0x41, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x0a,
0x13, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b,
0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x22, 0x0a, 0x1e, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52,
0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x4e, 0x4f, 0x54,
0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x55,
0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f,
0x46, 0x45, 0x45, 0x53, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52,
0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x45, 0x4c, 0x41,
0x50, 0x53, 0x45, 0x44, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52,
0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x5f, 0x46, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x10,
0x04, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e,
0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x46, 0x45, 0x45, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x41,
0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x4e, 0x45, 0x52,
0x5f, 0x46, 0x45, 0x45, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52,
0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x50, 0x52, 0x45, 0x50, 0x41, 0x59, 0x10, 0x07, 0x12, 0x1f,
0x0a, 0x1b, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x46, 0x41,
0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x4f, 0x46, 0x46, 0x10, 0x08, 0x12,
0x18, 0x0a, 0x14, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c,
0x4f, 0x4f, 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x09, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x55, 0x54,
0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x49, 0x4e,
0x10, 0x0a, 0x12, 0x1c, 0x0a, 0x18, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f,
0x4e, 0x5f, 0x4c, 0x49, 0x51, 0x55, 0x49, 0x44, 0x49, 0x54, 0x59, 0x5f, 0x4f, 0x4b, 0x10, 0x0b,
0x12, 0x23, 0x0a, 0x1f, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f,
0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49,
0x45, 0x4e, 0x54, 0x10, 0x0c, 0x12, 0x20, 0x0a, 0x1c, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45,
0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49,
0x43, 0x49, 0x45, 0x4e, 0x54, 0x10, 0x0d, 0x32, 0xc2, 0x07, 0x0a, 0x0a, 0x53, 0x77, 0x61, 0x70,
0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x07, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75,
0x74, 0x12, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70,
0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6c, 0x6f, 0x6f,
0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x37, 0x0a, 0x06, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, 0x16, 0x2e, 0x6c, 0x6f,
0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77,
0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x4d, 0x6f,
0x6e, 0x69, 0x74, 0x6f, 0x72, 0x12, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e,
0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13,
0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74, 0x61,
0x74, 0x75, 0x73, 0x30, 0x01, 0x12, 0x42, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61,
0x70, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73,
0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e,
0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x53, 0x77, 0x61,
0x70, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e,
0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74,
0x61, 0x74, 0x75, 0x73, 0x12, 0x40, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x54,
0x65, 0x72, 0x6d, 0x73, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54,
0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c, 0x6f,
0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75,
0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63,
0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e,
0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c,
0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f,
0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x54, 0x65,
0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x47,
0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x15, 0x2e,
0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49,
0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36,
0x0a, 0x05, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70,
0x63, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16,
0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4c, 0x73, 0x61,
0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70,
0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4c,
0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22,
0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75,
0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x71, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73,
0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63,
0x12, 0x5d, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x2e, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65,
0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73,
0x2e, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x22, 0x1c, 0x0a, 0x1a, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79,
0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6c, 0x6f, 0x6f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15,
0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x0a, 0x13, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65,
0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x72, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x71, 0x75, 0x61, 0x6c,
0x4b, 0x0a, 0x0c, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x12, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e,
0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x03,
0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x06,
0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x6c,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x61, 0x73, 0x6f,
0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x6c, 0x6f, 0x6e, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0xb6, 0x01, 0x0a, 0x14, 0x53, 0x75,
0x6f, 0x70, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x6f, 0x75, 0x74, 0x18, 0x01,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c,
0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x6c,
0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74, 0x12, 0x2f, 0x0a, 0x07, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x69,
0x6e, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70,
0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52,
0x06, 0x6c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, 0x39, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x71, 0x75,
0x61, 0x6c, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e,
0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x71, 0x75, 0x61, 0x6c, 0x69,
0x66, 0x69, 0x65, 0x64, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x69,
0x65, 0x64, 0x2a, 0x25, 0x0a, 0x08, 0x53, 0x77, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c,
0x0a, 0x08, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07,
0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x49, 0x4e, 0x10, 0x01, 0x2a, 0x73, 0x0a, 0x09, 0x53, 0x77, 0x61,
0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41,
0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x52, 0x45, 0x49, 0x4d, 0x41, 0x47,
0x45, 0x5f, 0x52, 0x45, 0x56, 0x45, 0x41, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e,
0x48, 0x54, 0x4c, 0x43, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x02,
0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x03, 0x12, 0x0a, 0x0a,
0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x4e, 0x56,
0x4f, 0x49, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x2a, 0xed,
0x01, 0x0a, 0x0d, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e,
0x12, 0x17, 0x0a, 0x13, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53,
0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x41, 0x49,
0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4f, 0x46, 0x46, 0x43,
0x48, 0x41, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52,
0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54,
0x10, 0x02, 0x12, 0x20, 0x0a, 0x1c, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45,
0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x45, 0x45, 0x50, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f,
0x55, 0x54, 0x10, 0x03, 0x12, 0x25, 0x0a, 0x21, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f,
0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49,
0x45, 0x4e, 0x54, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x04, 0x12, 0x1c, 0x0a, 0x18, 0x46,
0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x54, 0x45,
0x4d, 0x50, 0x4f, 0x52, 0x41, 0x52, 0x59, 0x10, 0x05, 0x12, 0x23, 0x0a, 0x1f, 0x46, 0x41, 0x49,
0x4c, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x43, 0x4f,
0x52, 0x52, 0x45, 0x43, 0x54, 0x5f, 0x41, 0x4d, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x06, 0x2a, 0x2f,
0x0a, 0x11, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x54,
0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00,
0x12, 0x0d, 0x0a, 0x09, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x10, 0x01, 0x2a,
0xa6, 0x03, 0x0a, 0x0a, 0x41, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x17,
0x0a, 0x13, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e,
0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x22, 0x0a, 0x1e, 0x41, 0x55, 0x54, 0x4f, 0x5f,
0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x4e, 0x4f,
0x54, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x41,
0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x53, 0x57, 0x45, 0x45, 0x50,
0x5f, 0x46, 0x45, 0x45, 0x53, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x41, 0x55, 0x54, 0x4f, 0x5f,
0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x45, 0x4c,
0x41, 0x50, 0x53, 0x45, 0x44, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x55, 0x54, 0x4f, 0x5f,
0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x5f, 0x46, 0x4c, 0x49, 0x47, 0x48, 0x54,
0x10, 0x04, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f,
0x4e, 0x5f, 0x53, 0x57, 0x41, 0x50, 0x5f, 0x46, 0x45, 0x45, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15,
0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x4e, 0x45,
0x52, 0x5f, 0x46, 0x45, 0x45, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x55, 0x54, 0x4f, 0x5f,
0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x50, 0x52, 0x45, 0x50, 0x41, 0x59, 0x10, 0x07, 0x12,
0x1f, 0x0a, 0x1b, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x46,
0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x4f, 0x46, 0x46, 0x10, 0x08,
0x12, 0x18, 0x0a, 0x14, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f,
0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x4f, 0x55, 0x54, 0x10, 0x09, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x55,
0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x4f, 0x50, 0x5f, 0x49,
0x4e, 0x10, 0x0a, 0x12, 0x1c, 0x0a, 0x18, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53,
0x4f, 0x4e, 0x5f, 0x4c, 0x49, 0x51, 0x55, 0x49, 0x44, 0x49, 0x54, 0x59, 0x5f, 0x4f, 0x4b, 0x10,
0x0b, 0x12, 0x23, 0x0a, 0x1f, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e,
0x5f, 0x42, 0x55, 0x44, 0x47, 0x45, 0x54, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43,
0x49, 0x45, 0x4e, 0x54, 0x10, 0x0c, 0x12, 0x20, 0x0a, 0x1c, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x52,
0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x46, 0x45, 0x45, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46,
0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x10, 0x0d, 0x32, 0xc2, 0x07, 0x0a, 0x0a, 0x53, 0x77, 0x61,
0x70, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x07, 0x4c, 0x6f, 0x6f, 0x70, 0x4f,
0x75, 0x74, 0x12, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f,
0x70, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6c, 0x6f,
0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x12, 0x16, 0x2e, 0x6c,
0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53,
0x77, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x4d,
0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x12, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63,
0x2e, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x53, 0x74,
0x61, 0x74, 0x75, 0x73, 0x30, 0x01, 0x12, 0x42, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77,
0x61, 0x70, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69,
0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a,
0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x77, 0x61,
0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x53, 0x77,
0x61, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63,
0x2e, 0x53, 0x77, 0x61, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x13, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x70, 0x53,
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x40, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x70, 0x4f, 0x75, 0x74,
0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e,
0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6c,
0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x4c, 0x6f, 0x6f, 0x70, 0x4f,
0x75, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70,
0x63, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19,
0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4f, 0x75, 0x74, 0x51, 0x75, 0x6f, 0x74,
0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x47, 0x65, 0x74,
0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x15, 0x2e, 0x6c, 0x6f,
0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x54,
0x65, 0x72, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0e,
0x47, 0x65, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x12, 0x15,
0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e,
0x49, 0x6e, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x36, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x15, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72,
0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4c, 0x73,
0x61, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x16, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72,
0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x17, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x12, 0x47, 0x65, 0x74,
0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12,
0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x71,
0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69,
0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
0x73, 0x12, 0x5d, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74,
0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70,
0x63, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69, 0x74, 0x79, 0x50, 0x61,
0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6c, 0x6f,
0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x71, 0x75, 0x69, 0x64, 0x69,
0x74, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x4b, 0x0a, 0x0c, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73,
0x12, 0x1c, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x67, 0x67, 0x65,
0x73, 0x74, 0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d,
0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74,
0x53, 0x77, 0x61, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27, 0x5a,
0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68,
0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x6c,
0x6f, 0x6f, 0x70, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (

@ -822,14 +822,6 @@ message LiquidityParameters {
*/ */
uint64 autoloop_budget_sat = 11; uint64 autoloop_budget_sat = 11;
/*
The start time for autoloop budget, expressed as a unix timestamp in
seconds. If this value is 0, the budget will be applied for all
automatically dispatched swaps. Swaps that were completed before this date
will not be included in budget calculations.
*/
uint64 autoloop_budget_start_sec = 12;
/* /*
The maximum number of automatically dispatched swaps that we allow to be in The maximum number of automatically dispatched swaps that we allow to be in
flight at any point in time. flight at any point in time.
@ -860,6 +852,12 @@ message LiquidityParameters {
order to revert to default behavior. order to revert to default behavior.
*/ */
string autoloop_dest_address = 18; string autoloop_dest_address = 18;
/*
The period over which the autoloop budget is refreshed, expressed in
seconds.
*/
uint64 autoloop_budget_refresh_period_sec = 19;
} }
enum LiquidityRuleType { enum LiquidityRuleType {

@ -656,11 +656,6 @@
"format": "uint64", "format": "uint64",
"description": "The total budget for automatically dispatched swaps since the budget start\ntime, expressed in satoshis." "description": "The total budget for automatically dispatched swaps since the budget start\ntime, expressed in satoshis."
}, },
"autoloop_budget_start_sec": {
"type": "string",
"format": "uint64",
"description": "The start time for autoloop budget, expressed as a unix timestamp in\nseconds. If this value is 0, the budget will be applied for all\nautomatically dispatched swaps. Swaps that were completed before this date\nwill not be included in budget calculations."
},
"auto_max_in_flight": { "auto_max_in_flight": {
"type": "string", "type": "string",
"format": "uint64", "format": "uint64",
@ -684,6 +679,11 @@
"autoloop_dest_address": { "autoloop_dest_address": {
"type": "string", "type": "string",
"description": "The destination address to use for autoloop loop outs. Set to \"default\" in\norder to revert to default behavior." "description": "The destination address to use for autoloop loop outs. Set to \"default\" in\norder to revert to default behavior."
},
"autoloop_budget_refresh_period_sec": {
"type": "string",
"format": "uint64",
"description": "The period over which the autoloop budget is refreshed, expressed in\nseconds."
} }
} }
}, },

@ -15,6 +15,9 @@ This file tracks release notes for the loop client.
## Next release ## Next release
#### New Features #### New Features
* Autoloop now uses a recurring budget. Users can now specify `autobudget` and
`autobudgetrefreshperiod` to specify the amount of the budget and the period
over which it will refresh.
#### Breaking Changes #### Breaking Changes

Loading…
Cancel
Save