From b5d2fb38945e76ef0b8cd7dee1c8564e865edcc4 Mon Sep 17 00:00:00 2001 From: Joost Jager Date: Tue, 2 Apr 2019 10:51:51 +0200 Subject: [PATCH] loopd: add loop in state InvoiceSettled --- cmd/loopd/swapclient_server.go | 2 + loopdb/swapstate.go | 7 ++ loopin.go | 175 ++++++++++++++++++--------------- loopin_test.go | 68 +++++++------ looprpc/client.pb.go | 153 ++++++++++++++-------------- looprpc/client.proto | 6 ++ looprpc/client.swagger.json | 5 +- 7 files changed, 234 insertions(+), 182 deletions(-) diff --git a/cmd/loopd/swapclient_server.go b/cmd/loopd/swapclient_server.go index 2668dc0..d0b9650 100644 --- a/cmd/loopd/swapclient_server.go +++ b/cmd/loopd/swapclient_server.go @@ -95,6 +95,8 @@ func (s *swapClientServer) marshallSwap(loopSwap *loop.SwapInfo) ( state = looprpc.SwapState_PREIMAGE_REVEALED case loopdb.StateHtlcPublished: state = looprpc.SwapState_HTLC_PUBLISHED + case loopdb.StateInvoiceSettled: + state = looprpc.SwapState_INVOICE_SETTLED case loopdb.StateSuccess: state = looprpc.SwapState_SUCCESS default: diff --git a/loopdb/swapstate.go b/loopdb/swapstate.go index 707d16b..db795a1 100644 --- a/loopdb/swapstate.go +++ b/loopdb/swapstate.go @@ -51,6 +51,10 @@ const ( // StateHtlcPublished means that the client published the on-chain htlc. StateHtlcPublished = 8 + + // StateInvoiceSettled means that the swap invoice has been paid by the + // server. + StateInvoiceSettled = 9 ) // SwapStateType defines the types of swap states that exist. Every swap state @@ -114,6 +118,9 @@ func (s SwapState) String() string { case StateFailTemporary: return "FailTemporary" + case StateInvoiceSettled: + return "InvoiceSettled" + default: return "Unknown" } diff --git a/loopin.go b/loopin.go index b8a8959..c301726 100644 --- a/loopin.go +++ b/loopin.go @@ -252,7 +252,7 @@ func (s *loopInSwap) execute(mainCtx context.Context, // permanently and losing funds. if err != nil { s.log.Errorf("Swap error: %v", err) - s.state = loopdb.StateFailTemporary + s.setState(loopdb.StateFailTemporary) // If we cannot send out this update, there is nothing we can do. _ = s.sendUpdate(mainCtx) @@ -282,7 +282,7 @@ func (s *loopInSwap) executeSwap(globalCtx context.Context) error { // If an external htlc was indicated, we can move to the // HtlcPublished state directly and wait for // confirmation. - s.state = loopdb.StateHtlcPublished + s.setState(loopdb.StateHtlcPublished) err = s.persistState(globalCtx) if err != nil { return err @@ -320,41 +320,7 @@ func (s *loopInSwap) executeSwap(globalCtx context.Context) error { // invoice, receive the preimage and sweep the htlc. We are waiting for // this to happen and simultaneously watch the htlc expiry height. When // the htlc expires, we will publish a timeout tx to reclaim the funds. - spend, err := s.waitForHtlcSpend(globalCtx, htlcOutpoint) - if err != nil { - return err - } - - // Determine the htlc input of the spending tx and inspect the witness - // to findout whether a success or a timeout tx spend the htlc. - htlcInput := spend.SpendingTx.TxIn[spend.SpenderInputIndex] - - if s.htlc.IsSuccessWitness(htlcInput.Witness) { - s.state = loopdb.StateSuccess - - // Server swept the htlc. The htlc value can be added to the - // server cost balance. - s.cost.Server += htlcValue - } else { - s.state = loopdb.StateFailTimeout - - // Now that the timeout tx confirmed, we can safely cancel the - // swap invoice. We still need to query the final invoice state. - // This is not a hodl invoice, so it may be that the invoice was - // already settled. This means that the server didn't succeed in - // sweeping the htlc after paying the invoice. - err := s.lnd.Invoices.CancelInvoice(globalCtx, s.hash) - if err != nil && err != channeldb.ErrInvoiceAlreadySettled { - return err - } - - // TODO: Add miner fee of timeout tx to swap cost balance. - } - - // Wait for a final state of the swap invoice. It should either be - // settled because the server successfully paid it or canceled because - // we canceled after our timeout tx confirmed. - err = s.waitForSwapInvoiceResult(globalCtx) + err = s.waitForSwapComplete(globalCtx, htlcOutpoint, htlcValue) if err != nil { return err } @@ -411,7 +377,7 @@ func (s *loopInSwap) publishOnChainHtlc(ctx context.Context) (bool, error) { // Verify whether it still makes sense to publish the htlc. if blocksRemaining < MinLoopInPublishDelta { - s.state = loopdb.StateFailTimeout + s.setState(loopdb.StateFailTimeout) return false, s.persistState(ctx) } @@ -425,7 +391,7 @@ func (s *loopInSwap) publishOnChainHtlc(ctx context.Context) (bool, error) { // Transition to state HtlcPublished before calling SendOutputs to // prevent us from ever paying multiple times after a crash. - s.state = loopdb.StateHtlcPublished + s.setState(loopdb.StateHtlcPublished) err = s.persistState(ctx) if err != nil { return false, err @@ -448,10 +414,11 @@ func (s *loopInSwap) publishOnChainHtlc(ctx context.Context) (bool, error) { } -// waitForHtlcSpend waits until a spending tx of the htlc gets confirmed and -// returns the spend details. -func (s *loopInSwap) waitForHtlcSpend(ctx context.Context, - htlc *wire.OutPoint) (*chainntnfs.SpendDetail, error) { +// waitForSwapComplete waits until a spending tx of the htlc gets confirmed and +// the swap invoice is either settled or canceled. If the htlc times out, the +// timeout tx will be published. +func (s *loopInSwap) waitForSwapComplete(ctx context.Context, + htlc *wire.OutPoint, htlcValue btcutil.Amount) error { // Register the htlc spend notification. rpcCtx, cancel := context.WithCancel(ctx) @@ -460,58 +427,61 @@ func (s *loopInSwap) waitForHtlcSpend(ctx context.Context, rpcCtx, nil, s.htlc.ScriptHash, s.InitiationHeight, ) if err != nil { - return nil, fmt.Errorf("register spend ntfn: %v", err) + return fmt.Errorf("register spend ntfn: %v", err) } - for { + // Register for swap invoice updates. + rpcCtx, cancel = context.WithCancel(ctx) + defer cancel() + s.log.Infof("Subscribing to swap invoice %v", s.hash) + swapInvoiceChan, swapInvoiceErr, err := s.lnd.Invoices.SubscribeSingleInvoice( + rpcCtx, s.hash, + ) + if err != nil { + return fmt.Errorf("subscribe to swap invoice: %v", err) + } + + htlcSpend := false + invoiceFinalized := false + for !htlcSpend || !invoiceFinalized { select { // Spend notification error. case err := <-spendErr: - return nil, err + return err + // Receive block epochs and start publishing the timeout tx + // whenever possible. case notification := <-s.blockEpochChan: s.height = notification.(int32) if s.height >= s.LoopInContract.CltvExpiry { err := s.publishTimeoutTx(ctx, htlc) if err != nil { - return nil, err + return err } } - // Htlc spend, break loop. + // The htlc spend is confirmed. Inspect the spending tx to + // determine the final swap state. case spendDetails := <-spendChan: s.log.Infof("Htlc spend by tx: %v", spendDetails.SpenderTxHash) - return spendDetails, nil - - case <-ctx.Done(): - return nil, ctx.Err() - } - } -} - -// waitForSwapPaid waits until our swap invoice gets paid by the server. -func (s *loopInSwap) waitForSwapInvoiceResult(ctx context.Context) error { - // Wait for swap invoice to be paid. - rpcCtx, cancel := context.WithCancel(ctx) - defer cancel() - s.log.Infof("Subscribing to swap invoice %v", s.hash) - swapInvoiceChan, swapInvoiceErr, err := s.lnd.Invoices.SubscribeSingleInvoice( - rpcCtx, s.hash, - ) - if err != nil { - return err - } + err := s.processHtlcSpend( + ctx, spendDetails, htlcValue, + ) + if err != nil { + return err + } - for { - select { + htlcSpend = true // Swap invoice ntfn error. case err := <-swapInvoiceErr: return err + // An update to the swap invoice occured. Check the new state + // and update the swap state accordingly. case update := <-swapInvoiceChan: s.log.Infof("Received swap invoice update: %v", update.State) @@ -521,18 +491,67 @@ func (s *loopInSwap) waitForSwapInvoiceResult(ctx context.Context) error { // Swap invoice was paid, so update server cost balance. case channeldb.ContractSettled: s.cost.Server -= update.AmtPaid - return nil + + // If invoice settlement and htlc spend happen + // in the expected order, move the swap to an + // intermediate state that indicates that the + // swap is complete from the user point of view, + // but still incomplete with regards to + // accounting data. + if s.state == loopdb.StateHtlcPublished { + s.setState(loopdb.StateInvoiceSettled) + err := s.persistState(ctx) + if err != nil { + return err + } + } + + invoiceFinalized = true // Canceled invoice has no effect on server cost // balance. case channeldb.ContractCanceled: - return nil + invoiceFinalized = true } case <-ctx.Done(): return ctx.Err() } } + + return nil +} + +func (s *loopInSwap) processHtlcSpend(ctx context.Context, + spend *chainntnfs.SpendDetail, htlcValue btcutil.Amount) error { + + // Determine the htlc input of the spending tx and inspect the witness + // to findout whether a success or a timeout tx spend the htlc. + htlcInput := spend.SpendingTx.TxIn[spend.SpenderInputIndex] + + if s.htlc.IsSuccessWitness(htlcInput.Witness) { + s.setState(loopdb.StateSuccess) + + // Server swept the htlc. The htlc value can be added to the + // server cost balance. + s.cost.Server += htlcValue + } else { + s.setState(loopdb.StateFailTimeout) + + // Now that the timeout tx confirmed, we can safely cancel the + // swap invoice. We still need to query the final invoice state. + // This is not a hodl invoice, so it may be that the invoice was + // already settled. This means that the server didn't succeed in + // sweeping the htlc after paying the invoice. + err := s.lnd.Invoices.CancelInvoice(ctx, s.hash) + if err != nil && err != channeldb.ErrInvoiceAlreadySettled { + return err + } + + // TODO: Add miner fee of timeout tx to swap cost balance. + } + + return nil } // publishTimeoutTx publishes a timeout tx after the on-chain htlc has expired. @@ -582,12 +601,8 @@ func (s *loopInSwap) publishTimeoutTx(ctx context.Context, // persistState updates the swap state and sends out an update notification. func (s *loopInSwap) persistState(ctx context.Context) error { - updateTime := time.Now() - - s.lastUpdateTime = updateTime - // Update state in store. - err := s.store.UpdateLoopIn(s.hash, updateTime, s.state) + err := s.store.UpdateLoopIn(s.hash, s.lastUpdateTime, s.state) if err != nil { return err } @@ -595,3 +610,9 @@ func (s *loopInSwap) persistState(ctx context.Context) error { // Send out swap update return s.sendUpdate(ctx) } + +// setState updates the swap state and last update timestamp. +func (s *loopInSwap) setState(state loopdb.SwapState) { + s.lastUpdateTime = time.Now() + s.state = state +} diff --git a/loopin_test.go b/loopin_test.go index 68a5a27..197f992 100644 --- a/loopin_test.go +++ b/loopin_test.go @@ -76,17 +76,6 @@ func TestLoopInSuccess(t *testing.T) { // Client starts listening for spend of htlc. <-ctx.lnd.RegisterSpendChannel - // Server spends htlc. - successTx := wire.MsgTx{} - successTx.AddTxIn(&wire.TxIn{ - Witness: [][]byte{{}, {}, {}}, - }) - - ctx.lnd.SpendChannel <- &chainntnfs.SpendDetail{ - SpendingTx: &successTx, - SpenderInputIndex: 0, - } - // Client starts listening for swap invoice updates. subscription := <-ctx.lnd.SingleInvoiceSubcribeChannel if subscription.Hash != ctx.server.swapHash { @@ -100,6 +89,21 @@ func TestLoopInSuccess(t *testing.T) { AmtPaid: 49000, } + // Swap is expected to move to the state InvoiceSettled + ctx.assertState(loopdb.StateInvoiceSettled) + ctx.store.assertLoopInState(loopdb.StateInvoiceSettled) + + // Server spends htlc. + successTx := wire.MsgTx{} + successTx.AddTxIn(&wire.TxIn{ + Witness: [][]byte{{}, {}, {}}, + }) + + ctx.lnd.SpendChannel <- &chainntnfs.SpendDetail{ + SpendingTx: &successTx, + SpenderInputIndex: 0, + } + ctx.assertState(loopdb.StateSuccess) ctx.store.assertLoopInState(loopdb.StateSuccess) @@ -162,6 +166,12 @@ func TestLoopInTimeout(t *testing.T) { // Client starts listening for spend of htlc. <-ctx.lnd.RegisterSpendChannel + // Client starts listening for swap invoice updates. + subscription := <-ctx.lnd.SingleInvoiceSubcribeChannel + if subscription.Hash != ctx.server.swapHash { + t.Fatal("client subscribing to wrong invoice") + } + // Let htlc expire. ctx.blockEpochChan <- swap.LoopInContract.CltvExpiry @@ -178,12 +188,6 @@ func TestLoopInTimeout(t *testing.T) { // safely cancel the swap invoice. <-ctx.lnd.FailInvoiceChannel - // Client starts listening for swap invoice updates. - subscription := <-ctx.lnd.SingleInvoiceSubcribeChannel - if subscription.Hash != ctx.server.swapHash { - t.Fatal("client subscribing to wrong invoice") - } - // Signal the the invoice was canceled. subscription.Update <- lndclient.InvoiceUpdate{ State: channeldb.ContractCanceled, @@ -340,19 +344,6 @@ func testLoopInResume(t *testing.T, state loopdb.SwapState, expired bool) { // Client starts listening for spend of htlc. <-ctx.lnd.RegisterSpendChannel - // Server spends htlc. - successTx := wire.MsgTx{} - successTx.AddTxIn(&wire.TxIn{ - Witness: [][]byte{{}, {}, {}}, - }) - successTxHash := successTx.TxHash() - - ctx.lnd.SpendChannel <- &chainntnfs.SpendDetail{ - SpendingTx: &successTx, - SpenderTxHash: &successTxHash, - SpenderInputIndex: 0, - } - // Client starts listening for swap invoice updates. subscription := <-ctx.lnd.SingleInvoiceSubcribeChannel if subscription.Hash != testPreimage.Hash() { @@ -366,5 +357,22 @@ func testLoopInResume(t *testing.T, state loopdb.SwapState, expired bool) { AmtPaid: 49000, } + // Swap is expected to move to the state InvoiceSettled + ctx.assertState(loopdb.StateInvoiceSettled) + ctx.store.assertLoopInState(loopdb.StateInvoiceSettled) + + // Server spends htlc. + successTx := wire.MsgTx{} + successTx.AddTxIn(&wire.TxIn{ + Witness: [][]byte{{}, {}, {}}, + }) + successTxHash := successTx.TxHash() + + ctx.lnd.SpendChannel <- &chainntnfs.SpendDetail{ + SpendingTx: &successTx, + SpenderTxHash: &successTxHash, + SpenderInputIndex: 0, + } + ctx.assertState(loopdb.StateSuccess) } diff --git a/looprpc/client.pb.go b/looprpc/client.pb.go index 2ac9d09..3ebbeac 100644 --- a/looprpc/client.pb.go +++ b/looprpc/client.pb.go @@ -46,7 +46,7 @@ func (x SwapType) String() string { return proto.EnumName(SwapType_name, int32(x)) } func (SwapType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_client_e350cb39252fe551, []int{0} + return fileDescriptor_client_ba4b73c10b9bbc2a, []int{0} } type SwapState int32 @@ -76,6 +76,10 @@ const ( // FAILED is the final swap state for a failed swap with or without loss of // the swap amount. SwapState_FAILED SwapState = 4 + // * + // INVOICE_SETTLED is reached when the swap invoice in a loop in swap has been + // paid, but we are still waiting for the htlc spend to confirm. + SwapState_INVOICE_SETTLED SwapState = 5 ) var SwapState_name = map[int32]string{ @@ -84,6 +88,7 @@ var SwapState_name = map[int32]string{ 2: "HTLC_PUBLISHED", 3: "SUCCESS", 4: "FAILED", + 5: "INVOICE_SETTLED", } var SwapState_value = map[string]int32{ "INITIATED": 0, @@ -91,13 +96,14 @@ var SwapState_value = map[string]int32{ "HTLC_PUBLISHED": 2, "SUCCESS": 3, "FAILED": 4, + "INVOICE_SETTLED": 5, } func (x SwapState) String() string { return proto.EnumName(SwapState_name, int32(x)) } func (SwapState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_client_e350cb39252fe551, []int{1} + return fileDescriptor_client_ba4b73c10b9bbc2a, []int{1} } type LoopOutRequest struct { @@ -155,7 +161,7 @@ func (m *LoopOutRequest) Reset() { *m = LoopOutRequest{} } func (m *LoopOutRequest) String() string { return proto.CompactTextString(m) } func (*LoopOutRequest) ProtoMessage() {} func (*LoopOutRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_client_e350cb39252fe551, []int{0} + return fileDescriptor_client_ba4b73c10b9bbc2a, []int{0} } func (m *LoopOutRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_LoopOutRequest.Unmarshal(m, b) @@ -268,7 +274,7 @@ func (m *LoopInRequest) Reset() { *m = LoopInRequest{} } func (m *LoopInRequest) String() string { return proto.CompactTextString(m) } func (*LoopInRequest) ProtoMessage() {} func (*LoopInRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_client_e350cb39252fe551, []int{1} + return fileDescriptor_client_ba4b73c10b9bbc2a, []int{1} } func (m *LoopInRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_LoopInRequest.Unmarshal(m, b) @@ -340,7 +346,7 @@ func (m *SwapResponse) Reset() { *m = SwapResponse{} } func (m *SwapResponse) String() string { return proto.CompactTextString(m) } func (*SwapResponse) ProtoMessage() {} func (*SwapResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_client_e350cb39252fe551, []int{2} + return fileDescriptor_client_ba4b73c10b9bbc2a, []int{2} } func (m *SwapResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SwapResponse.Unmarshal(m, b) @@ -384,7 +390,7 @@ func (m *MonitorRequest) Reset() { *m = MonitorRequest{} } func (m *MonitorRequest) String() string { return proto.CompactTextString(m) } func (*MonitorRequest) ProtoMessage() {} func (*MonitorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_client_e350cb39252fe551, []int{3} + return fileDescriptor_client_ba4b73c10b9bbc2a, []int{3} } func (m *MonitorRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MonitorRequest.Unmarshal(m, b) @@ -437,7 +443,7 @@ func (m *SwapStatus) Reset() { *m = SwapStatus{} } func (m *SwapStatus) String() string { return proto.CompactTextString(m) } func (*SwapStatus) ProtoMessage() {} func (*SwapStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_client_e350cb39252fe551, []int{4} + return fileDescriptor_client_ba4b73c10b9bbc2a, []int{4} } func (m *SwapStatus) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SwapStatus.Unmarshal(m, b) @@ -516,7 +522,7 @@ func (m *TermsRequest) Reset() { *m = TermsRequest{} } func (m *TermsRequest) String() string { return proto.CompactTextString(m) } func (*TermsRequest) ProtoMessage() {} func (*TermsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_client_e350cb39252fe551, []int{5} + return fileDescriptor_client_ba4b73c10b9bbc2a, []int{5} } func (m *TermsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TermsRequest.Unmarshal(m, b) @@ -568,7 +574,7 @@ func (m *TermsResponse) Reset() { *m = TermsResponse{} } func (m *TermsResponse) String() string { return proto.CompactTextString(m) } func (*TermsResponse) ProtoMessage() {} func (*TermsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_client_e350cb39252fe551, []int{6} + return fileDescriptor_client_ba4b73c10b9bbc2a, []int{6} } func (m *TermsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TermsResponse.Unmarshal(m, b) @@ -650,7 +656,7 @@ func (m *QuoteRequest) Reset() { *m = QuoteRequest{} } func (m *QuoteRequest) String() string { return proto.CompactTextString(m) } func (*QuoteRequest) ProtoMessage() {} func (*QuoteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_client_e350cb39252fe551, []int{7} + return fileDescriptor_client_ba4b73c10b9bbc2a, []int{7} } func (m *QuoteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QuoteRequest.Unmarshal(m, b) @@ -696,7 +702,7 @@ func (m *QuoteResponse) Reset() { *m = QuoteResponse{} } func (m *QuoteResponse) String() string { return proto.CompactTextString(m) } func (*QuoteResponse) ProtoMessage() {} func (*QuoteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_client_e350cb39252fe551, []int{8} + return fileDescriptor_client_ba4b73c10b9bbc2a, []int{8} } func (m *QuoteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QuoteResponse.Unmarshal(m, b) @@ -1093,66 +1099,67 @@ var _SwapClient_serviceDesc = grpc.ServiceDesc{ Metadata: "client.proto", } -func init() { proto.RegisterFile("client.proto", fileDescriptor_client_e350cb39252fe551) } - -var fileDescriptor_client_e350cb39252fe551 = []byte{ - // 925 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xdd, 0x8e, 0xdb, 0x44, - 0x18, 0xad, 0x9d, 0x6c, 0x7e, 0xbe, 0x75, 0xbc, 0xce, 0xb4, 0xdd, 0x86, 0x40, 0xa5, 0x60, 0x68, - 0x89, 0xf6, 0x62, 0x03, 0xdb, 0x0b, 0x04, 0x37, 0x28, 0x4d, 0xd2, 0x6e, 0xa4, 0x6c, 0x37, 0x38, - 0x59, 0x24, 0x6e, 0xb0, 0xa6, 0xc9, 0x74, 0x6b, 0xc9, 0x9e, 0x71, 0xed, 0x71, 0x9b, 0x15, 0xe2, - 0x86, 0x37, 0x00, 0xde, 0x04, 0xf1, 0x26, 0xbc, 0x02, 0xaf, 0xc0, 0x3d, 0x9a, 0x9f, 0xb8, 0x76, - 0xc2, 0xde, 0xf4, 0xce, 0xf9, 0xe6, 0xcc, 0x99, 0xef, 0x3b, 0x73, 0xce, 0x04, 0xac, 0x55, 0x18, - 0x10, 0xca, 0x4f, 0xe3, 0x84, 0x71, 0x86, 0xea, 0x21, 0x63, 0x71, 0x12, 0xaf, 0xba, 0x9f, 0x5c, - 0x33, 0x76, 0x1d, 0x92, 0x01, 0x8e, 0x83, 0x01, 0xa6, 0x94, 0x71, 0xcc, 0x03, 0x46, 0x53, 0x05, - 0x73, 0xff, 0x34, 0xc1, 0x9e, 0x31, 0x16, 0x5f, 0x66, 0xdc, 0x23, 0x6f, 0x32, 0x92, 0x72, 0xe4, - 0x40, 0x05, 0x47, 0xbc, 0x63, 0xf4, 0x8c, 0x7e, 0xc5, 0x13, 0x9f, 0x08, 0x41, 0x75, 0x4d, 0x52, - 0xde, 0x31, 0x7b, 0x46, 0xbf, 0xe9, 0xc9, 0x6f, 0x34, 0x80, 0x7b, 0x11, 0xde, 0xf8, 0xe9, 0x3b, - 0x1c, 0xfb, 0x09, 0xcb, 0x78, 0x40, 0xaf, 0xfd, 0x57, 0x84, 0x74, 0x2a, 0x72, 0x5b, 0x3b, 0xc2, - 0x9b, 0xc5, 0x3b, 0x1c, 0x7b, 0x6a, 0xe5, 0x19, 0x21, 0xe8, 0x09, 0x1c, 0x8b, 0x0d, 0x71, 0x42, - 0x62, 0x7c, 0x53, 0xda, 0x52, 0x95, 0x5b, 0xee, 0x46, 0x78, 0x33, 0x97, 0x8b, 0x85, 0x4d, 0x3d, - 0xb0, 0xf2, 0x53, 0x04, 0xf4, 0x40, 0x42, 0x41, 0xb3, 0x0b, 0xc4, 0xe7, 0x60, 0x17, 0x68, 0x45, - 0xe3, 0x35, 0x89, 0xb1, 0x72, 0xba, 0x61, 0xc4, 0x91, 0x0b, 0x2d, 0x81, 0x8a, 0x02, 0x4a, 0x12, - 0x49, 0x54, 0x97, 0xa0, 0xc3, 0x08, 0x6f, 0x2e, 0x44, 0x4d, 0x30, 0xf5, 0xc1, 0x11, 0x9a, 0xf9, - 0x2c, 0xe3, 0xfe, 0xea, 0x35, 0xa6, 0x94, 0x84, 0x9d, 0x46, 0xcf, 0xe8, 0x57, 0x3d, 0x3b, 0x54, - 0x0a, 0x8d, 0x54, 0xd5, 0xfd, 0xcb, 0x80, 0x96, 0x10, 0x6d, 0x4a, 0x6f, 0xd7, 0x6c, 0xb7, 0x73, - 0x73, 0xaf, 0xf3, 0xbd, 0x9e, 0x2a, 0xfb, 0x3d, 0x3d, 0x86, 0x23, 0xd9, 0x53, 0x40, 0xf3, 0x96, - 0xaa, 0xb2, 0xa5, 0x56, 0x28, 0xcf, 0xd7, 0x1d, 0xa1, 0xcf, 0xa0, 0x45, 0x36, 0x9c, 0x24, 0x14, - 0x87, 0xfe, 0x6b, 0x1e, 0xae, 0xa4, 0x50, 0x0d, 0xcf, 0xda, 0x16, 0xcf, 0x79, 0xb8, 0x72, 0x87, - 0x60, 0xc9, 0x3b, 0x21, 0x69, 0xcc, 0x68, 0x4a, 0x90, 0x0d, 0x66, 0xb0, 0x96, 0x3d, 0x37, 0x3d, - 0x33, 0x58, 0xa3, 0x4f, 0xc1, 0x12, 0x7b, 0x7d, 0xbc, 0x5e, 0x27, 0x24, 0x4d, 0xf5, 0x75, 0x1f, - 0x8a, 0xda, 0x50, 0x95, 0x5c, 0x07, 0xec, 0x0b, 0x46, 0x03, 0xce, 0x12, 0x3d, 0xb9, 0xfb, 0xaf, - 0x01, 0x20, 0x58, 0x17, 0x1c, 0xf3, 0x2c, 0xfd, 0x1f, 0x21, 0xd4, 0x29, 0x66, 0x7e, 0xca, 0x23, - 0xa8, 0xf2, 0x9b, 0x58, 0x4d, 0x6b, 0x9f, 0xb5, 0x4f, 0xb5, 0x4f, 0x4f, 0x05, 0xc9, 0xf2, 0x26, - 0x26, 0x9e, 0x5c, 0x46, 0x7d, 0x38, 0x48, 0x39, 0xe6, 0xca, 0x1d, 0xf6, 0x19, 0x2a, 0xe1, 0xc4, - 0x61, 0xc4, 0x53, 0x00, 0xf4, 0x05, 0x1c, 0x05, 0x34, 0xe0, 0x81, 0xf4, 0xb5, 0xcf, 0x83, 0x68, - 0x6b, 0x13, 0xfb, 0x7d, 0x79, 0x19, 0x44, 0xea, 0x82, 0x71, 0xca, 0xfd, 0x2c, 0x5e, 0x63, 0x4e, - 0x14, 0x52, 0x99, 0xc5, 0x16, 0xf5, 0x2b, 0x59, 0x96, 0xc8, 0x5d, 0x25, 0xea, 0xfb, 0x4a, 0xd8, - 0x60, 0x2d, 0x49, 0x12, 0xa5, 0x5b, 0x1d, 0x7e, 0x33, 0xa1, 0xa5, 0x0b, 0x5a, 0xde, 0x13, 0x68, - 0xcb, 0xdb, 0x8f, 0xf1, 0x4d, 0x44, 0x28, 0xf7, 0x65, 0x84, 0x94, 0xda, 0x47, 0x62, 0x61, 0xae, - 0xea, 0x63, 0xe1, 0x1f, 0x17, 0x5a, 0x5b, 0xa7, 0xf8, 0x2f, 0x71, 0xba, 0xb5, 0xcb, 0x61, 0xaa, - 0xbc, 0xf2, 0x14, 0xa7, 0xa4, 0x84, 0x49, 0x84, 0x32, 0x95, 0x12, 0xc6, 0x13, 0x5a, 0x3c, 0x04, - 0x28, 0x24, 0x41, 0x05, 0xab, 0x19, 0xe7, 0x31, 0x78, 0x0c, 0x47, 0x51, 0x40, 0x95, 0x29, 0x71, - 0xc4, 0x32, 0xca, 0xb5, 0x54, 0xad, 0x28, 0xa0, 0x42, 0xd8, 0xa1, 0x2c, 0x4a, 0xdc, 0xd6, 0xbc, - 0x1a, 0x57, 0xd3, 0x38, 0xe5, 0x5f, 0x8d, 0x7b, 0x08, 0xb0, 0x0a, 0xf9, 0x5b, 0x7f, 0x4d, 0x42, - 0x8e, 0xa5, 0x4a, 0x07, 0x5e, 0x53, 0x54, 0xc6, 0xa2, 0xe0, 0xf6, 0xc0, 0xfa, 0x3e, 0x63, 0x9c, - 0xdc, 0x9a, 0x12, 0xf7, 0x15, 0xb4, 0x34, 0x42, 0x8b, 0xf6, 0x11, 0x34, 0xf2, 0xc8, 0x28, 0x5c, - 0x5d, 0xcf, 0xb7, 0x33, 0x9b, 0xb9, 0x3b, 0xdb, 0xc7, 0xd0, 0xdc, 0x8d, 0x52, 0x23, 0xd2, 0x39, - 0x3a, 0x79, 0x04, 0x8d, 0xad, 0xbf, 0x90, 0x05, 0x8d, 0xd9, 0xe5, 0xe5, 0xdc, 0xbf, 0xbc, 0x5a, - 0x3a, 0x77, 0xd0, 0x21, 0xd4, 0xe5, 0xaf, 0xe9, 0x0b, 0xc7, 0x38, 0xf9, 0x09, 0x9a, 0xb9, 0xbd, - 0x50, 0x0b, 0x9a, 0xd3, 0x17, 0xd3, 0xe5, 0x74, 0xb8, 0x9c, 0x8c, 0x9d, 0x3b, 0xe8, 0x3e, 0xb4, - 0xe7, 0xde, 0x64, 0x7a, 0x31, 0x7c, 0x3e, 0xf1, 0xbd, 0xc9, 0x0f, 0x93, 0xe1, 0x6c, 0x32, 0x76, - 0x0c, 0x84, 0xc0, 0x3e, 0x5f, 0xce, 0x46, 0xfe, 0xfc, 0xea, 0xe9, 0x6c, 0xba, 0x38, 0x9f, 0x8c, - 0x1d, 0x53, 0x70, 0x2e, 0xae, 0x46, 0xa3, 0xc9, 0x62, 0xe1, 0x54, 0x10, 0x40, 0xed, 0xd9, 0x70, - 0x2a, 0xc0, 0xd5, 0xb3, 0xdf, 0xab, 0x2a, 0x2c, 0x23, 0xf9, 0x52, 0x23, 0x0f, 0xea, 0xfa, 0xed, - 0x45, 0x0f, 0x72, 0x7f, 0x97, 0x5f, 0xe3, 0xee, 0xfd, 0x92, 0xf1, 0xb7, 0x3a, 0xb9, 0x0f, 0x7e, - 0xfd, 0xfb, 0x9f, 0x3f, 0xcc, 0xb6, 0x6b, 0x0d, 0xde, 0x7e, 0x35, 0x10, 0x88, 0x01, 0xcb, 0xf8, - 0xb7, 0xc6, 0x09, 0xfa, 0x1a, 0x6a, 0xea, 0x69, 0x42, 0xc7, 0x25, 0xca, 0xfc, 0xad, 0xba, 0x85, - 0x11, 0x7d, 0x03, 0x75, 0x1d, 0xed, 0x42, 0x33, 0xe5, 0xb0, 0x77, 0xef, 0xee, 0xa5, 0x30, 0x4b, - 0xbf, 0x34, 0xd0, 0x8f, 0x60, 0xe9, 0xae, 0x65, 0x02, 0xd0, 0xfb, 0x13, 0x8a, 0x11, 0xe9, 0x1e, - 0xef, 0x96, 0xf5, 0x2c, 0x5d, 0x39, 0xcb, 0x3d, 0x84, 0x8a, 0xb3, 0x0c, 0xb8, 0xa4, 0xf2, 0x73, - 0x6a, 0xe9, 0x93, 0x02, 0x75, 0xd1, 0x59, 0x05, 0xea, 0x92, 0x9d, 0xdc, 0x9e, 0xa4, 0xee, 0xa2, - 0x4e, 0x89, 0xfa, 0x8d, 0xc0, 0x0c, 0x7e, 0xc6, 0x11, 0xff, 0x05, 0x7d, 0x07, 0xf6, 0x73, 0xc2, - 0x95, 0x42, 0x1f, 0xd2, 0x7d, 0x89, 0xe0, 0x43, 0x7a, 0x7c, 0x59, 0x93, 0xff, 0xc4, 0x4f, 0xfe, - 0x0b, 0x00, 0x00, 0xff, 0xff, 0xe3, 0xae, 0x80, 0xa3, 0xc0, 0x07, 0x00, 0x00, +func init() { proto.RegisterFile("client.proto", fileDescriptor_client_ba4b73c10b9bbc2a) } + +var fileDescriptor_client_ba4b73c10b9bbc2a = []byte{ + // 941 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xdd, 0x8e, 0xda, 0x46, + 0x18, 0x8d, 0x0d, 0xbb, 0xc0, 0xb7, 0xc6, 0xc0, 0x6c, 0xb2, 0xa1, 0xb4, 0x91, 0xa8, 0xdb, 0xa4, + 0x68, 0x2f, 0x96, 0x76, 0x73, 0x51, 0xb5, 0x37, 0x15, 0x01, 0x27, 0x6b, 0x89, 0x5d, 0xa8, 0x61, + 0x23, 0xf5, 0xca, 0x9a, 0xc0, 0x64, 0x63, 0xc9, 0xf6, 0x38, 0xf6, 0x38, 0x61, 0x55, 0xf5, 0xa6, + 0x6f, 0xd0, 0xf6, 0x4d, 0xaa, 0xbe, 0x49, 0x5f, 0xa1, 0xaf, 0xd0, 0xfb, 0x6a, 0x7e, 0x70, 0x6c, + 0xe8, 0xde, 0xe4, 0xce, 0x9c, 0x39, 0x73, 0xe6, 0xfb, 0xce, 0x9c, 0x6f, 0x00, 0x63, 0x15, 0xf8, + 0x24, 0x62, 0x67, 0x71, 0x42, 0x19, 0x45, 0xb5, 0x80, 0xd2, 0x38, 0x89, 0x57, 0xbd, 0xcf, 0x6e, + 0x28, 0xbd, 0x09, 0xc8, 0x10, 0xc7, 0xfe, 0x10, 0x47, 0x11, 0x65, 0x98, 0xf9, 0x34, 0x4a, 0x25, + 0xcd, 0xfa, 0x53, 0x07, 0x73, 0x4a, 0x69, 0x3c, 0xcb, 0x98, 0x4b, 0xde, 0x66, 0x24, 0x65, 0xa8, + 0x0d, 0x15, 0x1c, 0xb2, 0xae, 0xd6, 0xd7, 0x06, 0x15, 0x97, 0x7f, 0x22, 0x04, 0xd5, 0x35, 0x49, + 0x59, 0x57, 0xef, 0x6b, 0x83, 0x86, 0x2b, 0xbe, 0xd1, 0x10, 0xee, 0x87, 0x78, 0xe3, 0xa5, 0xef, + 0x71, 0xec, 0x25, 0x34, 0x63, 0x7e, 0x74, 0xe3, 0xbd, 0x26, 0xa4, 0x5b, 0x11, 0xdb, 0x3a, 0x21, + 0xde, 0x2c, 0xde, 0xe3, 0xd8, 0x95, 0x2b, 0xcf, 0x09, 0x41, 0x4f, 0xe1, 0x84, 0x6f, 0x88, 0x13, + 0x12, 0xe3, 0xdb, 0xd2, 0x96, 0xaa, 0xd8, 0x72, 0x1c, 0xe2, 0xcd, 0x5c, 0x2c, 0x16, 0x36, 0xf5, + 0xc1, 0xc8, 0x4f, 0xe1, 0xd4, 0x03, 0x41, 0x05, 0xa5, 0xce, 0x19, 0x5f, 0x82, 0x59, 0x90, 0xe5, + 0x85, 0x1f, 0x0a, 0x8e, 0x91, 0xcb, 0x8d, 0x42, 0x86, 0x2c, 0x68, 0x72, 0x56, 0xe8, 0x47, 0x24, + 0x11, 0x42, 0x35, 0x41, 0x3a, 0x0a, 0xf1, 0xe6, 0x92, 0x63, 0x5c, 0x69, 0x00, 0x6d, 0xee, 0x99, + 0x47, 0x33, 0xe6, 0xad, 0xde, 0xe0, 0x28, 0x22, 0x41, 0xb7, 0xde, 0xd7, 0x06, 0x55, 0xd7, 0x0c, + 0xa4, 0x43, 0x63, 0x89, 0x5a, 0x7f, 0x69, 0xd0, 0xe4, 0xa6, 0x39, 0xd1, 0xdd, 0x9e, 0xed, 0x56, + 0xae, 0xef, 0x55, 0xbe, 0x57, 0x53, 0x65, 0xbf, 0xa6, 0x27, 0xd0, 0x12, 0x35, 0xf9, 0x51, 0x5e, + 0x52, 0x55, 0x94, 0xd4, 0x0c, 0xc4, 0xf9, 0xaa, 0x22, 0xf4, 0x05, 0x34, 0xc9, 0x86, 0x91, 0x24, + 0xc2, 0x81, 0xf7, 0x86, 0x05, 0x2b, 0x61, 0x54, 0xdd, 0x35, 0xb6, 0xe0, 0x05, 0x0b, 0x56, 0xd6, + 0x08, 0x0c, 0x71, 0x27, 0x24, 0x8d, 0x69, 0x94, 0x12, 0x64, 0x82, 0xee, 0xaf, 0x45, 0xcd, 0x0d, + 0x57, 0xf7, 0xd7, 0xe8, 0x73, 0x30, 0xf8, 0x5e, 0x0f, 0xaf, 0xd7, 0x09, 0x49, 0x53, 0x75, 0xdd, + 0x47, 0x1c, 0x1b, 0x49, 0xc8, 0x6a, 0x83, 0x79, 0x49, 0x23, 0x9f, 0xd1, 0x44, 0x75, 0x6e, 0xfd, + 0xab, 0x01, 0x70, 0xd5, 0x05, 0xc3, 0x2c, 0x4b, 0xff, 0xc7, 0x08, 0x79, 0x8a, 0x9e, 0x9f, 0xf2, + 0x18, 0xaa, 0xec, 0x36, 0x96, 0xdd, 0x9a, 0xe7, 0x9d, 0x33, 0x95, 0xd3, 0x33, 0x2e, 0xb2, 0xbc, + 0x8d, 0x89, 0x2b, 0x96, 0xd1, 0x00, 0x0e, 0x52, 0x86, 0x99, 0x4c, 0x87, 0x79, 0x8e, 0x4a, 0x3c, + 0x7e, 0x18, 0x71, 0x25, 0x01, 0x7d, 0x05, 0x2d, 0x3f, 0xf2, 0x99, 0x2f, 0x72, 0xed, 0x31, 0x3f, + 0xdc, 0xc6, 0xc4, 0xfc, 0x00, 0x2f, 0xfd, 0x50, 0x5e, 0x30, 0x4e, 0x99, 0x97, 0xc5, 0x6b, 0xcc, + 0x88, 0x64, 0xca, 0xb0, 0x98, 0x1c, 0xbf, 0x16, 0xb0, 0x60, 0xee, 0x3a, 0x51, 0xdb, 0x77, 0xc2, + 0x04, 0x63, 0x49, 0x92, 0x30, 0xdd, 0xfa, 0xf0, 0x9b, 0x0e, 0x4d, 0x05, 0x28, 0x7b, 0x4f, 0xa1, + 0x23, 0x6e, 0x3f, 0xc6, 0xb7, 0x21, 0x89, 0x98, 0x27, 0x46, 0x48, 0xba, 0xdd, 0xe2, 0x0b, 0x73, + 0x89, 0x4f, 0x78, 0x7e, 0x2c, 0x68, 0x6e, 0x93, 0xe2, 0xbd, 0xc2, 0xe9, 0x36, 0x2e, 0x47, 0xa9, + 0xcc, 0xca, 0x33, 0x9c, 0x92, 0x12, 0x27, 0xe1, 0xce, 0x54, 0x4a, 0x1c, 0x97, 0x7b, 0xf1, 0x08, + 0xa0, 0x30, 0x09, 0x72, 0xb0, 0x1a, 0x71, 0x3e, 0x06, 0x4f, 0xa0, 0x15, 0xfa, 0x91, 0x0c, 0x25, + 0x0e, 0x69, 0x16, 0x31, 0x65, 0x55, 0x33, 0xf4, 0x23, 0x6e, 0xec, 0x48, 0x80, 0x82, 0xb7, 0x0d, + 0xaf, 0xe2, 0x1d, 0x2a, 0x9e, 0xcc, 0xaf, 0xe2, 0x3d, 0x02, 0x58, 0x05, 0xec, 0x9d, 0xb7, 0x26, + 0x01, 0xc3, 0xc2, 0xa5, 0x03, 0xb7, 0xc1, 0x91, 0x09, 0x07, 0xac, 0x3e, 0x18, 0x3f, 0x66, 0x94, + 0x91, 0x3b, 0xa7, 0xc4, 0x7a, 0x0d, 0x4d, 0xc5, 0x50, 0xa6, 0x7d, 0x02, 0xf5, 0x7c, 0x64, 0x24, + 0xaf, 0xa6, 0xfa, 0xdb, 0xe9, 0x4d, 0xdf, 0xed, 0xed, 0x53, 0x68, 0xec, 0x8e, 0x52, 0x3d, 0x54, + 0x73, 0x74, 0xfa, 0x18, 0xea, 0xdb, 0x7c, 0x21, 0x03, 0xea, 0xd3, 0xd9, 0x6c, 0xee, 0xcd, 0xae, + 0x97, 0xed, 0x7b, 0xe8, 0x08, 0x6a, 0xe2, 0x97, 0x73, 0xd5, 0xd6, 0x4e, 0x53, 0x68, 0xe4, 0xf1, + 0x42, 0x4d, 0x68, 0x38, 0x57, 0xce, 0xd2, 0x19, 0x2d, 0xed, 0x49, 0xfb, 0x1e, 0x7a, 0x00, 0x9d, + 0xb9, 0x6b, 0x3b, 0x97, 0xa3, 0x17, 0xb6, 0xe7, 0xda, 0x2f, 0xed, 0xd1, 0xd4, 0x9e, 0xb4, 0x35, + 0x84, 0xc0, 0xbc, 0x58, 0x4e, 0xc7, 0xde, 0xfc, 0xfa, 0xd9, 0xd4, 0x59, 0x5c, 0xd8, 0x93, 0xb6, + 0xce, 0x35, 0x17, 0xd7, 0xe3, 0xb1, 0xbd, 0x58, 0xb4, 0x2b, 0x08, 0xe0, 0xf0, 0xf9, 0xc8, 0xe1, + 0xe4, 0x2a, 0x3a, 0x86, 0x96, 0x73, 0xf5, 0x72, 0xe6, 0x8c, 0x6d, 0x6f, 0x61, 0x2f, 0x97, 0x1c, + 0x3c, 0x38, 0xff, 0xbd, 0x2a, 0x27, 0x68, 0x2c, 0x9e, 0x6f, 0xe4, 0x42, 0x4d, 0x3d, 0xc8, 0xe8, + 0x61, 0x1e, 0xfa, 0xf2, 0x13, 0xdd, 0x7b, 0x50, 0x9a, 0x86, 0xad, 0x79, 0xd6, 0xc3, 0x5f, 0xff, + 0xfe, 0xe7, 0x0f, 0xbd, 0x63, 0x19, 0xc3, 0x77, 0xdf, 0x0c, 0x39, 0x63, 0x48, 0x33, 0xf6, 0xbd, + 0x76, 0x8a, 0xbe, 0x85, 0x43, 0xf9, 0x5e, 0xa1, 0x93, 0x92, 0x64, 0xfe, 0x80, 0xdd, 0xa1, 0x88, + 0xbe, 0x83, 0x9a, 0x9a, 0xf7, 0x42, 0x31, 0xe5, 0x17, 0xa0, 0x77, 0xbc, 0x37, 0x9a, 0x59, 0xfa, + 0xb5, 0x86, 0x7e, 0x02, 0x43, 0x55, 0x2d, 0xc6, 0x02, 0x7d, 0x38, 0xa1, 0x38, 0x37, 0xbd, 0x93, + 0x5d, 0x58, 0xf5, 0xd2, 0x13, 0xbd, 0xdc, 0x47, 0xa8, 0xd8, 0xcb, 0x90, 0x09, 0x29, 0x2f, 0x97, + 0x16, 0xe1, 0x29, 0x48, 0x17, 0xe3, 0x56, 0x90, 0x2e, 0x65, 0xcc, 0xea, 0x0b, 0xe9, 0x1e, 0xea, + 0x96, 0xa4, 0xdf, 0x72, 0xce, 0xf0, 0x67, 0x1c, 0xb2, 0x5f, 0xd0, 0x0f, 0x60, 0xbe, 0x20, 0x4c, + 0x3a, 0xf4, 0x31, 0xd5, 0x97, 0x04, 0x3e, 0xa6, 0xc6, 0x57, 0x87, 0xe2, 0xef, 0xf9, 0xe9, 0x7f, + 0x01, 0x00, 0x00, 0xff, 0xff, 0xc4, 0x2d, 0xd7, 0x0b, 0xd5, 0x07, 0x00, 0x00, } diff --git a/looprpc/client.proto b/looprpc/client.proto index 1978b0b..42f17b3 100644 --- a/looprpc/client.proto +++ b/looprpc/client.proto @@ -265,6 +265,12 @@ enum SwapState { the swap amount. */ FAILED = 4; + + /** + INVOICE_SETTLED is reached when the swap invoice in a loop in swap has been + paid, but we are still waiting for the htlc spend to confirm. + */ + INVOICE_SETTLED = 5; } message TermsRequest { diff --git a/looprpc/client.swagger.json b/looprpc/client.swagger.json index 6a1203c..1f13322 100644 --- a/looprpc/client.swagger.json +++ b/looprpc/client.swagger.json @@ -171,10 +171,11 @@ "PREIMAGE_REVEALED", "HTLC_PUBLISHED", "SUCCESS", - "FAILED" + "FAILED", + "INVOICE_SETTLED" ], "default": "INITIATED", - "description": " - INITIATED: *\nINITIATED is the initial state of a swap. At that point, the initiation\ncall to the server has been made and the payment process has been started\nfor the swap and prepayment invoices.\n - PREIMAGE_REVEALED: *\nPREIMAGE_REVEALED is reached when the sweep tx publication is first\nattempted. From that point on, we should consider the preimage to no\nlonger be secret and we need to do all we can to get the sweep confirmed.\nThis state will mostly coalesce with StateHtlcConfirmed, except in the\ncase where we wait for fees to come down before we sweep.\n - HTLC_PUBLISHED: *\nHTLC_PUBLISHED is reached when the htlc tx has been published in a loop in\nswap.\n - SUCCESS: *\nSUCCESS is the final swap state that is reached when the sweep tx has\nthe required confirmation depth.\n - FAILED: *\nFAILED is the final swap state for a failed swap with or without loss of\nthe swap amount." + "description": " - INITIATED: *\nINITIATED is the initial state of a swap. At that point, the initiation\ncall to the server has been made and the payment process has been started\nfor the swap and prepayment invoices.\n - PREIMAGE_REVEALED: *\nPREIMAGE_REVEALED is reached when the sweep tx publication is first\nattempted. From that point on, we should consider the preimage to no\nlonger be secret and we need to do all we can to get the sweep confirmed.\nThis state will mostly coalesce with StateHtlcConfirmed, except in the\ncase where we wait for fees to come down before we sweep.\n - HTLC_PUBLISHED: *\nHTLC_PUBLISHED is reached when the htlc tx has been published in a loop in\nswap.\n - SUCCESS: *\nSUCCESS is the final swap state that is reached when the sweep tx has\nthe required confirmation depth.\n - FAILED: *\nFAILED is the final swap state for a failed swap with or without loss of\nthe swap amount.\n - INVOICE_SETTLED: *\nINVOICE_SETTLED is reached when the swap invoice in a loop in swap has been\npaid, but we are still waiting for the htlc spend to confirm." }, "looprpcSwapStatus": { "type": "object",