Fix parsing of settings transactions

This commit is contained in:
Chris Clark
2015-07-13 18:18:56 -07:00
parent 7c357c5d52
commit 18ac8a9d03
12 changed files with 154 additions and 38 deletions

View File

@@ -1,6 +1,18 @@
'use strict';
const Transaction = require('./utils').core.Transaction;
const flagIndices = Transaction.set_clear_flags.AccountSet;
const core = require('./utils').core;
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 = {
requireDestinationTag: flagIndices.asfRequireDest,
@@ -28,5 +40,6 @@ const AccountFields = {
module.exports = {
AccountFields,
AccountFlagIndices
AccountFlagIndices,
AccountFlags
};

View File

@@ -8,6 +8,7 @@
"requireAuthorization": {"type": "boolean"},
"disallowIncomingXRP": {"type": "boolean"},
"disableMasterKey": {"type": "boolean"},
"enableTransactionIDTracking": {"type": "boolean"},
"noFreeze": {"type": "boolean"},
"globalFreeze": {"type": "boolean"},
"defaultRipple": {"type": "boolean"},

View File

@@ -2,27 +2,60 @@
'use strict';
const _ = require('lodash');
const assert = require('assert');
const AccountSetFlags = require('./utils').constants.AccountSetFlags;
const AccountFlags = require('./utils').constants.AccountFlags;
const parseFields = require('./fields');
function getName(flagNumber) {
return _.findKey(AccountSetFlags, (v) => v === flagNumber);
function getAccountRootModifiedNode(tx: Object) {
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) {
const txType = tx.TransactionType;
assert(txType === 'AccountSet' || txType === 'SetRegularKey');
const settings = {};
if (tx.SetFlag) {
settings[getName(tx.SetFlag)] = true;
}
if (tx.ClearFlag) {
settings[getName(tx.ClearFlag)] = false;
}
if (tx.RegularKey) {
settings.regularKey = tx.RegularKey;
}
return _.assign(settings, parseFields(tx));
const regularKey = tx.RegularKey ? {regularKey: tx.RegularKey} : {};
return _.assign(regularKey, parseFlags(tx), parseFields(tx));
}
module.exports = parseSettings;

View File

@@ -1,21 +1,10 @@
'use strict';
const _ = require('lodash');
const utils = require('./utils');
const flags = utils.common.core.Remote.flags.account_root;
const validate = utils.common.validate;
const parseFields = require('./parse/fields');
const composeAsync = utils.common.composeAsync;
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 AccountFlags = utils.common.constants.AccountFlags;
function parseFlags(value) {
const settings = {};

View File

@@ -58,7 +58,7 @@ function getTransaction(identifier, options, callback) {
}
async.waterfall([
_.partial(remote.requestTx.bind(remote), {hash: identifier}),
_.partial(remote.requestTx.bind(remote), {hash: identifier, binary: false}),
_.partial(attachTransactionDate, remote)
], callbackWrapper);
}

View File

@@ -7,7 +7,7 @@ const validate = utils.common.validate;
const TrustSetFlags = {
authorized: {set: 'SetAuth'},
allowRippling: {set: 'ClearNoRipple', unset: 'NoRipple'},
frozed: {set: 'SetFreeze', unset: 'ClearFreeze'}
frozen: {set: 'SetFreeze', unset: 'ClearFreeze'}
};
function createTrustlineTransaction(account, trustline) {