wallet: fixes for wallet server.
This commit is contained in:
parent
877cecbedc
commit
749d4edc11
10
bin/cli
10
bin/cli
@ -430,7 +430,7 @@ CLI.prototype.retoken = async function retoken() {
|
||||
CLI.prototype.rescan = async function rescan() {
|
||||
const height = this.config.uint(0);
|
||||
|
||||
await this.client.rescan(height);
|
||||
await this.wallet.rescan(height);
|
||||
|
||||
this.log('Rescanning...');
|
||||
};
|
||||
@ -658,6 +658,9 @@ CLI.prototype.handleWallet = async function handleWallet() {
|
||||
case 'resend':
|
||||
await this.resendWallet();
|
||||
break;
|
||||
case 'rescan':
|
||||
await this.rescan();
|
||||
break;
|
||||
default:
|
||||
this.log('Unrecognized command.');
|
||||
this.log('Commands:');
|
||||
@ -692,6 +695,7 @@ CLI.prototype.handleWallet = async function handleWallet() {
|
||||
this.log(' $ lock: Lock wallet.');
|
||||
this.log(' $ unlock [passphrase] [timeout?]: Unlock wallet.');
|
||||
this.log(' $ resend: Resend pending transactions.');
|
||||
this.log(' $ rescan [height]: Rescan for transactions.');
|
||||
this.log('Other Options:');
|
||||
this.log(' --passphrase [passphrase]: For signing & account creation.');
|
||||
this.log(' --account [account-name]: Account name.');
|
||||
@ -734,9 +738,6 @@ CLI.prototype.handleNode = async function handleNode() {
|
||||
case 'block':
|
||||
await this.getBlock();
|
||||
break;
|
||||
case 'rescan':
|
||||
await this.rescan();
|
||||
break;
|
||||
case 'reset':
|
||||
await this.reset();
|
||||
break;
|
||||
@ -760,7 +761,6 @@ CLI.prototype.handleNode = async function handleNode() {
|
||||
this.log(' $ tx [hash/address]: View transactions.');
|
||||
this.log(' $ coin [hash+index/address]: View coins.');
|
||||
this.log(' $ block [hash/height]: View block.');
|
||||
this.log(' $ rescan [height]: Rescan for transactions.');
|
||||
this.log(' $ reset [height/hash]: Reset chain to desired block.');
|
||||
this.log(' $ resend: Resend pending transactions.');
|
||||
this.log(' $ backup [path]: Backup the wallet db.');
|
||||
|
||||
@ -905,7 +905,7 @@ Chain.prototype.reorganize = async function reorganize(competitor) {
|
||||
competitor.height
|
||||
);
|
||||
|
||||
await this.fire('reorganize', tip, competitor);
|
||||
await this.call('reorganize', tip, competitor);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -942,7 +942,7 @@ Chain.prototype.reorganizeSPV = async function reorganizeSPV(competitor) {
|
||||
for (const entry of disconnect) {
|
||||
const headers = entry.toHeaders();
|
||||
const view = new CoinView();
|
||||
await this.fire('disconnect', entry, headers, view);
|
||||
await this.call('disconnect', entry, headers, view);
|
||||
}
|
||||
|
||||
this.logger.warning(
|
||||
@ -957,7 +957,7 @@ Chain.prototype.reorganizeSPV = async function reorganizeSPV(competitor) {
|
||||
'Chain replay from height %d necessary.',
|
||||
fork.height);
|
||||
|
||||
await this.fire('reorganize', tip, competitor);
|
||||
await this.call('reorganize', tip, competitor);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -985,7 +985,7 @@ Chain.prototype.disconnect = async function disconnect(entry) {
|
||||
|
||||
this.emit('tip', prev);
|
||||
|
||||
await this.fire('disconnect', entry, block, view);
|
||||
await this.call('disconnect', entry, block, view);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1035,7 +1035,7 @@ Chain.prototype.reconnect = async function reconnect(entry) {
|
||||
this.emit('tip', entry);
|
||||
this.emit('reconnect', entry, block);
|
||||
|
||||
await this.fire('connect', entry, block, view);
|
||||
await this.call('connect', entry, block, view);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1103,7 +1103,7 @@ Chain.prototype.setBestChain = async function setBestChain(entry, block, prev, f
|
||||
this.emit('tip', entry);
|
||||
this.emit('block', block, entry);
|
||||
|
||||
await this.fire('connect', entry, block, view);
|
||||
await this.call('connect', entry, block, view);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1198,7 +1198,7 @@ Chain.prototype._reset = async function _reset(block, silent) {
|
||||
this.emit('tip', tip);
|
||||
|
||||
if (!silent)
|
||||
await this.fire('reset', tip);
|
||||
await this.call('reset', tip);
|
||||
|
||||
// Reset the orphan map completely. There may
|
||||
// have been some orphans on a forked chain we
|
||||
|
||||
@ -1307,7 +1307,7 @@ ChainDB.prototype.scan = async function scan(start, filter, iter) {
|
||||
const block = await this.getBlock(entry.hash);
|
||||
const txs = [];
|
||||
|
||||
total++;
|
||||
total += 1;
|
||||
|
||||
if (!block) {
|
||||
if (!this.options.spv && !this.options.prune)
|
||||
|
||||
@ -498,7 +498,7 @@ class HTTP extends Server {
|
||||
|
||||
const tx = TX.fromRaw(data);
|
||||
|
||||
this.node.send(tx);
|
||||
this.node.relay(tx);
|
||||
|
||||
return null;
|
||||
});
|
||||
@ -655,7 +655,7 @@ class HTTP extends Server {
|
||||
for (const tx of txs)
|
||||
raw.push(tx.toRaw());
|
||||
|
||||
return socket.fire('block rescan', block, raw);
|
||||
return socket.call('block rescan', block, raw);
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -209,6 +209,37 @@ AsyncEmitter.prototype.listenerCount = function listenerCount(type) {
|
||||
return listeners.length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a listener.
|
||||
* @param {String} type
|
||||
* @param {Function} handler
|
||||
*/
|
||||
|
||||
AsyncEmitter.prototype.listen = function listen(type, handler) {
|
||||
return this.on(type, handler);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a listener.
|
||||
* @param {String} type
|
||||
* @param {Function} handler
|
||||
*/
|
||||
|
||||
AsyncEmitter.prototype.hook = function hook(type, handler) {
|
||||
return this.on(type, handler);
|
||||
};
|
||||
|
||||
/**
|
||||
* Emit event.
|
||||
* @param {String} type
|
||||
* @param {...Object} args
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
AsyncEmitter.prototype.fire = function fire() {
|
||||
return this.emit.apply(this, arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
* Emit an event synchronously.
|
||||
* @method
|
||||
@ -280,7 +311,7 @@ AsyncEmitter.prototype.emit = function emit(type) {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
AsyncEmitter.prototype.fire = async function fire(type) {
|
||||
AsyncEmitter.prototype.call = async function call(type) {
|
||||
assert(typeof type === 'string', '`type` must be a string.');
|
||||
|
||||
const listeners = this._events[type];
|
||||
@ -343,15 +374,15 @@ AsyncEmitter.prototype.fire = async function fire(type) {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
AsyncEmitter.prototype.tryFire = async function tryFire(type) {
|
||||
AsyncEmitter.prototype.tryCall = async function tryCall(type) {
|
||||
try {
|
||||
await this.fire.apply(this, arguments);
|
||||
await this.call.apply(this, arguments);
|
||||
} catch (e) {
|
||||
if (type === 'error')
|
||||
return;
|
||||
|
||||
try {
|
||||
await this.fire('error', e);
|
||||
await this.call('error', e);
|
||||
} catch (e) {
|
||||
;
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ AsyncObject.prototype.__open = async function __open() {
|
||||
if (this.loaded)
|
||||
return;
|
||||
|
||||
await this.fire('preopen');
|
||||
await this.call('preopen');
|
||||
|
||||
this.loading = true;
|
||||
|
||||
@ -76,7 +76,7 @@ AsyncObject.prototype.__open = async function __open() {
|
||||
this.loading = false;
|
||||
this.loaded = true;
|
||||
|
||||
await this.fire('open');
|
||||
await this.call('open');
|
||||
};
|
||||
|
||||
/**
|
||||
@ -105,7 +105,7 @@ AsyncObject.prototype.__close = async function __close() {
|
||||
if (!this.loaded)
|
||||
return;
|
||||
|
||||
await this.fire('preclose');
|
||||
await this.call('preclose');
|
||||
|
||||
this.closing = true;
|
||||
|
||||
@ -120,7 +120,7 @@ AsyncObject.prototype.__close = async function __close() {
|
||||
this.closing = false;
|
||||
this.loaded = false;
|
||||
|
||||
await this.fire('close');
|
||||
await this.call('close');
|
||||
};
|
||||
|
||||
/**
|
||||
@ -151,6 +151,27 @@ AsyncObject.prototype._close = function _close(callback) {
|
||||
throw new Error('Abstract method.');
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a listener.
|
||||
* @param {String} type
|
||||
* @param {Function} handler
|
||||
*/
|
||||
|
||||
AsyncObject.prototype.listen = function listen(type, handler) {
|
||||
return this.on(type, handler);
|
||||
};
|
||||
|
||||
/**
|
||||
* Emit event.
|
||||
* @param {String} type
|
||||
* @param {...Object} args
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
AsyncObject.prototype.fire = function fire() {
|
||||
return this.emit.apply(this, arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a hook listener.
|
||||
* @param {String} type
|
||||
@ -174,8 +195,8 @@ AsyncObject.prototype.hook = function hook(type, handler) {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
AsyncObject.prototype.fire = async function fire() {
|
||||
await this.fireHook.apply(this, arguments);
|
||||
AsyncObject.prototype.call = async function call() {
|
||||
await this.callHook.apply(this, arguments);
|
||||
this.emit.apply(this, arguments);
|
||||
};
|
||||
|
||||
@ -188,7 +209,7 @@ AsyncObject.prototype.fire = async function fire() {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
AsyncObject.prototype.fireHook = async function fireHook(type) {
|
||||
AsyncObject.prototype.callHook = async function callHook(type) {
|
||||
assert(typeof type === 'string', '`type` must be a string.');
|
||||
|
||||
const listeners = this._hooks[type];
|
||||
|
||||
@ -335,6 +335,7 @@ Bloom.prototype.toRaw = function toRaw() {
|
||||
|
||||
Bloom.prototype.fromReader = function fromReader(br) {
|
||||
this.filter = br.readVarBytes();
|
||||
this.size = this.filter.length * 8;
|
||||
this.n = br.readU32();
|
||||
this.tweak = br.readU32();
|
||||
this.update = br.readU8();
|
||||
|
||||
@ -21,24 +21,24 @@ class WalletClient extends NodeClient {
|
||||
async open() {
|
||||
await super.open();
|
||||
|
||||
this.listen('block connect', (entry, txs) => {
|
||||
this.emit('block connect', ...parseBlock(entry, txs));
|
||||
this.parse('block connect', (entry, txs) => {
|
||||
return parseBlock(entry, txs);
|
||||
});
|
||||
|
||||
this.listen('block disconnect', (entry) => {
|
||||
this.emit('block disconnect', parseEntry(entry));
|
||||
this.parse('block disconnect', (entry) => {
|
||||
return parseEntry(entry);
|
||||
});
|
||||
|
||||
this.listen('block rescan', (entry, txs) => {
|
||||
this.emit('block rescan', ...parseBlock(entry, txs));
|
||||
this.parse('block rescan', (entry, txs) => {
|
||||
return parseBlock(entry, txs);
|
||||
});
|
||||
|
||||
this.listen('chain reset', (tip) => {
|
||||
this.emit('chain reset', parseEntry(tip));
|
||||
this.parse('chain reset', (tip) => {
|
||||
return parseEntry(tip);
|
||||
});
|
||||
|
||||
this.listen('tx', (tx) => {
|
||||
this.emit('tx', TX.fromRaw(tx));
|
||||
this.parse('tx', (tx) => {
|
||||
return TX.fromRaw(tx);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ function NodeClient(node) {
|
||||
this.node = node;
|
||||
this.network = node.network;
|
||||
this.filter = null;
|
||||
this.listen = false;
|
||||
this.listening = false;
|
||||
|
||||
this._init();
|
||||
}
|
||||
@ -38,28 +38,28 @@ Object.setPrototypeOf(NodeClient.prototype, AsyncObject.prototype);
|
||||
|
||||
NodeClient.prototype._init = function _init() {
|
||||
this.node.on('connect', (entry, block) => {
|
||||
if (!this.listen)
|
||||
if (!this.listening)
|
||||
return;
|
||||
|
||||
this.emit('block connect', entry, block.txs);
|
||||
});
|
||||
|
||||
this.node.on('disconnect', (entry, block) => {
|
||||
if (!this.listen)
|
||||
if (!this.listening)
|
||||
return;
|
||||
|
||||
this.emit('block disconnect', entry);
|
||||
});
|
||||
|
||||
this.node.on('tx', (tx) => {
|
||||
if (!this.listen)
|
||||
if (!this.listening)
|
||||
return;
|
||||
|
||||
this.emit('tx', tx);
|
||||
});
|
||||
|
||||
this.node.on('reset', (tip) => {
|
||||
if (!this.listen)
|
||||
if (!this.listening)
|
||||
return;
|
||||
|
||||
this.emit('chain reset', tip);
|
||||
@ -72,7 +72,7 @@ NodeClient.prototype._init = function _init() {
|
||||
*/
|
||||
|
||||
NodeClient.prototype._open = function _open(options) {
|
||||
this.listen = true;
|
||||
this.listening = true;
|
||||
this.emit('open');
|
||||
return Promise.resolve();
|
||||
};
|
||||
@ -83,7 +83,7 @@ NodeClient.prototype._open = function _open(options) {
|
||||
*/
|
||||
|
||||
NodeClient.prototype._close = function _close() {
|
||||
this.listen = false;
|
||||
this.listening = false;
|
||||
this.emit('close');
|
||||
return Promise.resolve();
|
||||
};
|
||||
@ -193,7 +193,7 @@ NodeClient.prototype.getHashes = async function getHashes(start = -1, end = -1)
|
||||
|
||||
NodeClient.prototype.rescan = function rescan(start) {
|
||||
return this.node.chain.scan(start, this.filter, (entry, txs) => {
|
||||
return this.fire('block rescan', entry, txs);
|
||||
return this.call('block rescan', entry, txs);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@ -107,7 +107,7 @@ WalletNode.prototype._open = async function _open(callback) {
|
||||
|
||||
await this.http.open();
|
||||
|
||||
this.logger.info('Node is loaded.');
|
||||
this.logger.info('Wallet node is loaded.');
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -133,9 +133,11 @@ WalletDB.prototype._open = async function _open() {
|
||||
id: 'primary'
|
||||
});
|
||||
|
||||
const addr = await wallet.receiveAddress();
|
||||
|
||||
this.logger.info(
|
||||
'Loaded primary wallet (id=%s, wid=%d, address=%s)',
|
||||
wallet.id, wallet.wid, await wallet.receiveAddress());
|
||||
wallet.id, wallet.wid, addr.toString(this.network));
|
||||
|
||||
this.primary = wallet;
|
||||
};
|
||||
@ -215,7 +217,7 @@ WalletDB.prototype.bind = function bind() {
|
||||
}
|
||||
});
|
||||
|
||||
this.client.on('block connect', async (entry, txs) => {
|
||||
this.client.listen('block connect', async (entry, txs) => {
|
||||
try {
|
||||
await this.addBlock(entry, txs);
|
||||
} catch (e) {
|
||||
@ -223,7 +225,7 @@ WalletDB.prototype.bind = function bind() {
|
||||
}
|
||||
});
|
||||
|
||||
this.client.on('block disconnect', async (entry) => {
|
||||
this.client.listen('block disconnect', async (entry) => {
|
||||
try {
|
||||
await this.removeBlock(entry);
|
||||
} catch (e) {
|
||||
@ -231,7 +233,7 @@ WalletDB.prototype.bind = function bind() {
|
||||
}
|
||||
});
|
||||
|
||||
this.client.on('block rescan', async (entry, txs) => {
|
||||
this.client.hook('block rescan', async (entry, txs) => {
|
||||
try {
|
||||
await this.rescanBlock(entry, txs);
|
||||
} catch (e) {
|
||||
@ -239,7 +241,7 @@ WalletDB.prototype.bind = function bind() {
|
||||
}
|
||||
});
|
||||
|
||||
this.client.on('tx', async (tx) => {
|
||||
this.client.listen('tx', async (tx) => {
|
||||
try {
|
||||
await this.addTX(tx);
|
||||
} catch (e) {
|
||||
@ -247,7 +249,7 @@ WalletDB.prototype.bind = function bind() {
|
||||
}
|
||||
});
|
||||
|
||||
this.client.on('chain reset', async (tip) => {
|
||||
this.client.listen('chain reset', async (tip) => {
|
||||
try {
|
||||
await this.resetChain(tip);
|
||||
} catch (e) {
|
||||
@ -1891,30 +1893,13 @@ WalletDB.prototype._removeBlock = async function _removeBlock(entry) {
|
||||
*/
|
||||
|
||||
WalletDB.prototype.rescanBlock = async function rescanBlock(entry, txs) {
|
||||
const unlock = await this.scanLock.lock();
|
||||
try {
|
||||
return await this._rescanBlock(entry, txs);
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Rescan a block.
|
||||
* @private
|
||||
* @param {ChainEntry} entry
|
||||
* @param {TX[]} txs
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
WalletDB.prototype._rescanBlock = async function _rescanBlock(entry, txs) {
|
||||
if (!this.rescanning) {
|
||||
this.logger.warning('Unsolicited rescan block: %s.', entry.height);
|
||||
this.logger.warning('Unsolicited rescan block: %d.', entry.height);
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry.height > this.state.height + 1) {
|
||||
this.logger.warning('Unsolicited rescan block: %s.', entry.height);
|
||||
this.logger.warning('Rescan block too high: %d.', entry.height);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user