mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-20 20:25:48 +00:00
Cleanup transaction submission
This commit is contained in:
@@ -192,11 +192,11 @@ util.inherits(Remote, EventEmitter);
|
|||||||
|
|
||||||
// Flags for ledger entries. In support of account_root().
|
// Flags for ledger entries. In support of account_root().
|
||||||
Remote.flags = {
|
Remote.flags = {
|
||||||
'account_root' : {
|
account_root : {
|
||||||
'PasswordSpent' : 0x00010000,
|
PasswordSpent: 0x00010000,
|
||||||
'RequireDestTag' : 0x00020000,
|
RequireDestTag: 0x00020000,
|
||||||
'RequireAuth' : 0x00040000,
|
RequireAuth: 0x00040000,
|
||||||
'DisallowXRP' : 0x00080000,
|
DisallowXRP: 0x00080000
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -917,9 +917,7 @@ Remote.prototype.ledger_accept = function (callback) {
|
|||||||
request.request();
|
request.request();
|
||||||
request.callback(callback);
|
request.callback(callback);
|
||||||
} else {
|
} else {
|
||||||
this.emit('error', {
|
this.emit('error', { error : 'notStandAlone' });
|
||||||
'error' : 'notStandAlone'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@@ -1102,11 +1100,10 @@ Remote.prototype.set_secret = function (account, secret) {
|
|||||||
Remote.prototype.request_ripple_balance = function (account, issuer, currency, current, callback) {
|
Remote.prototype.request_ripple_balance = function (account, issuer, currency, current, callback) {
|
||||||
var request = this.request_ledger_entry('ripple_state'); // YYY Could be cached per ledger.
|
var request = this.request_ledger_entry('ripple_state'); // YYY Could be cached per ledger.
|
||||||
|
|
||||||
return request.ripple_state(account, issuer, currency)
|
request.ripple_state(account, issuer, currency);
|
||||||
.ledger_choose(current)
|
request.ledger_choose(current);
|
||||||
.on('success', function (message) {
|
request.once(success, function(message) {
|
||||||
var node = message.node;
|
var node = message.node;
|
||||||
|
|
||||||
var lowLimit = Amount.from_json(node.LowLimit);
|
var lowLimit = Amount.from_json(node.LowLimit);
|
||||||
var highLimit = Amount.from_json(node.HighLimit);
|
var highLimit = Amount.from_json(node.HighLimit);
|
||||||
// The amount the low account holds of issuer.
|
// The amount the low account holds of issuer.
|
||||||
@@ -1115,24 +1112,26 @@ Remote.prototype.request_ripple_balance = function (account, issuer, currency, c
|
|||||||
var accountHigh = UInt160.from_json(account).equals(highLimit.issuer());
|
var accountHigh = UInt160.from_json(account).equals(highLimit.issuer());
|
||||||
|
|
||||||
request.emit('ripple_state', {
|
request.emit('ripple_state', {
|
||||||
'account_balance' : ( accountHigh ? balance.negate() : balance.clone()).parse_issuer(account),
|
account_balance : ( accountHigh ? balance.negate() : balance.clone()).parse_issuer(account),
|
||||||
'peer_balance' : (!accountHigh ? balance.negate() : balance.clone()).parse_issuer(issuer),
|
peer_balance : (!accountHigh ? balance.negate() : balance.clone()).parse_issuer(issuer),
|
||||||
|
|
||||||
'account_limit' : ( accountHigh ? highLimit : lowLimit).clone().parse_issuer(issuer),
|
account_limit : ( accountHigh ? highLimit : lowLimit).clone().parse_issuer(issuer),
|
||||||
'peer_limit' : (!accountHigh ? highLimit : lowLimit).clone().parse_issuer(account),
|
peer_limit : (!accountHigh ? highLimit : lowLimit).clone().parse_issuer(account),
|
||||||
|
|
||||||
'account_quality_in' : ( accountHigh ? node.HighQualityIn : node.LowQualityIn),
|
account_quality_in : ( accountHigh ? node.HighQualityIn : node.LowQualityIn),
|
||||||
'peer_quality_in' : (!accountHigh ? node.HighQualityIn : node.LowQualityIn),
|
peer_quality_in : (!accountHigh ? node.HighQualityIn : node.LowQualityIn),
|
||||||
|
|
||||||
'account_quality_out' : ( accountHigh ? node.HighQualityOut : node.LowQualityOut),
|
account_quality_out : ( accountHigh ? node.HighQualityOut : node.LowQualityOut),
|
||||||
'peer_quality_out' : (!accountHigh ? node.HighQualityOut : node.LowQualityOut),
|
peer_quality_out : (!accountHigh ? node.HighQualityOut : node.LowQualityOut),
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
.callback(callback, 'ripple_state');
|
|
||||||
|
request.callback(callback, 'ripple_state');
|
||||||
|
|
||||||
|
return request;
|
||||||
};
|
};
|
||||||
|
|
||||||
Remote.prototype.request_ripple_path_find = function (src_account, dst_account, dst_amount, src_currencies, callback) {
|
Remote.prototype.request_ripple_path_find = function (src_account, dst_account, dst_amount, src_currencies, callback) {
|
||||||
var self = this;
|
|
||||||
var request = new Request(this, 'ripple_path_find');
|
var request = new Request(this, 'ripple_path_find');
|
||||||
|
|
||||||
request.message.source_account = UInt160.json_rewrite(src_account);
|
request.message.source_account = UInt160.json_rewrite(src_account);
|
||||||
@@ -1143,11 +1142,13 @@ Remote.prototype.request_ripple_path_find = function (src_account, dst_account,
|
|||||||
request.message.source_currencies = src_currencies.map(function (ci) {
|
request.message.source_currencies = src_currencies.map(function (ci) {
|
||||||
var ci_new = { };
|
var ci_new = { };
|
||||||
|
|
||||||
if ('issuer' in ci)
|
if (ci.hasOwnProperty('issuer')) {
|
||||||
ci_new.issuer = UInt160.json_rewrite(ci.issuer);
|
ci_new.issuer = UInt160.json_rewrite(ci.issuer);
|
||||||
|
}
|
||||||
|
|
||||||
if ('currency' in ci)
|
if (ci.hasOwnProperty('currency')) {
|
||||||
ci_new.currency = Currency.json_rewrite(ci.currency);
|
ci_new.currency = Currency.json_rewrite(ci.currency);
|
||||||
|
}
|
||||||
|
|
||||||
return ci_new;
|
return ci_new;
|
||||||
});
|
});
|
||||||
@@ -1211,15 +1212,27 @@ Remote.prototype.transaction = function () {
|
|||||||
return new Transaction(this);
|
return new Transaction(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate a transaction fee for a number of tx fee units.
|
||||||
|
*
|
||||||
|
* This takes into account the last known network and local load fees.
|
||||||
|
*
|
||||||
|
* @return {Amount} Final fee in XRP for specified number of fee units.
|
||||||
|
*/
|
||||||
|
Remote.prototype.fee_tx = function (units) {
|
||||||
|
var fee_unit = this.fee_tx_unit();
|
||||||
|
return Amount.from_json(String(Math.ceil(units * fee_unit)));
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current recommended transaction fee unit.
|
* Get the current recommended transaction fee unit.
|
||||||
*
|
*
|
||||||
* Multiply this value with the number of fee units in order to calculate the
|
* Multiply this value with the number of fee units in order to calculate the
|
||||||
* recommended fee for the transaction you are trying to submit.
|
* recommended fee for the transaction you are trying to submit.
|
||||||
*
|
*
|
||||||
* @return {Number} Recommended amount for one fee unit.
|
* @return {Number} Recommended amount for one fee unit as float.
|
||||||
*/
|
*/
|
||||||
Remote.prototype.fee_tx = function () {
|
Remote.prototype.fee_tx_unit = function () {
|
||||||
var fee_unit = this._fee_base / this._fee_ref;
|
var fee_unit = this._fee_base / this._fee_ref;
|
||||||
|
|
||||||
// Apply load fees
|
// Apply load fees
|
||||||
@@ -1236,8 +1249,17 @@ Remote.prototype.fee_tx = function () {
|
|||||||
*
|
*
|
||||||
* Returns the base reserve with load fees and safety margin applied.
|
* Returns the base reserve with load fees and safety margin applied.
|
||||||
*/
|
*/
|
||||||
Remote.prototype.fee_reserve_base = function () {
|
Remote.prototype.reserve = function (owner_count) {
|
||||||
// XXX
|
var reserve_base = Amount.from_json(String(this._reserve_base));
|
||||||
|
var reserve_inc = Amount.from_json(String(this._reserve_inc));
|
||||||
|
|
||||||
|
owner_count = owner_count || 0;
|
||||||
|
|
||||||
|
if (owner_count < 0) {
|
||||||
|
throw new Error('Owner count must not be negative.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return reserve_base.add(reserve_inc.product_human(owner_count));
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.Remote = Remote;
|
exports.Remote = Remote;
|
||||||
|
|||||||
@@ -85,10 +85,8 @@ function Transaction(remote) {
|
|||||||
util.inherits(Transaction, EventEmitter);
|
util.inherits(Transaction, EventEmitter);
|
||||||
|
|
||||||
// XXX This needs to be determined from the network.
|
// XXX This needs to be determined from the network.
|
||||||
Transaction.fees = {
|
Transaction.fee_units = {
|
||||||
default : Amount.from_json('10'),
|
default: 10,
|
||||||
nickname_create : Amount.from_json('1000'),
|
|
||||||
offer : Amount.from_json('10'),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Transaction.flags = {
|
Transaction.flags = {
|
||||||
@@ -98,20 +96,20 @@ Transaction.flags = {
|
|||||||
RequireAuth: 0x00040000,
|
RequireAuth: 0x00040000,
|
||||||
OptionalAuth: 0x00080000,
|
OptionalAuth: 0x00080000,
|
||||||
DisallowXRP: 0x00100000,
|
DisallowXRP: 0x00100000,
|
||||||
AllowXRP : 0x00200000,
|
AllowXRP: 0x00200000
|
||||||
},
|
},
|
||||||
|
|
||||||
OfferCreate: {
|
OfferCreate: {
|
||||||
Passive: 0x00010000,
|
Passive: 0x00010000,
|
||||||
ImmediateOrCancel: 0x00020000,
|
ImmediateOrCancel: 0x00020000,
|
||||||
FillOrKill: 0x00040000,
|
FillOrKill: 0x00040000,
|
||||||
Sell : 0x00080000,
|
Sell: 0x00080000
|
||||||
},
|
},
|
||||||
|
|
||||||
Payment: {
|
Payment: {
|
||||||
NoRippleDirect: 0x00010000,
|
NoRippleDirect: 0x00010000,
|
||||||
PartialPayment: 0x00020000,
|
PartialPayment: 0x00020000,
|
||||||
LimitQuality : 0x00040000,
|
LimitQuality: 0x00040000
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -121,12 +119,12 @@ Transaction.HASH_SIGN = 0x53545800;
|
|||||||
Transaction.HASH_SIGN_TESTNET = 0x73747800;
|
Transaction.HASH_SIGN_TESTNET = 0x73747800;
|
||||||
|
|
||||||
Transaction.prototype.consts = {
|
Transaction.prototype.consts = {
|
||||||
'telLOCAL_ERROR' : -399,
|
telLOCAL_ERROR : -399,
|
||||||
'temMALFORMED' : -299,
|
temMALFORMED : -299,
|
||||||
'tefFAILURE' : -199,
|
tefFAILURE : -199,
|
||||||
'terRETRY' : -99,
|
terRETRY : -99,
|
||||||
'tesSUCCESS' : 0,
|
tesSUCCESS : 0,
|
||||||
'tecCLAIMED' : 100,
|
tecCLAIMED : 100,
|
||||||
};
|
};
|
||||||
|
|
||||||
Transaction.prototype.isTelLocal = function (ter) {
|
Transaction.prototype.isTelLocal = function (ter) {
|
||||||
@@ -183,11 +181,11 @@ Transaction.prototype.get_fee = function() {
|
|||||||
Transaction.prototype.complete = function () {
|
Transaction.prototype.complete = function () {
|
||||||
var tx_json = this.tx_json;
|
var tx_json = this.tx_json;
|
||||||
|
|
||||||
if (tx_json.Fee === void(0) && this.remote.local_fee) {
|
if (typeof tx_json.Fee === 'undefined' && this.remote.local_fee === void(0)) {
|
||||||
tx_json.Fee = Transaction.fees['default'].to_json();
|
this.tx_json.Fee = this.remote.fee_tx(this.fee_units()).to_json();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx_json.SigningPubKey === void(0) && (!this.remote || this.remote.local_signing)) {
|
if (typeof tx_json.SigningPubKey === 'undefined' && (!this.remote || this.remote.local_signing)) {
|
||||||
var seed = Seed.from_json(this._secret);
|
var seed = Seed.from_json(this._secret);
|
||||||
var key = seed.get_key(this.tx_json.Account);
|
var key = seed.get_key(this.tx_json.Account);
|
||||||
tx_json.SigningPubKey = key.to_hex_pub();
|
tx_json.SigningPubKey = key.to_hex_pub();
|
||||||
@@ -212,9 +210,10 @@ Transaction.prototype.sign = function () {
|
|||||||
var seed = Seed.from_json(this._secret);
|
var seed = Seed.from_json(this._secret);
|
||||||
var hash = this.signing_hash();
|
var hash = this.signing_hash();
|
||||||
|
|
||||||
if (this.tx_json.TxnSignature && hash === this._previous_signing_hash) {
|
var previously_signed = this.tx_json.TxnSignature
|
||||||
return;
|
&& hash === this._previous_signing_hash;
|
||||||
}
|
|
||||||
|
if (previously_signed) return;
|
||||||
|
|
||||||
var key = seed.get_key(this.tx_json.Account);
|
var key = seed.get_key(this.tx_json.Account);
|
||||||
var sig = key.sign(hash, 0);
|
var sig = key.sign(hash, 0);
|
||||||
@@ -478,7 +477,7 @@ Transaction.prototype.ripple_line_set = function (src, limit, quality_in, qualit
|
|||||||
this.tx_json.Account = UInt160.json_rewrite(src);
|
this.tx_json.Account = UInt160.json_rewrite(src);
|
||||||
|
|
||||||
// Allow limit of 0 through.
|
// Allow limit of 0 through.
|
||||||
if (limit !== undefined)
|
if (limit !== void(0))
|
||||||
this.tx_json.LimitAmount = Amount.json_rewrite(limit);
|
this.tx_json.LimitAmount = Amount.json_rewrite(limit);
|
||||||
|
|
||||||
if (quality_in)
|
if (quality_in)
|
||||||
@@ -503,6 +502,21 @@ Transaction.prototype.wallet_add = function (src, amount, authorized_key, public
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of fee units this transaction will cost.
|
||||||
|
*
|
||||||
|
* Each Ripple transaction based on its type and makeup costs a certain number
|
||||||
|
* of fee units. The fee units are calculated on a per-server basis based on the
|
||||||
|
* current load on both the network and the server.
|
||||||
|
*
|
||||||
|
* @see https://ripple.com/wiki/Transaction_Fee
|
||||||
|
*
|
||||||
|
* @return {Number} Number of fee units for this transaction.
|
||||||
|
*/
|
||||||
|
Transaction.prototype.fee_units = function () {
|
||||||
|
return Transaction.fee_units['default'];
|
||||||
|
};
|
||||||
|
|
||||||
// Submit a transaction to the network.
|
// Submit a transaction to the network.
|
||||||
// XXX Don't allow a submit without knowing ledger_index.
|
// XXX Don't allow a submit without knowing ledger_index.
|
||||||
// XXX Have a network canSubmit(), post events for following.
|
// XXX Have a network canSubmit(), post events for following.
|
||||||
@@ -521,13 +535,13 @@ Transaction.prototype.wallet_add = function (src, amount, authorized_key, public
|
|||||||
Transaction.prototype.submit = function (callback) {
|
Transaction.prototype.submit = function (callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
this.callback = (typeof callback === 'function') ? callback : function(){};
|
this.callback = typeof callback === 'function' ? callback : function(){};
|
||||||
|
|
||||||
this.once('error', function transaction_error(error, message) {
|
this.once('error', function(error, message) {
|
||||||
self.callback(error, message);
|
self.callback(error, message);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.once('success', function transaction_success(message) {
|
this.once('success', function(message) {
|
||||||
self.callback(null, message);
|
self.callback(null, message);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -157,7 +157,9 @@ var create_accounts = function (remote, src, amount, accounts, callback) {
|
|||||||
.on('proposed', function (m) {
|
.on('proposed', function (m) {
|
||||||
// console.log("proposed: %s", JSON.stringify(m));
|
// console.log("proposed: %s", JSON.stringify(m));
|
||||||
|
|
||||||
callback(m.result != 'tesSUCCESS');
|
if (m.result != 'tesSUCCESS') {
|
||||||
|
callback(new Error("Transaction did not succeed."));
|
||||||
|
} else callback(null);
|
||||||
})
|
})
|
||||||
.on('error', function (m) {
|
.on('error', function (m) {
|
||||||
// console.log("error: %s", JSON.stringify(m));
|
// console.log("error: %s", JSON.stringify(m));
|
||||||
|
|||||||
Reference in New Issue
Block a user