txdb: add coin locking system.
This commit is contained in:
parent
77502ca496
commit
e235f3bee6
@ -255,6 +255,7 @@ function TXDB(wallet) {
|
||||
this.logger = wallet.db.logger;
|
||||
this.network = wallet.db.network;
|
||||
this.options = wallet.db.options;
|
||||
this.locked = {};
|
||||
|
||||
this.locker = new bcoin.locker(this);
|
||||
this.coinCache = new bcoin.lru(10000, 1);
|
||||
@ -808,6 +809,9 @@ TXDB.prototype.add = function add(tx, info, callback) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
// Clear any locked coins to free up memory.
|
||||
self.unlockTX(tx);
|
||||
|
||||
self.emit('tx', tx, info);
|
||||
|
||||
if (tx.ts !== 0)
|
||||
@ -1000,6 +1004,9 @@ TXDB.prototype._confirm = function _confirm(tx, info, callback) {
|
||||
// and remove pending flag to mark as confirmed.
|
||||
assert(tx.height >= 0);
|
||||
|
||||
// Clear any locked coins to free up memory.
|
||||
self.unlockTX(tx);
|
||||
|
||||
// Save the original received time.
|
||||
tx.ps = existing.ps;
|
||||
|
||||
@ -1308,6 +1315,90 @@ TXDB.prototype._unconfirm = function unconfirm(tx, info, callback, force) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Lock all coins in a transaction.
|
||||
* @param {TX} tx
|
||||
*/
|
||||
|
||||
TXDB.prototype.lockTX = function lockTX(tx) {
|
||||
var i, input;
|
||||
|
||||
if (tx.isCoinbase())
|
||||
return;
|
||||
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
this.lockCoin(input.prevout);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Unlock all coins in a transaction.
|
||||
* @param {TX} tx
|
||||
*/
|
||||
|
||||
TXDB.prototype.unlockTX = function unlockTX(tx) {
|
||||
var i, input;
|
||||
|
||||
if (tx.isCoinbase())
|
||||
return;
|
||||
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
this.unlockCoin(input.prevout);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Lock a single coin.
|
||||
* @param {Coin|Outpoint} coin
|
||||
*/
|
||||
|
||||
TXDB.prototype.lockCoin = function lockCoin(coin) {
|
||||
var key = coin.hash + coin.index;
|
||||
this.locked[key] = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unlock a single coin.
|
||||
* @param {Coin|Outpoint} coin
|
||||
*/
|
||||
|
||||
TXDB.prototype.unlockCoin = function unlockCoin(coin) {
|
||||
var key = coin.hash + coin.index;
|
||||
delete this.locked[key];
|
||||
};
|
||||
|
||||
/**
|
||||
* Test locked status of a single coin.
|
||||
* @param {Coin|Outpoint} coin
|
||||
*/
|
||||
|
||||
TXDB.prototype.isLocked = function isLocked(coin) {
|
||||
var key = coin.hash + coin.index;
|
||||
return this.locked[key] === true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Filter array of coins or outpoints
|
||||
* for only unlocked ones.
|
||||
* @param {Coin[]|Outpoint[]}
|
||||
* @returns {Array}
|
||||
*/
|
||||
|
||||
TXDB.prototype.filterLocked = function filterLocked(coins) {
|
||||
var out = [];
|
||||
var i, coin;
|
||||
|
||||
for (i = 0; i < coins.length; i++) {
|
||||
coin = coins[i];
|
||||
if (!this.isLocked(coin))
|
||||
out.push(coins);
|
||||
}
|
||||
|
||||
return coins;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get hashes of all transactions in the database.
|
||||
* @param {Number?} account
|
||||
|
||||
@ -815,6 +815,9 @@ Wallet.prototype.fund = function fund(tx, options, callback, force) {
|
||||
rate = self.network.getRate();
|
||||
}
|
||||
|
||||
// Don't use any locked coins.
|
||||
coins = self.tx.filterLocked(coins);
|
||||
|
||||
try {
|
||||
tx.fund(coins, {
|
||||
selection: options.selection || 'age',
|
||||
@ -2053,8 +2056,6 @@ function Account(db, options) {
|
||||
if (!(this instanceof Account))
|
||||
return new Account(db, options);
|
||||
|
||||
EventEmitter.call(this);
|
||||
|
||||
assert(db, 'Database is required.');
|
||||
|
||||
this.db = db;
|
||||
@ -2082,8 +2083,6 @@ function Account(db, options) {
|
||||
this.fromOptions(options);
|
||||
}
|
||||
|
||||
utils.inherits(Account, EventEmitter);
|
||||
|
||||
/**
|
||||
* Inject properties from options object.
|
||||
* @private
|
||||
|
||||
Loading…
Reference in New Issue
Block a user