refactor: browser. benchmarks.
This commit is contained in:
parent
f158a73a2d
commit
8cb6faa078
1
Makefile
1
Makefile
@ -1,6 +1,5 @@
|
|||||||
all:
|
all:
|
||||||
@npm run browserify
|
@npm run browserify
|
||||||
@npm run uglify
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@npm run clean
|
@npm run clean
|
||||||
|
|||||||
@ -7,6 +7,7 @@ var utils = bcoin.utils;
|
|||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var scriptTypes = constants.scriptTypes;
|
var scriptTypes = constants.scriptTypes;
|
||||||
var bench = require('./bench');
|
var bench = require('./bench');
|
||||||
|
var co = require('../lib/utils/spawn').co;
|
||||||
|
|
||||||
bcoin.cache();
|
bcoin.cache();
|
||||||
|
|
||||||
@ -35,115 +36,89 @@ var walletdb = new bcoin.walletdb({
|
|||||||
// db: 'leveldb'
|
// db: 'leveldb'
|
||||||
db: 'memory'
|
db: 'memory'
|
||||||
});
|
});
|
||||||
var wallet;
|
|
||||||
var addrs = [];
|
|
||||||
|
|
||||||
function runBench(callback) {
|
var runBench = co(function* runBench() {
|
||||||
utils.serial([
|
var i, j, wallet, addrs, jobs, end;
|
||||||
function(next) {
|
var result, nonce, tx, options;
|
||||||
walletdb.create(function(err, w) {
|
|
||||||
assert.ifError(err);
|
|
||||||
wallet = w;
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function(next) {
|
|
||||||
var end = bench('accounts');
|
|
||||||
utils.forRange(0, 1000, function(i, next) {
|
|
||||||
wallet.createAccount({}, function(err, account) {
|
|
||||||
assert.ifError(err);
|
|
||||||
addrs.push(account.receiveAddress.getAddress());
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
}, function(err) {
|
|
||||||
assert.ifError(err);
|
|
||||||
end(1000);
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function(next) {
|
|
||||||
var end = bench('addrs');
|
|
||||||
utils.forRange(0, 1000, function(i, next) {
|
|
||||||
utils.forRange(0, 10, function(j, next) {
|
|
||||||
wallet.createReceive(i, function(err, addr) {
|
|
||||||
assert.ifError(err);
|
|
||||||
addrs.push(addr);
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
}, next);
|
|
||||||
}, function(err) {
|
|
||||||
assert.ifError(err);
|
|
||||||
end(1000 * 10);
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function(next) {
|
|
||||||
var nonce = new bn(0);
|
|
||||||
var end;
|
|
||||||
utils.forRange(0, 10000, function(i, next) {
|
|
||||||
var t1 = bcoin.mtx()
|
|
||||||
.addOutput(addrs[(i + 0) % addrs.length], 50460)
|
|
||||||
.addOutput(addrs[(i + 1) % addrs.length], 50460)
|
|
||||||
.addOutput(addrs[(i + 2) % addrs.length], 50460)
|
|
||||||
.addOutput(addrs[(i + 3) % addrs.length], 50460);
|
|
||||||
|
|
||||||
t1.addInput(dummyInput);
|
// Open and Create
|
||||||
nonce.addn(1);
|
yield walletdb.open();
|
||||||
t1.inputs[0].script.set(0, nonce);
|
wallet = yield walletdb.create();
|
||||||
t1.inputs[0].script.compile();
|
addrs = [];
|
||||||
|
|
||||||
walletdb.addTX(t1.toTX(), function(err) {
|
// Accounts
|
||||||
assert.ifError(err);
|
jobs = [];
|
||||||
next();
|
for (i = 0; i < 1000; i++)
|
||||||
});
|
jobs.push(wallet.createAccount({}));
|
||||||
}, function(err) {
|
|
||||||
assert.ifError(err);
|
|
||||||
end(10000);
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
end = bench('tx');
|
|
||||||
},
|
|
||||||
function(next) {
|
|
||||||
var end = bench('balance');
|
|
||||||
wallet.getBalance(function(err, balance) {
|
|
||||||
assert.ifError(err);
|
|
||||||
end(1);
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function(next) {
|
|
||||||
var end = bench('coins');
|
|
||||||
wallet.getCoins(function(err) {
|
|
||||||
assert.ifError(err);
|
|
||||||
end(1);
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function(next) {
|
|
||||||
var end = bench('create');
|
|
||||||
var options = {
|
|
||||||
rate: 10000,
|
|
||||||
outputs: [{
|
|
||||||
value: 50460,
|
|
||||||
address: addrs[0]
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
wallet.createTX(options, function(err) {
|
|
||||||
assert.ifError(err);
|
|
||||||
end(1);
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
], function(err) {
|
|
||||||
assert.ifError(err);
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
walletdb.open(function(err) {
|
end = bench('accounts');
|
||||||
assert.ifError(err);
|
result = yield Promise.all(jobs);
|
||||||
runBench(function(err) {
|
end(1000);
|
||||||
assert.ifError(err);
|
|
||||||
process.exit(0);
|
for (i = 0; i < result.length; i++)
|
||||||
|
addrs.push(result[i].receiveAddress.getAddress());
|
||||||
|
|
||||||
|
// Addresses
|
||||||
|
jobs = [];
|
||||||
|
for (i = 0; i < 1000; i++) {
|
||||||
|
for (j = 0; j < 10; j++)
|
||||||
|
jobs.push(wallet.createReceive(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
end = bench('addrs');
|
||||||
|
result = yield Promise.all(jobs);
|
||||||
|
end(1000 * 10);
|
||||||
|
|
||||||
|
for (i = 0; i < result.length; i++)
|
||||||
|
addrs.push(result[i].getAddress());
|
||||||
|
|
||||||
|
// TX
|
||||||
|
jobs = [];
|
||||||
|
nonce = new bn(0);
|
||||||
|
for (i = 0; i < 10000; i++) {
|
||||||
|
tx = bcoin.mtx()
|
||||||
|
.addOutput(addrs[(i + 0) % addrs.length], 50460)
|
||||||
|
.addOutput(addrs[(i + 1) % addrs.length], 50460)
|
||||||
|
.addOutput(addrs[(i + 2) % addrs.length], 50460)
|
||||||
|
.addOutput(addrs[(i + 3) % addrs.length], 50460);
|
||||||
|
|
||||||
|
tx.addInput(dummyInput);
|
||||||
|
nonce.addn(1);
|
||||||
|
tx.inputs[0].script.set(0, nonce);
|
||||||
|
tx.inputs[0].script.compile();
|
||||||
|
|
||||||
|
jobs.push(walletdb.addTX(tx.toTX()));
|
||||||
|
}
|
||||||
|
|
||||||
|
end = bench('tx');
|
||||||
|
result = yield Promise.all(jobs);
|
||||||
|
end(10000);
|
||||||
|
|
||||||
|
// Balance
|
||||||
|
end = bench('balance');
|
||||||
|
result = yield wallet.getBalance();
|
||||||
|
end(1);
|
||||||
|
|
||||||
|
// Coins
|
||||||
|
end = bench('coins');
|
||||||
|
result = yield wallet.getCoins();
|
||||||
|
end(1);
|
||||||
|
|
||||||
|
// Create
|
||||||
|
end = bench('create');
|
||||||
|
options = {
|
||||||
|
rate: 10000,
|
||||||
|
outputs: [{
|
||||||
|
value: 50460,
|
||||||
|
address: addrs[0]
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
yield wallet.createTX(options);
|
||||||
|
end(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
runBench().then(process.exit).catch(function(err) {
|
||||||
|
utils.nextTick(function() {
|
||||||
|
throw err;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
9
bin/node
9
bin/node
@ -32,16 +32,7 @@ process.on('uncaughtException', function(err) {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
process.on('unhandledRejection', function(err, promise) {
|
|
||||||
node.logger.debug('Unhandled Rejection');
|
|
||||||
node.logger.debug(err.stack);
|
|
||||||
node.logger.error(err);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
node.open().then(function() {
|
node.open().then(function() {
|
||||||
node.pool.connect();
|
node.pool.connect();
|
||||||
node.startSync();
|
node.startSync();
|
||||||
}).catch(function(e) {
|
|
||||||
throw e;
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -31,13 +31,6 @@ process.on('uncaughtException', function(err) {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
process.on('unhandledRejection', function(err, promise) {
|
|
||||||
node.logger.debug('Unhandled Rejection');
|
|
||||||
node.logger.debug(err.stack);
|
|
||||||
node.logger.error(err);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
node.open().then(function() {
|
node.open().then(function() {
|
||||||
if (process.argv.indexOf('--test') !== -1) {
|
if (process.argv.indexOf('--test') !== -1) {
|
||||||
node.pool.watchAddress('1VayNert3x1KzbpzMGt2qdqrAThiRovi8');
|
node.pool.watchAddress('1VayNert3x1KzbpzMGt2qdqrAThiRovi8');
|
||||||
@ -50,6 +43,4 @@ node.open().then(function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
node.startSync();
|
node.startSync();
|
||||||
}).catch(function(err) {
|
|
||||||
throw err;
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -92,220 +92,6 @@ more bitcoin magic).</small>
|
|||||||
</form>
|
</form>
|
||||||
<input type="button" id="newaddr" value="New Address">
|
<input type="button" id="newaddr" value="New Address">
|
||||||
<div id="floating" class="floating"></div>
|
<div id="floating" class="floating"></div>
|
||||||
<script>
|
<script src="/index.js"></script>
|
||||||
;(function() {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var utils = bcoin.utils;
|
|
||||||
var body = document.getElementsByTagName('body')[0];
|
|
||||||
var log = document.getElementById('log');
|
|
||||||
var wdiv = document.getElementById('wallet');
|
|
||||||
var tdiv = document.getElementById('tx');
|
|
||||||
var floating = document.getElementById('floating');
|
|
||||||
var send = document.getElementById('send');
|
|
||||||
var newaddr = document.getElementById('newaddr');
|
|
||||||
var chainState = document.getElementById('state');
|
|
||||||
var items = [];
|
|
||||||
var scrollback = 0;
|
|
||||||
var logger, node, options;
|
|
||||||
|
|
||||||
body.onmouseup = function() {
|
|
||||||
floating.style.display = 'none';
|
|
||||||
};
|
|
||||||
|
|
||||||
floating.onmouseup = function(ev) {
|
|
||||||
ev.stopPropagation();
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
function show(obj) {
|
|
||||||
floating.innerHTML = escape(utils.inspectify(obj, false));
|
|
||||||
floating.style.display = 'block';
|
|
||||||
}
|
|
||||||
|
|
||||||
logger = new bcoin.logger({ level: 'debug' });
|
|
||||||
logger.writeConsole = function(level, args) {
|
|
||||||
var msg = utils.format(args, false);
|
|
||||||
if (++scrollback > 1000) {
|
|
||||||
log.innerHTML = '';
|
|
||||||
scrollback = 1;
|
|
||||||
}
|
|
||||||
log.innerHTML += '<span style="color:blue;">' + utils.now() + '</span> ';
|
|
||||||
if (level === 'error')
|
|
||||||
log.innerHTML += '<span style="color:red;">[' + level + ']</span> ';
|
|
||||||
else
|
|
||||||
log.innerHTML += '[' + level + '] ';
|
|
||||||
log.innerHTML += escape(msg) + '\n';
|
|
||||||
log.scrollTop = log.scrollHeight;
|
|
||||||
};
|
|
||||||
|
|
||||||
send.onsubmit = function(ev) {
|
|
||||||
var value = document.getElementById('amount').value;
|
|
||||||
var address = document.getElementById('address').value;
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
outputs: [{
|
|
||||||
address: address,
|
|
||||||
value: utils.satoshi(value)
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
|
|
||||||
node.wallet.createTX(options, function(err, tx) {
|
|
||||||
if (err)
|
|
||||||
return node.logger.error(err);
|
|
||||||
|
|
||||||
node.wallet.sign(tx, function(err) {
|
|
||||||
if (err)
|
|
||||||
return node.logger.error(err);
|
|
||||||
|
|
||||||
node.sendTX(tx, function(err) {
|
|
||||||
if (err)
|
|
||||||
return node.logger.error(err);
|
|
||||||
|
|
||||||
show(tx);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
ev.preventDefault();
|
|
||||||
ev.stopPropagation();
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
newaddr.onmouseup = function() {
|
|
||||||
node.wallet.createReceive(function(err) {
|
|
||||||
if (err)
|
|
||||||
throw err;
|
|
||||||
formatWallet(node.wallet);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function kb(size) {
|
|
||||||
size /= 1000;
|
|
||||||
return size.toFixed(2) + 'kb';
|
|
||||||
}
|
|
||||||
|
|
||||||
function create(html) {
|
|
||||||
var el = document.createElement('div');
|
|
||||||
el.innerHTML = html;
|
|
||||||
return el.firstChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
function escape(html, encode) {
|
|
||||||
return html
|
|
||||||
.replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&')
|
|
||||||
.replace(/</g, '<')
|
|
||||||
.replace(/>/g, '>')
|
|
||||||
.replace(/"/g, '"')
|
|
||||||
.replace(/'/g, ''');
|
|
||||||
}
|
|
||||||
|
|
||||||
function addItem(tx) {
|
|
||||||
var el;
|
|
||||||
|
|
||||||
if (items.length === 20) {
|
|
||||||
el = items.shift();
|
|
||||||
tdiv.removeChild(el);
|
|
||||||
el.onmouseup = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
el = create('<a style="display:block;" href="#'
|
|
||||||
+ tx.rhash + '">' + tx.rhash + ' (' + tx.height
|
|
||||||
+ ' - ' + kb(tx.getSize()) + ')</a>');
|
|
||||||
tdiv.appendChild(el);
|
|
||||||
|
|
||||||
el.onmouseup = function(ev) {
|
|
||||||
show(tx);
|
|
||||||
ev.stopPropagation();
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
items.push(el);
|
|
||||||
|
|
||||||
chainState.innerHTML = ''
|
|
||||||
+ 'tx=' + node.chain.db.state.tx
|
|
||||||
+ ' coin=' + node.chain.db.state.coin
|
|
||||||
+ ' value=' + utils.btc(node.chain.db.state.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatWallet(wallet) {
|
|
||||||
var html = '';
|
|
||||||
var key = wallet.master.toJSON().key;
|
|
||||||
html += '<b>Wallet</b><br>';
|
|
||||||
if (bcoin.network.get().type === 'segnet4') {
|
|
||||||
html += 'Current Address (p2wpkh): <b>' + wallet.getAddress() + '</b><br>';
|
|
||||||
html += 'Current Address (p2wpkh behind p2sh): <b>' + wallet.getProgramAddress() + '</b><br>';
|
|
||||||
} else {
|
|
||||||
html += 'Current Address: <b>' + wallet.getAddress() + '</b><br>';
|
|
||||||
}
|
|
||||||
html += 'Extended Private Key: <b>' + key.xprivkey + '</b><br>';
|
|
||||||
html += 'Mnemonic: <b>' + key.mnemonic.phrase + '</b><br>';
|
|
||||||
wallet.getBalance(function(err, balance) {
|
|
||||||
if (err)
|
|
||||||
throw err;
|
|
||||||
|
|
||||||
html += 'Confirmed Balance: <b>' + utils.btc(balance.confirmed) + '</b><br>';
|
|
||||||
html += 'Unconfirmed Balance: <b>' + utils.btc(balance.unconfirmed) + '</b><br>';
|
|
||||||
html += 'Balance: <b>' + utils.btc(balance.total) + '</b><br>';
|
|
||||||
|
|
||||||
wallet.getHistory(function(err, txs) {
|
|
||||||
if (err)
|
|
||||||
throw err;
|
|
||||||
|
|
||||||
wallet.toDetails(txs, function(err, txs) {
|
|
||||||
if (err)
|
|
||||||
throw err;
|
|
||||||
|
|
||||||
html += 'TXs:\n';
|
|
||||||
wdiv.innerHTML = html;
|
|
||||||
|
|
||||||
txs.forEach(function(tx) {
|
|
||||||
var el = create('<a style="display:block;" href="#' + tx.hash + '">' + tx.hash + '</a>');
|
|
||||||
wdiv.appendChild(el);
|
|
||||||
el.onmouseup = function(ev) {
|
|
||||||
show(tx.toJSON());
|
|
||||||
ev.stopPropagation();
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
options = bcoin.config({
|
|
||||||
query: true,
|
|
||||||
network: 'segnet4',
|
|
||||||
db: 'leveldb',
|
|
||||||
useWorkers: true,
|
|
||||||
coinCache: true,
|
|
||||||
logger: logger
|
|
||||||
});
|
|
||||||
|
|
||||||
bcoin.set(options);
|
|
||||||
|
|
||||||
node = new bcoin.fullnode(options);
|
|
||||||
|
|
||||||
node.on('error', function(err) {
|
|
||||||
;
|
|
||||||
});
|
|
||||||
|
|
||||||
node.chain.on('block', addItem);
|
|
||||||
node.mempool.on('tx', addItem);
|
|
||||||
|
|
||||||
node.open(function(err) {
|
|
||||||
if (err)
|
|
||||||
throw err;
|
|
||||||
|
|
||||||
node.startSync();
|
|
||||||
|
|
||||||
formatWallet(node.wallet);
|
|
||||||
|
|
||||||
node.wallet.on('update', function() {
|
|
||||||
formatWallet(node.wallet);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
216
browser/index.js
Normal file
216
browser/index.js
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
;(function() {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var utils = bcoin.utils;
|
||||||
|
var body = document.getElementsByTagName('body')[0];
|
||||||
|
var log = document.getElementById('log');
|
||||||
|
var wdiv = document.getElementById('wallet');
|
||||||
|
var tdiv = document.getElementById('tx');
|
||||||
|
var floating = document.getElementById('floating');
|
||||||
|
var send = document.getElementById('send');
|
||||||
|
var newaddr = document.getElementById('newaddr');
|
||||||
|
var chainState = document.getElementById('state');
|
||||||
|
var cb = bcoin.spawn.cb;
|
||||||
|
var items = [];
|
||||||
|
var scrollback = 0;
|
||||||
|
var logger, node, options;
|
||||||
|
|
||||||
|
body.onmouseup = function() {
|
||||||
|
floating.style.display = 'none';
|
||||||
|
};
|
||||||
|
|
||||||
|
floating.onmouseup = function(ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
function show(obj) {
|
||||||
|
floating.innerHTML = escape(utils.inspectify(obj, false));
|
||||||
|
floating.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
logger = new bcoin.logger({ level: 'debug' });
|
||||||
|
logger.writeConsole = function(level, args) {
|
||||||
|
var msg = utils.format(args, false);
|
||||||
|
if (++scrollback > 1000) {
|
||||||
|
log.innerHTML = '';
|
||||||
|
scrollback = 1;
|
||||||
|
}
|
||||||
|
log.innerHTML += '<span style="color:blue;">' + utils.now() + '</span> ';
|
||||||
|
if (level === 'error')
|
||||||
|
log.innerHTML += '<span style="color:red;">[' + level + ']</span> ';
|
||||||
|
else
|
||||||
|
log.innerHTML += '[' + level + '] ';
|
||||||
|
log.innerHTML += escape(msg) + '\n';
|
||||||
|
log.scrollTop = log.scrollHeight;
|
||||||
|
};
|
||||||
|
|
||||||
|
send.onsubmit = function(ev) {
|
||||||
|
var value = document.getElementById('amount').value;
|
||||||
|
var address = document.getElementById('address').value;
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
outputs: [{
|
||||||
|
address: address,
|
||||||
|
value: utils.satoshi(value)
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
cb(node.wallet.createTX(options), function(err, tx) {
|
||||||
|
if (err)
|
||||||
|
return node.logger.error(err);
|
||||||
|
|
||||||
|
cb(node.wallet.sign(tx), function(err) {
|
||||||
|
if (err)
|
||||||
|
return node.logger.error(err);
|
||||||
|
|
||||||
|
cb(node.sendTX(tx), function(err) {
|
||||||
|
if (err)
|
||||||
|
return node.logger.error(err);
|
||||||
|
|
||||||
|
show(tx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
newaddr.onmouseup = function() {
|
||||||
|
cb(node.wallet.createReceive(), function(err) {
|
||||||
|
if (err)
|
||||||
|
throw err;
|
||||||
|
formatWallet(node.wallet);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function kb(size) {
|
||||||
|
size /= 1000;
|
||||||
|
return size.toFixed(2) + 'kb';
|
||||||
|
}
|
||||||
|
|
||||||
|
function create(html) {
|
||||||
|
var el = document.createElement('div');
|
||||||
|
el.innerHTML = html;
|
||||||
|
return el.firstChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
function escape(html, encode) {
|
||||||
|
return html
|
||||||
|
.replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, ''');
|
||||||
|
}
|
||||||
|
|
||||||
|
function addItem(tx) {
|
||||||
|
var el;
|
||||||
|
|
||||||
|
if (items.length === 20) {
|
||||||
|
el = items.shift();
|
||||||
|
tdiv.removeChild(el);
|
||||||
|
el.onmouseup = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
el = create('<a style="display:block;" href="#'
|
||||||
|
+ tx.rhash + '">' + tx.rhash + ' (' + tx.height
|
||||||
|
+ ' - ' + kb(tx.getSize()) + ')</a>');
|
||||||
|
tdiv.appendChild(el);
|
||||||
|
|
||||||
|
el.onmouseup = function(ev) {
|
||||||
|
show(tx);
|
||||||
|
ev.stopPropagation();
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
items.push(el);
|
||||||
|
|
||||||
|
chainState.innerHTML = ''
|
||||||
|
+ 'tx=' + node.chain.db.state.tx
|
||||||
|
+ ' coin=' + node.chain.db.state.coin
|
||||||
|
+ ' value=' + utils.btc(node.chain.db.state.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatWallet(wallet) {
|
||||||
|
var html = '';
|
||||||
|
var key = wallet.master.toJSON().key;
|
||||||
|
html += '<b>Wallet</b><br>';
|
||||||
|
if (bcoin.network.get().type === 'segnet4') {
|
||||||
|
html += 'Current Address (p2wpkh): <b>' + wallet.getAddress() + '</b><br>';
|
||||||
|
html += 'Current Address (p2wpkh behind p2sh): <b>' + wallet.getProgramAddress() + '</b><br>';
|
||||||
|
} else {
|
||||||
|
html += 'Current Address: <b>' + wallet.getAddress() + '</b><br>';
|
||||||
|
}
|
||||||
|
html += 'Extended Private Key: <b>' + key.xprivkey + '</b><br>';
|
||||||
|
html += 'Mnemonic: <b>' + key.mnemonic.phrase + '</b><br>';
|
||||||
|
cb(wallet.getBalance(), function(err, balance) {
|
||||||
|
if (err)
|
||||||
|
throw err;
|
||||||
|
|
||||||
|
html += 'Confirmed Balance: <b>' + utils.btc(balance.confirmed) + '</b><br>';
|
||||||
|
html += 'Unconfirmed Balance: <b>' + utils.btc(balance.unconfirmed) + '</b><br>';
|
||||||
|
html += 'Balance: <b>' + utils.btc(balance.total) + '</b><br>';
|
||||||
|
|
||||||
|
cb(wallet.getHistory(), function(err, txs) {
|
||||||
|
if (err)
|
||||||
|
throw err;
|
||||||
|
|
||||||
|
cb(wallet.toDetails(txs), function(err, txs) {
|
||||||
|
if (err)
|
||||||
|
throw err;
|
||||||
|
|
||||||
|
html += 'TXs:\n';
|
||||||
|
wdiv.innerHTML = html;
|
||||||
|
|
||||||
|
txs.forEach(function(tx) {
|
||||||
|
var el = create('<a style="display:block;" href="#' + tx.hash + '">' + tx.hash + '</a>');
|
||||||
|
wdiv.appendChild(el);
|
||||||
|
el.onmouseup = function(ev) {
|
||||||
|
show(tx.toJSON());
|
||||||
|
ev.stopPropagation();
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
options = bcoin.config({
|
||||||
|
query: true,
|
||||||
|
network: 'segnet4',
|
||||||
|
db: 'leveldb',
|
||||||
|
useWorkers: true,
|
||||||
|
coinCache: true,
|
||||||
|
logger: logger
|
||||||
|
});
|
||||||
|
|
||||||
|
bcoin.set(options);
|
||||||
|
|
||||||
|
node = new bcoin.fullnode(options);
|
||||||
|
|
||||||
|
node.on('error', function(err) {
|
||||||
|
;
|
||||||
|
});
|
||||||
|
|
||||||
|
node.chain.on('block', addItem);
|
||||||
|
node.mempool.on('tx', addItem);
|
||||||
|
|
||||||
|
cb(node.open(), function(err) {
|
||||||
|
if (err)
|
||||||
|
throw err;
|
||||||
|
|
||||||
|
node.startSync();
|
||||||
|
|
||||||
|
formatWallet(node.wallet);
|
||||||
|
|
||||||
|
node.wallet.on('update', function() {
|
||||||
|
formatWallet(node.wallet);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
@ -15,22 +15,27 @@ proxy.on('error', function(err) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
var index = fs.readFileSync(__dirname + '/index.html');
|
var index = fs.readFileSync(__dirname + '/index.html');
|
||||||
|
var indexjs = fs.readFileSync(__dirname + '/index.js');
|
||||||
var bcoin = fs.readFileSync(__dirname + '/bcoin.js');
|
var bcoin = fs.readFileSync(__dirname + '/bcoin.js');
|
||||||
var worker = fs.readFileSync(__dirname + '/../lib/workers/worker.js');
|
var worker = fs.readFileSync(__dirname + '/../lib/workers/worker.js');
|
||||||
|
|
||||||
server.get('/favicon.ico', function(req, res, next, send) {
|
server.get('/favicon.ico', function(req, res, send, next) {
|
||||||
send(404, '', 'text');
|
send(404, '', 'text');
|
||||||
});
|
});
|
||||||
|
|
||||||
server.get('/', function(req, res, next, send) {
|
server.get('/', function(req, res, send, next) {
|
||||||
send(200, index, 'html');
|
send(200, index, 'html');
|
||||||
});
|
});
|
||||||
|
|
||||||
server.get('/bcoin.js', function(req, res, next, send) {
|
server.get('/index.js', function(req, res, send, next) {
|
||||||
|
send(200, indexjs, 'js');
|
||||||
|
});
|
||||||
|
|
||||||
|
server.get('/bcoin.js', function(req, res, send, next) {
|
||||||
send(200, bcoin, 'js');
|
send(200, bcoin, 'js');
|
||||||
});
|
});
|
||||||
|
|
||||||
server.get('/bcoin-worker.js', function(req, res, next, send) {
|
server.get('/bcoin-worker.js', function(req, res, send, next) {
|
||||||
send(200, worker, 'js');
|
send(200, worker, 'js');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -53,12 +53,12 @@ function exec(gen) {
|
|||||||
* Execute generator function
|
* Execute generator function
|
||||||
* with a context and execute.
|
* with a context and execute.
|
||||||
* @param {GeneratorFunction} generator
|
* @param {GeneratorFunction} generator
|
||||||
* @param {Object} self
|
* @param {Object} ctx
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function spawn(generator, self) {
|
function spawn(generator, ctx) {
|
||||||
var gen = generator.call(self);
|
var gen = generator.call(ctx);
|
||||||
return exec(gen);
|
return exec(gen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +80,8 @@ function co(generator) {
|
|||||||
/**
|
/**
|
||||||
* Wrap a generator function to be
|
* Wrap a generator function to be
|
||||||
* executed into a function that
|
* executed into a function that
|
||||||
* returns a promise.
|
* returns a promise (with a lock).
|
||||||
|
* @param {String} name - lock name.
|
||||||
* @param {GeneratorFunction}
|
* @param {GeneratorFunction}
|
||||||
* @returns {Function}
|
* @returns {Function}
|
||||||
*/
|
*/
|
||||||
@ -115,7 +116,7 @@ function cob(generator) {
|
|||||||
|
|
||||||
if (arguments.length === 0
|
if (arguments.length === 0
|
||||||
|| typeof arguments[arguments.length - 1] !== 'function') {
|
|| typeof arguments[arguments.length - 1] !== 'function') {
|
||||||
throw new Error('Function must accept a callback.');
|
throw new Error((generator.name || 'Function') + ' requires a callback.');
|
||||||
}
|
}
|
||||||
|
|
||||||
args = new Array(arguments.length - 1);
|
args = new Array(arguments.length - 1);
|
||||||
@ -126,12 +127,7 @@ function cob(generator) {
|
|||||||
|
|
||||||
gen = generator.apply(this, args);
|
gen = generator.apply(this, args);
|
||||||
|
|
||||||
return cb(exec(gen), function(err, result) {
|
return cb(exec(gen), callback);
|
||||||
// Escape the promise's scope:
|
|
||||||
utils.nextTick(function() {
|
|
||||||
callback(err, result);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +146,7 @@ function con(generator) {
|
|||||||
|
|
||||||
if (arguments.length === 0
|
if (arguments.length === 0
|
||||||
|| typeof arguments[arguments.length - 1] !== 'function') {
|
|| typeof arguments[arguments.length - 1] !== 'function') {
|
||||||
throw new Error('Function must accept a callback.');
|
throw new Error((generator.name || 'Function') + ' requires a callback.');
|
||||||
}
|
}
|
||||||
|
|
||||||
args = new Array(arguments.length);
|
args = new Array(arguments.length);
|
||||||
@ -179,9 +175,13 @@ function con(generator) {
|
|||||||
|
|
||||||
function cb(promise, callback) {
|
function cb(promise, callback) {
|
||||||
promise.then(function(value) {
|
promise.then(function(value) {
|
||||||
callback(null, value);
|
utils.nextTick(function() {
|
||||||
|
callback(null, value);
|
||||||
|
});
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
callback(err);
|
utils.nextTick(function() {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,9 +204,7 @@ function wait() {
|
|||||||
|
|
||||||
function timeout(time) {
|
function timeout(time) {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
setTimeout(function() {
|
setTimeout(resolve, time);
|
||||||
resolve();
|
|
||||||
}, time);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,8 +218,10 @@ function timeout(time) {
|
|||||||
|
|
||||||
function wrap(resolve, reject) {
|
function wrap(resolve, reject) {
|
||||||
return function(err, result) {
|
return function(err, result) {
|
||||||
if (err)
|
if (err) {
|
||||||
return reject(err);
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
resolve(result);
|
resolve(result);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -234,19 +234,16 @@ function wrap(resolve, reject) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function call(func) {
|
function call(func) {
|
||||||
var args = new Array(Math.max(0, arguments.length - 1));
|
var self = this;
|
||||||
|
var args = new Array(arguments.length);
|
||||||
var i;
|
var i;
|
||||||
|
|
||||||
for (i = 1; i < arguments.length; i++)
|
for (i = 1; i < arguments.length; i++)
|
||||||
args[i] = arguments[i];
|
args[i] = arguments[i];
|
||||||
|
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
args.push(function(err, result) {
|
args.push(wrap(resolve, reject));
|
||||||
if (err)
|
func.apply(self, args);
|
||||||
return reject(err);
|
|
||||||
resolve(result);
|
|
||||||
});
|
|
||||||
func.apply(null, args);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,29 +252,30 @@ function call(func) {
|
|||||||
* style callbacks into a function that
|
* style callbacks into a function that
|
||||||
* returns a promise.
|
* returns a promise.
|
||||||
* @param {Function} func
|
* @param {Function} func
|
||||||
* @param {Object?} self
|
* @param {Object?} ctx
|
||||||
* @returns {Function}
|
* @returns {Function}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function promisify(func, self) {
|
function promisify(func, ctx) {
|
||||||
return function() {
|
return function() {
|
||||||
var args = new Array(arguments.length);
|
return call.call(ctx, arguments);
|
||||||
var i;
|
|
||||||
|
|
||||||
for (i = 0; i < args.length; i++)
|
|
||||||
args[i] = arguments[i];
|
|
||||||
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
args.push(function(err, result) {
|
|
||||||
if (err)
|
|
||||||
return reject(err);
|
|
||||||
resolve(result);
|
|
||||||
});
|
|
||||||
func.apply(self, args);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This drives me nuts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
window.onunhandledrejection = function(event) {
|
||||||
|
throw event.reason;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
process.on('unhandledRejection', function(err, promise) {
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expose
|
* Expose
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1435,7 +1435,7 @@ Wallet.prototype.getTX = function getTX(hash) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Wallet.prototype.addTX = function addTX(tx) {
|
Wallet.prototype.addTX = function addTX(tx) {
|
||||||
this.db.addTX(tx);
|
return this.db.addTX(tx);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user