refactor. coin/utxo.

This commit is contained in:
Christopher Jeffrey 2016-03-25 13:00:11 -07:00
parent c91cf7571b
commit 6c238c844f
6 changed files with 101 additions and 108 deletions

View File

@ -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);

View File

@ -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;
};

View File

@ -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);

View File

@ -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);
}

View File

@ -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()
};
};

View File

@ -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) {