Skip to content

Commit 6b8cd61

Browse files
author
Alan Cohen
committed
Filter insufficient source funds paths from pathfind results
When pathfinding with source amount, we need to filter out paths where source amount is not equal to the specified source amount. This is due to the behavior of rippled when specifying a source amount during pathfinding. Example: { "command": "ripple_path_find", "source_account": "rhFQQ4ATC6MDF9ghTq3qAoCsGbGtjnhcXF", "destination_account": "rp91GUd5R3Rk3ipqW7XBdtrUJcX8epzGyb", "destination_amount": { "currency": "EUR", "issuer": "rp91GUd5R3Rk3ipqW7XBdtrUJcX8epzGyb", "value": -1 }, "send_max": { "currency": "USD", "issuer": "rhFQQ4ATC6MDF9ghTq3qAoCsGbGtjnhcXF", "value": "1234567891" }, "id": 2 } { "id": 2, "result": { "alternatives": [ { "destination_amount": { "currency": "EUR", "issuer": "rp91GUd5R3Rk3ipqW7XBdtrUJcX8epzGyb", "value": "3999889.62127857" }, "paths_canonical": [], "paths_computed": [ [ { "account": "rcsxQxEqU2qquAKp3tBUJy8Z2t19ioQPJ", "type": 1, "type_hex": "0000000000000001" }, { "currency": "EUR", "issuer": "rp91GUd5R3Rk3ipqW7XBdtrUJcX8epzGyb", "type": 48, "type_hex": "0000000000000030" } ] ], "source_amount": { "currency": "USD", "issuer": "rhFQQ4ATC6MDF9ghTq3qAoCsGbGtjnhcXF", "value": "4170759.906037564" } } ], "destination_account": "rp91GUd5R3Rk3ipqW7XBdtrUJcX8epzGyb", "destination_amount": { "currency": "EUR", "issuer": "rp91GUd5R3Rk3ipqW7XBdtrUJcX8epzGyb", "value": "-1" }, "destination_currencies": [ "EUR", "XRP" ], "full_reply": true, "id": 2, "source_account": "rhFQQ4ATC6MDF9ghTq3qAoCsGbGtjnhcXF", "status": "success" }, "status": "success", "type": "response" }
1 parent 0d6aaee commit 6b8cd61

File tree

8 files changed

+143
-3
lines changed

8 files changed

+143
-3
lines changed

src/ledger/pathfind.js

+17-1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,20 @@ function conditionallyAddDirectXRPPath(connection: Connection, address: string,
8585
xrpBalance => addDirectXrpPath(paths, xrpBalance));
8686
}
8787

88+
function filterSourceFundsLowPaths(pathfind: PathFind,
89+
paths: RippledPathsResponse
90+
): RippledPathsResponse {
91+
if (pathfind.source.amount &&
92+
pathfind.destination.amount.value === undefined && paths.alternatives) {
93+
paths.alternatives = _.filter(paths.alternatives, alt => {
94+
return alt.source_amount &&
95+
pathfind.source.amount &&
96+
alt.source_amount.value === pathfind.source.amount.value;
97+
});
98+
}
99+
return paths;
100+
}
101+
88102
function formatResponse(pathfind: PathFind, paths: RippledPathsResponse) {
89103
if (paths.alternatives && paths.alternatives.length > 0) {
90104
return parsePathfind(paths);
@@ -116,7 +130,9 @@ function getPaths(pathfind: PathFind): Promise<GetPaths> {
116130
const address = pathfind.source.address;
117131
return requestPathFind(this.connection, pathfind).then(paths =>
118132
conditionallyAddDirectXRPPath(this.connection, address, paths)
119-
).then(paths => formatResponse(pathfind, paths));
133+
)
134+
.then(paths => filterSourceFundsLowPaths(pathfind, paths))
135+
.then(paths => formatResponse(pathfind, paths));
120136
}
121137

122138
module.exports = getPaths;

test/api-test.js

+9
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,15 @@ describe('RippleAPI', function() {
10491049
});
10501050
});
10511051

1052+
it('getPaths - no paths source amount', function() {
1053+
return this.api.getPaths(requests.getPaths.NoPathsSource).then(() => {
1054+
assert(false, 'Should throw NotFoundError');
1055+
}).catch(error => {
1056+
assert(error instanceof this.api.errors.NotFoundError);
1057+
});
1058+
});
1059+
1060+
10521061
it('getPaths - no paths with source currencies', function() {
10531062
const pathfind = requests.getPaths.NoPathsWithCurrencies;
10541063
return this.api.getPaths(pathfind).then(() => {

test/fixtures/addresses.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ module.exports = {
66
FOURTH_ACCOUNT: 'rJnZ4YHCUsHvQu7R6mZohevKJDHFzVD6Zr',
77
ISSUER: 'rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM',
88
NOTFOUND: 'rajTAg3hon5Lcu1RxQQPxTgHvqfhc1EaUS',
9-
SECRET: 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
9+
SECRET: 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV',
10+
SOURCE_LOW_FUNDS: 'rhVgDEfS1r1fLyRUZCpab4TdowZcAJwHy2'
1011
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"source": {
3+
"address": "rhVgDEfS1r1fLyRUZCpab4TdowZcAJwHy2",
4+
"amount": {
5+
"value": "1000002",
6+
"currency": "USD"
7+
}
8+
},
9+
"destination": {
10+
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
11+
"amount": {"currency": "USD"}
12+
}
13+
}

test/fixtures/requests/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ module.exports = {
5353
XrpToXrpNotEnough: require('./getpaths/xrp2xrp-not-enough'),
5454
NotAcceptCurrency: require('./getpaths/not-accept-currency'),
5555
NoPaths: require('./getpaths/no-paths'),
56+
NoPathsSource: require('./getpaths/no-paths-source-amount'),
5657
NoPathsWithCurrencies: require('./getpaths/no-paths-with-currencies'),
5758
sendAll: require('./getpaths/send-all'),
5859
invalid: require('./getpaths/invalid'),

test/fixtures/rippled/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ module.exports = {
3838
sendUSD: require('./path-find-send-usd'),
3939
sendAll: require('./path-find-send-all'),
4040
XrpToXrp: require('./path-find-xrp-to-xrp'),
41-
srcActNotFound: require('./path-find-srcActNotFound')
41+
srcActNotFound: require('./path-find-srcActNotFound'),
42+
sourceAmountLow: require('./path-find-srcAmtLow')
4243
},
4344
tx: {
4445
Payment: require('./tx/payment.json'),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
{
2+
"id": 0,
3+
"result": {
4+
"full_reply": true,
5+
"alternatives": [
6+
{
7+
"paths_canonical": [],
8+
"paths_computed": [
9+
[
10+
{
11+
"account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
12+
"type": 1,
13+
"type_hex": "0000000000000001"
14+
}
15+
],
16+
[
17+
{
18+
"account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
19+
"type": 1,
20+
"type_hex": "0000000000000001"
21+
},
22+
{
23+
"account": "rLMJ4db4uwHcd6NHg6jvTaYb8sH5Gy4tg5",
24+
"type": 1,
25+
"type_hex": "0000000000000001"
26+
},
27+
{
28+
"account": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
29+
"type": 1,
30+
"type_hex": "0000000000000001"
31+
}
32+
],
33+
[
34+
{
35+
"account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
36+
"type": 1,
37+
"type_hex": "0000000000000001"
38+
},
39+
{
40+
"currency": "USD",
41+
"issuer": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
42+
"type": 48,
43+
"type_hex": "0000000000000030"
44+
},
45+
{
46+
"account": "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun",
47+
"type": 1,
48+
"type_hex": "0000000000000001"
49+
}
50+
],
51+
[
52+
{
53+
"account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
54+
"type": 1,
55+
"type_hex": "0000000000000001"
56+
},
57+
{
58+
"account": "rLMJ4db4uwHcd6NHg6jvTaYb8sH5Gy4tg5",
59+
"type": 1,
60+
"type_hex": "0000000000000001"
61+
},
62+
{
63+
"account": "r9vbV3EHvXWjSkeQ6CAcYVPGeq7TuiXY2X",
64+
"type": 1,
65+
"type_hex": "0000000000000001"
66+
}
67+
]
68+
],
69+
"source_amount": {
70+
"currency": "USD",
71+
"issuer": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
72+
"value": "0.000001002"
73+
}
74+
}
75+
],
76+
"source_account": "rhVgDEfS1r1fLyRUZCpab4TdowZcAJwHy2",
77+
"destination_amount": {
78+
"currency": "USD",
79+
"value": "-1",
80+
"issuer": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59"
81+
},
82+
"destination_account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
83+
"destination_currencies": [
84+
"JOE",
85+
"BTC",
86+
"DYM",
87+
"CNY",
88+
"EUR",
89+
"015841551A748AD2C1F76FF6ECB0CCCD00000000",
90+
"MXN",
91+
"USD",
92+
"XRP"
93+
]
94+
},
95+
"status": "success",
96+
"type": "response"
97+
}

test/mock-rippled.js

+2
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ module.exports = function(port) {
323323
}
324324
if (request.source_account === addresses.NOTFOUND) {
325325
response = createResponse(request, fixtures.path_find.srcActNotFound);
326+
} else if (request.source_account === addresses.SOURCE_LOW_FUNDS) {
327+
response = createResponse(request, fixtures.path_find.sourceAmountLow);
326328
} else if (request.source_account === addresses.OTHER_ACCOUNT) {
327329
response = createResponse(request, fixtures.path_find.sendUSD);
328330
} else if (request.source_account === addresses.THIRD_ACCOUNT) {

0 commit comments

Comments
 (0)