bolt07 1.8.3 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -1
- package/LICENSE +1 -1
- package/ids/chan_number.js +0 -1
- package/package.json +2 -5
- package/routing/hops_from_channels.js +7 -1
- package/routing/policy_fee.js +12 -1
- package/routing/route_from_channels.js +2 -0
- package/routing/route_from_hops.js +12 -12
- package/test/addresses/test_decode_socket.js +4 -2
- package/test/addresses/test_encode_base32.js +4 -2
- package/test/addresses/test_encode_socket.js +4 -2
- package/test/ids/test_chan_format.js +5 -3
- package/test/ids/test_chan_number.js +5 -3
- package/test/ids/test_components_from_buffer.js +3 -2
- package/test/ids/test_decode_chan_id.js +7 -5
- package/test/ids/test_encode_chan_id.js +7 -5
- package/test/ids/test_raw_chan_id.js +5 -3
- package/test/routing/test_hops_from_channels.js +139 -2
- package/test/routing/test_policy_fee.js +32 -4
- package/test/routing/test_route_from_channels.js +4 -2
- package/test/routing/test_route_from_hops.js +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
# Versions
|
|
2
2
|
|
|
3
|
-
## 1.
|
|
3
|
+
## 1.9.0
|
|
4
|
+
|
|
5
|
+
- `hopsFromChannels`, `routeFromChannels`, `routeFromHops`: Add support for
|
|
6
|
+
inbound discounts
|
|
7
|
+
|
|
8
|
+
## 1.8.4
|
|
4
9
|
|
|
5
10
|
- `decodeSocket`: Decode a connection socket from hex data
|
|
6
11
|
- `encodeSocket`: Encode a connection socket to hex data
|
package/LICENSE
CHANGED
package/ids/chan_number.js
CHANGED
package/package.json
CHANGED
|
@@ -10,9 +10,6 @@
|
|
|
10
10
|
"bn.js": "5.2.1"
|
|
11
11
|
},
|
|
12
12
|
"description": "Utilities for working with bolt07 data formats",
|
|
13
|
-
"devDependencies": {
|
|
14
|
-
"@alexbosworth/tap": "15.0.12"
|
|
15
|
-
},
|
|
16
13
|
"keywords": [
|
|
17
14
|
"bolt",
|
|
18
15
|
"channel-id",
|
|
@@ -29,7 +26,7 @@
|
|
|
29
26
|
"url": "https://github.com/alexbosworth/bolt07.git"
|
|
30
27
|
},
|
|
31
28
|
"scripts": {
|
|
32
|
-
"test": "
|
|
29
|
+
"test": "npx nyc@15.1 node --experimental-test-coverage --test"
|
|
33
30
|
},
|
|
34
|
-
"version": "1.
|
|
31
|
+
"version": "1.9.0"
|
|
35
32
|
}
|
|
@@ -15,6 +15,8 @@ const payNodesCount = 2;
|
|
|
15
15
|
base_fee_mtokens: <Base Fee Millitokens String>
|
|
16
16
|
cltv_delta: <Locktime Delta Number>
|
|
17
17
|
fee_rate: <Fees Charged Per Million Tokens Number>
|
|
18
|
+
[inbound_base_discount_mtokens]: <Source Base Fee Reduction String>
|
|
19
|
+
[inbound_rate_discount]: <Source Per Million Rate Reduction Number>
|
|
18
20
|
is_disabled: <Channel Is Disabled Bool>
|
|
19
21
|
min_htlc_mtokens: <Minimum HTLC Millitokens Value String>
|
|
20
22
|
public_key: <Node Public Key String>
|
|
@@ -34,6 +36,8 @@ const payNodesCount = 2;
|
|
|
34
36
|
channel_capacity: <Maximum Tokens Number>
|
|
35
37
|
cltv_delta: <CLTV Delta Number>
|
|
36
38
|
fee_rate: <Fee Rate In Millitokens Per Million Number>
|
|
39
|
+
[inbound_base_discount_mtokens]: <Source Base Fee Reduction String>
|
|
40
|
+
[inbound_rate_discount]: <Source Per Million Rate Reduction Number>
|
|
37
41
|
public_key: <Public Key Hex String>
|
|
38
42
|
}]
|
|
39
43
|
}
|
|
@@ -74,7 +78,7 @@ module.exports = ({channels, destination}) => {
|
|
|
74
78
|
const nextPolicy = chans[i + [channel].length];
|
|
75
79
|
let overridePolicy;
|
|
76
80
|
|
|
77
|
-
const peer = channel.policies.find(n => n.public_key === nextHop);
|
|
81
|
+
const peer = channel.policies.find(n => n.public_key === nextHop) || {};
|
|
78
82
|
const policy = channel.policies.find(n => n.public_key !== nextHop);
|
|
79
83
|
|
|
80
84
|
if (!policy) {
|
|
@@ -104,6 +108,8 @@ module.exports = ({channels, destination}) => {
|
|
|
104
108
|
channel_capacity: channel.capacity,
|
|
105
109
|
cltv_delta: cltvDelta || defaultCltvDelta,
|
|
106
110
|
fee_rate: (overridePolicy || policy).fee_rate,
|
|
111
|
+
inbound_base_discount_mtokens: peer.inbound_base_discount_mtokens,
|
|
112
|
+
inbound_rate_discount: peer.inbound_rate_discount,
|
|
107
113
|
public_key: nextHop,
|
|
108
114
|
};
|
|
109
115
|
});
|
package/routing/policy_fee.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const none = '0';
|
|
1
2
|
const rateDivisor = BigInt(1e6);
|
|
2
3
|
|
|
3
4
|
/** Fee for policy
|
|
@@ -7,6 +8,8 @@ const rateDivisor = BigInt(1e6);
|
|
|
7
8
|
policy: {
|
|
8
9
|
base_fee_mtokens: <Base Fee Millitokens String>
|
|
9
10
|
fee_rate: <Fee Rate Number>
|
|
11
|
+
[inbound_base_discount_mtokens]: <Source Base Fee Reduction String>
|
|
12
|
+
[inbound_rate_discount]: <Source Per Million Rate Reduction Number>
|
|
10
13
|
}
|
|
11
14
|
}
|
|
12
15
|
|
|
@@ -38,8 +41,16 @@ module.exports = ({mtokens, policy}) => {
|
|
|
38
41
|
const baseFeeMtokens = BigInt(policy.base_fee_mtokens);
|
|
39
42
|
const feeRate = BigInt(policy.fee_rate);
|
|
40
43
|
const forwardMtokens = BigInt(mtokens);
|
|
44
|
+
const lowerBaseFee = BigInt(policy.inbound_base_discount_mtokens || none);
|
|
45
|
+
const lowerFeeRate = BigInt(policy.inbound_rate_discount || none);
|
|
41
46
|
|
|
47
|
+
const discount = lowerBaseFee + forwardMtokens * lowerFeeRate / rateDivisor;
|
|
42
48
|
const fee = baseFeeMtokens + forwardMtokens * feeRate / rateDivisor;
|
|
43
49
|
|
|
44
|
-
|
|
50
|
+
// Exit early when the discount drowns out the fee
|
|
51
|
+
if (-discount > fee) {
|
|
52
|
+
return {fee_mtokens: none};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return {fee_mtokens: (fee + discount).toString()};
|
|
45
56
|
};
|
|
@@ -17,6 +17,8 @@ const {isArray} = Array;
|
|
|
17
17
|
base_fee_mtokens: <Base Fee Millitokens String>
|
|
18
18
|
cltv_delta: <Locktime Delta Number>
|
|
19
19
|
fee_rate: <Fees Charged in Millitokens Per Million Number>
|
|
20
|
+
[inbound_base_discount_mtokens]: <Source Base Fee Reduction String>
|
|
21
|
+
[inbound_rate_discount]: <Source Per Million Rate Reduction Number>
|
|
20
22
|
is_disabled: <Channel Is Disabled Bool>
|
|
21
23
|
max_htlc_mtokens: <Maximum HTLC Millitokens Value String>
|
|
22
24
|
min_htlc_mtokens: <Minimum HTLC Millitokens Value String>
|
|
@@ -17,6 +17,8 @@ const minFee = 0;
|
|
|
17
17
|
[channel_capacity]: <Channel Capacity Tokens Number>
|
|
18
18
|
cltv_delta: <CLTV Delta Number>
|
|
19
19
|
fee_rate: <Fee Rate In Millitokens Per Million Number>
|
|
20
|
+
[inbound_base_discount_mtokens]: <Source Base Fee Reduction String>
|
|
21
|
+
[inbound_rate_discount]: <Source Per Million Rate Reduction Number>
|
|
20
22
|
public_key: <Next Hop Public Key Hex String>
|
|
21
23
|
}]
|
|
22
24
|
initial_cltv: <Initial CLTV Delta Number>
|
|
@@ -58,15 +60,13 @@ const minFee = 0;
|
|
|
58
60
|
}
|
|
59
61
|
*/
|
|
60
62
|
module.exports = args => {
|
|
61
|
-
const {height, hops, mtokens} = args;
|
|
62
|
-
|
|
63
63
|
const finalCltvDelta = args.cltv_delta || defaultCltvBuffer;
|
|
64
64
|
|
|
65
|
-
if (height === undefined) {
|
|
65
|
+
if (args.height === undefined) {
|
|
66
66
|
throw new Error('ExpectedChainHeightForRoute');
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
if (!isArray(hops) || !hops.length) {
|
|
69
|
+
if (!isArray(args.hops) || !args.hops.length) {
|
|
70
70
|
throw new Error('ExpectedHopsToConstructRouteFrom');
|
|
71
71
|
}
|
|
72
72
|
|
|
@@ -74,12 +74,12 @@ module.exports = args => {
|
|
|
74
74
|
throw new Error('ExpectedInitialCltvDeltaToConstructRouteFromHops');
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
if (!mtokens) {
|
|
77
|
+
if (!args.mtokens) {
|
|
78
78
|
throw new Error('ExpectedMillitokensToSendAcrossHops');
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
// Check hops for validity
|
|
82
|
-
hops.forEach((hop, i) => {
|
|
82
|
+
args.hops.forEach((hop, i) => {
|
|
83
83
|
if (hop.base_fee_mtokens === undefined) {
|
|
84
84
|
throw new Error('ExpectedHopBaseFeeMillitokensForRouteConstruction');
|
|
85
85
|
}
|
|
@@ -103,12 +103,12 @@ module.exports = args => {
|
|
|
103
103
|
return;
|
|
104
104
|
});
|
|
105
105
|
|
|
106
|
-
let forwardMtokens = BigInt(mtokens);
|
|
107
|
-
const [firstHop] = hops.slice();
|
|
108
|
-
let timeoutHeight = height + finalCltvDelta;
|
|
106
|
+
let forwardMtokens = BigInt(args.mtokens);
|
|
107
|
+
const [firstHop] = args.hops.slice();
|
|
108
|
+
let timeoutHeight = args.height + finalCltvDelta;
|
|
109
109
|
|
|
110
110
|
// To construct the route, we need to go backwards from the end
|
|
111
|
-
const backwardsPath = hops.slice().reverse().map((hop, i, hops) => {
|
|
111
|
+
const backwardsPath = args.hops.slice().reverse().map((hop, i, hops) => {
|
|
112
112
|
let feeMtokens = BigInt(minFee);
|
|
113
113
|
|
|
114
114
|
if (!!i) {
|
|
@@ -138,9 +138,9 @@ module.exports = args => {
|
|
|
138
138
|
.map(n => BigInt(n.fee_mtokens))
|
|
139
139
|
.reduce((sum, n) => sum + n, BigInt(minFee));
|
|
140
140
|
|
|
141
|
-
const totalMtokens = totalFeeMtokens + BigInt(mtokens);
|
|
141
|
+
const totalMtokens = totalFeeMtokens + BigInt(args.mtokens);
|
|
142
142
|
|
|
143
|
-
if (hops.length === 1) {
|
|
143
|
+
if (args.hops.length === 1) {
|
|
144
144
|
timeoutHeight -= args.initial_cltv;
|
|
145
145
|
}
|
|
146
146
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const strictSame = require('node:assert').strict.deepStrictEqual;
|
|
2
|
+
const test = require('node:test');
|
|
3
|
+
const {throws} = require('node:assert').strict;
|
|
2
4
|
|
|
3
5
|
const {decodeSocket} = require('./../../');
|
|
4
6
|
|
|
@@ -53,7 +55,7 @@ const tests = [
|
|
|
53
55
|
];
|
|
54
56
|
|
|
55
57
|
tests.forEach(({args, description, error, expected}) => {
|
|
56
|
-
return test(description, (
|
|
58
|
+
return test(description, (t, end) => {
|
|
57
59
|
if (!!error) {
|
|
58
60
|
throws(() => decodeSocket(args), new Error(error), 'Got expected error');
|
|
59
61
|
} else {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const strictSame = require('node:assert').strict.deepStrictEqual;
|
|
2
|
+
const test = require('node:test');
|
|
3
|
+
const {throws} = require('node:assert').strict;
|
|
2
4
|
|
|
3
5
|
const encodeBase32 = require('./../../addresses/encode_base32');
|
|
4
6
|
|
|
@@ -25,7 +27,7 @@ const tests = [
|
|
|
25
27
|
];
|
|
26
28
|
|
|
27
29
|
tests.forEach(({args, description, error, expected}) => {
|
|
28
|
-
return test(description, (
|
|
30
|
+
return test(description, (t, end) => {
|
|
29
31
|
if (!!error) {
|
|
30
32
|
throws(() => encodeBase32(args), new Error(error), 'Got expected error');
|
|
31
33
|
} else {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const strictSame = require('node:assert').strict.deepStrictEqual;
|
|
2
|
+
const test = require('node:test');
|
|
3
|
+
const {throws} = require('node:assert').strict;
|
|
2
4
|
|
|
3
5
|
const {encodeSocket} = require('./../../');
|
|
4
6
|
|
|
@@ -40,7 +42,7 @@ const tests = [
|
|
|
40
42
|
];
|
|
41
43
|
|
|
42
44
|
tests.forEach(({args, description, error, expected}) => {
|
|
43
|
-
return test(description, (
|
|
45
|
+
return test(description, (t, end) => {
|
|
44
46
|
if (!!error) {
|
|
45
47
|
throws(() => encodeSocket(args), new Error(error), 'Got expected error');
|
|
46
48
|
} else {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const strictSame = require('node:assert').strict.deepStrictEqual;
|
|
2
|
+
const test = require('node:test');
|
|
3
|
+
const {throws} = require('node:assert').strict;
|
|
2
4
|
|
|
3
5
|
const {chanFormat} = require('./../../');
|
|
4
6
|
|
|
@@ -36,7 +38,7 @@ const tests = [
|
|
|
36
38
|
];
|
|
37
39
|
|
|
38
40
|
tests.forEach(({args, description, error, expected}) => {
|
|
39
|
-
return test(description, (
|
|
41
|
+
return test(description, (t, end) => {
|
|
40
42
|
if (!!error) {
|
|
41
43
|
throws(() => chanFormat(args), new Error(error), 'Got expected error');
|
|
42
44
|
|
|
@@ -45,7 +47,7 @@ tests.forEach(({args, description, error, expected}) => {
|
|
|
45
47
|
|
|
46
48
|
const {channel} = chanFormat(args);
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
strictSame(channel, expected.channel, 'Channel formatted returned');
|
|
49
51
|
|
|
50
52
|
return end();
|
|
51
53
|
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const strictSame = require('node:assert').strict.deepStrictEqual;
|
|
2
|
+
const test = require('node:test');
|
|
3
|
+
const {throws} = require('node:assert').strict;
|
|
2
4
|
|
|
3
5
|
const {chanNumber} = require('./../../');
|
|
4
6
|
|
|
@@ -36,7 +38,7 @@ const tests = [
|
|
|
36
38
|
];
|
|
37
39
|
|
|
38
40
|
tests.forEach(({args, description, error, expected}) => {
|
|
39
|
-
return test(description, (
|
|
41
|
+
return test(description, (t, end) => {
|
|
40
42
|
if (!!error) {
|
|
41
43
|
throws(() => chanNumber(args), new Error(error), 'Got expected error');
|
|
42
44
|
|
|
@@ -45,7 +47,7 @@ tests.forEach(({args, description, error, expected}) => {
|
|
|
45
47
|
|
|
46
48
|
const {number} = chanNumber(args);
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
strictSame(number, expected.number, 'Channel id number returned');
|
|
49
51
|
|
|
50
52
|
return end();
|
|
51
53
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
const
|
|
1
|
+
const test = require('node:test');
|
|
2
|
+
const {throws} = require('node:assert').strict;
|
|
2
3
|
|
|
3
4
|
const componentsFromBuffer = require('./../../ids/components_from_buffer');
|
|
4
5
|
|
|
@@ -16,7 +17,7 @@ const tests = [
|
|
|
16
17
|
];
|
|
17
18
|
|
|
18
19
|
tests.forEach(({args, description, error, expected}) => {
|
|
19
|
-
return test(description, (
|
|
20
|
+
return test(description, (t, end) => {
|
|
20
21
|
if (!!error) {
|
|
21
22
|
throws(() => componentsFromBuffer(args), new Error(error), 'Got error');
|
|
22
23
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const strictSame = require('node:assert').strict.deepStrictEqual;
|
|
2
|
+
const test = require('node:test');
|
|
3
|
+
const {throws} = require('node:assert').strict;
|
|
2
4
|
|
|
3
5
|
const {decodeChanId} = require('./../../');
|
|
4
6
|
|
|
@@ -51,7 +53,7 @@ const tests = [
|
|
|
51
53
|
];
|
|
52
54
|
|
|
53
55
|
tests.forEach(({args, description, error, expected}) => {
|
|
54
|
-
return test(description, (
|
|
56
|
+
return test(description, (t, end) => {
|
|
55
57
|
if (!!error) {
|
|
56
58
|
throws(() => decodeChanId(args), new Error(error), 'Got expected err');
|
|
57
59
|
|
|
@@ -60,9 +62,9 @@ tests.forEach(({args, description, error, expected}) => {
|
|
|
60
62
|
|
|
61
63
|
const decoded = decodeChanId(args);
|
|
62
64
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
strictSame(decoded.block_height, expected.block_height, 'Block height');
|
|
66
|
+
strictSame(decoded.block_index, expected.block_index, 'Block index');
|
|
67
|
+
strictSame(decoded.output_index, expected.output_index, 'Output index');
|
|
66
68
|
|
|
67
69
|
return end();
|
|
68
70
|
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const strictSame = require('node:assert').strict.deepStrictEqual;
|
|
2
|
+
const test = require('node:test');
|
|
3
|
+
const {throws} = require('node:assert').strict;
|
|
2
4
|
|
|
3
5
|
const {encodeChanId} = require('./../../');
|
|
4
6
|
|
|
@@ -48,7 +50,7 @@ const tests = [
|
|
|
48
50
|
];
|
|
49
51
|
|
|
50
52
|
tests.forEach(({args, description, error, expected}) => {
|
|
51
|
-
return test(description, (
|
|
53
|
+
return test(description, (t, end) => {
|
|
52
54
|
if (!!error) {
|
|
53
55
|
throws(() => encodeChanId(args), new Error(error), 'Got expected err');
|
|
54
56
|
|
|
@@ -57,9 +59,9 @@ tests.forEach(({args, description, error, expected}) => {
|
|
|
57
59
|
|
|
58
60
|
const encoded = encodeChanId(args);
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
strictSame(encoded.channel, expected.channel, 'Channel components');
|
|
63
|
+
strictSame(encoded.id, expected.id, 'Channel id returned');
|
|
64
|
+
strictSame(encoded.number, expected.number, 'Channel number returned');
|
|
63
65
|
|
|
64
66
|
return end();
|
|
65
67
|
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const strictSame = require('node:assert').strict.deepStrictEqual;
|
|
2
|
+
const test = require('node:test');
|
|
3
|
+
const {throws} = require('node:assert').strict;
|
|
2
4
|
|
|
3
5
|
const {rawChanId} = require('./../../');
|
|
4
6
|
|
|
@@ -36,7 +38,7 @@ const tests = [
|
|
|
36
38
|
];
|
|
37
39
|
|
|
38
40
|
tests.forEach(({args, description, error, expected}) => {
|
|
39
|
-
return test(description, (
|
|
41
|
+
return test(description, (t, end) => {
|
|
40
42
|
if (!!error) {
|
|
41
43
|
throws(() => rawChanId(args), new Error(error), 'Got expected error');
|
|
42
44
|
|
|
@@ -45,7 +47,7 @@ tests.forEach(({args, description, error, expected}) => {
|
|
|
45
47
|
|
|
46
48
|
const {id} = rawChanId(args);
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
strictSame(id, expected.id, 'Raw channel id returned');
|
|
49
51
|
|
|
50
52
|
return end();
|
|
51
53
|
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const strictSame = require('node:assert').strict.deepStrictEqual;
|
|
2
|
+
const test = require('node:test');
|
|
3
|
+
const {throws} = require('node:assert').strict;
|
|
2
4
|
|
|
3
5
|
const betaChannels = require('./../fixtures/graph_beta').channels;
|
|
4
6
|
const charlieChannels = require('./../fixtures/graph_charlie').channels;
|
|
@@ -108,6 +110,8 @@ const tests = [
|
|
|
108
110
|
channel_capacity: 16777215,
|
|
109
111
|
cltv_delta: 40,
|
|
110
112
|
fee_rate: 2500,
|
|
113
|
+
inbound_base_discount_mtokens: undefined,
|
|
114
|
+
inbound_rate_discount: undefined,
|
|
111
115
|
public_key: 'b',
|
|
112
116
|
},
|
|
113
117
|
{
|
|
@@ -116,6 +120,8 @@ const tests = [
|
|
|
116
120
|
channel_capacity: 16777215,
|
|
117
121
|
cltv_delta: 30,
|
|
118
122
|
fee_rate: 2500,
|
|
123
|
+
inbound_base_discount_mtokens: undefined,
|
|
124
|
+
inbound_rate_discount: undefined,
|
|
119
125
|
public_key: 'c',
|
|
120
126
|
},
|
|
121
127
|
{
|
|
@@ -124,6 +130,8 @@ const tests = [
|
|
|
124
130
|
channel_capacity: 16777215,
|
|
125
131
|
cltv_delta: 144,
|
|
126
132
|
fee_rate: 1,
|
|
133
|
+
inbound_base_discount_mtokens: undefined,
|
|
134
|
+
inbound_rate_discount: undefined,
|
|
127
135
|
public_key: 'd',
|
|
128
136
|
},
|
|
129
137
|
{
|
|
@@ -132,6 +140,8 @@ const tests = [
|
|
|
132
140
|
channel_capacity: 16777215,
|
|
133
141
|
cltv_delta: 144,
|
|
134
142
|
fee_rate: 1,
|
|
143
|
+
inbound_base_discount_mtokens: undefined,
|
|
144
|
+
inbound_rate_discount: undefined,
|
|
135
145
|
public_key: 'e',
|
|
136
146
|
},
|
|
137
147
|
],
|
|
@@ -149,6 +159,8 @@ const tests = [
|
|
|
149
159
|
channel_capacity: 8429350,
|
|
150
160
|
cltv_delta: 40,
|
|
151
161
|
fee_rate: 2500,
|
|
162
|
+
inbound_base_discount_mtokens: undefined,
|
|
163
|
+
inbound_rate_discount: undefined,
|
|
152
164
|
public_key: '03e50492eab4107a773141bb419e107bda3de3d55652e6e1a41225f06a0bbf2d56',
|
|
153
165
|
},
|
|
154
166
|
{
|
|
@@ -157,6 +169,8 @@ const tests = [
|
|
|
157
169
|
channel_capacity: 2000000,
|
|
158
170
|
cltv_delta: 40,
|
|
159
171
|
fee_rate: 2500,
|
|
172
|
+
inbound_base_discount_mtokens: undefined,
|
|
173
|
+
inbound_rate_discount: undefined,
|
|
160
174
|
public_key: '03bb88ccc444534da7b5b64b4f7b15e1eccb18e102db0e400d4b9cfe93763aa26d',
|
|
161
175
|
},
|
|
162
176
|
{
|
|
@@ -165,6 +179,8 @@ const tests = [
|
|
|
165
179
|
channel_capacity: 400000,
|
|
166
180
|
cltv_delta: 40,
|
|
167
181
|
fee_rate: 100,
|
|
182
|
+
inbound_base_discount_mtokens: undefined,
|
|
183
|
+
inbound_rate_discount: undefined,
|
|
168
184
|
public_key: '028dcc199be86786818c8c32bffe9db8855c5fca98951eec99d1fa335d841605c2',
|
|
169
185
|
},
|
|
170
186
|
{
|
|
@@ -173,6 +189,8 @@ const tests = [
|
|
|
173
189
|
channel_capacity: 364355,
|
|
174
190
|
cltv_delta: 40,
|
|
175
191
|
fee_rate: 1,
|
|
192
|
+
inbound_base_discount_mtokens: undefined,
|
|
193
|
+
inbound_rate_discount: undefined,
|
|
176
194
|
public_key: '03277a99c297a53859b42a9bb8cb2c5c17b9eaa44509bae150e2ea35ca5aa29bd9',
|
|
177
195
|
},
|
|
178
196
|
],
|
|
@@ -187,6 +205,8 @@ const tests = [
|
|
|
187
205
|
channel_capacity: 1000,
|
|
188
206
|
cltv_delta: 40,
|
|
189
207
|
fee_rate: 7,
|
|
208
|
+
inbound_base_discount_mtokens: undefined,
|
|
209
|
+
inbound_rate_discount: undefined,
|
|
190
210
|
public_key: 'alice',
|
|
191
211
|
},
|
|
192
212
|
{
|
|
@@ -195,6 +215,8 @@ const tests = [
|
|
|
195
215
|
channel_capacity: 2000,
|
|
196
216
|
cltv_delta: 40,
|
|
197
217
|
fee_rate: 7,
|
|
218
|
+
inbound_base_discount_mtokens: undefined,
|
|
219
|
+
inbound_rate_discount: undefined,
|
|
198
220
|
public_key: 'bob',
|
|
199
221
|
},
|
|
200
222
|
{
|
|
@@ -203,6 +225,8 @@ const tests = [
|
|
|
203
225
|
channel_capacity: 3000,
|
|
204
226
|
cltv_delta: 40,
|
|
205
227
|
fee_rate: 9,
|
|
228
|
+
inbound_base_discount_mtokens: undefined,
|
|
229
|
+
inbound_rate_discount: undefined,
|
|
206
230
|
public_key: 'charlie',
|
|
207
231
|
},
|
|
208
232
|
],
|
|
@@ -238,6 +262,8 @@ const tests = [
|
|
|
238
262
|
channel_capacity: 100,
|
|
239
263
|
cltv_delta: 40,
|
|
240
264
|
fee_rate: 1,
|
|
265
|
+
inbound_base_discount_mtokens: undefined,
|
|
266
|
+
inbound_rate_discount: undefined,
|
|
241
267
|
public_key: Buffer.alloc(33).toString('hex'),
|
|
242
268
|
}],
|
|
243
269
|
},
|
|
@@ -271,10 +297,121 @@ const tests = [
|
|
|
271
297
|
description: 'Mapping hops from channels requires hop channel ids',
|
|
272
298
|
expected: [],
|
|
273
299
|
},
|
|
300
|
+
{
|
|
301
|
+
args: {
|
|
302
|
+
channels: [
|
|
303
|
+
{
|
|
304
|
+
capacity: 16777215,
|
|
305
|
+
destination: 'b',
|
|
306
|
+
id: '1x1x1',
|
|
307
|
+
policies: [
|
|
308
|
+
{
|
|
309
|
+
_policy_a_has_to_b: true,
|
|
310
|
+
base_fee_mtokens: '0',
|
|
311
|
+
fee_rate: 5000,
|
|
312
|
+
is_disabled: false,
|
|
313
|
+
min_htlc_mtokens: '2000',
|
|
314
|
+
public_key: 'a',
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
_policy_b_has_to_a: true,
|
|
318
|
+
base_fee_mtokens: '0',
|
|
319
|
+
fee_rate: 0,
|
|
320
|
+
inbound_base_discount_mtokens: '-5000',
|
|
321
|
+
inbound_rate_discount: 0,
|
|
322
|
+
is_disabled: false,
|
|
323
|
+
public_key: 'b',
|
|
324
|
+
},
|
|
325
|
+
],
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
capacity: 16777215,
|
|
329
|
+
destination: 'c',
|
|
330
|
+
id: '2x2x2',
|
|
331
|
+
policies: [
|
|
332
|
+
{
|
|
333
|
+
_policy_b_has_to_c: true,
|
|
334
|
+
base_fee_mtokens: '0',
|
|
335
|
+
fee_rate: 50000,
|
|
336
|
+
is_disabled: false,
|
|
337
|
+
min_htlc_mtokens: '2000',
|
|
338
|
+
public_key: 'b',
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
_policy_c_has_to_b: true,
|
|
342
|
+
base_fee_mtokens: '0',
|
|
343
|
+
fee_rate: 0,
|
|
344
|
+
inbound_base_discount_mtokens: '8000',
|
|
345
|
+
inbound_rate_discount: 200000,
|
|
346
|
+
is_disabled: false,
|
|
347
|
+
public_key: 'c',
|
|
348
|
+
},
|
|
349
|
+
],
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
capacity: 16777215,
|
|
353
|
+
destination: 'd',
|
|
354
|
+
id: '3x3x3',
|
|
355
|
+
policies: [
|
|
356
|
+
{
|
|
357
|
+
_policy_c_has_to_d: true,
|
|
358
|
+
base_fee_mtokens: '9000',
|
|
359
|
+
fee_rate: 100000,
|
|
360
|
+
is_disabled: false,
|
|
361
|
+
min_htlc_mtokens: '2000',
|
|
362
|
+
public_key: 'c',
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
_policy_d_has_to_c: true,
|
|
366
|
+
base_fee_mtokens: '0',
|
|
367
|
+
fee_rate: 0,
|
|
368
|
+
inbound_base_discount_mtokens: '-2000',
|
|
369
|
+
inbound_rate_discount: -80000,
|
|
370
|
+
is_disabled: false,
|
|
371
|
+
public_key: 'd',
|
|
372
|
+
},
|
|
373
|
+
],
|
|
374
|
+
},
|
|
375
|
+
],
|
|
376
|
+
},
|
|
377
|
+
description: 'Map channels with inbound fee rates',
|
|
378
|
+
expected: [
|
|
379
|
+
{
|
|
380
|
+
base_fee_mtokens: '0',
|
|
381
|
+
channel: '1x1x1',
|
|
382
|
+
channel_capacity: 16777215,
|
|
383
|
+
cltv_delta: 40,
|
|
384
|
+
fee_rate: 50000,
|
|
385
|
+
inbound_base_discount_mtokens: '-5000',
|
|
386
|
+
inbound_rate_discount: 0,
|
|
387
|
+
public_key: 'b',
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
base_fee_mtokens: '0',
|
|
391
|
+
channel: '2x2x2',
|
|
392
|
+
channel_capacity: 16777215,
|
|
393
|
+
cltv_delta: 40,
|
|
394
|
+
fee_rate: 50000,
|
|
395
|
+
inbound_base_discount_mtokens: '8000',
|
|
396
|
+
inbound_rate_discount: 200000,
|
|
397
|
+
public_key: 'c',
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
base_fee_mtokens: '9000',
|
|
401
|
+
channel: '3x3x3',
|
|
402
|
+
channel_capacity: 16777215,
|
|
403
|
+
cltv_delta: 40,
|
|
404
|
+
fee_rate: 100000,
|
|
405
|
+
inbound_base_discount_mtokens: '-2000',
|
|
406
|
+
inbound_rate_discount: -80000,
|
|
407
|
+
public_key: 'd',
|
|
408
|
+
},
|
|
409
|
+
],
|
|
410
|
+
},
|
|
274
411
|
];
|
|
275
412
|
|
|
276
413
|
tests.forEach(({args, description, error, expected}) => {
|
|
277
|
-
return test(description, (
|
|
414
|
+
return test(description, (t, end) => {
|
|
278
415
|
if (!!error) {
|
|
279
416
|
throws(() => hopsFromChannels(args), new Error(error), 'Got error');
|
|
280
417
|
} else {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const strictSame = require('node:assert').strict.deepStrictEqual;
|
|
2
|
+
const test = require('node:test');
|
|
3
|
+
const {throws} = require('node:assert').strict;
|
|
2
4
|
|
|
3
5
|
const policyFee = require('./../../routing/policy_fee');
|
|
4
6
|
|
|
@@ -25,17 +27,43 @@ const tests = [
|
|
|
25
27
|
},
|
|
26
28
|
{
|
|
27
29
|
args: {mtokens: '1000000', policy: {base_fee_mtokens: '1', fee_rate: 1}},
|
|
28
|
-
description: 'Fee
|
|
30
|
+
description: 'Fee is calculated',
|
|
29
31
|
expected: {fee_mtokens: '2'},
|
|
30
32
|
},
|
|
33
|
+
{
|
|
34
|
+
args: {
|
|
35
|
+
mtokens: '1000000',
|
|
36
|
+
policy: {
|
|
37
|
+
base_fee_mtokens: '1',
|
|
38
|
+
fee_rate: 1,
|
|
39
|
+
inbound_base_discount_mtokens: '-1',
|
|
40
|
+
inbound_rate_discount: -1,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
description: 'Fee rate with discount is calculated',
|
|
44
|
+
expected: {fee_mtokens: '0'},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
args: {
|
|
48
|
+
mtokens: '1000000',
|
|
49
|
+
policy: {
|
|
50
|
+
base_fee_mtokens: '1',
|
|
51
|
+
fee_rate: 1,
|
|
52
|
+
inbound_base_discount_mtokens: '-10',
|
|
53
|
+
inbound_rate_discount: -1,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
description: 'Fee rate with big discount is calculated',
|
|
57
|
+
expected: {fee_mtokens: '0'},
|
|
58
|
+
},
|
|
31
59
|
];
|
|
32
60
|
|
|
33
61
|
tests.forEach(({args, description, error, expected}) => {
|
|
34
|
-
return test(description, (
|
|
62
|
+
return test(description, (t, end) => {
|
|
35
63
|
if (!!error) {
|
|
36
64
|
throws(() => policyFee(args), new Error(error), 'Got expected error');
|
|
37
65
|
} else {
|
|
38
|
-
|
|
66
|
+
strictSame(policyFee(args).fee_mtokens, expected.fee_mtokens, 'Fee');
|
|
39
67
|
}
|
|
40
68
|
|
|
41
69
|
return end();
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const strictSame = require('node:assert').strict.deepStrictEqual;
|
|
2
|
+
const test = require('node:test');
|
|
3
|
+
const {throws} = require('node:assert').strict;
|
|
2
4
|
|
|
3
5
|
const {routeFromChannels} = require('./../../');
|
|
4
6
|
|
|
@@ -938,7 +940,7 @@ const tests = [
|
|
|
938
940
|
];
|
|
939
941
|
|
|
940
942
|
tests.forEach(({args, description, error, expected}) => {
|
|
941
|
-
return test(description, (
|
|
943
|
+
return test(description, (t, end) => {
|
|
942
944
|
if (!!error) {
|
|
943
945
|
throws(() => routeFromChannels(args), new Error(error), 'Got error');
|
|
944
946
|
} else {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const strictSame = require('node:assert').strict.deepStrictEqual;
|
|
2
|
+
const test = require('node:test');
|
|
3
|
+
const {throws} = require('node:assert').strict;
|
|
2
4
|
|
|
3
5
|
const {routeFromHops} = require('./../../');
|
|
4
6
|
|
|
@@ -340,7 +342,7 @@ const tests = [
|
|
|
340
342
|
];
|
|
341
343
|
|
|
342
344
|
tests.forEach(({args, description, error, expected}) => {
|
|
343
|
-
return test(description, (
|
|
345
|
+
return test(description, (t, end) => {
|
|
344
346
|
if (!!error) {
|
|
345
347
|
throws(() => routeFromHops(args), new Error(error), 'Got expected err');
|
|
346
348
|
} else {
|