Skip to content

Commit

Permalink
Merge pull request #708 from sputn1ck/listinstantouts
Browse files Browse the repository at this point in the history
Add `listinstantouts` command
  • Loading branch information
sputn1ck authored Mar 5, 2024
2 parents 65b8cb6 + 034bc24 commit 5d75e99
Show file tree
Hide file tree
Showing 13 changed files with 711 additions and 239 deletions.
28 changes: 28 additions & 0 deletions cmd/loop/instantout.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,31 @@ func instantOut(ctx *cli.Context) error {

return nil
}

var listInstantOutsCommand = cli.Command{
Name: "listinstantouts",
Usage: "list all instant out swaps",
Description: `
List all instant out swaps.
`,
Action: listInstantOuts,
}

func listInstantOuts(ctx *cli.Context) error {
// First set up the swap client itself.
client, cleanup, err := getClient(ctx)
if err != nil {
return err
}
defer cleanup()

resp, err := client.ListInstantOuts(
context.Background(), &looprpc.ListInstantOutsRequest{},
)
if err != nil {
return err
}

printRespJSON(resp)
return nil
}
2 changes: 1 addition & 1 deletion cmd/loop/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func main() {
listSwapsCommand, swapInfoCommand, getLiquidityParamsCommand,
setLiquidityRuleCommand, suggestSwapCommand, setParamsCommand,
getInfoCommand, abandonSwapCommand, reservationsCommands,
instantOutCommand,
instantOutCommand, listInstantOutsCommand,
}

err := app.Run(os.Args)
Expand Down
18 changes: 9 additions & 9 deletions instantout/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,13 @@ func (f *FSM) InitInstantOutAction(eventCtx fsm.EventContext) fsm.EventType {
protocolVersion: ProtocolVersionFullReservation,
initiationHeight: initCtx.initationHeight,
outgoingChanSet: initCtx.outgoingChanSet,
cltvExpiry: initCtx.cltvExpiry,
CltvExpiry: initCtx.cltvExpiry,
clientPubkey: keyRes.PubKey,
serverPubkey: serverPubkey,
value: btcutil.Amount(reservationAmt),
Value: btcutil.Amount(reservationAmt),
htlcFeeRate: feeRate,
swapInvoice: instantOutResponse.SwapInvoice,
reservations: reservations,
Reservations: reservations,
keyLocator: keyRes.KeyLocator,
sweepAddress: sweepAddress,
}
Expand All @@ -211,7 +211,7 @@ func (f *FSM) InitInstantOutAction(eventCtx fsm.EventContext) fsm.EventType {
func (f *FSM) PollPaymentAcceptedAction(_ fsm.EventContext) fsm.EventType {
// Now that we're doing the swap, we first lock the reservations
// so that they can't be used for other swaps.
for _, reservation := range f.InstantOut.reservations {
for _, reservation := range f.InstantOut.Reservations {
err := f.cfg.ReservationManager.LockReservation(
f.ctx, reservation.ID,
)
Expand All @@ -227,7 +227,7 @@ func (f *FSM) PollPaymentAcceptedAction(_ fsm.EventContext) fsm.EventType {
Invoice: f.InstantOut.swapInvoice,
Timeout: defaultSendpaymentTimeout,
MaxParts: defaultMaxParts,
MaxFee: getMaxRoutingFee(f.InstantOut.value),
MaxFee: getMaxRoutingFee(f.InstantOut.Value),
},
)
if err != nil {
Expand Down Expand Up @@ -301,7 +301,7 @@ func (f *FSM) BuildHTLCAction(eventCtx fsm.EventContext) fsm.EventType {
return f.handleErrorAndUnlockReservations(err)
}

if len(htlcInitRes.HtlcServerNonces) != len(f.InstantOut.reservations) {
if len(htlcInitRes.HtlcServerNonces) != len(f.InstantOut.Reservations) {
return f.handleErrorAndUnlockReservations(
errors.New("invalid number of server nonces"),
)
Expand Down Expand Up @@ -435,8 +435,8 @@ func (f *FSM) PushPreimageAction(eventCtx fsm.EventContext) fsm.EventType {
return OnErrorPublishHtlc
}

f.InstantOut.finalizedSweeplessSweepTx = sweepTx
txHash := f.InstantOut.finalizedSweeplessSweepTx.TxHash()
f.InstantOut.FinalizedSweeplessSweepTx = sweepTx
txHash := f.InstantOut.FinalizedSweeplessSweepTx.TxHash()

f.InstantOut.SweepTxHash = &txHash

Expand Down Expand Up @@ -598,7 +598,7 @@ func (f *FSM) handleErrorAndUnlockReservations(err error) fsm.EventType {
defer cancel()

// Unlock the reservations.
for _, reservation := range f.InstantOut.reservations {
for _, reservation := range f.InstantOut.Reservations {
err := f.cfg.ReservationManager.UnlockReservation(
ctx, reservation.ID,
)
Expand Down
38 changes: 19 additions & 19 deletions instantout/instantout.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@ type InstantOut struct {
// State is the current state of the swap.
State fsm.StateType

// cltvExpiry is the expiry of the swap.
cltvExpiry int32
// CltvExpiry is the expiry of the swap.
CltvExpiry int32

// outgoingChanSet optionally specifies the short channel ids of the
// channels that may be used to loop out.
outgoingChanSet loopdb.ChannelSet

// reservations are the reservations that are used in as inputs for the
// Reservations are the Reservations that are used in as inputs for the
// instant out swap.
reservations []*reservation.Reservation
Reservations []*reservation.Reservation

// protocolVersion is the version of the protocol that is used for the
// swap.
Expand All @@ -53,8 +53,8 @@ type InstantOut struct {
// initiationHeight is the height at which the swap was initiated.
initiationHeight int32

// value is the amount that is swapped.
value btcutil.Amount
// Value is the amount that is swapped.
Value btcutil.Amount

// keyLocator is the key locator that is used for the swap.
keyLocator keychain.KeyLocator
Expand All @@ -81,9 +81,9 @@ type InstantOut struct {
// SweepTxHash is the hash of the sweep transaction.
SweepTxHash *chainhash.Hash

// finalizedSweeplessSweepTx is the transaction that is used to sweep
// FinalizedSweeplessSweepTx is the transaction that is used to sweep
// the funds in the cooperative path.
finalizedSweeplessSweepTx *wire.MsgTx
FinalizedSweeplessSweepTx *wire.MsgTx

// sweepConfirmationHeight is the height at which the sweep
// transaction was confirmed.
Expand All @@ -93,7 +93,7 @@ type InstantOut struct {
// getHtlc returns the swap.htlc for the instant out.
func (i *InstantOut) getHtlc(chainParams *chaincfg.Params) (*swap.Htlc, error) {
return swap.NewHtlcV2(
i.cltvExpiry, pubkeyTo33ByteSlice(i.serverPubkey),
i.CltvExpiry, pubkeyTo33ByteSlice(i.serverPubkey),
pubkeyTo33ByteSlice(i.clientPubkey), i.SwapHash, chainParams,
)
}
Expand All @@ -104,11 +104,11 @@ func (i *InstantOut) createMusig2Session(ctx context.Context,
[][]byte, error) {

// Create the htlc musig2 context.
musig2Sessions := make([]*input.MuSig2SessionInfo, len(i.reservations))
clientNonces := make([][]byte, len(i.reservations))
musig2Sessions := make([]*input.MuSig2SessionInfo, len(i.Reservations))
clientNonces := make([][]byte, len(i.Reservations))

// Create the sessions and nonces from the reservations.
for idx, reservation := range i.reservations {
for idx, reservation := range i.Reservations {
session, err := reservation.Musig2CreateSession(ctx, signer)
if err != nil {
return nil, nil, err
Expand All @@ -123,12 +123,12 @@ func (i *InstantOut) createMusig2Session(ctx context.Context,

// getInputReservation returns the input reservation for the instant out.
func (i *InstantOut) getInputReservations() (InputReservations, error) {
if len(i.reservations) == 0 {
if len(i.Reservations) == 0 {
return nil, errors.New("no reservations")
}

inputs := make(InputReservations, len(i.reservations))
for idx, reservation := range i.reservations {
inputs := make(InputReservations, len(i.Reservations))
for idx, reservation := range i.Reservations {
pkScript, err := reservation.GetPkScript()
if err != nil {
return nil, err
Expand Down Expand Up @@ -170,7 +170,7 @@ func (i *InstantOut) createHtlcTransaction(network *chaincfg.Params) (
// Estimate the fee
weight := htlcWeight(len(inputReservations))
fee := i.htlcFeeRate.FeeForWeight(weight)
if fee > i.value/5 {
if fee > i.Value/5 {
return nil, errors.New("fee is higher than 20% of " +
"sweep value")
}
Expand All @@ -182,7 +182,7 @@ func (i *InstantOut) createHtlcTransaction(network *chaincfg.Params) (

// Create the sweep output
sweepOutput := &wire.TxOut{
Value: int64(i.value) - int64(fee),
Value: int64(i.Value) - int64(fee),
PkScript: htlc.PkScript,
}

Expand Down Expand Up @@ -214,7 +214,7 @@ func (i *InstantOut) createSweeplessSweepTx(feerate chainfee.SatPerKWeight) (
// Estimate the fee
weight := sweeplessSweepWeight(len(inputReservations))
fee := feerate.FeeForWeight(weight)
if fee > i.value/5 {
if fee > i.Value/5 {
return nil, errors.New("fee is higher than 20% of " +
"sweep value")
}
Expand All @@ -226,7 +226,7 @@ func (i *InstantOut) createSweeplessSweepTx(feerate chainfee.SatPerKWeight) (

// Create the sweep output
sweepOutput := &wire.TxOut{
Value: int64(i.value) - int64(fee),
Value: int64(i.Value) - int64(fee),
PkScript: pkscript,
}

Expand Down
5 changes: 5 additions & 0 deletions instantout/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,8 @@ func (m *Manager) GetInstantOutQuote(ctx context.Context,
OnChainFee: chainFee,
}, nil
}

// ListInstantOuts returns all instant outs from the database.
func (m *Manager) ListInstantOuts(ctx context.Context) ([]*InstantOut, error) {
return m.cfg.Store.ListInstantLoopOuts(ctx)
}
18 changes: 9 additions & 9 deletions instantout/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ func (s *SQLStore) CreateInstantLoopOut(ctx context.Context,
SwapHash: instantOut.SwapHash[:],
Preimage: instantOut.swapPreimage[:],
InitiationTime: s.clock.Now(),
AmountRequested: int64(instantOut.value),
CltvExpiry: instantOut.cltvExpiry,
AmountRequested: int64(instantOut.Value),
CltvExpiry: instantOut.CltvExpiry,
MaxMinerFee: 0,
MaxSwapFee: 0,
InitiationHeight: instantOut.initiationHeight,
Expand All @@ -114,7 +114,7 @@ func (s *SQLStore) CreateInstantLoopOut(ctx context.Context,
}

reservationIdByteSlice := reservationIdsToByteSlice(
instantOut.reservations,
instantOut.Reservations,
)
instantOutArgs := sqlc.InsertInstantOutParams{
SwapHash: instantOut.SwapHash[:],
Expand Down Expand Up @@ -172,9 +172,9 @@ func (s *SQLStore) UpdateInstantLoopOut(ctx context.Context,
}

var finalSweeplessSweepTx []byte
if instantOut.finalizedSweeplessSweepTx != nil {
if instantOut.FinalizedSweeplessSweepTx != nil {
var buffer bytes.Buffer
err := instantOut.finalizedSweeplessSweepTx.Serialize(
err := instantOut.FinalizedSweeplessSweepTx.Serialize(
&buffer,
)
if err != nil {
Expand Down Expand Up @@ -355,12 +355,12 @@ func (s *SQLStore) sqlInstantOutToInstantOut(ctx context.Context,
instantOut := &InstantOut{
SwapHash: swapHash,
swapPreimage: swapPreImage,
cltvExpiry: row.CltvExpiry,
CltvExpiry: row.CltvExpiry,
outgoingChanSet: outgoingChanSet,
reservations: reservations,
Reservations: reservations,
protocolVersion: ProtocolVersion(row.ProtocolVersion),
initiationHeight: row.InitiationHeight,
value: btcutil.Amount(row.AmountRequested),
Value: btcutil.Amount(row.AmountRequested),
keyLocator: keychain.KeyLocator{
Family: keychain.KeyFamily(row.ClientKeyFamily),
Index: uint32(row.ClientKeyIndex),
Expand All @@ -372,7 +372,7 @@ func (s *SQLStore) sqlInstantOutToInstantOut(ctx context.Context,
sweepAddress: sweepAddress,
finalizedHtlcTx: finalizedHtlcTx,
SweepTxHash: sweepTxHash,
finalizedSweeplessSweepTx: finalizedSweepLessSweepTx,
FinalizedSweeplessSweepTx: finalizedSweepLessSweepTx,
sweepConfirmationHeight: uint32(deserializeNullInt32(
row.SweepConfirmationHeight,
)),
Expand Down
4 changes: 4 additions & 0 deletions loopd/perms/perms.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,8 @@ var RequiredPermissions = map[string][]bakery.Op{
Entity: "swap",
Action: "read",
}},
"/looprpc.SwapClient/ListInstantOuts": {{
Entity: "swap",
Action: "read",
}},
}
41 changes: 41 additions & 0 deletions loopd/swapclient_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,47 @@ func (s *swapClientServer) InstantOutQuote(ctx context.Context,
}, nil
}

// ListInstantOuts returns a list of all currently known instant out swaps and
// their current status.
func (s *swapClientServer) ListInstantOuts(ctx context.Context,
_ *clientrpc.ListInstantOutsRequest) (
*clientrpc.ListInstantOutsResponse, error) {

instantOuts, err := s.instantOutManager.ListInstantOuts(ctx)
if err != nil {
return nil, err
}

rpcSwaps := make([]*clientrpc.InstantOut, 0, len(instantOuts))
for _, instantOut := range instantOuts {
rpcSwaps = append(rpcSwaps, rpcInstantOut(instantOut))
}

return &clientrpc.ListInstantOutsResponse{
Swaps: rpcSwaps,
}, nil
}

func rpcInstantOut(instantOut *instantout.InstantOut) *clientrpc.InstantOut {
var sweepTxId string
if instantOut.SweepTxHash != nil {
sweepTxId = instantOut.SweepTxHash.String()
}

reservations := make([][]byte, len(instantOut.Reservations))
for i, res := range instantOut.Reservations {
reservations[i] = res.ID[:]
}

return &clientrpc.InstantOut{
SwapHash: instantOut.SwapHash[:],
State: string(instantOut.State),
Amount: uint64(instantOut.Value),
SweepTxId: sweepTxId,
ReservationIds: reservations,
}
}

func rpcAutoloopReason(reason liquidity.Reason) (clientrpc.AutoReason, error) {
switch reason {
case liquidity.ReasonNone:
Expand Down
Loading

0 comments on commit 5d75e99

Please sign in to comment.