Fix getPaths (#930)

* getPaths:
  * Filter paths correctly
  * Use correct value when XRP is the destination currency
This commit is contained in:
Elliot Lee
2018-08-23 17:37:02 -07:00
committed by GitHub
parent 181cfd69de
commit b9c953fce6
3 changed files with 120 additions and 12 deletions

View File

@@ -1,7 +1,13 @@
import * as _ from 'lodash'
import BigNumber from 'bignumber.js'
import {getXRPBalance, renameCounterpartyToIssuer} from './utils'
import {validate, toRippledAmount, errors} from '../common'
import {
validate,
toRippledAmount,
errors,
xrpToDrops,
dropsToXrp
} from '../common'
import {Connection} from '../common'
import parsePathfind from './parse/pathfind'
import {RippledAmount, Amount} from '../common/types/objects'
@@ -23,7 +29,11 @@ function addParams(request: PathFindRequest, result: RippledPathsResponse
function requestPathFind(connection: Connection, pathfind: PathFind
): Promise<RippledPathsResponse> {
const destinationAmount: Amount = _.assign(
{value: '-1'},
{
// This is converted back to drops by toRippledAmount()
value: pathfind.destination.amount.currency === 'XRP' ?
dropsToXrp('-1') : '-1'
},
pathfind.destination.amount
)
const request: PathFindRequest = {
@@ -95,13 +105,21 @@ function filterSourceFundsLowPaths(pathfind: PathFind,
): RippledPathsResponse {
if (pathfind.source.amount &&
pathfind.destination.amount.value === undefined && paths.alternatives) {
paths.alternatives = _.filter(paths.alternatives, alt =>
!!alt.source_amount &&
!!pathfind.source.amount &&
// TODO: Returns false when alt.source_amount is a string. Fix?
typeof alt.source_amount !== 'string' &&
new BigNumber(alt.source_amount.value).eq(pathfind.source.amount.value)
paths.alternatives = _.filter(paths.alternatives, alt => {
if (!alt.source_amount) {
return false
}
const pathfindSourceAmountValue = new BigNumber(
pathfind.source.amount.currency === 'XRP' ?
xrpToDrops(pathfind.source.amount.value) :
pathfind.source.amount.value)
const altSourceAmountValue = new BigNumber(
typeof alt.source_amount === 'string' ?
alt.source_amount :
alt.source_amount.value
)
return altSourceAmountValue.eq(pathfindSourceAmountValue)
})
}
return paths
}

View File

@@ -2328,6 +2328,45 @@ describe('RippleAPI', function () {
_.partial(checkResult, responses.getPaths.XrpToUsd, 'getPaths'));
});
it('getPaths - result path has source_amount in drops', function () {
return this.api.getPaths({
source: {
address: 'rB2NTuTTS3eNCsWxZYzJ4wqRqxNLZqA9Vx',
amount: {
value: this.api.dropsToXrp(1000000),
currency: 'XRP'
}
},
destination: {
address: 'rhpJkBfZGQyT1xeDbwtKEuSrSXw3QZSAy5',
amount: {
counterparty: 'rGpGaj4sxEZGenW1prqER25EUi7x4fqK9u',
currency: 'EUR'
}
}
}).then(
_.partial(checkResult, [
{
"source": {
"address": "rB2NTuTTS3eNCsWxZYzJ4wqRqxNLZqA9Vx",
"amount": {
"currency": "XRP",
"value": "1"
}
},
"destination": {
"address": "rhpJkBfZGQyT1xeDbwtKEuSrSXw3QZSAy5",
"minAmount": {
"currency": "EUR",
"value": "1",
"counterparty": "rGpGaj4sxEZGenW1prqER25EUi7x4fqK9u"
}
},
"paths": "[[{\"currency\":\"USD\",\"issuer\":\"rGpGaj4sxEZGenW1prqER25EUi7x4fqK9u\"},{\"currency\":\"EUR\",\"issuer\":\"rGpGaj4sxEZGenW1prqER25EUi7x4fqK9u\"}]]"
}
], 'getPaths'));
});
it('getPaths - queuing', function () {
return Promise.all([
this.api.getPaths(requests.getPaths.normal),

View File

@@ -485,7 +485,57 @@ module.exports = function createMockRippled(port) {
if (request.subcommand === 'close') { // for path_find command
return;
}
if (request.source_account === addresses.NOTFOUND) {
if (request.source_account === 'rB2NTuTTS3eNCsWxZYzJ4wqRqxNLZqA9Vx') {
// getPaths - result path has source_amount in drops
response = createResponse(request, {
"id": 0,
"type": "response",
"status": "success",
"result": {
"alternatives": [
{
"destination_amount": {
"currency": "EUR",
"issuer": "rGpGaj4sxEZGenW1prqER25EUi7x4fqK9u",
"value": "1"
},
"paths_canonical": [],
"paths_computed": [
[
{
"currency": "USD",
"issuer": "rGpGaj4sxEZGenW1prqER25EUi7x4fqK9u",
"type": 48,
"type_hex": "0000000000000030"
},
{
"currency": "EUR",
"issuer": "rGpGaj4sxEZGenW1prqER25EUi7x4fqK9u",
"type": 48,
"type_hex": "0000000000000030"
}
]
],
"source_amount": "1000000"
}
],
"destination_account": "rhpJkBfZGQyT1xeDbwtKEuSrSXw3QZSAy5",
"destination_amount": {
"currency": "EUR",
"issuer": "rGpGaj4sxEZGenW1prqER25EUi7x4fqK9u",
"value": "-1"
},
"destination_currencies": [
"EUR",
"XRP"
],
"full_reply": true,
"id": 2,
"source_account": "rB2NTuTTS3eNCsWxZYzJ4wqRqxNLZqA9Vx",
"status": "success"
}
})
} else if (request.source_account === addresses.NOTFOUND) {
response = createResponse(request, fixtures.path_find.srcActNotFound);
} else if (request.source_account === addresses.SOURCE_LOW_FUNDS) {
response = createResponse(request, fixtures.path_find.sourceAmountLow);
@@ -497,8 +547,9 @@ module.exports = function createMockRippled(port) {
destination_address: request.destination_address
});
} else if (request.source_account === addresses.ACCOUNT) {
if (request.destination_account ===
'ra5nK24KXen9AHvsdFTKHSANinZseWnPcX') {
if (request.destination_account === 'ra5nK24KXen9AHvsdFTKHSANinZseWnPcX' &&
// Important: Ensure that destination_amount.value is correct
request.destination_amount.value === "-1") {
response = createResponse(request, fixtures.path_find.sendAll);
} else {
response = fixtures.path_find.generate.generateIOUPaymentPaths(