Skip to content

Commit

Permalink
add support for mpp records when building routes
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbosworth committed Jul 20, 2020
1 parent aadc923 commit c5d3070
Show file tree
Hide file tree
Showing 12 changed files with 164 additions and 66 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Versions

## 49.4.0

- `getRouteThroughHops`: Add support for specifying MPP records and TLV messages
- `routeFromChannels`: Add support for specifying TLV messages

## 49.3.7

- `updateRoutingFees`: Allow specifying zero `base_fee_tokens`, `fee_rate`
Expand Down
71 changes: 45 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2258,34 +2258,45 @@ Requires `offchain:read` permission

This method is not supported by LND v0.7.1

{
[cltv_delta]: <Final CLTV Delta Number>
lnd: <Authenticated LND API Object>
[mtokens]: <Millitokens to Send String>
[outgoing_channel]: <Outgoing Channel Id String>
public_keys: [<Public Key Hex String>]
}

@returns via cbk or Promise
{
route: {
fee: <Route Fee Tokens Number>
fee_mtokens: <Route Fee Millitokens String>
hops: [{
channel: <Standard Format Channel Id String>
channel_capacity: <Channel Capacity Tokens Number>
fee: <Fee Number>
fee_mtokens: <Fee Millitokens String>
forward: <Forward Tokens Number>
forward_mtokens: <Forward Millitokens String>
public_key: <Forward Edge Public Key Hex String>
timeout: <Timeout Block Height Number>
{
[cltv_delta]: <Final CLTV Delta Number>
lnd: <Authenticated LND API Object>
[mtokens]: <Millitokens to Send String>
[outgoing_channel]: <Outgoing Channel Id String>
[messages]: [{
type: <Message Type Number String>
value: <Message Raw Value Hex Encoded String>
}]
mtokens: <Total Fee-Inclusive Millitokens String>
timeout: <Route Timeout Height Number>
tokens: <Total Fee-Inclusive Tokens Number>
[payment]: <Payment Identifier Hex String>
public_keys: [<Public Key Hex String>]
[tokens]: <Tokens to Send Number>
[total_mtokens]: <Payment Total Millitokens String>
}

@returns via cbk or Promise
{
route: {
fee: <Route Fee Tokens Number>
fee_mtokens: <Route Fee Millitokens String>
hops: [{
channel: <Standard Format Channel Id String>
channel_capacity: <Channel Capacity Tokens Number>
fee: <Fee Number>
fee_mtokens: <Fee Millitokens String>
forward: <Forward Tokens Number>
forward_mtokens: <Forward Millitokens String>
public_key: <Forward Edge Public Key Hex String>
timeout: <Timeout Block Height Number>
}]
mtokens: <Total Fee-Inclusive Millitokens String>
[payment]: <Payment Identifier Hex String>
safe_fee: <Payment Forwarding Fee Rounded Up Tokens Number>
safe_tokens: <Payment Tokens Rounded Up Number>
timeout: <Route Timeout Height Number>
tokens: <Total Fee-Inclusive Tokens Number>
[total_mtokens]: <Payment Total Millitokens String>
}
}
}

Example:

Expand Down Expand Up @@ -3601,6 +3612,10 @@ Either next hop destination in channels or final destination is required
[cltv_delta]: <Final CLTV Delta Number>
[destination]: <Destination Public Key Hex String>
height: <Current Block Height Number>
[messages]: [{
type: <Message Type Number String>
value: <Message Raw Value Hex Encoded String>
}]
mtokens: <Millitokens To Send String>
[payment]: <Payment Identification Value Hex String>
[total_mtokens]: <Sum of Shards Millitokens String>
Expand All @@ -3624,6 +3639,10 @@ Either next hop destination in channels or final destination is required
[public_key]: <Public Key Hex String>
timeout: <Timeout Block Height Number>
}]
[messages]: [{
type: <Message Type Number String>
value: <Message Raw Value Hex Encoded String>
}]
mtokens: <Total Fee-Inclusive Millitokens String>
[payment]: <Payment Identification Value Hex String>
timeout: <Timeout Block Height Number>
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"express": "4.17.1",
"invoices": "1.1.1",
"is-base64": "1.1.0",
"lightning": "2.0.28",
"lightning": "2.0.29",
"macaroon": "3.0.4",
"morgan": "1.10.0",
"ws": "7.3.1"
Expand Down Expand Up @@ -60,5 +60,5 @@
"tower_server-integration-tests": "tap --no-coverage test/tower_serverrpc-integration/*.js",
"wallet-integration-tests": "tap --no-coverage test/walletrpc-integration/*.js"
},
"version": "49.3.7"
"version": "49.4.0"
}
9 changes: 9 additions & 0 deletions routing/route_from_channels.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ const {isArray} = Array;
[cltv_delta]: <Final CLTV Delta Number>
[destination]: <Destination Public Key Hex String>
height: <Current Block Height Number>
[messages]: [{
type: <Message Type Number String>
value: <Message Raw Value Hex Encoded String>
}]
mtokens: <Millitokens To Send String>
[payment]: <Payment Identification Value Hex String>
[total_mtokens]: <Sum of Shards Millitokens String>
Expand All @@ -49,6 +53,10 @@ const {isArray} = Array;
[public_key]: <Public Key Hex String>
timeout: <Timeout Block Height Number>
}]
[messages]: [{
type: <Message Type Number String>
value: <Message Raw Value Hex Encoded String>
}]
mtokens: <Total Fee-Inclusive Millitokens String>
[payment]: <Payment Identification Value Hex String>
timeout: <Timeout Block Height Number>
Expand Down Expand Up @@ -84,6 +92,7 @@ module.exports = args => {
height: args.height,
hops: path.hops,
initial_cltv: path.initial_cltv || defaultInitialCltvDelta,
messages: args.messages,
mtokens: args.mtokens,
payment: args.payment,
total_mtokens: args.total_mtokens,
Expand Down
9 changes: 9 additions & 0 deletions routing/route_from_hops.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ const minFee = 0;
public_key: <Next Hop Public Key Hex String>
}]
initial_cltv: <Initial CLTV Delta Number>
[messages]: [{
type: <Message Type Number String>
value: <Message Raw Value Hex Encoded String>
}]
mtokens: <Millitokens To Send String>
[payment]: <Payment Identification Value Hex String>
[total_mtokens]: <Total Millitokens For Sharded Payments String>
Expand All @@ -42,6 +46,10 @@ const minFee = 0;
[public_key]: <Public Key Hex String>
timeout: <Timeout Block Height Number>
}]
[messages]: [{
type: <Message Type Number String>
value: <Message Raw Value Hex Encoded String>
}]
mtokens: <Total Fee-Inclusive Millitokens String>
[payment]: <Payment Identification Value Hex String>
timeout: <Timeout Block Height Number>
Expand Down Expand Up @@ -140,6 +148,7 @@ module.exports = args => {
fee: asTokens({mtokens: totalFeeMtokens}).tokens,
fee_mtokens: totalFeeMtokens.toString(),
hops: backwardsPath.slice().reverse(),
messages: args.messages,
mtokens: totalMtokens.toString(),
payment: args.payment,
timeout: timeoutHeight + args.initial_cltv,
Expand Down
1 change: 1 addition & 0 deletions test/integration/test_get_chain_transactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ test(`Get chain transactions`, async ({deepIs, end, equal, fail}) => {
'0d5b0fefa4d9082f7964836f5e58c3a6bda8e471': true,
'1e04b7f54360427a23a5daf4a5a0648e6a81f3a6': true,
'4f2221d56c8212ddc4f48a4e6a6ee57255e61195': true,
'86114c575c2dff9dff1e1bb4df961c64aea9fc1c': true,
'ae6e84ddfd3c4d2366e151a04aca3f78b4078ed5': true,
'd62c575f8499a314eb27f12462d20500b6bda2c7': true,
'e8833042799d71dba209fe305ce3ae105c154cfe': true,
Expand Down
2 changes: 1 addition & 1 deletion test/integration/test_get_closed_channels.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const maxChanTokens = Math.pow(2, 24) - 1;
const times = 1000;

// Getting closed channels should return closed channels
test(`Close channel`, async ({end, equal}) => {
test(`Get closed channels`, async ({end, equal}) => {
const cluster = await createCluster({is_remote_skipped: true});

const {lnd} = cluster.control;
Expand Down
4 changes: 4 additions & 0 deletions test/router/test_get_route_through_hops.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,12 @@ const tests = [
}],
messages: [],
mtokens: '1',
payment: undefined,
safe_fee: 1,
safe_tokens: 1,
timeout: 1,
tokens: 0,
total_mtokens: undefined,
},
},
},
Expand Down Expand Up @@ -191,10 +193,12 @@ const tests = [
}],
messages: [],
mtokens: '1',
payment: undefined,
safe_fee: 1,
safe_tokens: 1,
timeout: 1,
tokens: 0,
total_mtokens: undefined,
},
},
},
Expand Down
55 changes: 47 additions & 8 deletions test/routerrpc-integration/test_get_route_through_hops.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ const {addPeer} = require('./../../');
const {createCluster} = require('./../macros');
const {createInvoice} = require('./../../');
const {decodePaymentRequest} = require('./../../');
const {getInvoice} = require('./../../');
const {getRouteThroughHops} = require('./../../');
const {getRoutes} = require('./../../');
const {getWalletVersion} = require('./../../');
const {payViaRoutes} = require('./../../');
const {setupChannel} = require('./../macros');
const {waitForRoute} = require('./../macros');

Expand Down Expand Up @@ -70,19 +73,55 @@ test(`Get route through hops`, async ({deepIs, end, equal}) => {
try {
const res = await getRouteThroughHops({
lnd,
cltv_delta: invoice.cltv_delta,
messages: [{type: '1000000', value: '01'}],
mtokens: (BigInt(invoice.tokens) * BigInt(1e3)).toString(),
payment: decodedRequest.payment,
public_keys: route.hops.map(n => n.public_key),
total_mtokens: invoice.mtokens,
});

delete res.route.confidence;
delete res.route.messages;
delete res.route.payment;
delete res.route.total_mtokens;
delete route.confidence;
delete route.payment;
delete route.total_mtokens;
await payViaRoutes({lnd, id: invoice.id, routes: [res.route]});

deepIs(res.route, route, 'Constructed route to destination');
const isTenOrAbove = await (async () => {
try {
return !!(await getWalletVersion({lnd}));
} catch (err) {
return false;
}
})();

if (isTenOrAbove) {
const got = await getInvoice({lnd: cluster.remote.lnd, id: invoice.id});

delete res.route.confidence;
delete route.confidence;

route.messages = [{type: '1000000', value: '01'}];
route.payment = decodedRequest.payment;
route.total_mtokens = decodedRequest.mtokens;

deepIs(res.route, route, 'Constructed route to destination');

const {payments} = got;

const [payment] = payments;

equal(payment.total_mtokens, invoice.mtokens, 'Got MPP total mtokens');

deepIs(payment.messages, route.messages, 'Remote got TLV messages');
} else {
delete res.route.confidence;
delete res.route.messages;
delete res.route.payment;
delete res.route.total_mtokens;
delete route.confidence;
delete route.messages;
delete route.payment;
delete route.total_mtokens;

deepIs(res.route, route, 'Constructed route to destination');
}
} catch (err) {
deepIs(err, [501, 'ExpectedRouterRpcWithGetRouteMethod'], 'Unimplemented');
}
Expand Down
Loading

0 comments on commit c5d3070

Please sign in to comment.