mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-17 19:05:47 +00:00
Fix parsing of settings transactions
This commit is contained in:
@@ -1,6 +1,18 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const Transaction = require('./utils').core.Transaction;
|
const core = require('./utils').core;
|
||||||
const flagIndices = Transaction.set_clear_flags.AccountSet;
|
const flagIndices = core.Transaction.set_clear_flags.AccountSet;
|
||||||
|
const flags = core.Remote.flags.account_root;
|
||||||
|
|
||||||
|
const AccountFlags = {
|
||||||
|
passwordSpent: flags.PasswordSpent,
|
||||||
|
requireDestinationTag: flags.RequireDestTag,
|
||||||
|
requireAuthorization: flags.RequireAuth,
|
||||||
|
disallowIncomingXRP: flags.DisallowXRP,
|
||||||
|
disableMasterKey: flags.DisableMaster,
|
||||||
|
noFreeze: flags.NoFreeze,
|
||||||
|
globalFreeze: flags.GlobalFreeze,
|
||||||
|
defaultRipple: flags.DefaultRipple
|
||||||
|
};
|
||||||
|
|
||||||
const AccountFlagIndices = {
|
const AccountFlagIndices = {
|
||||||
requireDestinationTag: flagIndices.asfRequireDest,
|
requireDestinationTag: flagIndices.asfRequireDest,
|
||||||
@@ -28,5 +40,6 @@ const AccountFields = {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
AccountFields,
|
AccountFields,
|
||||||
AccountFlagIndices
|
AccountFlagIndices,
|
||||||
|
AccountFlags
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
"requireAuthorization": {"type": "boolean"},
|
"requireAuthorization": {"type": "boolean"},
|
||||||
"disallowIncomingXRP": {"type": "boolean"},
|
"disallowIncomingXRP": {"type": "boolean"},
|
||||||
"disableMasterKey": {"type": "boolean"},
|
"disableMasterKey": {"type": "boolean"},
|
||||||
|
"enableTransactionIDTracking": {"type": "boolean"},
|
||||||
"noFreeze": {"type": "boolean"},
|
"noFreeze": {"type": "boolean"},
|
||||||
"globalFreeze": {"type": "boolean"},
|
"globalFreeze": {"type": "boolean"},
|
||||||
"defaultRipple": {"type": "boolean"},
|
"defaultRipple": {"type": "boolean"},
|
||||||
|
|||||||
@@ -2,27 +2,60 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const AccountSetFlags = require('./utils').constants.AccountSetFlags;
|
const AccountFlags = require('./utils').constants.AccountFlags;
|
||||||
const parseFields = require('./fields');
|
const parseFields = require('./fields');
|
||||||
|
|
||||||
function getName(flagNumber) {
|
function getAccountRootModifiedNode(tx: Object) {
|
||||||
return _.findKey(AccountSetFlags, (v) => v === flagNumber);
|
const modifiedNodes = tx.meta.AffectedNodes.filter(node =>
|
||||||
|
node.ModifiedNode.LedgerEntryType === 'AccountRoot');
|
||||||
|
assert(modifiedNodes.length === 1);
|
||||||
|
return modifiedNodes[0].ModifiedNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseFlags(tx: Object) {
|
||||||
|
const settings = {};
|
||||||
|
if (tx.TransactionType !== 'AccountSet') {
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
const node = getAccountRootModifiedNode(tx);
|
||||||
|
const oldFlags = _.get(node.PreviousFields, 'Flags');
|
||||||
|
const newFlags = _.get(node.FinalFields, 'Flags');
|
||||||
|
|
||||||
|
if (oldFlags !== undefined && newFlags !== undefined) {
|
||||||
|
const changedFlags = oldFlags ^ newFlags;
|
||||||
|
const setFlags = newFlags & changedFlags;
|
||||||
|
const clearedFlags = oldFlags & changedFlags;
|
||||||
|
_.forEach(AccountFlags, (flagValue, flagName) => {
|
||||||
|
if (setFlags & flagValue) {
|
||||||
|
settings[flagName] = true;
|
||||||
|
} else if (clearedFlags & flagValue) {
|
||||||
|
settings[flagName] = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// enableTransactionIDTracking requires a special case because it
|
||||||
|
// does not affect the Flags field; instead it adds/removes a field called
|
||||||
|
// "AccountTxnID" to/from the account root.
|
||||||
|
|
||||||
|
const oldField = _.get(node.PreviousFields, 'AccountTxnID');
|
||||||
|
const newField = _.get(node.FinalFields, 'AccountTxnID');
|
||||||
|
if (newField && !oldField) {
|
||||||
|
settings.enableTransactionIDTracking = true;
|
||||||
|
} else if (oldField && !newField) {
|
||||||
|
settings.enableTransactionIDTracking = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseSettings(tx: Object) {
|
function parseSettings(tx: Object) {
|
||||||
const txType = tx.TransactionType;
|
const txType = tx.TransactionType;
|
||||||
assert(txType === 'AccountSet' || txType === 'SetRegularKey');
|
assert(txType === 'AccountSet' || txType === 'SetRegularKey');
|
||||||
const settings = {};
|
|
||||||
if (tx.SetFlag) {
|
const regularKey = tx.RegularKey ? {regularKey: tx.RegularKey} : {};
|
||||||
settings[getName(tx.SetFlag)] = true;
|
return _.assign(regularKey, parseFlags(tx), parseFields(tx));
|
||||||
}
|
|
||||||
if (tx.ClearFlag) {
|
|
||||||
settings[getName(tx.ClearFlag)] = false;
|
|
||||||
}
|
|
||||||
if (tx.RegularKey) {
|
|
||||||
settings.regularKey = tx.RegularKey;
|
|
||||||
}
|
|
||||||
return _.assign(settings, parseFields(tx));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = parseSettings;
|
module.exports = parseSettings;
|
||||||
|
|||||||
@@ -1,21 +1,10 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const utils = require('./utils');
|
const utils = require('./utils');
|
||||||
const flags = utils.common.core.Remote.flags.account_root;
|
|
||||||
const validate = utils.common.validate;
|
const validate = utils.common.validate;
|
||||||
const parseFields = require('./parse/fields');
|
const parseFields = require('./parse/fields');
|
||||||
const composeAsync = utils.common.composeAsync;
|
const composeAsync = utils.common.composeAsync;
|
||||||
|
const AccountFlags = utils.common.constants.AccountFlags;
|
||||||
const AccountFlags = {
|
|
||||||
passwordSpent: flags.PasswordSpent,
|
|
||||||
requireDestinationTag: flags.RequireDestTag,
|
|
||||||
requireAuthorization: flags.RequireAuth,
|
|
||||||
disallowIncomingXRP: flags.DisallowXRP,
|
|
||||||
disableMasterKey: flags.DisableMaster,
|
|
||||||
noFreeze: flags.NoFreeze,
|
|
||||||
globalFreeze: flags.GlobalFreeze,
|
|
||||||
defaultRipple: flags.DefaultRipple
|
|
||||||
};
|
|
||||||
|
|
||||||
function parseFlags(value) {
|
function parseFlags(value) {
|
||||||
const settings = {};
|
const settings = {};
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ function getTransaction(identifier, options, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
_.partial(remote.requestTx.bind(remote), {hash: identifier}),
|
_.partial(remote.requestTx.bind(remote), {hash: identifier, binary: false}),
|
||||||
_.partial(attachTransactionDate, remote)
|
_.partial(attachTransactionDate, remote)
|
||||||
], callbackWrapper);
|
], callbackWrapper);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const validate = utils.common.validate;
|
|||||||
const TrustSetFlags = {
|
const TrustSetFlags = {
|
||||||
authorized: {set: 'SetAuth'},
|
authorized: {set: 'SetAuth'},
|
||||||
allowRippling: {set: 'ClearNoRipple', unset: 'NoRipple'},
|
allowRippling: {set: 'ClearNoRipple', unset: 'NoRipple'},
|
||||||
frozed: {set: 'SetFreeze', unset: 'ClearFreeze'}
|
frozen: {set: 'SetFreeze', unset: 'ClearFreeze'}
|
||||||
};
|
};
|
||||||
|
|
||||||
function createTrustlineTransaction(account, trustline) {
|
function createTrustlineTransaction(account, trustline) {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ const getOrdersResponse = require('./fixtures/get-orders-response');
|
|||||||
const getOrderbookResponse = require('./fixtures/get-orderbook-response');
|
const getOrderbookResponse = require('./fixtures/get-orderbook-response');
|
||||||
const getServerInfoResponse = require('./fixtures/get-server-info-response');
|
const getServerInfoResponse = require('./fixtures/get-server-info-response');
|
||||||
const getPathsResponse = require('./fixtures/get-paths-response');
|
const getPathsResponse = require('./fixtures/get-paths-response');
|
||||||
|
const settingsTransactionResponse = require('./fixtures/settings-tx-response');
|
||||||
const address = addresses.ACCOUNT;
|
const address = addresses.ACCOUNT;
|
||||||
|
|
||||||
const orderbook = {
|
const orderbook = {
|
||||||
@@ -121,6 +122,13 @@ describe('RippleAPI', function() {
|
|||||||
_.partial(checkResult, transactionResponse, done));
|
_.partial(checkResult, transactionResponse, done));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('getTransaction - settings', function(done) {
|
||||||
|
const hash =
|
||||||
|
'4FB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA1B';
|
||||||
|
this.api.getTransaction(hash, {},
|
||||||
|
_.partial(checkResult, settingsTransactionResponse, done));
|
||||||
|
});
|
||||||
|
|
||||||
it('getTransactions', function(done) {
|
it('getTransactions', function(done) {
|
||||||
const options = {types: ['payment', 'order'], outgoing: true, limit: 2};
|
const options = {types: ['payment', 'order'], outgoing: true, limit: 2};
|
||||||
this.api.getTransactions(address, options,
|
this.api.getTransactions(address, options,
|
||||||
|
|||||||
41
test/fixtures/account-set-tx.json
vendored
Normal file
41
test/fixtures/account-set-tx.json
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"Account": "rLVKsA4F9iJBbA6rX2x4wCmkj6drgtqpQe",
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 2147483648,
|
||||||
|
"Sequence": 1,
|
||||||
|
"SetFlag": 2,
|
||||||
|
"SigningPubKey": "03EA3ADCA632F125EC2CC4F7F6A82DE0DCE2B65290CAC1F22242C5163F0DA9652D",
|
||||||
|
"TransactionType": "AccountSet",
|
||||||
|
"TxnSignature": "3045022100DE8B666B1A31EA65011B0F32130AB91A5747E32FA49B3054CEE8E8362DBAB98A022040CF0CF254677A8E5CD04C59CA2ED7F6F15F7E184641BAE169C561650967B226",
|
||||||
|
"date": 460832270,
|
||||||
|
"hash": "4FB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA1B",
|
||||||
|
"inLedger": 8206418,
|
||||||
|
"ledger_index": 8206418,
|
||||||
|
"meta": {
|
||||||
|
"AffectedNodes": [
|
||||||
|
{
|
||||||
|
"ModifiedNode": {
|
||||||
|
"FinalFields": {
|
||||||
|
"Account": "rLVKsA4F9iJBbA6rX2x4wCmkj6drgtqpQe",
|
||||||
|
"Balance": "29999990",
|
||||||
|
"Flags": 786432,
|
||||||
|
"OwnerCount": 0,
|
||||||
|
"Sequence": 2
|
||||||
|
},
|
||||||
|
"LedgerEntryType": "AccountRoot",
|
||||||
|
"LedgerIndex": "3F5072C4875F32ED770DAF3610A716600ED7C7BB0348FADC7A98E011BB2CD36F",
|
||||||
|
"PreviousFields": {
|
||||||
|
"Balance": "30000000",
|
||||||
|
"Flags": 4194304,
|
||||||
|
"Sequence": 1
|
||||||
|
},
|
||||||
|
"PreviousTxnID": "3FB0350A3742BBCC0D8AA3C5247D1AEC01177D0A24D9C34762BAA2FEA8AD88B3",
|
||||||
|
"PreviousTxnLgrSeq": 8206397
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"TransactionIndex": 5,
|
||||||
|
"TransactionResult": "tesSUCCESS"
|
||||||
|
},
|
||||||
|
"validated": true
|
||||||
|
}
|
||||||
10
test/fixtures/mock.js
vendored
10
test/fixtures/mock.js
vendored
@@ -3,7 +3,6 @@
|
|||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const addresses = require('./addresses');
|
const addresses = require('./addresses');
|
||||||
const accountTransactionsResponse = require('./acct-tx-response');
|
const accountTransactionsResponse = require('./acct-tx-response');
|
||||||
const SerializedObject = require('ripple-lib').SerializedObject;
|
|
||||||
const BASE_LEDGER_INDEX = 8819951;
|
const BASE_LEDGER_INDEX = 8819951;
|
||||||
|
|
||||||
module.exports.accountTransactionsResponse = accountTransactionsResponse;
|
module.exports.accountTransactionsResponse = accountTransactionsResponse;
|
||||||
@@ -645,15 +644,14 @@ const BINARY_TRANSACTION_SYNTH = module.exports.BINARY_TRANSACTION_SYNTH = {
|
|||||||
validated: true
|
validated: true
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.transactionResponse = function(request) {
|
const EXAMPLE_TX = _.merge(BINARY_TRANSACTION_SYNTH, BINARY_TRANSACTION, {meta: METADATA});
|
||||||
|
|
||||||
|
module.exports.transactionResponse = function(request, transaction) {
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
id: request.id,
|
id: request.id,
|
||||||
status: 'success',
|
status: 'success',
|
||||||
type: 'response',
|
type: 'response',
|
||||||
result: _.extend({
|
result: transaction || EXAMPLE_TX
|
||||||
meta: SerializedObject.from_json(METADATA).to_hex(),
|
|
||||||
tx: SerializedObject.from_json(BINARY_TRANSACTION).to_hex()
|
|
||||||
}, BINARY_TRANSACTION_SYNTH)
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
28
test/fixtures/settings-tx-response.json
vendored
Normal file
28
test/fixtures/settings-tx-response.json
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"type": "settings",
|
||||||
|
"address": "rLVKsA4F9iJBbA6rX2x4wCmkj6drgtqpQe",
|
||||||
|
"id": "4FB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA1B",
|
||||||
|
"specification": {
|
||||||
|
"requireAuthorization": true,
|
||||||
|
"disallowIncomingXRP": true,
|
||||||
|
"globalFreeze": false,
|
||||||
|
"sequence": 1
|
||||||
|
},
|
||||||
|
"outcome": {
|
||||||
|
"result": "tesSUCCESS",
|
||||||
|
"timestamp": "2014-08-08T16:57:50.000Z",
|
||||||
|
"fee": "0.00001",
|
||||||
|
"balanceChanges": {
|
||||||
|
"rLVKsA4F9iJBbA6rX2x4wCmkj6drgtqpQe": [
|
||||||
|
{
|
||||||
|
"currency": "XRP",
|
||||||
|
"value": "-0.00001"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"orderbookChanges": {},
|
||||||
|
"ledgerVersion": 8206418,
|
||||||
|
"indexInLedger": 5,
|
||||||
|
"sequence": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
2
test/fixtures/trustline-response.json
vendored
2
test/fixtures/trustline-response.json
vendored
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"Flags": 131072,
|
"Flags": 2228224,
|
||||||
"TransactionType": "TrustSet",
|
"TransactionType": "TrustSet",
|
||||||
"Account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
"Account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||||
"LimitAmount": {
|
"LimitAmount": {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ const addresses = require('./fixtures/addresses');
|
|||||||
const hashes = require('./fixtures/hashes');
|
const hashes = require('./fixtures/hashes');
|
||||||
const accountOffersResponse = require('./fixtures/acct-offers-response');
|
const accountOffersResponse = require('./fixtures/acct-offers-response');
|
||||||
const bookOffers = require('./fixtures/book-offers-response');
|
const bookOffers = require('./fixtures/book-offers-response');
|
||||||
|
const accountSetTransactionResponse = require('./fixtures/account-set-tx.json');
|
||||||
const paths = require('./fixtures/paths');
|
const paths = require('./fixtures/paths');
|
||||||
|
|
||||||
function isUSD(json) {
|
function isUSD(json) {
|
||||||
@@ -101,6 +102,10 @@ module.exports = function(port) {
|
|||||||
assert.strictEqual(request.command, 'tx');
|
assert.strictEqual(request.command, 'tx');
|
||||||
if (request.transaction === hashes.VALID_TRANSACTION_HASH) {
|
if (request.transaction === hashes.VALID_TRANSACTION_HASH) {
|
||||||
conn.send(fixtures.transactionResponse(request));
|
conn.send(fixtures.transactionResponse(request));
|
||||||
|
} else if (request.transaction ===
|
||||||
|
'4FB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA1B') {
|
||||||
|
const transaction = accountSetTransactionResponse;
|
||||||
|
conn.send(fixtures.transactionResponse(request, transaction));
|
||||||
} else if (request.transaction === hashes.NOTFOUND_TRANSACTION_HASH) {
|
} else if (request.transaction === hashes.NOTFOUND_TRANSACTION_HASH) {
|
||||||
conn.send(fixtures.transactionNotFoundResponse(request));
|
conn.send(fixtures.transactionNotFoundResponse(request));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user