remove old pool methods. readme.
This commit is contained in:
parent
3154a1c914
commit
3c4d4c2724
284
README.md
284
README.md
@ -31,6 +31,177 @@ Read the docs here: http://bcoin.io/docs/
|
|||||||
|
|
||||||
## Example Usage
|
## Example Usage
|
||||||
|
|
||||||
|
### Creating a blockchain and mempool
|
||||||
|
|
||||||
|
``` js
|
||||||
|
var bcoin = require('bcoin').set('regtest');
|
||||||
|
var chain = new bcoin.chain({ db: 'memory' });
|
||||||
|
var mempool = new bcoin.mempool({ chain: chain, db: 'memory' });
|
||||||
|
var miner = new bcoin.miner({ chain: chain, mempool: mempool });
|
||||||
|
|
||||||
|
// Create a block "attempt"
|
||||||
|
miner.open(function(err) {
|
||||||
|
if (err)
|
||||||
|
throw err;
|
||||||
|
|
||||||
|
miner.createBlock(function(err, attempt) {
|
||||||
|
if (err)
|
||||||
|
throw err;
|
||||||
|
|
||||||
|
// Mine the block on the worker pool (use mine() for the master process)
|
||||||
|
attempt.mineAsync(function(err, block) {
|
||||||
|
if (err)
|
||||||
|
throw err;
|
||||||
|
|
||||||
|
// Add the block to the chain
|
||||||
|
chain.add(block, function(err) {
|
||||||
|
if (err)
|
||||||
|
throw err;
|
||||||
|
|
||||||
|
console.log('Added %s to the blockchain.', block.rhash);
|
||||||
|
console.log(block);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Connecting to the P2P network
|
||||||
|
|
||||||
|
``` js
|
||||||
|
var bcoin = require('bcoin').set('main');
|
||||||
|
|
||||||
|
var chain = new bcoin.chain({ db: 'leveldb' });
|
||||||
|
var mempool = new bcoin.mempool({ chain: chain, db: 'memory' });
|
||||||
|
var pool = new bcoin.pool({ chain: chain, mempool: mempool, size: 8 });
|
||||||
|
|
||||||
|
pool.open(function(err) {
|
||||||
|
if (err)
|
||||||
|
throw err;
|
||||||
|
|
||||||
|
// Connect, start retrieving and relaying txs
|
||||||
|
pool.connect();
|
||||||
|
|
||||||
|
// Start the blockchain sync.
|
||||||
|
pool.startSync();
|
||||||
|
|
||||||
|
chain.on('block', function(block) {
|
||||||
|
console.log('Added block:');
|
||||||
|
console.log(block);
|
||||||
|
});
|
||||||
|
|
||||||
|
mempool.on('tx', function(tx) {
|
||||||
|
console.log('Added tx to mempool:');
|
||||||
|
console.log(tx);
|
||||||
|
});
|
||||||
|
|
||||||
|
pool.on('tx', function(tx) {
|
||||||
|
console.log('Saw transaction:');
|
||||||
|
console.log(tx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start up a segnet4 sync while
|
||||||
|
// we're at it (because we can).
|
||||||
|
|
||||||
|
var tchain = new bcoin.chain({
|
||||||
|
network: 'segnet4',
|
||||||
|
db: 'memory'
|
||||||
|
});
|
||||||
|
|
||||||
|
var tmempool = new bcoin.mempool({
|
||||||
|
network: 'segnet4',
|
||||||
|
chain: tchain,
|
||||||
|
db: 'memory'
|
||||||
|
});
|
||||||
|
|
||||||
|
var tpool = new bcoin.pool({
|
||||||
|
network: 'segnet4',
|
||||||
|
chain: tchain,
|
||||||
|
mempool: tmempool,
|
||||||
|
size: 8
|
||||||
|
});
|
||||||
|
|
||||||
|
tpool.open(function(err) {
|
||||||
|
if (err)
|
||||||
|
throw err;
|
||||||
|
|
||||||
|
// Connect, start retrieving and relaying txs
|
||||||
|
tpool.connect();
|
||||||
|
|
||||||
|
// Start the blockchain sync.
|
||||||
|
tpool.startSync();
|
||||||
|
|
||||||
|
tchain.on('block', function(block) {
|
||||||
|
console.log('Added segnet4 block:');
|
||||||
|
console.log(block);
|
||||||
|
});
|
||||||
|
|
||||||
|
tmempool.on('tx', function(tx) {
|
||||||
|
console.log('Added segnet4 tx to mempool:');
|
||||||
|
console.log(tx);
|
||||||
|
});
|
||||||
|
|
||||||
|
tpool.on('tx', function(tx) {
|
||||||
|
console.log('Saw segnet4 transaction:');
|
||||||
|
console.log(tx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Doing an SPV sync
|
||||||
|
|
||||||
|
``` js
|
||||||
|
var bcoin = require('bcoin').set('testnet');
|
||||||
|
|
||||||
|
var chain = new bcoin.chain({
|
||||||
|
db: 'leveldb',
|
||||||
|
// A custom chaindb location:
|
||||||
|
location: process.env.HOME + '/chain.db',
|
||||||
|
spv: true
|
||||||
|
});
|
||||||
|
|
||||||
|
var pool = new bcoin.pool({
|
||||||
|
chain: chain,
|
||||||
|
spv: true,
|
||||||
|
size: 8
|
||||||
|
});
|
||||||
|
|
||||||
|
var walletdb = new bcoin.walletdb({ db: 'memory' });
|
||||||
|
|
||||||
|
pool.open(function(err) {
|
||||||
|
if (err)
|
||||||
|
throw err;
|
||||||
|
|
||||||
|
var wallet = new bcoin.wallet({
|
||||||
|
provider: walletdb.provider(),
|
||||||
|
derivation: 'bip44',
|
||||||
|
type: 'pubkeyhash'
|
||||||
|
});
|
||||||
|
|
||||||
|
walletdb.save(wallet);
|
||||||
|
pool.watchWallet(wallet);
|
||||||
|
|
||||||
|
console.log('Created wallet with address %s', wallet.getAddress());
|
||||||
|
|
||||||
|
// Connect, start retrieving and relaying txs
|
||||||
|
pool.connect();
|
||||||
|
|
||||||
|
// Start the blockchain sync.
|
||||||
|
pool.startSync();
|
||||||
|
|
||||||
|
pool.on('tx', function(tx) {
|
||||||
|
wallet.addTX(tx);
|
||||||
|
});
|
||||||
|
|
||||||
|
wallet.on('balance', function(balance) {
|
||||||
|
console.log('Balance updated.');
|
||||||
|
console.log(bcoin.utils.btc(balance.unconfirmed));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
### High-level usage for Node object
|
### High-level usage for Node object
|
||||||
|
|
||||||
``` js
|
``` js
|
||||||
@ -52,10 +223,11 @@ node.open(function(err) {
|
|||||||
// Create a new wallet (or get an existing one with the same ID)
|
// Create a new wallet (or get an existing one with the same ID)
|
||||||
var options = {
|
var options = {
|
||||||
id: 'mywallet',
|
id: 'mywallet',
|
||||||
|
passphrase: 'foo',
|
||||||
witness: false,
|
witness: false,
|
||||||
type: 'pubkeyhash',
|
type: 'pubkeyhash',
|
||||||
derivation: 'bip44',
|
derivation: 'bip44',
|
||||||
passphrase: 'foo'
|
accountIndex: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
node.createWallet(options, function(err, wallet) {
|
node.createWallet(options, function(err, wallet) {
|
||||||
@ -72,6 +244,7 @@ node.open(function(err) {
|
|||||||
wallet.once('balance', function(balance) {
|
wallet.once('balance', function(balance) {
|
||||||
var newReceiving = wallet.createAddress();
|
var newReceiving = wallet.createAddress();
|
||||||
console.log('Created new receiving address: %s', newReceiving);
|
console.log('Created new receiving address: %s', newReceiving);
|
||||||
|
|
||||||
// Create a transaction, fill
|
// Create a transaction, fill
|
||||||
// it with coins, and sign it.
|
// it with coins, and sign it.
|
||||||
wallet.createTX({
|
wallet.createTX({
|
||||||
@ -133,115 +306,6 @@ $ node bin/bcoin-cli wallet primary --passphrase=node
|
|||||||
$ node bin/bcoin-cli mempool
|
$ node bin/bcoin-cli mempool
|
||||||
```
|
```
|
||||||
|
|
||||||
### Creating a blockchain and mempool
|
|
||||||
|
|
||||||
``` js
|
|
||||||
var bcoin = require('bcoin').set('regtest');
|
|
||||||
var chain = new bcoin.chain({ db: 'memory' });
|
|
||||||
var mempool = new bcoin.mempool({ chain: chain, db: 'memory' });
|
|
||||||
var miner = new bcoin.miner({ chain: chain, mempool: mempool });
|
|
||||||
|
|
||||||
// Create a block "attempt"
|
|
||||||
miner.createBlock(function(err, attempt) {
|
|
||||||
if (err)
|
|
||||||
throw err;
|
|
||||||
|
|
||||||
// Mine the block on the worker pool (use mine() for the master process)
|
|
||||||
attempt.mineAsync(function(err, block) {
|
|
||||||
if (err)
|
|
||||||
throw err;
|
|
||||||
|
|
||||||
// Add the block to the chain
|
|
||||||
chain.add(block, function(err) {
|
|
||||||
if (err)
|
|
||||||
throw err;
|
|
||||||
|
|
||||||
console.log('Added %s to the blockchain.', block.rhash);
|
|
||||||
console.log(block);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Connecting to the P2P network
|
|
||||||
|
|
||||||
``` js
|
|
||||||
var bcoin = require('bcoin').set('testnet');
|
|
||||||
|
|
||||||
var chain = new bcoin.chain({ db: 'leveldb' });
|
|
||||||
var mempool = new bcoin.mempool({ chain: chain, db: 'memory' });
|
|
||||||
var pool = new bcoin.pool({ chain: chain, mempool: mempool, size: 8 });
|
|
||||||
|
|
||||||
// Connect, start retrieving and relaying txs
|
|
||||||
pool.connect();
|
|
||||||
|
|
||||||
// Start the blockchain sync.
|
|
||||||
pool.startSync();
|
|
||||||
|
|
||||||
chain.on('block', function(block) {
|
|
||||||
console.log('Added block:');
|
|
||||||
console.log(block);
|
|
||||||
});
|
|
||||||
|
|
||||||
mempool.on('tx', function(tx) {
|
|
||||||
console.log('Added tx to mempool:');
|
|
||||||
console.log(tx);
|
|
||||||
});
|
|
||||||
|
|
||||||
pool.on('tx', function(tx) {
|
|
||||||
console.log('Saw transaction:');
|
|
||||||
console.log(tx);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Doing an SPV sync
|
|
||||||
|
|
||||||
``` js
|
|
||||||
var bcoin = require('bcoin').set('testnet');
|
|
||||||
|
|
||||||
var chain = new bcoin.chain({
|
|
||||||
db: 'leveldb',
|
|
||||||
location: process.env.HOME + '/chain.db',
|
|
||||||
spv: true
|
|
||||||
});
|
|
||||||
|
|
||||||
var pool = new bcoin.pool({
|
|
||||||
chain: chain,
|
|
||||||
spv: true,
|
|
||||||
size: 8
|
|
||||||
});
|
|
||||||
|
|
||||||
var walletdb = new bcoin.walletdb({ db: 'memory' });
|
|
||||||
|
|
||||||
var wallet = new bcoin.wallet({
|
|
||||||
provider: walletdb.provider(),
|
|
||||||
derivation: 'bip44',
|
|
||||||
type: 'pubkeyhash'
|
|
||||||
});
|
|
||||||
|
|
||||||
walletdb.save(wallet);
|
|
||||||
pool.watchWallet(wallet);
|
|
||||||
|
|
||||||
console.log('Created wallet with address %s', wallet.getAddress());
|
|
||||||
|
|
||||||
// Connect, start retrieving and relaying txs
|
|
||||||
pool.connect();
|
|
||||||
|
|
||||||
// Start the blockchain sync.
|
|
||||||
pool.startSync();
|
|
||||||
|
|
||||||
pool.on('tx', function(tx) {
|
|
||||||
wallet.addTX(tx);
|
|
||||||
});
|
|
||||||
|
|
||||||
wallet.on('balance', function(balance) {
|
|
||||||
console.log('Balance updated.');
|
|
||||||
console.log(bcoin.utils.btc(balance.unconfirmed));
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### TX creation
|
### TX creation
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|||||||
@ -1359,29 +1359,27 @@ Pool.prototype.removeWallet = function removeWallet(wallet) {
|
|||||||
if (!this.options.spv)
|
if (!this.options.spv)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
assert(this.loaded);
|
assert(this.loaded, 'Pool is not loaded.');
|
||||||
|
|
||||||
this.unwatchWallet(wallet);
|
this.unwatchWallet(wallet);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an address to the bloom filter (SPV-only).
|
* Add an address to the bloom filter (SPV-only).
|
||||||
* @param {Base58Address} address
|
* @param {Address|Base58Address} address
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Pool.prototype.watchAddress = function watchAddress(address) {
|
Pool.prototype.watchAddress = function watchAddress(address) {
|
||||||
var hash = bcoin.address.getHash(address);
|
this.watch(bcoin.address.getHash(address));
|
||||||
this.watch(hash);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove an address from the bloom filter (SPV-only).
|
* Remove an address from the bloom filter (SPV-only).
|
||||||
* @param {Base58Address} address
|
* @param {Address|Base58Address} address
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Pool.prototype.unwatchAddress = function unwatchAddress(address) {
|
Pool.prototype.unwatchAddress = function unwatchAddress(address) {
|
||||||
var hash = bcoin.address.getHash(address);
|
this.unwatch(bcoin.address.getHash(address));
|
||||||
this.unwatch(hash);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1416,7 +1414,7 @@ Pool.prototype.unwatchWallet = function unwatchWallet(wallet) {
|
|||||||
Pool.prototype.searchWallet = function(wallet, callback) {
|
Pool.prototype.searchWallet = function(wallet, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
assert(this.loaded);
|
assert(this.loaded, 'Pool is not loaded.');
|
||||||
|
|
||||||
callback = utils.asyncify(callback);
|
callback = utils.asyncify(callback);
|
||||||
|
|
||||||
@ -1473,75 +1471,6 @@ Pool.prototype.searchWallet = function(wallet, callback) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Search for a specific piece of data within a time range (SPV-only).
|
|
||||||
* @param {Buffer|Hash} id
|
|
||||||
* @param {Object} range - Range in the format
|
|
||||||
* of `{start:Number, end:Number}`.
|
|
||||||
* @param {Function} callback
|
|
||||||
*/
|
|
||||||
|
|
||||||
Pool.prototype.search = function search(id, range, callback) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
assert(this.loaded);
|
|
||||||
|
|
||||||
if (!this.options.spv)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (range == null) {
|
|
||||||
range = id;
|
|
||||||
id = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof id === 'string')
|
|
||||||
id = new Buffer(id, 'hex');
|
|
||||||
|
|
||||||
if (typeof range === 'number')
|
|
||||||
range = { start: range, end: null };
|
|
||||||
else if (range)
|
|
||||||
range = { start: range.start, end: range.end };
|
|
||||||
else
|
|
||||||
range = { start: 0, end: 0 };
|
|
||||||
|
|
||||||
if (!range.end)
|
|
||||||
range.end = utils.now();
|
|
||||||
|
|
||||||
if (!range.start)
|
|
||||||
range.start = utils.now() - 432000;
|
|
||||||
|
|
||||||
if (id)
|
|
||||||
this.watch(id);
|
|
||||||
|
|
||||||
callback = utils.asyncify(callback);
|
|
||||||
|
|
||||||
function done(err, completed) {
|
|
||||||
self.removeListener('block', onBlock);
|
|
||||||
if (id)
|
|
||||||
self.unwatch(id);
|
|
||||||
callback(err, completed);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onBlock(block) {
|
|
||||||
if (block.ts >= range.end)
|
|
||||||
done(null, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.on('block', onBlock);
|
|
||||||
|
|
||||||
if (range.start < this.chain.tip.ts) {
|
|
||||||
this.chain.resetTime(range.start, function(err) {
|
|
||||||
if (err)
|
|
||||||
return done(err);
|
|
||||||
|
|
||||||
self.stopSync();
|
|
||||||
self.startSync();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
done(null, false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queue a `getdata` request to be sent. Checks existence
|
* Queue a `getdata` request to be sent. Checks existence
|
||||||
* in the chain before requesting.
|
* in the chain before requesting.
|
||||||
@ -1710,23 +1639,6 @@ Pool.prototype.fulfill = function fulfill(hash) {
|
|||||||
return item;
|
return item;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Send `getdata` for a block, wait for response.
|
|
||||||
* @param {Hash}
|
|
||||||
* @param {Function} callback - Returns [Error, {@link Block}].
|
|
||||||
*/
|
|
||||||
|
|
||||||
Pool.prototype.getBlock = function getBlock(hash, callback) {
|
|
||||||
if (!this.peers.load)
|
|
||||||
return setTimeout(this.getBlock.bind(this, hash, callback), 1000);
|
|
||||||
|
|
||||||
this.getData(this.peers.load, this.block.type, hash, true, function(block) {
|
|
||||||
callback(null, block);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.scheduleRequests(this.peers.load);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Broadcast a block.
|
* Broadcast a block.
|
||||||
* @param {Block} block
|
* @param {Block} block
|
||||||
@ -1738,84 +1650,6 @@ Pool.prototype.sendBlock = function sendBlock(block, callback) {
|
|||||||
return this.broadcast(block, callback);
|
return this.broadcast(block, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Search for a transaction, wait for response (SPV-only).
|
|
||||||
* @param {Hash}
|
|
||||||
* @param {Object} range - Time range in the form
|
|
||||||
* of `{start:Number, end:Number}`.
|
|
||||||
* @param {Function} callback - Returns [Error, {@link Block}].
|
|
||||||
*/
|
|
||||||
|
|
||||||
Pool.prototype.getTX = function getTX(hash, range, callback) {
|
|
||||||
var self = this;
|
|
||||||
var cbs, tx, found, delta;
|
|
||||||
|
|
||||||
if (!this.peers.load)
|
|
||||||
return setTimeout(this.getTX.bind(this, hash, range, callback), 1000);
|
|
||||||
|
|
||||||
if (!this.options.spv)
|
|
||||||
return callback(new Error('Cannot get tx with full node'));
|
|
||||||
|
|
||||||
if (typeof range === 'function') {
|
|
||||||
callback = range;
|
|
||||||
range = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not perform duplicate searches
|
|
||||||
if (this.validate.map[hash])
|
|
||||||
return this.validate.map[hash].push(callback);
|
|
||||||
|
|
||||||
cbs = [callback];
|
|
||||||
this.validate.map[hash] = cbs;
|
|
||||||
|
|
||||||
// Add request without queueing it to get notification at the time of load
|
|
||||||
tx = null;
|
|
||||||
found = false;
|
|
||||||
this.getData(this.peers.load, self.tx.type, hash, { noQueue: true }, function(t) {
|
|
||||||
found = true;
|
|
||||||
tx = t;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Do incremental search until the TX is found
|
|
||||||
delta = this.validate.delta;
|
|
||||||
|
|
||||||
// Start from the existing range if given
|
|
||||||
if (range)
|
|
||||||
range = { start: range.start, end: range.end };
|
|
||||||
else
|
|
||||||
range = { start: utils.now() - delta, end: 0 };
|
|
||||||
|
|
||||||
function done(err, tx, range) {
|
|
||||||
var i;
|
|
||||||
|
|
||||||
delete self.validate.map[hash];
|
|
||||||
|
|
||||||
for (i = 0; i < cbs.length; i++)
|
|
||||||
cbs[i](err, tx, range);
|
|
||||||
}
|
|
||||||
|
|
||||||
(function next() {
|
|
||||||
self.search(hash, range, function(err, completed) {
|
|
||||||
if (err)
|
|
||||||
return done(err);
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
return done(null, tx, range);
|
|
||||||
|
|
||||||
if (!completed)
|
|
||||||
return done();
|
|
||||||
|
|
||||||
// Not found yet, continue scanning
|
|
||||||
range.end = range.start;
|
|
||||||
range.start -= delta;
|
|
||||||
if (range.start < 0)
|
|
||||||
range.start = 0;
|
|
||||||
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Broadcast a transaction.
|
* Broadcast a transaction.
|
||||||
* @param {TX} tx
|
* @param {TX} tx
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user