Merge pull request #326 from isocolsky/fee_level_def

Redefine fee levels
This commit is contained in:
Matias Alejo Garcia 2015-08-14 10:29:32 -03:00
commit 3bcabaf9e4
2 changed files with 50 additions and 35 deletions

View File

@ -53,20 +53,35 @@ function WalletService() {
// Time after which a Tx proposal can be erased by any copayer. in seconds
WalletService.deleteLockTime = 24 * 3600;
WalletService.DELETE_LOCKTIME = 24 * 3600;
// Allowed consecutive txp rejections before backoff is applied.
WalletService.backoffOffset = 3;
WalletService.BACKOFF_OFFSET = 3;
// Time a copayer need to wait to create a new TX after her tx previous proposal we rejected. (incremental). in Minutes.
WalletService.backoffTimeMinutes = 2;
WalletService.BACKOFF_TIME = 2;
// Fund scanning parameters
WalletService.scanConfig = {
SCAN_WINDOW: 20,
DERIVATION_DELAY: 10, // in milliseconds
WalletService.SCAN_CONFIG = {
scanWindow: 20,
derivationDelay: 10, // in milliseconds
};
WalletService.FEE_LEVELS = [{
name: 'priority',
nbBlocks: 1,
defaultValue: 50000
}, {
name: 'normal',
nbBlocks: 2,
defaultValue: 20000
}, {
name: 'economy',
nbBlocks: 6,
defaultValue: 10000
}];
/**
* Initializes global settings for all instances.
* @param {Object} opts
@ -810,7 +825,7 @@ WalletService.prototype.getFeeLevels = function(opts, cb) {
if (network != 'livenet' && network != 'testnet')
return cb(new ClientError('Invalid network'));
var levels = WalletUtils.FEE_LEVELS;
var levels = WalletService.FEE_LEVELS;
var samplePoints = _.uniq(_.pluck(levels, 'nbBlocks'));
self._sampleFeeLevels(network, samplePoints, function(err, feeSamples) {
var values = _.map(levels, function(level) {
@ -924,7 +939,7 @@ WalletService.prototype._selectTxInputs = function(txp, cb) {
WalletService.prototype._canCreateTx = function(copayerId, cb) {
var self = this;
self.storage.fetchLastTxs(self.walletId, copayerId, 5 + WalletService.backoffOffset, function(err, txs) {
self.storage.fetchLastTxs(self.walletId, copayerId, 5 + WalletService.BACKOFF_OFFSET, function(err, txs) {
if (err) return cb(err);
if (!txs.length)
@ -934,7 +949,7 @@ WalletService.prototype._canCreateTx = function(copayerId, cb) {
status: 'rejected'
});
var exceededRejections = lastRejections.length - WalletService.backoffOffset;
var exceededRejections = lastRejections.length - WalletService.BACKOFF_OFFSET;
if (exceededRejections <= 0)
return cb(null, true);
@ -942,7 +957,7 @@ WalletService.prototype._canCreateTx = function(copayerId, cb) {
var lastTxTs = txs[0].createdOn;
var now = Math.floor(Date.now() / 1000);
var timeSinceLastRejection = now - lastTxTs;
var backoffTime = 60 * Math.pow(WalletService.backoffTimeMinutes, exceededRejections);
var backoffTime = 60 * Math.pow(WalletService.BACKOFF_TIME, exceededRejections);
if (timeSinceLastRejection <= backoffTime)
log.debug('Not allowing to create TX: timeSinceLastRejection/backoffTime', timeSinceLastRejection, backoffTime);
@ -1132,7 +1147,7 @@ WalletService.prototype.removeWallet = function(opts, cb) {
WalletService.prototype.getRemainingDeleteLockTime = function(txp) {
var now = Math.floor(Date.now() / 1000);
var lockTimeRemaining = txp.createdOn + WalletService.deleteLockTime - now;
var lockTimeRemaining = txp.createdOn + WalletService.DELETE_LOCKTIME - now;
if (lockTimeRemaining < 0)
return 0;
@ -1663,7 +1678,7 @@ WalletService.prototype.scan = function(opts, cb) {
async.mapSeries(_.range(size), function(i, next) {
setTimeout(function() {
next(null, derivator.derive());
}, WalletService.scanConfig.DERIVATION_DELAY)
}, WalletService.SCAN_CONFIG.derivationDelay)
}, cb);
};
@ -1679,7 +1694,7 @@ WalletService.prototype.scan = function(opts, cb) {
async.whilst(function() {
return activity;
}, function(next) {
deriveAddresses(WalletService.scanConfig.SCAN_WINDOW, derivator, function(err, addresses) {
deriveAddresses(WalletService.SCAN_CONFIG.scanWindow, derivator, function(err, addresses) {
if (err) return next(err);
networkName = networkName || Bitcore.Address(addresses[0].address).toObject().network;
checkActivity(_.pluck(addresses, 'address'), networkName, function(err, thereIsActivity) {
@ -1689,7 +1704,7 @@ WalletService.prototype.scan = function(opts, cb) {
if (thereIsActivity) {
allAddresses.push(addresses);
} else {
derivator.rewind(WalletService.scanConfig.SCAN_WINDOW);
derivator.rewind(WalletService.SCAN_CONFIG.scanWindow);
}
next();
});

View File

@ -1523,8 +1523,8 @@ describe('Wallet service', function() {
it('should get current fee levels', function(done) {
helpers.stubFeeLevels({
1: 40000,
4: 20000,
12: 18000,
2: 20000,
6: 18000,
});
server.getFeeLevels({}, function(err, fees) {
should.not.exist(err);
@ -1535,10 +1535,10 @@ describe('Wallet service', function() {
fees.priority.nbBlocks.should.equal(1);
fees.normal.feePerKB.should.equal(20000);
fees.normal.nbBlocks.should.equal(4);
fees.normal.nbBlocks.should.equal(2);
fees.economy.feePerKB.should.equal(18000);
fees.economy.nbBlocks.should.equal(12);
fees.economy.nbBlocks.should.equal(6);
done();
});
});
@ -1558,8 +1558,8 @@ describe('Wallet service', function() {
it('should get default fees if network cannot estimate (returns -1)', function(done) {
helpers.stubFeeLevels({
1: -1,
4: 18000,
12: 0,
2: 18000,
6: 0,
});
server.getFeeLevels({}, function(err, fees) {
should.not.exist(err);
@ -1570,10 +1570,10 @@ describe('Wallet service', function() {
should.not.exist(fees.priority.nbBlocks);
fees.normal.feePerKB.should.equal(18000);
fees.normal.nbBlocks.should.equal(4);
fees.normal.nbBlocks.should.equal(2);
fees.economy.feePerKB.should.equal(0);
fees.economy.nbBlocks.should.equal(12);
fees.economy.nbBlocks.should.equal(6);
done();
});
});
@ -2247,7 +2247,7 @@ describe('Wallet service', function() {
});
},
function(next) {
var clock = sinon.useFakeTimers(Date.now() + (WalletService.backoffTimeMinutes + 2) * 60 * 1000, 'Date');
var clock = sinon.useFakeTimers(Date.now() + (WalletService.BACKOFF_TIME + 2) * 60 * 1000, 'Date');
var txOpts = helpers.createSimpleProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 1, null, TestData.copayers[0].privKey_1H_0);
server.createTx(txOpts, function(err, tx) {
clock.restore();
@ -2259,7 +2259,7 @@ describe('Wallet service', function() {
},
function(next) {
// Do not allow a 5th tx before backoff time
var clock = sinon.useFakeTimers(Date.now() + (WalletService.backoffTimeMinutes + 2) * 60 * 1000 + 1, 'Date');
var clock = sinon.useFakeTimers(Date.now() + (WalletService.BACKOFF_TIME + 2) * 60 * 1000 + 1, 'Date');
var txOpts = helpers.createSimpleProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 1, null, TestData.copayers[0].privKey_1H_0);
server.createTx(txOpts, function(err, tx) {
clock.restore();
@ -3514,7 +3514,7 @@ describe('Wallet service', function() {
server.getPendingTxs({}, function(err, txs) {
should.not.exist(err);
txs[0].deleteLockTime.should.be.above(WalletService.deleteLockTime - 10);
txs[0].deleteLockTime.should.be.above(WalletService.DELETE_LOCKTIME - 10);
var clock = sinon.useFakeTimers(Date.now() + 1 + 24 * 3600 * 1000, 'Date');
server.removePendingTx({
@ -3539,7 +3539,7 @@ describe('Wallet service', function() {
}, function(err) {
should.not.exist(err);
var clock = sinon.useFakeTimers(Date.now() + 2000 + WalletService.deleteLockTime * 1000, 'Date');
var clock = sinon.useFakeTimers(Date.now() + 2000 + WalletService.DELETE_LOCKTIME * 1000, 'Date');
server2.removePendingTx({
txProposalId: txp.id
}, function(err) {
@ -3856,11 +3856,11 @@ describe('Wallet service', function() {
describe('#scan', function() {
var server, wallet;
var scanConfigOld = WalletService.scanConfig;
var scanConfigOld = WalletService.SCAN_CONFIG;
beforeEach(function(done) {
this.timeout(5000);
WalletService.scanConfig.SCAN_WINDOW = 2;
WalletService.scanConfig.DERIVATION_DELAY = 0;
WalletService.SCAN_CONFIG.scanWindow = 2;
WalletService.SCAN_CONFIG.derivationDelay = 0;
helpers.createAndJoinWallet(1, 2, function(s, w) {
server = s;
@ -3869,7 +3869,7 @@ describe('Wallet service', function() {
});
});
afterEach(function() {
WalletService.scanConfig = scanConfigOld;
WalletService.SCAN_CONFIG = scanConfigOld;
});
it('should scan main addresses', function(done) {
@ -3999,11 +3999,11 @@ describe('Wallet service', function() {
describe('#startScan', function() {
var server, wallet;
var scanConfigOld = WalletService.scanConfig;
var scanConfigOld = WalletService.SCAN_CONFIG;
beforeEach(function(done) {
this.timeout(5000);
WalletService.scanConfig.SCAN_WINDOW = 2;
WalletService.scanConfig.DERIVATION_DELAY = 0;
WalletService.SCAN_CONFIG.scanWindow = 2;
WalletService.SCAN_CONFIG.derivationDelay = 0;
helpers.createAndJoinWallet(1, 2, function(s, w) {
server = s;
@ -4012,7 +4012,7 @@ describe('Wallet service', function() {
});
});
afterEach(function() {
WalletService.scanConfig = scanConfigOld;
WalletService.SCAN_CONFIG = scanConfigOld;
server.messageBroker.removeAllListeners();
});
@ -4072,7 +4072,7 @@ describe('Wallet service', function() {
});
it('should start multiple asynchronous scans for different wallets', function(done) {
helpers.stubAddressActivity(['3K2VWMXheGZ4qG35DyGjA2dLeKfaSr534A']);
WalletService.scanConfig.SCAN_WINDOW = 1;
WalletService.SCAN_CONFIG.scanWindow = 1;
var scans = 0;
server.messageBroker.onMessage(function(n) {