Update remote

This commit is contained in:
wltsmrz
2013-07-27 04:03:33 +09:00
parent a5206d2959
commit 342d5a1aa1

View File

@@ -18,6 +18,7 @@
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var Request = require('./request').Request;
var Server = require('./server').Server;
var Amount = require('./amount').Amount;
var Currency = require('./currency').Currency;
@@ -31,250 +32,7 @@ var utils = require('./utils');
var config = require('./config');
var sjcl = require('../../../build/sjcl');
// Request events emitted:
// 'success' : Request successful.
// 'error' : Request failed.
// 'remoteError'
// 'remoteUnexpected'
// 'remoteDisconnected'
function Request(remote, command) {
EventEmitter.call(this);
this.remote = remote;
this.requested = false;
this.message = {
command : command,
id : void(0)
};
};
util.inherits(Request, EventEmitter);
// Send the request to a remote.
Request.prototype.request = function (remote) {
if (!this.requested) {
this.requested = true;
this.remote.request(this);
this.emit('request', remote);
}
};
Request.prototype.callback = function(callback, successEvent, errorEvent) {
if (callback && typeof callback === 'function') {
this.once(successEvent || 'success', callback.bind(this, null));
this.once(errorEvent || 'error' , callback.bind(this));
this.request();
}
return this;
};
Request.prototype.timeout = function(duration, callback) {
if (!this.requested) {
this.once('request', this.timeout.bind(this, duration, callback));
return;
};
var self = this;
var emit = this.emit;
var timed_out = false;
var timeout = setTimeout(function() {
timed_out = true;
if (typeof callback === 'function') callback();
emit.call(self, 'timeout');
}, duration);
this.emit = function() {
if (timed_out) return;
else clearTimeout(timeout);
emit.apply(self, arguments);
};
return this;
};
Request.prototype.build_path = function (build) {
if (build) {
this.message.build_path = true;
}
return this;
};
Request.prototype.ledger_choose = function (current) {
if (current) {
this.message.ledger_index = this.remote._ledger_current_index;
} else {
this.message.ledger_hash = this.remote._ledger_hash;
}
return this;
};
// Set the ledger for a request.
// - ledger_entry
// - transaction_entry
Request.prototype.ledger_hash = function (h) {
this.message.ledger_hash = h;
return this;
};
// Set the ledger_index for a request.
// - ledger_entry
Request.prototype.ledger_index = function (ledger_index) {
this.message.ledger_index = ledger_index;
return this;
};
Request.prototype.ledger_select = function (ledger_spec) {
switch (ledger_spec) {
case 'current':
case 'closed':
case 'verified':
this.message.ledger_index = ledger_spec;
break;
default:
// XXX Better test needed
if (String(ledger_spec).length > 12) {
this.message.ledger_hash = ledger_spec;
} else {
this.message.ledger_index = ledger_spec;
}
break;
}
return this;
};
Request.prototype.account_root = function (account) {
this.message.account_root = UInt160.json_rewrite(account);
return this;
};
Request.prototype.index = function (hash) {
this.message.index = hash;
return this;
};
// Provide the information id an offer.
// --> account
// --> seq : sequence number of transaction creating offer (integer)
Request.prototype.offer_id = function (account, seq) {
this.message.offer = {
account: UInt160.json_rewrite(account),
seq: seq
};
return this;
};
// --> index : ledger entry index.
Request.prototype.offer_index = function (index) {
this.message.offer = index;
return this;
};
Request.prototype.secret = function (s) {
if (s) {
this.message.secret = s;
}
return this;
};
Request.prototype.tx_hash = function (h) {
this.message.tx_hash = h;
return this;
};
Request.prototype.tx_json = function (j) {
this.message.tx_json = j;
return this;
};
Request.prototype.tx_blob = function (j) {
this.message.tx_blob = j;
return this;
};
Request.prototype.ripple_state = function (account, issuer, currency) {
this.message.ripple_state = {
'accounts' : [
UInt160.json_rewrite(account),
UInt160.json_rewrite(issuer)
],
'currency' : currency
};
return this;
};
Request.prototype.accounts = function (accounts, realtime) {
if (!Array.isArray(accounts)) {
accounts = [ accounts ];
}
// Process accounts parameters
var procAccounts = accounts.map(function(account) {
return UInt160.json_rewrite(account);
});
if (realtime) {
this.message.rt_accounts = procAccounts;
} else {
this.message.accounts = procAccounts;
}
return this;
};
Request.prototype.rt_accounts = function (accounts) {
return this.accounts(accounts, true);
};
Request.prototype.books = function (books, snapshot) {
var procBooks = [];
for (var i = 0, l = books.length; i < l; i++) {
var book = books[i];
var json = {};
function processSide(side) {
if (!book[side]) throw new Error('Missing '+side);
var obj = json[side] = {
currency: Currency.json_rewrite(book[side].currency)
};
if (obj.currency !== 'XRP') {
obj.issuer = UInt160.json_rewrite(book[side].issuer);
}
}
processSide('taker_gets');
processSide('taker_pays');
if (snapshot) json.snapshot = true;
if (book.both) json.both = true;
procBooks.push(json);
}
this.message.books = procBooks;
return this;
};
//------------------------------------------------------------------------------
/**
Interface to manage the connection to a Ripple server.
@@ -606,13 +364,25 @@ Remote.prototype.ledger_hash = function () {
// It is possible for messages to be dispatched after the connection is closed.
Remote.prototype._handle_message = function (json) {
var self = this;
var message = JSON.parse(json);
var unexpected = false;
var request;
var message
if (typeof message !== 'object') {
try {
message = JSON.parse(json);
unexpected = typeof message !== 'object';
} catch(exception) {
unexpected = true;
} else {
}
if (unexpected) {
// Unexpected response from remote.
this.emit('error', {
error: 'remoteUnexpected',
error_message: 'Unexpected response from remote.'
});
return;
}
switch (message.type) {
case 'response':
// Handled by the server that sent the request
@@ -648,17 +418,15 @@ Remote.prototype._handle_message = function (json) {
// Pass the event on to any related Account objects
var affected = message.mmeta.getAffectedAccounts();
for (var i = 0, l = affected.length; i < l; i++) {
for (var i=0, l=affected.length; i<l; i++) {
var account = self._accounts[affected[i]];
if (account) account.notifyTx(message);
}
// Pass the event on to any related OrderBooks
affected = message.mmeta.getAffectedBooks();
for (i = 0, l = affected.length; i < l; i++) {
for (i=0, l=affected.length; i<l; i++) {
var book = self._books[affected[i]];
if (book) book.notifyTx(message);
}
@@ -668,6 +436,8 @@ Remote.prototype._handle_message = function (json) {
// XXX Should be tracked by the Server object
case 'serverStatus':
self.emit('server_status', message);
if ('load_base' in message && 'load_factor' in message &&
(message.load_base !== self._load_base || message.load_factor != self._load_factor))
{
@@ -684,16 +454,6 @@ Remote.prototype._handle_message = function (json) {
this.emit('net_' + message.type, message);
break;
}
}
// Unexpected response from remote.
if (unexpected) {
console.log('unexpected message from trusted remote: %s', json);
(request || this).emit('error', {
'error' : 'remoteUnexpected',
'error_message' : 'Unexpected response from remote.'
});
}
};
Remote.prototype._set_primary_server = function (server) {
@@ -776,10 +536,12 @@ Remote.prototype.request_ledger = function (ledger, opts, callback) {
if (opts.transactions) request.message.transactions = true;
if (opts.accounts) request.message.accounts = true;
break;
case 'function':
callback = opts;
opts = void(0);
break;
default:
//DEPRECATED
console.log('request_ledger: full parameter is deprecated');
@@ -922,10 +684,12 @@ Remote.prototype.request_unsubscribe = function (streams, callback) {
// .ledger_index()
Remote.prototype.request_transaction_entry = function (hash, callback) {
//utils.assert(this.trusted); // If not trusted, need to check proof, maybe talk packet protocol.
var request = new Request(this, 'transaction_entry');
return (new Request(this, 'transaction_entry'))
.tx_hash(hash)
.callback(callback);
request.tx_hash(hash);
request.callback(callback);
return request;
};
// DEPRECATED: use request_transaction_entry
@@ -1209,19 +973,17 @@ Remote.prototype.request_owner_count = function (account, current, callback) {
return request;
};
Remote.prototype.account = function (accountId, callback) {
Remote.prototype.get_account =
Remote.prototype.account = function (accountId) {
var accountId = UInt160.json_rewrite(accountId);
var account = this._accounts[accountId];
if (!this._accounts[accountId]) {
var account = new Account(this, accountId);
if (!account) {
account = new Account(this, accountId);
if (!account.is_valid()) return account;
this._accounts[accountId] = account;
}
var account = this._accounts[accountId];
return account;
};
@@ -1444,6 +1206,7 @@ Remote.prototype.request_connect = function (ip, port, callback) {
return request;
};
Remote.prototype.create_transaction =
Remote.prototype.transaction = function () {
return new Transaction(this);
};
@@ -1456,8 +1219,7 @@ Remote.prototype.transaction = function () {
*
* @return {Number} Recommended amount for one fee unit.
*/
Remote.prototype.fee_tx = function ()
{
Remote.prototype.fee_tx = function () {
var fee_unit = this._fee_base / this._fee_ref;
// Apply load fees
@@ -1474,8 +1236,7 @@ Remote.prototype.fee_tx = function ()
*
* Returns the base reserve with load fees and safety margin applied.
*/
Remote.prototype.fee_reserve_base = function ()
{
Remote.prototype.fee_reserve_base = function () {
// XXX
};