compute total bytes to send max

This commit is contained in:
Ivan Socolsky 2015-07-27 12:19:27 -03:00
parent 5b3671b079
commit 26aef25be6
3 changed files with 36 additions and 27 deletions

View File

@ -171,10 +171,9 @@ TxProposal.prototype.getRawTx = function() {
return t.uncheckedSerialize();
};
TxProposal.prototype.estimateFee = function() {
TxProposal.prototype.getEstimatedSize = function() {
// Note: found empirically based on all multisig P2SH inputs and within m & n allowed limits.
var safetyMargin = 0.05;
var walletM = this.requiredSignatures;
var overhead = 4 + 4 + 9 + 9;
@ -185,7 +184,13 @@ TxProposal.prototype.estimateFee = function() {
var size = overhead + inputSize * nbInputs + outputSize * nbOutputs;
var fee = this.feePerKb * (size * (1 + safetyMargin)) / 1000;
return parseInt((size * (1 + safetyMargin)).toFixed(0));
};
TxProposal.prototype.estimateFee = function() {
var size = this.getEstimatedSize();
var fee = this.feePerKb * size / 1000;
// Round up to nearest bit
this.fee = parseInt((Math.ceil(fee / 100) * 100).toFixed(0));

View File

@ -692,7 +692,7 @@ WalletService.prototype._totalizeUtxos = function(utxos) {
};
WalletService.prototype._computeKbToSendMax = function(utxos, amount, cb) {
WalletService.prototype._computeBytesToSendMax = function(utxos, cb) {
var self = this;
var unlockedUtxos = _.reject(utxos, 'locked');
@ -701,17 +701,16 @@ WalletService.prototype._computeKbToSendMax = function(utxos, amount, cb) {
self.getWallet({}, function(err, wallet) {
if (err) return cb(err);
var t = WalletUtils.newBitcoreTransaction();
try {
_.each(unlockedUtxos, function(i) {
t.from(i, i.publicKeys, wallet.m);
});
t.to(utxos[0].address, amount);
var sizeInKb = Math.ceil(t._estimateSize() / 1000);
return cb(null, sizeInKb);
} catch (ex) {
return cb(ex);
}
var txp = Model.TxProposal.create({
walletId: self.walletId,
requiredSignatures: wallet.m,
walletN: wallet.n,
});
txp.inputs = unlockedUtxos;
var size = txp.getEstimatedSize();
return cb(null, size);
});
};
@ -744,11 +743,11 @@ WalletService.prototype.getBalance = function(opts, cb) {
balance.byAddress = _.values(byAddress);
self._computeKbToSendMax(utxos, balance.availableAmount, function(err, sizeInKb) {
self._computeBytesToSendMax(utxos, function(err, sizeInBytes) {
if (err) {
log.error('Could not compute fees needed to transfer max amount', err);
}
balance.totalKbToSendMax = sizeInKb || 0;
balance.totalBytesToSendMax = sizeInBytes || 0;
return cb(null, balance);
});
});

View File

@ -1370,7 +1370,7 @@ describe('Wallet service', function() {
balance.totalAmount.should.equal(helpers.toSatoshi(6));
balance.lockedAmount.should.equal(0);
balance.availableAmount.should.equal(helpers.toSatoshi(6));
balance.totalKbToSendMax.should.equal(1);
balance.totalBytesToSendMax.should.equal(578);
balance.totalConfirmedAmount.should.equal(helpers.toSatoshi(4));
balance.lockedConfirmedAmount.should.equal(0);
@ -1396,7 +1396,7 @@ describe('Wallet service', function() {
balance.totalAmount.should.equal(0);
balance.lockedAmount.should.equal(0);
balance.availableAmount.should.equal(0);
balance.totalKbToSendMax.should.equal(0);
balance.totalBytesToSendMax.should.equal(0);
should.exist(balance.byAddress);
balance.byAddress.length.should.equal(0);
done();
@ -1412,7 +1412,7 @@ describe('Wallet service', function() {
balance.totalAmount.should.equal(0);
balance.lockedAmount.should.equal(0);
balance.availableAmount.should.equal(0);
balance.totalKbToSendMax.should.equal(0);
balance.totalBytesToSendMax.should.equal(0);
should.exist(balance.byAddress);
balance.byAddress.length.should.equal(0);
done();
@ -1440,7 +1440,7 @@ describe('Wallet service', function() {
should.exist(balance);
balance.totalAmount.should.equal(helpers.toSatoshi(9));
balance.lockedAmount.should.equal(0);
balance.totalKbToSendMax.should.equal(2);
balance.totalBytesToSendMax.should.equal(1535);
done();
});
});
@ -2093,18 +2093,21 @@ describe('Wallet service', function() {
balance.totalAmount.should.equal(helpers.toSatoshi(9));
balance.lockedAmount.should.equal(0);
balance.availableAmount.should.equal(helpers.toSatoshi(9));
balance.totalKbToSendMax.should.equal(3);
var max = (balance.totalAmount - balance.lockedAmount) - (balance.totalKbToSendMax * 10000);
balance.totalBytesToSendMax.should.equal(2896);
var sizeInKB = balance.totalBytesToSendMax / 1000;
var fee = parseInt((Math.ceil(sizeInKB * 10000 / 100) * 100).toFixed(0));
var max = balance.availableAmount - fee;
var txOpts = helpers.createSimpleProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', max / 1e8, null, TestData.copayers[0].privKey_1H_0);
server.createTx(txOpts, function(err, tx) {
should.not.exist(err);
should.exist(tx);
tx.amount.should.equal(max);
var estimatedFee = 2900 * 10000 / 1000; // estimated size = 2900 bytes
var estimatedFee = 2896 * 10000 / 1000;
tx.fee.should.be.within(0.9 * estimatedFee, 1.1 * estimatedFee);
server.getBalance({}, function(err, balance) {
should.not.exist(err);
balance.lockedAmount.should.equal(helpers.toSatoshi(9));
balance.availableAmount.should.equal(0);
done();
});
});
@ -2121,14 +2124,16 @@ describe('Wallet service', function() {
balance.totalAmount.should.equal(helpers.toSatoshi(9));
balance.lockedAmount.should.equal(helpers.toSatoshi(4));
balance.availableAmount.should.equal(helpers.toSatoshi(5));
balance.totalKbToSendMax.should.equal(2);
var max = (balance.totalAmount - balance.lockedAmount) - (balance.totalKbToSendMax * 2000);
balance.totalBytesToSendMax.should.equal(1653);
var sizeInKB = balance.totalBytesToSendMax / 1000;
var fee = parseInt((Math.ceil(sizeInKB * 2000 / 100) * 100).toFixed(0));
var max = balance.availableAmount - fee;
var txOpts = helpers.createSimpleProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', max / 1e8, null, TestData.copayers[0].privKey_1H_0, 2000);
server.createTx(txOpts, function(err, tx) {
should.not.exist(err);
should.exist(tx);
tx.amount.should.equal(max);
var estimatedFee = 1650 * 2000 / 1000; // estimated size = 1650 bytes
var estimatedFee = 1653 * 2000 / 1000;
tx.fee.should.be.within(0.9 * estimatedFee, 1.1 * estimatedFee);
server.getBalance({}, function(err, balance) {
should.not.exist(err);