Merge branch 'develop' of https://github.com/ripple/ripple-lib into develop

This commit is contained in:
wltsmrz
2013-11-13 11:41:17 -08:00
7 changed files with 248 additions and 39 deletions

View File

@@ -15,6 +15,7 @@ var sjcl = utils.sjcl;
var UInt128 = require('./uint128').UInt128;
var UInt160 = require('./uint160').UInt160;
var UInt256 = require('./uint256').UInt256;
var Base = require('./base').Base;
var amount = require('./amount');
var Amount = amount.Amount;
@@ -381,6 +382,7 @@ var STAmount = exports.Amount = new SerializedType({
var currency = STCurrency.parse(so);
var issuer_bytes = so.read(20);
var issuer = UInt160.from_bytes(issuer_bytes);
issuer.set_version(Base.VER_ACCOUNT_ID);
var offset = ((value_bytes[0] & 0x3f) << 2) + (value_bytes[1] >>> 6) - 97;
var mantissa_bytes = value_bytes.slice(1);
mantissa_bytes[0] &= 0x3f;
@@ -441,6 +443,7 @@ var STAccount = exports.Account = new SerializedType({
}
var result = UInt160.from_bytes(so.read(len));
result.set_version(Base.VER_ACCOUNT_ID);
//console.log('PARSED 160:', result.to_json());
if (false && !result.is_valid()) {
@@ -482,7 +485,7 @@ var STPathSet = exports.PathSet = new SerializedType({
if (entry.currency) {
var currency = Currency.from_json(entry.currency);
STCurrency.serialize(so, currency);
STCurrency.serialize(so, currency, entry.non_native);
}
if (entry.issuer) {
@@ -529,14 +532,20 @@ var STPathSet = exports.PathSet = new SerializedType({
/*var bta = so.read(20);
console.log('BTA:', bta);*/
entry.account = STHash160.parse(so);
entry.account.set_version(Base.VER_ACCOUNT_ID);
}
if (tag_byte & this.typeCurrency) {
//console.log('entry.currency');
entry.currency = STCurrency.parse(so)
entry.currency = STCurrency.parse(so);
if (entry.currency.to_json() === "XRP" &&
!entry.currency.is_native()) {
entry.non_native = true;
}
}
if (tag_byte & this.typeIssuer) {
//console.log('entry.issuer');
entry.issuer = STHash160.parse(so); //should know to use Base58?
entry.issuer.set_version(Base.VER_ACCOUNT_ID);
//console.log('DONE WITH ISSUER!');
}
@@ -625,14 +634,14 @@ function parse(so) {
var type = TYPES_MAP[type_bits];
assert(type, 'Unknown type: ' + type_bits);
assert(type, 'Unknown type - header byte is 0x' + tag_byte.toString(16));
var field_bits = tag_byte & 0x0f;
var field_name = (field_bits === 0)
? field_name = FIELDS_MAP[type_bits][so.read(1)[0]]
: field_name = FIELDS_MAP[type_bits][field_bits];
assert(field_name, 'Unknown field: ' + tag_byte);
assert(field_name, 'Unknown field - header byte is 0x' + tag_byte.toString(16));
return [ field_name, type.parse(so) ]; //key, value
};

View File

@@ -28,8 +28,8 @@ function TransactionManager(account) {
// transaction sequence number
this._load_sequence();
function cache_transaction(transaction) {
var transaction = TransactionManager.normalize_transaction(transaction);
function cache_transaction(res) {
var transaction = TransactionManager.normalize_transaction(res);
var sequence = transaction.tx_json.Sequence;
var hash = transaction.hash;
@@ -40,7 +40,7 @@ function TransactionManager(account) {
self.remote._trace('transactionmanager: transaction_received: %s', transaction.tx_json);
if (pending) {
pending.emit('success', transaction);
pending.emit('success', res);
} else {
self._cache[hash] = transaction;
}

View File

@@ -129,9 +129,6 @@ UInt.prototype.parse_generic = function (j) {
if ('string' !== typeof j) {
this._value = NaN;
}
else if (j[0] === "r") {
this._value = Base.decode_check(Base.VER_ACCOUNT_ID, j);
}
else if (this.constructor.width === j.length) {
this._value = new BigInteger(utils.stringToArray(j), 256);
}

View File

@@ -15,6 +15,7 @@ var Base = require('./base').Base;
var UInt160 = extend(function () {
// Internal form: NaN or BigInteger
this._value = NaN;
this._version_byte = void(0);
}, UInt);
UInt160.width = 20;
@@ -28,6 +29,16 @@ var HEX_ONE = UInt160.HEX_ONE = '0000000000000000000000000000000000000
var STR_ZERO = UInt160.STR_ZERO = utils.hexToString(HEX_ZERO);
var STR_ONE = UInt160.STR_ONE = utils.hexToString(HEX_ONE);
UInt160.prototype.set_version = function (j) {
this._version_byte = j;
return this;
};
UInt160.prototype.get_version = function () {
return this._version_byte;
};
// value = NaN on error.
UInt160.prototype.parse_json = function (j) {
// Canonicalize and validate
@@ -36,13 +47,30 @@ UInt160.prototype.parse_json = function (j) {
}
if (typeof j === 'number' && !isNaN(j)) {
this._value = new BigInteger(String(j));
// Allow raw numbers - DEPRECATED
// This is used mostly by the test suite and is supported
// as a legacy feature only. DO NOT RELY ON THIS BEHAVIOR.
this._value = new BigInteger(String(j));
this._version_byte = Base.VER_ACCOUNT_ID;
} else if (typeof j !== 'string') {
this._value = NaN;
} else if (j[0] === 'r') {
this._value = Base.decode_check(Base.VER_ACCOUNT_ID, j);
this._value = Base.decode_check(Base.VER_ACCOUNT_ID, j);
this._version_byte = Base.VER_ACCOUNT_ID;
} else {
this._value = NaN;
this.parse_hex(j);
}
return this;
};
UInt160.prototype.parse_generic = function (j) {
UInt.prototype.parse_generic.call(this, j);
if (isNaN(this._value)) {
if ("string" === typeof j && j[0] === 'r') {
this._value = Base.decode_check(Base.VER_ACCOUNT_ID, j);
}
}
return this;
@@ -50,17 +78,22 @@ UInt160.prototype.parse_json = function (j) {
// XXX Json form should allow 0 and 1, C++ doesn't currently allow it.
UInt160.prototype.to_json = function (opts) {
var opts = opts || {};
var output = NaN;
opts = opts || {};
if (this._value instanceof BigInteger) {
output = Base.encode_check(Base.VER_ACCOUNT_ID, this.to_bytes());
if (opts.gateways && output in opts.gateways) {
output = opts.gateways[output];
// If this value has a type, return a Base58 encoded string.
if ("number" === typeof this._version_byte) {
var output = Base.encode_check(this._version_byte, this.to_bytes());
if (opts.gateways && output in opts.gateways) {
output = opts.gateways[output];
}
return output;
} else {
return this.to_hex();
}
}
return output;
return NaN;
};
exports.UInt160 = UInt160;

View File

@@ -36,7 +36,7 @@ describe('Amount', function() {
assert.deepEqual(new BigInteger(), UInt160.from_generic('0')._value);
});
it('Parse 0 export', function () {
assert.strictEqual(UInt160.ACCOUNT_ZERO, UInt160.from_generic('0').to_json());
assert.strictEqual(UInt160.ACCOUNT_ZERO, UInt160.from_generic('0').set_version(0).to_json());
});
it('Parse 1', function () {
assert.deepEqual(new BigInteger([1]), UInt160.from_generic('1')._value);

View File

@@ -2,7 +2,7 @@ var utils = require('./testutils');
var assert = require('assert');
var SerializedObject = utils.load_module('serializedobject').SerializedObject;
describe('Serialied object', function() {
describe('Serialized object', function() {
describe('Serialized object', function() {
it('From json and back', function() {
var input_json = {
@@ -18,7 +18,7 @@ describe('Serialied object', function() {
issuer: 'r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV'
},
{
currency:'XRP'
currency: 'XRP'
}
]],
SendMax: {

View File

@@ -378,19 +378,37 @@ describe('Serialized types', function() {
describe('Hash160', function() {
it('Serialize 0', function () {
var hex = '0000000000000000000000000000000000000000';
var base58 = 'rrrrrrrrrrrrrrrrrrrrrhoLvTp';
var so = new SerializedObject();
types.Hash160.serialize(so, 'rrrrrrrrrrrrrrrrrrrrrhoLvTp');
assert.strictEqual(so.to_hex(), '0000000000000000000000000000000000000000');
types.Hash160.serialize(so, base58);
assert.strictEqual(so.to_hex(), hex);
so = new SerializedObject();
types.Hash160.serialize(so, hex);
assert.strictEqual(so.to_hex(), hex);
});
it('Serialize 1', function () {
var hex = '0000000000000000000000000000000000000001';
var base58 = 'rrrrrrrrrrrrrrrrrrrrBZbvji';
var so = new SerializedObject();
types.Hash160.serialize(so, 'rrrrrrrrrrrrrrrrrrrrBZbvji');
assert.strictEqual(so.to_hex(), '0000000000000000000000000000000000000001');
types.Hash160.serialize(so, base58);
assert.strictEqual(so.to_hex(), hex);
so = new SerializedObject();
types.Hash160.serialize(so, hex);
assert.strictEqual(so.to_hex(), hex);
});
it('Serialize FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', function () {
var hex = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
var base58 = 'rQLbzfJH5BT1FS9apRLKV3G8dWEA5njaQi';
var so = new SerializedObject();
types.Hash160.serialize(so, 'rQLbzfJH5BT1FS9apRLKV3G8dWEA5njaQi');
assert.strictEqual(so.to_hex(), 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF');
types.Hash160.serialize(so, base58);
assert.strictEqual(so.to_hex(), hex);
so = new SerializedObject();
types.Hash160.serialize(so, hex);
assert.strictEqual(so.to_hex(), hex);
});
it('Parse 0', function () {
var val = '0000000000000000000000000000000000000000';
@@ -410,6 +428,14 @@ describe('Serialized types', function() {
var num = types.Hash160.parse(so);
assert.strictEqual(num.to_hex(), val);
});
it('Parse 0 as JSON', function () {
// Hash160 should be returned as hex in JSON, unlike
// addresses.
var val = '0000000000000000000000000000000000000000';
var so = new SerializedObject(val);
var num = types.Hash160.parse(so);
assert.strictEqual(num.to_json(), val);
});
});
describe('Hash256', function() {
@@ -539,6 +565,60 @@ describe('Serialized types', function() {
});
});
describe('Account', function() {
it('Serialize 0', function () {
var hex = '0000000000000000000000000000000000000000';
var base58 = 'rrrrrrrrrrrrrrrrrrrrrhoLvTp';
var so = new SerializedObject();
types.Account.serialize(so, base58);
assert.strictEqual(so.to_hex(), "14"+hex);
so = new SerializedObject();
types.Account.serialize(so, hex);
assert.strictEqual(so.to_hex(), "14"+hex);
});
it('Serialize 1', function () {
var hex = '0000000000000000000000000000000000000001';
var base58 = 'rrrrrrrrrrrrrrrrrrrrBZbvji';
var so = new SerializedObject();
types.Account.serialize(so, base58);
assert.strictEqual(so.to_hex(), "14"+hex);
so = new SerializedObject();
types.Account.serialize(so, hex);
assert.strictEqual(so.to_hex(), "14"+hex);
});
it('Serialize FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', function () {
var hex = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
var base58 = 'rQLbzfJH5BT1FS9apRLKV3G8dWEA5njaQi';
var so = new SerializedObject();
types.Account.serialize(so, base58);
assert.strictEqual(so.to_hex(), "14"+hex);
so = new SerializedObject();
types.Account.serialize(so, hex);
assert.strictEqual(so.to_hex(), "14"+hex);
});
it('Parse 0', function () {
var val = '140000000000000000000000000000000000000000';
var so = new SerializedObject(val);
var num = types.Account.parse(so);
assert.strictEqual(num.to_json(), 'rrrrrrrrrrrrrrrrrrrrrhoLvTp');
});
it('Parse 1', function () {
var val = '140000000000000000000000000000000000000001';
var so = new SerializedObject(val);
var num = types.Account.parse(so);
assert.strictEqual(num.to_json(), 'rrrrrrrrrrrrrrrrrrrrBZbvji');
});
it('Parse HASH160_MAX', function () {
var val = '14FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
var so = new SerializedObject(val);
var num = types.Account.parse(so);
assert.strictEqual(num.to_json(), 'rQLbzfJH5BT1FS9apRLKV3G8dWEA5njaQi');
});
});
describe('PathSet', function() {
it('Serialize single empty path [[]]', function () {
var so = new SerializedObject();
@@ -564,24 +644,114 @@ describe('Serialized types', function() {
}]]);
assert.strictEqual(so.to_hex(), '31000000000000000000000000000000000000007B00000000000000000000000055534400000000000000000000000000000000000000000000000315FF31000000000000000000000000000000000000007B000000000000000000000000425443000000000000000000000000000000000000000000000003153100000000000000000000000000000000000003DB0000000000000000000000004555520000000000000000000000000000000000000000000000014100'); //TODO: Check this independently
});
it('Serialize path through XRP', function () {
var hex = '31000000000000000000000000000000000000007B00000000000000000000000055534400000000000000000000000000000000000000000000000315FF1000000000000000000000000000000000000000003100000000000000000000000000000000000003DB0000000000000000000000004555520000000000000000000000000000000000000000000000014100';
var json = [
[ {
account: "rrrrrrrrrrrrrrrrrrrrNxV3Xza",
currency: 'USD',
issuer: "rrrrrrrrrrrrrrrrrrrpYnYCNYf"
}],
[{
currency: "XRP"
}, {
account: "rrrrrrrrrrrrrrrrrrrpvQsW3V3",
currency: 'EUR',
issuer: "rrrrrrrrrrrrrrrrrrrdHRtqg2"
}]
];
var so = new SerializedObject();
types.PathSet.serialize(so, json);
assert.strictEqual(so.to_hex(), hex);
so = new SerializedObject(hex);
var parsed_path = SerializedObject.jsonify_structure(types.PathSet.parse(so));
assert.deepEqual(parsed_path, json);
});
it('Serialize path through XRP IOUs', function () {
// Appears in the history
// TX #0CBB429C456ED999CC691DFCC8E62E8C8C7E9522C2BEA967FED0D7E2A9B28D13
// Note that XRP IOUs are no longer allowed, so this functionality is
// for historic transactions only.
var hex = '31585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C10000000000000000000000004254430000000000585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C131E4FE687C90257D3D2D694C8531CDEECBE84F33670000000000000000000000004254430000000000E4FE687C90257D3D2D694C8531CDEECBE84F3367310A20B3C85F482532A9578DBB3950B85CA06594D100000000000000000000000042544300000000000A20B3C85F482532A9578DBB3950B85CA06594D13000000000000000000000000055534400000000000A20B3C85F482532A9578DBB3950B85CA06594D1FF31585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C10000000000000000000000004254430000000000585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C131E4FE687C90257D3D2D694C8531CDEECBE84F33670000000000000000000000004254430000000000E4FE687C90257D3D2D694C8531CDEECBE84F33673115036E2D3F5437A83E5AC3CAEE34FF2C21DEB618000000000000000000000000425443000000000015036E2D3F5437A83E5AC3CAEE34FF2C21DEB6183000000000000000000000000055534400000000000A20B3C85F482532A9578DBB3950B85CA06594D1FF31585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C10000000000000000000000004254430000000000585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C13157180C769B66D942EE69E6DCC940CA48D82337AD000000000000000000000000425443000000000057180C769B66D942EE69E6DCC940CA48D82337AD1000000000000000000000000058525000000000003000000000000000000000000055534400000000000A20B3C85F482532A9578DBB3950B85CA06594D100';
var json = [
[{
"account": "r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K",
"currency": "BTC",
"issuer": "r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K"
}, {
"account": "rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo",
"currency": "BTC",
"issuer": "rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo"
}, {
"account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"currency": "BTC",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}, {
"currency": "USD",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}],
[{
"account": "r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K",
"currency": "BTC",
"issuer": "r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K"
}, {
"account": "rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo",
"currency": "BTC",
"issuer": "rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo"
}, {
"account": "rpvfJ4mR6QQAeogpXEKnuyGBx8mYCSnYZi",
"currency": "BTC",
"issuer": "rpvfJ4mR6QQAeogpXEKnuyGBx8mYCSnYZi"
}, {
"currency": "USD",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}],
[{
"account": "r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K",
"currency": "BTC",
"issuer": "r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K"
}, {
"account": "r3AWbdp2jQLXLywJypdoNwVSvr81xs3uhn",
"currency": "BTC",
"issuer": "r3AWbdp2jQLXLywJypdoNwVSvr81xs3uhn"
}, {
"currency": "XRP",
"non_native": true
}, {
"currency": "USD",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}]
];
var so = new SerializedObject();
types.PathSet.serialize(so, json);
assert.strictEqual(so.to_hex(), hex);
so = new SerializedObject(hex);
var parsed_path = SerializedObject.jsonify_structure(types.PathSet.parse(so));
assert.deepEqual(parsed_path, json);
});
it('Parse single empty path [[]]', function () {
var so = new SerializedObject('00');
var parsed_path = types.PathSet.parse(so)
var parsed_path = SerializedObject.jsonify_structure(types.PathSet.parse(so));
assert.deepEqual(parsed_path, [[]]);
});
it('Parse [[e],[e,e]]', function () {
var so = new SerializedObject('31000000000000000000000000000000000000007B00000000000000000000000055534400000000000000000000000000000000000000000000000315FF31000000000000000000000000000000000000007B000000000000000000000000425443000000000000000000000000000000000000000000000003153100000000000000000000000000000000000003DB0000000000000000000000004555520000000000000000000000000000000000000000000000014100');
var parsed_path = types.PathSet.parse(so);
var comp =[ [ { account: 'rrrrrrrrrrrrrrrrrrrrNxV3Xza',
currency: 'USD',
issuer: 'rrrrrrrrrrrrrrrrrrrpYnYCNYf' } ],
[ { account: 'rrrrrrrrrrrrrrrrrrrrNxV3Xza',
currency: 'BTC',
issuer: 'rrrrrrrrrrrrrrrrrrrpYnYCNYf' },
{ account: 'rrrrrrrrrrrrrrrrrrrpvQsW3V3',
currency: 'EUR',
issuer: 'rrrrrrrrrrrrrrrrrrrdHRtqg2' } ] ];
var comp = [ [ { account: 'rrrrrrrrrrrrrrrrrrrrNxV3Xza',
currency: 'USD',
issuer: 'rrrrrrrrrrrrrrrrrrrpYnYCNYf' } ],
[ { account: 'rrrrrrrrrrrrrrrrrrrrNxV3Xza',
currency: 'BTC',
issuer: 'rrrrrrrrrrrrrrrrrrrpYnYCNYf' },
{ account: 'rrrrrrrrrrrrrrrrrrrpvQsW3V3',
currency: 'EUR',
issuer: 'rrrrrrrrrrrrrrrrrrrdHRtqg2' } ] ];
assert.deepEqual(SerializedObject.jsonify_structure(parsed_path, ""), comp);
});
});