Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, to not open up the scope, we could just provide getters for these members. That would also reduce the diff.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd tend to agree, but given that the added use-case doesn't involve sharing state as all instantouts are fetched from the DB, we can keep the exported members too.

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