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));
|
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) {
|
Coin.prototype.toExtended = function toExtended(enc) {
|
||||||
var data = bcoin.protocol.framer.coin(this, true);
|
var data = bcoin.protocol.framer.coin(this, true);
|
||||||
|
|
||||||
|
|||||||
@ -17,30 +17,27 @@ module.exports = function ldb(name, options) {
|
|||||||
: process.env.BCOIN_DB;
|
: process.env.BCOIN_DB;
|
||||||
|
|
||||||
if (!db[file]) {
|
if (!db[file]) {
|
||||||
if (options.db && typeof options.db !== 'string') {
|
if (!options)
|
||||||
bcoin.ensurePrefix();
|
options = {};
|
||||||
backend = options.db;
|
|
||||||
} else if (bcoin.isBrowser && backend !== 'memdown') {
|
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');
|
backend = require('level-js');
|
||||||
} else {
|
} 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')
|
if (backend !== 'memdown')
|
||||||
bcoin.ensurePrefix();
|
bcoin.ensurePrefix();
|
||||||
|
|
||||||
backend = require(backend);
|
backend = require(backend);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options)
|
|
||||||
options = {};
|
|
||||||
|
|
||||||
db[file] = new LowlevelUp(file, {
|
db[file] = new LowlevelUp(file, {
|
||||||
keyEncoding: 'ascii',
|
keyEncoding: 'ascii',
|
||||||
valueEncoding: 'binary',
|
valueEncoding: 'binary',
|
||||||
@ -100,12 +97,9 @@ function LowlevelUp(file, options) {
|
|||||||
this.db = this.db.db;
|
this.db = this.db.db;
|
||||||
|
|
||||||
this.binding = this.db;
|
this.binding = this.db;
|
||||||
this.hasBinding = false;
|
|
||||||
|
|
||||||
if (this.db.binding) {
|
if (this.db.binding)
|
||||||
this.binding = this.db.binding;
|
this.binding = this.db.binding;
|
||||||
this.hasBinding = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.binding.open(options, function(err) {
|
this.binding.open(options, function(err) {
|
||||||
if (err)
|
if (err)
|
||||||
@ -161,8 +155,6 @@ LowlevelUp.prototype.batch = function batch(ops, options, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
LowlevelUp.prototype.iterator = function iterator(options) {
|
LowlevelUp.prototype.iterator = function iterator(options) {
|
||||||
if (this.hasBinding)
|
|
||||||
return new Iterator(this.binding, options);
|
|
||||||
return this.db.iterator(options);
|
return this.db.iterator(options);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -176,55 +168,3 @@ LowlevelUp.prototype.getProperty = function getProperty(name) {
|
|||||||
LowlevelUp.prototype.approximateSize = function approximateSize(start, end, callback) {
|
LowlevelUp.prototype.approximateSize = function approximateSize(start, end, callback) {
|
||||||
return this.binding.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);
|
return this.db.open(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Mempool.prototype.addBlock = function addBlock(block) {
|
Mempool.prototype.addBlock = function addBlock(block, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
callback = utils.ensure(callback);
|
callback = utils.ensure(callback);
|
||||||
// Remove now-mined transactions
|
// Remove now-mined transactions
|
||||||
@ -139,7 +139,7 @@ Mempool.prototype.getCoinsByAddress = function getCoinsByAddress(addresses, call
|
|||||||
};
|
};
|
||||||
|
|
||||||
Mempool.prototype.getByAddress =
|
Mempool.prototype.getByAddress =
|
||||||
Mempool.prototype.getTXByAddress = function getTXByAddress(addresses) {
|
Mempool.prototype.getTXByAddress = function getTXByAddress(addresses, callback) {
|
||||||
return this.tx.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) {
|
utils.forEachSerial(resolved, function(tx, next) {
|
||||||
self.addUnchecked(tx, peer, function(err) {
|
self.addUnchecked(tx, peer, function(err) {
|
||||||
if (err) {
|
if (err)
|
||||||
self.emit('error', err);
|
self.emit('error', err);
|
||||||
}
|
|
||||||
next();
|
next();
|
||||||
}, true);
|
}, true);
|
||||||
}, callback);
|
}, callback);
|
||||||
|
|||||||
@ -106,8 +106,7 @@ Framer.prototype.getBlocks = function getBlocks(hashes, stop) {
|
|||||||
return this.packet('getblocks', Framer.getBlocks(hashes, stop));
|
return this.packet('getblocks', Framer.getBlocks(hashes, stop));
|
||||||
};
|
};
|
||||||
|
|
||||||
Framer.prototype.utxo =
|
Framer.prototype.utxo = function _coin(coin) {
|
||||||
Framer.prototype.coin = function _coin(coin) {
|
|
||||||
return this.packet('utxo', Framer.coin(coin, false));
|
return this.packet('utxo', Framer.coin(coin, false));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -319,8 +318,7 @@ Framer._getBlocks = function _getBlocks(hashes, stop, writer) {
|
|||||||
return p;
|
return p;
|
||||||
};
|
};
|
||||||
|
|
||||||
Framer.utxo =
|
Framer.utxo = function _utxo(coin, writer) {
|
||||||
Framer.coin = function _coin(coin, extended, writer) {
|
|
||||||
var p = new BufferWriter(writer);
|
var p = new BufferWriter(writer);
|
||||||
var height = coin.height;
|
var height = coin.height;
|
||||||
|
|
||||||
@ -334,8 +332,28 @@ Framer.coin = function _coin(coin, extended, writer) {
|
|||||||
p.write64(coin.value);
|
p.write64(coin.value);
|
||||||
p.writeVarBytes(coin.script.encode());
|
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) {
|
if (extended) {
|
||||||
p.writeU8(coin.coinbase ? 1 : 0);
|
|
||||||
p.writeHash(coin.hash);
|
p.writeHash(coin.hash);
|
||||||
p.writeU32(coin.index);
|
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) {
|
Parser.parseCoin = function parseCoin(p, extended) {
|
||||||
var version, height, value, script, hash, index, coinbase;
|
var version, height, value, script, hash, index, coinbase;
|
||||||
|
|
||||||
@ -444,32 +467,26 @@ Parser.parseCoin = function parseCoin(p, extended) {
|
|||||||
|
|
||||||
version = p.readU32();
|
version = p.readU32();
|
||||||
height = 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)
|
if (height === 0x7fffffff)
|
||||||
height = -1;
|
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 {
|
return {
|
||||||
version: version,
|
version: version,
|
||||||
height: height,
|
height: height,
|
||||||
value: value,
|
value: value,
|
||||||
script: script,
|
script: script,
|
||||||
|
coinbase: coinbase,
|
||||||
hash: hash,
|
hash: hash,
|
||||||
index: index,
|
index: index,
|
||||||
coinbase: coinbase,
|
|
||||||
_size: p.end()
|
_size: p.end()
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -327,7 +327,7 @@ TXPool.prototype._add = function add(tx, map, callback, force) {
|
|||||||
utils.forEachSerial(tx.inputs, function(input, next, i) {
|
utils.forEachSerial(tx.inputs, function(input, next, i) {
|
||||||
var key;
|
var key;
|
||||||
|
|
||||||
if (input.isCoinbase())
|
if (tx.isCoinbase())
|
||||||
return next();
|
return next();
|
||||||
|
|
||||||
key = input.prevout.hash + '/' + input.prevout.index;
|
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
|
// Add TX to inputs and spend money
|
||||||
input.output = coin;
|
input.output = coin;
|
||||||
|
|
||||||
assert(input.prevout.hash === coin.hash);
|
|
||||||
assert(input.prevout.index === coin.index);
|
|
||||||
|
|
||||||
// Skip invalid transactions
|
// Skip invalid transactions
|
||||||
if (self.options.verify) {
|
if (self.options.verify) {
|
||||||
if (!tx.verify(i))
|
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;
|
updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -640,7 +637,7 @@ TXPool.prototype._confirm = function _confirm(tx, map, callback, force) {
|
|||||||
|
|
||||||
coin.height = tx.height;
|
coin.height = tx.height;
|
||||||
|
|
||||||
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toExtended());
|
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toRaw());
|
||||||
|
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
@ -768,7 +765,7 @@ TXPool.prototype._remove = function remove(tx, map, callback, force) {
|
|||||||
tx.inputs.forEach(function(input) {
|
tx.inputs.forEach(function(input) {
|
||||||
var address = input.getAddress();
|
var address = input.getAddress();
|
||||||
|
|
||||||
if (input.isCoinbase())
|
if (tx.isCoinbase())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!input.output)
|
if (!input.output)
|
||||||
@ -791,7 +788,7 @@ TXPool.prototype._remove = function remove(tx, map, callback, force) {
|
|||||||
batch.put(prefix + 'u/t/'
|
batch.put(prefix + 'u/t/'
|
||||||
+ input.prevout.hash
|
+ input.prevout.hash
|
||||||
+ '/' + input.prevout.index,
|
+ '/' + input.prevout.index,
|
||||||
input.output.toExtended());
|
input.output.toRaw());
|
||||||
|
|
||||||
if (self.options.indexSpent) {
|
if (self.options.indexSpent) {
|
||||||
batch.del(prefix + 's/t/'
|
batch.del(prefix + 's/t/'
|
||||||
@ -920,7 +917,7 @@ TXPool.prototype._unconfirm = function unconfirm(tx, map, callback, force) {
|
|||||||
|
|
||||||
coin.height = tx.height;
|
coin.height = tx.height;
|
||||||
|
|
||||||
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toExtended());
|
batch.put(prefix + 'u/t/' + hash + '/' + i, coin.toRaw());
|
||||||
|
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
@ -1494,7 +1491,7 @@ TXPool.prototype.getCoin = function getCoin(hash, index, callback) {
|
|||||||
return callback();
|
return callback();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
coin = bcoin.coin.fromExtended(coin);
|
coin = bcoin.coin.fromRaw(coin);
|
||||||
coin.hash = hash;
|
coin.hash = hash;
|
||||||
coin.index = index;
|
coin.index = index;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user