multi: restructure invoice Terms field

This commit restructures an invoice's ContractTerms to better encompass
the restrictions placed on settling. For instance, the final ctlv delta
and invoice expiry are moved from the main invoice body (where
additional metadata is stored). Additionally, it moves the State field
outside of the terms since it is rather metadata about the invoice
instead of any terms offered to the sender in the payment request.
This commit is contained in:
Conner Fromknecht committed 2019-11-22 02:25:02 -08:00
1 parent 6cabea563e
commit 3b253e05f6
8 files changed
+81 -82

No files matched your search

+12 -12
View File
@@ -179,7 +179,7 @@ func (i *InvoiceRegistry) invoiceEventNotifier() {
// For backwards compatibility, do not notify
// all invoice subscribers of cancel and accept
// events.
state := e.invoice.Terms.State
state := e.invoice.State
if state != channeldb.ContractCanceled &&
state != channeldb.ContractAccepted {
@@ -231,7 +231,7 @@ func (i *InvoiceRegistry) dispatchToClients(event *invoiceEvent) {
// ensure we don't duplicate any events.
// TODO(joostjager): Refactor switches.
state := event.invoice.Terms.State
state := event.invoice.State
switch {
// If we've already sent this settle event to
// the client, then we can skip this.
@@ -277,14 +277,14 @@ func (i *InvoiceRegistry) dispatchToClients(event *invoiceEvent) {
// the latest add/settle index it has. We'll use this to ensure
// we don't send a notification twice, which can happen if a new
// event is added while we're catching up a new client.
switch event.invoice.Terms.State {
switch event.invoice.State {
case channeldb.ContractSettled:
client.settleIndex = invoice.SettleIndex
case channeldb.ContractOpen:
client.addIndex = invoice.AddIndex
default:
log.Errorf("unexpected invoice state: %v",
event.invoice.Terms.State)
event.invoice.State)
}
}
}
@@ -467,7 +467,7 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash,
// If the invoice is already canceled, there is no further
// checking to do.
if inv.Terms.State == channeldb.ContractCanceled {
if inv.State == channeldb.ContractCanceled {
debugLog("invoice already canceled")
return nil, errNoUpdate
}
@@ -486,7 +486,7 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash,
return nil, errNoUpdate
}
if expiry < uint32(currentHeight+inv.FinalCltvDelta) {
if expiry < uint32(currentHeight+inv.Terms.FinalCltvDelta) {
debugLog("expiry too soon")
return nil, errNoUpdate
}
@@ -506,7 +506,7 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash,
// Don't update invoice state if we are accepting a duplicate
// payment. We do accept or settle the HTLC.
switch inv.Terms.State {
switch inv.State {
case channeldb.ContractAccepted:
debugLog("accepting duplicate payment to accepted invoice")
update.State = channeldb.ContractAccepted
@@ -546,7 +546,7 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash,
}
if updateSubscribers {
i.notifyClients(rHash, invoice, invoice.Terms.State)
i.notifyClients(rHash, invoice, invoice.State)
}
// Inspect latest htlc state on the invoice.
@@ -597,7 +597,7 @@ func (i *InvoiceRegistry) SettleHodlInvoice(preimage lntypes.Preimage) error {
updateInvoice := func(invoice *channeldb.Invoice) (
*channeldb.InvoiceUpdateDesc, error) {
switch invoice.Terms.State {
switch invoice.State {
case channeldb.ContractOpen:
return nil, channeldb.ErrInvoiceStillOpen
case channeldb.ContractCanceled:
@@ -639,7 +639,7 @@ func (i *InvoiceRegistry) SettleHodlInvoice(preimage lntypes.Preimage) error {
AcceptHeight: int32(htlc.AcceptHeight),
})
}
i.notifyClients(hash, invoice, invoice.Terms.State)
i.notifyClients(hash, invoice, invoice.State)
return nil
}
@@ -655,7 +655,7 @@ func (i *InvoiceRegistry) CancelInvoice(payHash lntypes.Hash) error {
updateInvoice := func(invoice *channeldb.Invoice) (
*channeldb.InvoiceUpdateDesc, error) {
switch invoice.Terms.State {
switch invoice.State {
case channeldb.ContractSettled:
return nil, channeldb.ErrInvoiceAlreadySettled
case channeldb.ContractCanceled:
@@ -868,7 +868,7 @@ func (i *InvoiceRegistry) SubscribeNotifications(addIndex, settleIndex uint64) *
invoiceEvent := ntfn.(*invoiceEvent)
var targetChan chan *channeldb.Invoice
state := invoiceEvent.invoice.Terms.State
state := invoiceEvent.invoice.State
switch state {
case channeldb.ContractOpen:
targetChan = client.NewInvoices
+24 -24
View File
@@ -115,9 +115,9 @@ func TestSettleInvoice(t *testing.T) {
// We expect the open state to be sent to the single invoice subscriber.
select {
case update := <-subscription.Updates:
if update.Terms.State != channeldb.ContractOpen {
if update.State != channeldb.ContractOpen {
t.Fatalf("expected state ContractOpen, but got %v",
update.Terms.State)
update.State)
}
case <-time.After(testTimeout):
t.Fatal("no update received")
@@ -126,9 +126,9 @@ func TestSettleInvoice(t *testing.T) {
// We expect a new invoice notification to be sent out.
select {
case newInvoice := <-allSubscriptions.NewInvoices:
if newInvoice.Terms.State != channeldb.ContractOpen {
if newInvoice.State != channeldb.ContractOpen {
t.Fatalf("expected state ContractOpen, but got %v",
newInvoice.Terms.State)
newInvoice.State)
}
case <-time.After(testTimeout):
t.Fatal("no update received")
@@ -167,9 +167,9 @@ func TestSettleInvoice(t *testing.T) {
// subscriber.
select {
case update := <-subscription.Updates:
if update.Terms.State != channeldb.ContractSettled {
if update.State != channeldb.ContractSettled {
t.Fatalf("expected state ContractOpen, but got %v",
update.Terms.State)
update.State)
}
if update.AmtPaid != amtPaid {
t.Fatal("invoice AmtPaid incorrect")
@@ -181,9 +181,9 @@ func TestSettleInvoice(t *testing.T) {
// We expect a settled notification to be sent out.
select {
case settledInvoice := <-allSubscriptions.SettledInvoices:
if settledInvoice.Terms.State != channeldb.ContractSettled {
if settledInvoice.State != channeldb.ContractSettled {
t.Fatalf("expected state ContractOpen, but got %v",
settledInvoice.Terms.State)
settledInvoice.State)
}
case <-time.After(testTimeout):
t.Fatal("no update received")
@@ -288,10 +288,10 @@ func TestCancelInvoice(t *testing.T) {
// We expect the open state to be sent to the single invoice subscriber.
select {
case update := <-subscription.Updates:
if update.Terms.State != channeldb.ContractOpen {
if update.State != channeldb.ContractOpen {
t.Fatalf(
"expected state ContractOpen, but got %v",
update.Terms.State,
update.State,
)
}
case <-time.After(testTimeout):
@@ -301,10 +301,10 @@ func TestCancelInvoice(t *testing.T) {
// We expect a new invoice notification to be sent out.
select {
case newInvoice := <-allSubscriptions.NewInvoices:
if newInvoice.Terms.State != channeldb.ContractOpen {
if newInvoice.State != channeldb.ContractOpen {
t.Fatalf(
"expected state ContractOpen, but got %v",
newInvoice.Terms.State,
newInvoice.State,
)
}
case <-time.After(testTimeout):
@@ -321,10 +321,10 @@ func TestCancelInvoice(t *testing.T) {
// subscriber.
select {
case update := <-subscription.Updates:
if update.Terms.State != channeldb.ContractCanceled {
if update.State != channeldb.ContractCanceled {
t.Fatalf(
"expected state ContractCanceled, but got %v",
update.Terms.State,
update.State,
)
}
case <-time.After(testTimeout):
@@ -402,16 +402,16 @@ func TestSettleHoldInvoice(t *testing.T) {
// We expect the open state to be sent to the single invoice subscriber.
update := <-subscription.Updates
if update.Terms.State != channeldb.ContractOpen {
if update.State != channeldb.ContractOpen {
t.Fatalf("expected state ContractOpen, but got %v",
update.Terms.State)
update.State)
}
// We expect a new invoice notification to be sent out.
newInvoice := <-allSubscriptions.NewInvoices
if newInvoice.Terms.State != channeldb.ContractOpen {
if newInvoice.State != channeldb.ContractOpen {
t.Fatalf("expected state ContractOpen, but got %v",
newInvoice.Terms.State)
newInvoice.State)
}
// Use slightly higher amount for accept/settle.
@@ -474,9 +474,9 @@ func TestSettleHoldInvoice(t *testing.T) {
// subscriber. For all invoice subscribers, we don't expect an update.
// Those only get notified on settle.
update = <-subscription.Updates
if update.Terms.State != channeldb.ContractAccepted {
if update.State != channeldb.ContractAccepted {
t.Fatalf("expected state ContractAccepted, but got %v",
update.Terms.State)
update.State)
}
if update.AmtPaid != amtPaid {
t.Fatal("invoice AmtPaid incorrect")
@@ -500,9 +500,9 @@ func TestSettleHoldInvoice(t *testing.T) {
// We expect a settled notification to be sent out for both all and
// single invoice subscribers.
settledInvoice := <-allSubscriptions.SettledInvoices
if settledInvoice.Terms.State != channeldb.ContractSettled {
if settledInvoice.State != channeldb.ContractSettled {
t.Fatalf("expected state ContractSettled, but got %v",
settledInvoice.Terms.State)
settledInvoice.State)
}
if settledInvoice.AmtPaid != amtPaid {
t.Fatalf("expected amount to be %v, but got %v",
@@ -510,9 +510,9 @@ func TestSettleHoldInvoice(t *testing.T) {
}
update = <-subscription.Updates
if update.Terms.State != channeldb.ContractSettled {
if update.State != channeldb.ContractSettled {
t.Fatalf("expected state ContractSettled, but got %v",
update.Terms.State)
update.State)
}
// Idempotency.