refactor. coin/utxo.
This commit is contained in:
parent
c91cf7571b
commit
6c238c844f
@ -176,6 +176,28 @@ Coin.fromRaw = function fromRaw(data, enc) {
|
||||
return new Coin(Coin._fromRaw(data, enc));
|
||||
};
|
||||
|
||||
Coin.prototype.toUTXO = function toUTXO(enc) {
|
||||
var data = bcoin.protocol.framer.utxo(this);
|
||||
|
||||
if (enc === 'hex')
|
||||
data = utils.toHex(data);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
Coin._fromUTXO = function _fromUTXO(data, enc) {
|
||||
if (enc === 'hex')
|
||||
data = new Buffer(data, 'hex');
|
||||
|
||||
data = bcoin.protocol.parser.parseUTXO(data);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
Coin.fromUTXO = function fromUTXO(data, enc) {
|
||||
return new Coin(Coin._fromUTXO(data, enc));
|
||||
};
|
||||
|
||||
Coin.prototype.toExtended = function toExtended(enc) {
|
||||
var data = bcoin.protocol.framer.coin(this, true);
|
||||
|
||||
|
||||
@ -17,30 +17,27 @@ module.exports = function ldb(name, options) {
|
||||
: process.env.BCOIN_DB;
|
||||
|
||||
if (!db[file]) {
|
||||
if (options.db && typeof options.db !== 'string') {
|
||||
bcoin.ensurePrefix();
|
||||
backend = options.db;
|
||||
} else if (bcoin.isBrowser && backend !== 'memdown') {
|
||||
if (!options)
|
||||
options = {};
|
||||
|
||||
if (!backend || backend === 'leveldb')
|
||||
backend = 'leveldown';
|
||||
else if (backend === 'rocksdb')
|
||||
backend = 'rocksdown';
|
||||
else if (backend === 'lmdb')
|
||||
backend = 'lmdb';
|
||||
else if (backend === 'memory')
|
||||
backend = 'memdown';
|
||||
|
||||
if (bcoin.isBrowser && backend !== 'memdown') {
|
||||
backend = require('level-js');
|
||||
} else {
|
||||
if (!backend || backend === 'leveldb')
|
||||
backend = 'leveldown';
|
||||
else if (backend === 'rocksdb')
|
||||
backend = 'rocksdown';
|
||||
else if (backend === 'lmdb')
|
||||
backend = 'lmdb';
|
||||
else if (backend === 'memory')
|
||||
backend = 'memdown';
|
||||
|
||||
if (backend !== 'memdown')
|
||||
bcoin.ensurePrefix();
|
||||
|
||||
backend = require(backend);
|
||||
}
|
||||
|
||||
if (!options)
|
||||
options = {};
|
||||
|
||||
db[file] = new LowlevelUp(file, {
|
||||
keyEncoding: 'ascii',
|
||||
valueEncoding: 'binary',
|
||||
@ -100,12 +97,9 @@ function LowlevelUp(file, options) {
|
||||
this.db = this.db.db;
|
||||
|
||||
this.binding = this.db;
|
||||
this.hasBinding = false;
|
||||
|
||||
if (this.db.binding) {
|
||||
if (this.db.binding)
|
||||
this.binding = this.db.binding;
|
||||
this.hasBinding = true;
|
||||
}
|
||||
|
||||
this.binding.open(options, function(err) {
|
||||
if (err)
|
||||
@ -161,8 +155,6 @@ LowlevelUp.prototype.batch = function batch(ops, options, callback) {
|
||||
};
|
||||
|
||||
LowlevelUp.prototype.iterator = function iterator(options) {
|
||||
if (this.hasBinding)
|
||||
return new Iterator(this.binding, options);
|
||||
return this.db.iterator(options);
|
||||
};
|
||||
|
||||
@ -176,55 +168,3 @@ LowlevelUp.prototype.getProperty = function getProperty(name) {
|
||||
LowlevelUp.prototype.approximateSize = function approximateSize(start, end, callback) {
|
||||
return this.binding.approximateSize(start, end, callback);
|
||||
};
|
||||
|
||||
function Iterator(binding, options) {
|
||||
this.binding = binding.iterator(options);
|
||||
this.cache = null;
|
||||
this.finished = false;
|
||||
}
|
||||
|
||||
Iterator.prototype.seek = function (key) {
|
||||
if (typeof key !== 'string')
|
||||
throw new Error('seek requires a string key');
|
||||
if (this.cache)
|
||||
this.cache.length = 0;
|
||||
this.cache = null;
|
||||
this.binding.seek(key);
|
||||
};
|
||||
|
||||
Iterator.prototype.next = function next(callback) {
|
||||
var self = this;
|
||||
var key, value;
|
||||
|
||||
if (this.cache && this.cache.length) {
|
||||
key = this.cache.pop();
|
||||
value = this.cache.pop();
|
||||
|
||||
utils.nextTick(function() {
|
||||
callback(null, key, value);
|
||||
});
|
||||
} else if (this.finished) {
|
||||
utils.nextTick(function() {
|
||||
callback();
|
||||
});
|
||||
} else {
|
||||
this.binding.next(function(err, array, finished) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
self.cache = array;
|
||||
self.finished = finished;
|
||||
self.next(callback);
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Iterator.prototype.end = function end(callback) {
|
||||
if (this.cache)
|
||||
this.cache.length = 0;
|
||||
delete this.cache;
|
||||
this.binding.end(callback);
|
||||
delete this.binding;
|
||||
};
|
||||
|
||||
@ -100,7 +100,7 @@ Mempool.prototype.open = function open(callback) {
|
||||
return this.db.open(callback);
|
||||
};
|
||||
|
||||
Mempool.prototype.addBlock = function addBlock(block) {
|
||||
Mempool.prototype.addBlock = function addBlock(block, callback) {
|
||||
var self = this;
|
||||
callback = utils.ensure(callback);
|
||||
// Remove now-mined transactions
|
||||
@ -139,7 +139,7 @@ Mempool.prototype.getCoinsByAddress = function getCoinsByAddress(addresses, call
|
||||
};
|
||||
|
||||
Mempool.prototype.getByAddress =
|
||||
Mempool.prototype.getTXByAddress = function getTXByAddress(addresses) {
|
||||
Mempool.prototype.getTXByAddress = function getTXByAddress(addresses, callback) {
|
||||
return this.tx.getTXByAddress(addresses, callback);
|
||||
};
|
||||
|
||||
@ -253,9 +253,8 @@ Mempool.prototype.addUnchecked = function addUnchecked(tx, peer, callback) {
|
||||
|
||||
utils.forEachSerial(resolved, function(tx, next) {
|
||||
self.addUnchecked(tx, peer, function(err) {
|
||||
if (err) {
|
||||
if (err)
|
||||
self.emit('error', err);
|
||||
}
|
||||
next();
|
||||
}, true);
|
||||
}, callback);
|
||||
|
||||
@ -106,8 +106,7 @@ Framer.prototype.getBlocks = function getBlocks(hashes, stop) {
|
||||
return this.packet('getblocks', Framer.getBlocks(hashes, stop));
|
||||
};
|
||||
|
||||
Framer.prototype.utxo =
|
||||
Framer.prototype.coin = function _coin(coin) {
|
||||
Framer.prototype.utxo = function _coin(coin) {
|
||||
return this.packet('utxo', Framer.coin(coin, false));
|
||||
};
|
||||
|
||||
@ -319,8 +318,7 @@ Framer._getBlocks = function _getBlocks(hashes, stop, writer) {
|
||||
return p;
|
||||
};
|
||||
|
||||
Framer.utxo =
|
||||
Framer.coin = function _coin(coin, extended, writer) {
|
||||
Framer.utxo = function _utxo(coin, writer) {
|
||||
var p = new BufferWriter(writer);
|
||||
var height = coin.height;
|
||||
|
||||
@ -334,8 +332,28 @@ Framer.coin = function _coin(coin, extended, writer) {
|
||||
p.write64(coin.value);
|
||||
p.writeVarBytes(coin.script.encode());
|
||||
|
||||
if (!writer)
|
||||
p = p.render();
|
||||
|
||||
return p;
|
||||
};
|
||||
|
||||
Framer.coin = function _coin(coin, extended, writer) {
|
||||
var p = new BufferWriter(writer);
|
||||
var height = coin.height;
|
||||
|
||||
if (height === -1)
|
||||
height = 0x7fffffff;
|
||||
|
||||
assert(coin.value.byteLength() <= 8);
|
||||
|
||||
p.writeU32(coin.version);
|
||||
p.writeU32(height);
|
||||
p.write64(coin.value);
|
||||
p.writeVarBytes(coin.script.encode());
|
||||
p.writeU8(coin.coinbase ? 1 : 0);
|
||||
|
||||
if (extended) {
|
||||
p.writeU8(coin.coinbase ? 1 : 0);
|
||||
p.writeHash(coin.hash);
|
||||
p.writeU32(coin.index);
|
||||
}
|
||||
|
||||
@ -436,6 +436,29 @@ Parser.parseOutput = function parseOutput(p) {
|
||||
};
|
||||
};
|
||||
|
||||
Parser.parseUTXO = function parseUTXO(p) {
|
||||
var version, height, value, script, hash, index, coinbase;
|
||||
|
||||
p = new BufferReader(p);
|
||||
p.start();
|
||||
|
||||
version = p.readU32();
|
||||
height = p.readU32();
|
||||
value = p.read64();
|
||||
script = new bcoin.script(p.readVarBytes());
|
||||
|
||||
if (height === 0x7fffffff)
|
||||
height = -1;
|
||||
|
||||
return {
|
||||
version: version,
|
||||
height: height,
|
||||
value: value,
|
||||
script: script,
|
||||
_size: p.end()
|
||||
};
|
||||
};
|
||||
|
||||
Parser.parseCoin = function parseCoin(p, extended) {
|
||||
var version, height, value, script, hash, index, coinbase;
|
||||
|
||||
@ -444,32 +467,26 @@ Parser.parseCoin = function parseCoin(p, extended) {
|
||||
|
||||
version = p.readU32();
|
||||
height = p.readU32();
|
||||
value = p.read64();
|
||||
script = new bcoin.script(p.readVarBytes());
|
||||
coinbase = p.readU8() === 1;
|
||||
|
||||
if (extended) {
|
||||
hash = p.readHash();
|
||||
index = p.readU32();
|
||||
}
|
||||
|
||||
if (height === 0x7fffffff)
|
||||
height = -1;
|
||||
|
||||
value = p.read64();
|
||||
|
||||
script = new bcoin.script(p.readVarBytes());
|
||||
|
||||
if (extended) {
|
||||
coinbase = p.readU8() === 1;
|
||||
hash = p.readHash();
|
||||
index = p.readU32();
|
||||
} else {
|
||||
coinbase = false;
|
||||
hash = utils.slice(constants.zeroHash);
|
||||
index = 0xffffffff;
|
||||
}
|
||||
|
||||
return {
|
||||
version: version,
|
||||
height: height,
|
||||
value: value,
|
||||
script: script,
|
||||
coinbase: coinbase,
|
||||
hash: hash,
|
||||
index: index,
|
||||
coinbase: coinbase,
|
||||
_size: p.end()
|
||||
};
|
||||
};
|
||||
|
||||
@ -327,7 +327,7 @@ TXPool.prototype._add = function add(tx, map, callback, force) {
|
||||
utils.forEachSerial(tx.inputs, function(input, next, i) {
|
||||
var key;
|
||||
|
||||
if (input.isCoinbase())
|
||||
if (tx.isCoinbase())
|
||||
return next();
|
||||
|
||||
key = input.prevout.hash + '/' + input.prevout.index;
|
||||
@ -344,9 +344,6 @@ TXPool.prototype._add = function add(tx, map, callback, force) {
|
||||
// Add TX to inputs and spend money
|
||||
input.output = coin;
|
||||
|
||||
assert(input.prevout.hash === coin.hash);
|
||||
assert(input.prevout.index === coin.index);
|
||||
|
||||
// Skip invalid transactions
|
||||
if (self.options.verify) {
|
||||
if (!tx.verify(i))
|
||||
@ -487,7 +484,7 @@ TXPool.prototype._add = function add(tx, map, callback, force) {
|
||||
});
|
||||
}
|
||||
|
||||
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toExtended());
|
||||
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toRaw());
|
||||
updated = true;
|
||||
}
|
||||
|
||||
@ -640,7 +637,7 @@ TXPool.prototype._confirm = function _confirm(tx, map, callback, force) {
|
||||
|
||||
coin.height = tx.height;
|
||||
|
||||
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toExtended());
|
||||
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toRaw());
|
||||
|
||||
next();
|
||||
});
|
||||
@ -768,7 +765,7 @@ TXPool.prototype._remove = function remove(tx, map, callback, force) {
|
||||
tx.inputs.forEach(function(input) {
|
||||
var address = input.getAddress();
|
||||
|
||||
if (input.isCoinbase())
|
||||
if (tx.isCoinbase())
|
||||
return;
|
||||
|
||||
if (!input.output)
|
||||
@ -791,7 +788,7 @@ TXPool.prototype._remove = function remove(tx, map, callback, force) {
|
||||
batch.put(prefix + 'u/t/'
|
||||
+ input.prevout.hash
|
||||
+ '/' + input.prevout.index,
|
||||
input.output.toExtended());
|
||||
input.output.toRaw());
|
||||
|
||||
if (self.options.indexSpent) {
|
||||
batch.del(prefix + 's/t/'
|
||||
@ -920,7 +917,7 @@ TXPool.prototype._unconfirm = function unconfirm(tx, map, callback, force) {
|
||||
|
||||
coin.height = tx.height;
|
||||
|
||||
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toExtended());
|
||||
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toRaw());
|
||||
|
||||
next();
|
||||
});
|
||||
@ -1494,7 +1491,7 @@ TXPool.prototype.getCoin = function getCoin(hash, index, callback) {
|
||||
return callback();
|
||||
|
||||
try {
|
||||
coin = bcoin.coin.fromExtended(coin);
|
||||
coin = bcoin.coin.fromRaw(coin);
|
||||
coin.hash = hash;
|
||||
coin.index = index;
|
||||
} catch (e) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user