lnrpc+itest: expose AMP fields on InvoiceHTLC

We also test that legacy keysend payments are promoted to AMP payments
on the receiver-sdie by asserting basic properties of the fields
returned via the rpc.
This commit is contained in:
Conner Fromknecht 2021-03-03 10:00:14 -08:00
parent 137258fb58
commit d004442efb
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7
6 changed files with 645 additions and 419 deletions

View File

@ -256,6 +256,37 @@
"invoicesrpcSettleInvoiceResp": {
"type": "object"
},
"lnrpcAMP": {
"type": "object",
"properties": {
"root_share": {
"type": "string",
"format": "byte",
"description": "An n-of-n secret share of the root seed from which child payment hashes\nand preimages are derived."
},
"set_id": {
"type": "string",
"format": "byte",
"description": "An identifier for the HTLC set that this HTLC belongs to."
},
"child_index": {
"type": "integer",
"format": "int64",
"description": "A nonce used to randomize the child preimage and child hash from a given\nroot_share."
},
"hash": {
"type": "string",
"format": "byte",
"description": "The payment hash of the AMP HTLC."
},
"preimage": {
"type": "string",
"format": "byte",
"description": "The preimage used to settle this AMP htlc. This field will only be\npopulated if the invoice is in InvoiceState_ACCEPTED or\nInvoiceState_SETTLED."
}
},
"description": "Details specific to AMP HTLCs."
},
"lnrpcFeature": {
"type": "object",
"properties": {
@ -489,6 +520,10 @@
"type": "string",
"format": "uint64",
"description": "The total amount of the mpp payment in msat."
},
"amp": {
"$ref": "#/definitions/lnrpcAMP",
"description": "Details relevant to AMP HTLCs, only populated if this is an AMP HTLC."
}
},
"title": "Details of an HTLC that paid to an invoice"

View File

@ -116,6 +116,25 @@ func CreateRPCInvoice(invoice *channeldb.Invoice,
MppTotalAmtMsat: uint64(htlc.MppTotalAmt),
}
// Populate any fields relevant to AMP payments.
if htlc.AMP != nil {
rootShare := htlc.AMP.Record.RootShare()
setID := htlc.AMP.Record.SetID()
var preimage []byte
if htlc.AMP.Preimage != nil {
preimage = htlc.AMP.Preimage[:]
}
rpcHtlc.Amp = &lnrpc.AMP{
RootShare: rootShare[:],
SetId: setID[:],
ChildIndex: uint32(htlc.AMP.Record.ChildIndex()),
Hash: htlc.AMP.Hash[:],
Preimage: preimage,
}
}
// Only report resolved times if htlc is resolved.
if htlc.State != channeldb.HtlcStateAccepted {
rpcHtlc.ResolveTime = htlc.ResolveTime.Unix()

File diff suppressed because it is too large Load Diff

View File

@ -2954,6 +2954,31 @@ message InvoiceHTLC {
// The total amount of the mpp payment in msat.
uint64 mpp_total_amt_msat = 10;
// Details relevant to AMP HTLCs, only populated if this is an AMP HTLC.
AMP amp = 11;
}
// Details specific to AMP HTLCs.
message AMP {
// An n-of-n secret share of the root seed from which child payment hashes
// and preimages are derived.
bytes root_share = 1;
// An identifier for the HTLC set that this HTLC belongs to.
bytes set_id = 2;
// A nonce used to randomize the child preimage and child hash from a given
// root_share.
uint32 child_index = 3;
// The payment hash of the AMP HTLC.
bytes hash = 4;
// The preimage used to settle this AMP htlc. This field will only be
// populated if the invoice is in InvoiceState_ACCEPTED or
// InvoiceState_SETTLED.
bytes preimage = 5;
}
message AddInvoiceResponse {

View File

@ -2468,6 +2468,37 @@
}
}
},
"lnrpcAMP": {
"type": "object",
"properties": {
"root_share": {
"type": "string",
"format": "byte",
"description": "An n-of-n secret share of the root seed from which child payment hashes\nand preimages are derived."
},
"set_id": {
"type": "string",
"format": "byte",
"description": "An identifier for the HTLC set that this HTLC belongs to."
},
"child_index": {
"type": "integer",
"format": "int64",
"description": "A nonce used to randomize the child preimage and child hash from a given\nroot_share."
},
"hash": {
"type": "string",
"format": "byte",
"description": "The payment hash of the AMP HTLC."
},
"preimage": {
"type": "string",
"format": "byte",
"description": "The preimage used to settle this AMP htlc. This field will only be\npopulated if the invoice is in InvoiceState_ACCEPTED or\nInvoiceState_SETTLED."
}
},
"description": "Details specific to AMP HTLCs."
},
"lnrpcAbandonChannelResponse": {
"type": "object"
},
@ -4186,6 +4217,10 @@
"type": "string",
"format": "uint64",
"description": "The total amount of the mpp payment in msat."
},
"amp": {
"$ref": "#/definitions/lnrpcAMP",
"description": "Details relevant to AMP HTLCs, only populated if this is an AMP HTLC."
}
},
"title": "Details of an HTLC that paid to an invoice"

View File

@ -15,6 +15,7 @@ import (
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record"
"github.com/stretchr/testify/require"
)
func testSingleHopInvoice(net *lntest.NetworkHarness, t *harnessTest) {
@ -162,6 +163,21 @@ func testSingleHopInvoice(net *lntest.NetworkHarness, t *harnessTest) {
t.Fatalf(err.Error())
}
// Assert that the invoice has the proper AMP fields set, since the
// legacy keysend payment should have been promoted into an AMP payment
// internally.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
keysendInvoice, err := net.Bob.LookupInvoice(
ctxt, &lnrpc.PaymentHash{
RHash: keySendHash[:],
},
)
require.NoError(t.t, err)
require.Equal(t.t, 1, len(keysendInvoice.Htlcs))
htlc := keysendInvoice.Htlcs[0]
require.Equal(t.t, uint64(0), htlc.MppTotalAmtMsat)
require.Nil(t.t, htlc.Amp)
// Now create an invoice and specify routing hints.
// We will test that the routing hints are encoded properly.
hintChannel := lnwire.ShortChannelID{BlockHeight: 10}