http: http and rpc fixes.

This commit is contained in:
Christopher Jeffrey 2016-11-25 14:13:47 -08:00
parent 0dbdf30e89
commit 024ff3e211
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
4 changed files with 119 additions and 115 deletions

View File

@ -417,18 +417,19 @@ CLI.prototype.backup = co(function* backup() {
CLI.prototype.importKey = co(function* importKey() {
var key = this.argv[0];
var account = this.config.account;
if (!key)
throw new Error('No key for import.');
if (util.isBase58(key)) {
yield this.wallet.importPrivate(key);
yield this.wallet.importPrivate(account, key);
this.log('Imported private key.');
return;
}
if (util.isHex(key)) {
yield this.wallet.importPublic(key);
yield this.wallet.importPublic(account, key);
this.log('Imported public key.');
return;
}
@ -438,7 +439,8 @@ CLI.prototype.importKey = co(function* importKey() {
CLI.prototype.importAddress = co(function* importKey() {
var address = this.argv[0];
yield this.wallet.importAddress(address);
var account = this.config.account;
yield this.wallet.importAddress(account, address);
this.log('Imported address.');
});

View File

@ -19,8 +19,8 @@
* t[hash] -> extended tx
* c[hash] -> coins
* u[hash] -> undo coins
* s[bit][hash] -> versionbits state
* v -> versionbits deployments
* v[bit][hash] -> versionbits state
* T[addr-hash][hash] -> dummy (tx by address)
* C[addr-hash][hash][index] -> dummy (coin by address)
* W+T[witaddr-hash][hash] -> dummy (tx by address)

View File

@ -789,7 +789,7 @@ HTTPClient.prototype.removeSharedKey = function removeSharedKey(id, account, key
*/
HTTPClient.prototype.importPrivate = function importPrivate(id, account, key) {
var options = { privateKey: key };
var options = { account: account, privateKey: key };
return this._post('/wallet/' + id + '/import', options);
};
@ -802,7 +802,7 @@ HTTPClient.prototype.importPrivate = function importPrivate(id, account, key) {
*/
HTTPClient.prototype.importPublic = function importPublic(id, account, key) {
var options = { publicKey: key };
var options = { account: account, publicKey: key };
return this._post('/wallet/' + id + '/import', options);
};
@ -815,7 +815,7 @@ HTTPClient.prototype.importPublic = function importPublic(id, account, key) {
*/
HTTPClient.prototype.importAddress = function importAddress(id, account, address) {
var options = { address: address };
var options = { account: account, address: address };
return this._post('/wallet/' + id + '/import', options);
};

View File

@ -299,8 +299,6 @@ RPC.prototype.execute = function execute(json) {
return this.selectwallet(json.params);
case 'setloglevel':
return this.setloglevel(json.params);
case 'restartsync':
return this.restartsync(json.params);
default:
return Promise.reject(new Error('Method not found: ' + json.method + '.'));
@ -625,14 +623,13 @@ RPC.prototype._getSoftforks = function _getSoftforks() {
};
RPC.prototype._getBIP9Softforks = co(function* _getBIP9Softforks() {
var tip = this.chain.tip;
var forks = {};
var keys = Object.keys(this.network.deployments);
var i, id, deployment, state;
var i, deployment, state;
for (i = 0; i < keys.length; i++) {
id = keys[i];
deployment = this.network.deployments[id];
state = yield this.chain.getState(this.chain.tip, id);
for (i = 0; i < this.network.deploys.length; i++) {
deployment = this.network.deploys[i];
state = yield this.chain.getState(tip, deployment);
switch (state) {
case constants.thresholdStates.DEFINED:
@ -652,7 +649,7 @@ RPC.prototype._getBIP9Softforks = co(function* _getBIP9Softforks() {
break;
}
forks[id] = {
forks[deployment.name] = {
status: state,
bit: deployment.bit,
startTime: deployment.startTime,
@ -680,7 +677,7 @@ RPC.prototype.getblockchaininfo = co(function* getblockchaininfo(args) {
pruned: this.chain.db.options.prune,
softforks: this._getSoftforks(),
bip9_softforks: yield this._getBIP9Softforks(),
pruneheight: this.chain.db.prune
pruneheight: this.chain.db.options.prune
? Math.max(0, this.chain.height - this.chain.db.keepBlocks)
: null
};
@ -939,9 +936,7 @@ RPC.prototype.getchaintips = co(function* getchaintips(args) {
for (i = 0; i < tips.length; i++) {
hash = tips[i];
entry = yield this.chain.db.get(hash);
if (!entry)
continue;
assert(entry);
fork = yield this._findFork(entry);
main = yield entry.isMainChain();
@ -1125,17 +1120,17 @@ RPC.prototype._entryToJSON = function _entryToJSON(entry) {
return {
size: entry.size,
fee: Amount.btc(entry.fee, true),
modifiedfee: Amount.btc(entry.fees, true),
modifiedfee: Amount.btc(entry.fee, true),
time: entry.ts,
height: entry.height,
startingpriority: entry.priority,
currentpriority: entry.getPriority(this.chain.height),
descendantcount: this.mempool.countDescendants(tx),
descendantsize: entry.sizes,
descendantfees: Amount.btc(entry.fees, true),
descendantfees: Amount.btc(entry.fee, true),
ancestorcount: this.mempool.countAncestors(tx),
ancestorsize: entry.sizes,
ancestorfees: Amount.btc(entry.fees, true),
ancestorfees: Amount.btc(entry.fee, true),
depends: this.mempool.getDepends(tx).map(util.revHex)
};
};
@ -1163,8 +1158,9 @@ RPC.prototype.gettxout = co(function* gettxout(args) {
throw new RPCError('Invalid parameter.');
if (mempool)
coin = yield this.node.getCoin(hash, index);
else
coin = this.mempool.getCoin(hash, index);
if (!coin)
coin = yield this.chain.db.getCoin(hash, index);
if (!coin)
@ -1738,7 +1734,7 @@ RPC.prototype._bindChain = function _bindChain() {
if (!self.attempt)
return;
if (util.now() - self.start > 5)
if (util.now() - self.start > 10)
self._clearBlock();
});
};
@ -1770,22 +1766,18 @@ RPC.prototype._totalTX = function _totalTX() {
};
RPC.prototype.getmininginfo = co(function* getmininginfo(args) {
var block, hashps;
var attempt = this.attempt;
var hashps;
if (args.help || args.length !== 0)
throw new RPCError('getmininginfo');
block = yield this.chain.db.getBlock(this.chain.tip.hash);
if (!block)
throw new RPCError('Block not found.');
hashps = yield this._hashps(120, -1);
return {
blocks: this.chain.height,
currentblocksize: block.getSize(),
currentblocktx: block.txs.length,
currentblocksize: attempt ? attempt.block.getBaseSize() : 0,
currentblocktx: attempt ? attempt.block.txs.length : 0,
difficulty: this._getDifficulty(),
errors: '',
genproclimit: this.proclimit,
@ -1840,22 +1832,22 @@ RPC.prototype.prioritisetransaction = function prioritisetransaction(args) {
return Promise.reject(new RPCError('Transaction not in mempool.'));
entry.priority += pri;
entry.fees += fee;
entry.fee += fee;
if (entry.priority < 0)
entry.priority = 0;
if (entry.fees < 0)
entry.fees = 0;
if (entry.fee < 0)
entry.fee = 0;
return Promise.resolve(true);
};
RPC.prototype._hashps = co(function* _hashps(lookup, height) {
var i, minTime, maxTime, workDiff, timeDiff, ps, tip, entry;
var tip = this.chain.tip;
var i, minTime, maxTime, workDiff, timeDiff, ps, entry;
tip = this.chain.tip;
if (height >= 0 && height < this.chain.tip.height)
if (height !== -1)
tip = yield this.chain.db.get(height);
if (!tip)
@ -2190,13 +2182,14 @@ RPC.prototype._fillCoins = function _fillCoins(tx) {
};
RPC.prototype._signrawtransaction = co(function* signrawtransaction(merged, txs, args) {
var type = constants.hashType.ALL;
var keys = [];
var keyMap = {};
var k, i, secret, key;
var coins, prevout, prev;
var coins = [];
var i, j, k, secret, key;
var coin, prevout, prev;
var hash, index, script, value;
var redeem, op, j;
var type, parts, tx;
var redeem, op, parts, tx;
if (args.length > 2 && Array.isArray(args[2])) {
k = args[2];
@ -2212,7 +2205,6 @@ RPC.prototype._signrawtransaction = co(function* signrawtransaction(merged, txs,
}
}
coins = [];
if (args.length > 1 && Array.isArray(args[1])) {
prevout = args[1];
@ -2235,27 +2227,29 @@ RPC.prototype._signrawtransaction = co(function* signrawtransaction(merged, txs,
}
script = Script.fromRaw(script, 'hex');
coins.push(new Coin({
hash: util.revHex(hash),
index: index,
script: script,
value: value,
coinbase: false,
height: -1
}));
coin = new Coin();
coin.hash = util.revHex(hash);
coin.index = index;
coin.script = script;
coin.value = value;
coin.coinbase = false;
coin.height = -1;
coins.push(coin);
if (keys.length === 0 || !util.isHex(prev.redeemScript))
continue;
if (script.isScripthash() || script.isWitnessScripthash()) {
redeem = Script.fromRaw(prev.redeemScript, 'hex');
for (j = 0; j < redeem.length; j++) {
op = redeem.get(j);
for (j = 0; j < redeem.code.length; j++) {
op = redeem.code[j];
if (!Buffer.isBuffer(op))
if (!op.data)
continue;
key = keyMap[op.toString('hex')];
key = keyMap[op.data.toString('hex')];
if (key) {
key.script = redeem;
key.witness = script.isWitnessScripthash();
@ -2268,14 +2262,16 @@ RPC.prototype._signrawtransaction = co(function* signrawtransaction(merged, txs,
tx.fillCoins(coins);
}
type = constants.hashType.ALL;
if (args.length > 3 && typeof args[3] === 'string') {
parts = args[3].split('|');
if (args.length > 3) {
parts = toString(args[3]).split('|');
type = constants.hashType[parts[0]];
if (type == null)
throw new RPCError('Invalid parameter');
if (parts.length > 2)
throw new RPCError('Invalid parameter');
if (parts.length === 2) {
if (parts[1] !== 'ANYONECANPAY')
throw new RPCError('Invalid parameter');
@ -2290,8 +2286,6 @@ RPC.prototype._signrawtransaction = co(function* signrawtransaction(merged, txs,
yield this.wallet.sign(merged, { type: type });
// TODO: Merge with other txs here.
return {
hex: merged.toRaw().toString('hex'),
complete: merged.isSigned()
@ -2309,8 +2303,8 @@ RPC.prototype.fundrawtransaction = co(function* fundrawtransaction(args) {
if (tx.outputs.length === 0)
throw new RPCError('TX must have at least one output.');
if (args.length === 2 && args[1]) {
options = args[1];
if (args.length > 1) {
options = toObject(args[1]);
changeAddress = toString(options.changeAddress);
if (changeAddress)
@ -2380,7 +2374,7 @@ RPC.prototype._createRedeem = co(function* _createRedeem(args) {
throw new RPCError('Invalid parameters.');
}
if (script.toRaw().length > constants.script.MAX_PUSH)
if (script.getSize() > constants.script.MAX_PUSH)
throw new RPCError('Redeem script exceeds size limit.');
return script;
@ -2404,23 +2398,6 @@ RPC.prototype.createmultisig = co(function* createmultisig(args) {
};
});
RPC.prototype._scriptForWitness = function scriptForWitness(script) {
var hash;
if (script.isPubkey()) {
hash = crypto.hash160(script.get(0));
return Script.fromProgram(0, hash);
}
if (script.isPubkeyhash()) {
hash = script.get(2);
return Script.fromProgram(0, hash);
}
hash = script.sha256();
return Script.fromProgram(0, hash);
};
RPC.prototype.createwitnessaddress = function createwitnessaddress(args) {
var raw, script, program;
@ -2429,7 +2406,7 @@ RPC.prototype.createwitnessaddress = function createwitnessaddress(args) {
raw = toString(args[1]);
script = Script.fromRaw(raw, 'hex');
program = this._scriptForWitness(script);
program = script.forWitness();
return Promise.resolve({
address: program.getAddress().toBase58(this.network),
@ -2712,6 +2689,7 @@ RPC.prototype.backupwallet = co(function* backupwallet(args) {
dest = toString(args[0]);
yield this.walletdb.backup(dest);
return null;
});
@ -2976,7 +2954,7 @@ RPC.prototype.getreceivedbyaccount = co(function* getreceivedbyaccount(args) {
for (j = 0; j < tx.outputs.length; j++) {
output = tx.outputs[j];
hash = output.getHash('hex');
if (filter[hash])
if (hash && filter[hash])
total += output.value;
}
}
@ -2985,7 +2963,6 @@ RPC.prototype.getreceivedbyaccount = co(function* getreceivedbyaccount(args) {
});
RPC.prototype.getreceivedbyaddress = co(function* getreceivedbyaddress(args) {
var self = this;
var minconf = 0;
var total = 0;
var i, j, hash, tx, output, txs;
@ -3008,7 +2985,7 @@ RPC.prototype.getreceivedbyaddress = co(function* getreceivedbyaddress(args) {
if (minconf) {
if (tx.height === -1)
continue;
if (!(self.chain.height - tx.height + 1 >= minconf))
if (!(this.chain.height - tx.height + 1 >= minconf))
continue;
}
for (j = 0; j < tx.outputs.length; j++) {
@ -3191,10 +3168,8 @@ RPC.prototype.importprivkey = co(function* importprivkey(args) {
yield this.wallet.importKey(0, key);
if (!rescan)
return null;
yield this.walletdb.rescan(0);
if (rescan)
yield this.walletdb.rescan(0);
return null;
});
@ -3202,16 +3177,22 @@ RPC.prototype.importprivkey = co(function* importprivkey(args) {
RPC.prototype.importwallet = co(function* importwallet(args) {
var file, keys, lines, line, parts;
var i, secret, time, label, addr;
var data, key;
var data, key, rescan;
if (args.help || args.length !== 1)
throw new RPCError('importwallet "filename"');
file = toString(args[0]);
throw new RPCError('importwallet "filename" ( rescan )');
if (fs.unsupported)
throw new RPCError('FS not available.');
file = toString(args[0]);
if (args.length > 1)
rescan = toBool(args[1]);
if (rescan && this.chain.db.options.prune)
throw new RPCError('Cannot rescan when pruned.');
data = yield readFile(file, 'utf8');
lines = data.split(/\n+/);
@ -3245,19 +3226,43 @@ RPC.prototype.importwallet = co(function* importwallet(args) {
yield this.wallet.importKey(0, key);
}
yield this.walletdb.rescan(0);
if (rescan)
yield this.walletdb.rescan(0);
return null;
});
RPC.prototype.importaddress = function importaddress(args) {
RPC.prototype.importaddress = co(function* importaddress(args) {
var addr, label, rescan, p2sh;
if (args.help || args.length < 1 || args.length > 4) {
return Promise.reject(new RPCError(
'importaddress "address" ( "label" rescan p2sh )'));
}
// Impossible to implement in bcoin.
return Promise.reject(new Error('Not implemented.'));
};
addr = toString(args[0]);
if (args.length > 1)
label = toString(args[1]);
if (args.length > 2)
rescan = toBool(args[2]);
if (args.length > 3)
p2sh = toBool(args[3]);
if (rescan && this.chain.db.options.prune)
throw new RPCError('Cannot rescan when pruned.');
addr = Address.fromBase58(addr);
yield this.wallet.importAddress(0, addr);
if (rescan)
yield this.walletdb.rescan(0);
return null;
});
RPC.prototype.importpubkey = co(function* importpubkey(args) {
var pubkey, label, rescan, key;
@ -3285,10 +3290,8 @@ RPC.prototype.importpubkey = co(function* importpubkey(args) {
yield this.wallet.importKey(0, key);
if (!rescan)
return null;
yield this.walletdb.rescan(0);
if (rescan)
yield this.walletdb.rescan(0);
return null;
});
@ -3417,10 +3420,13 @@ RPC.prototype._listReceived = co(function* _listReceived(minconf, empty, account
for (j = 0; j < tx.outputs.length; j++) {
output = tx.outputs[j];
address = output.getAddress();
if (!address)
continue;
hash = address.getHash('hex');
entry = map[hash];
if (entry) {
if (entry.confirmations === -1 || conf < entry.confirmations)
entry.confirmations = conf;
@ -3431,6 +3437,7 @@ RPC.prototype._listReceived = co(function* _listReceived(minconf, empty, account
}
keys = Object.keys(map);
for (i = 0; i < keys.length; i++) {
key = keys[i];
entry = map[key];
@ -3439,6 +3446,7 @@ RPC.prototype._listReceived = co(function* _listReceived(minconf, empty, account
if (account) {
map = {};
for (i = 0; i < out.length; i++) {
entry = out[i];
item = map[entry.account];
@ -3449,8 +3457,10 @@ RPC.prototype._listReceived = co(function* _listReceived(minconf, empty, account
}
item.amount += entry.amount;
}
out = [];
keys = Object.keys(map);
for (i = 0; i < keys.length; i++) {
key = keys[i];
entry = map[key];
@ -3460,10 +3470,13 @@ RPC.prototype._listReceived = co(function* _listReceived(minconf, empty, account
for (i = 0; i < out.length; i++) {
entry = out[i];
if (!empty && entry.amount === 0)
continue;
if (entry.confirmations === -1)
entry.confirmations = 0;
entry.amount = Amount.btc(entry.amount, true);
result.push(entry);
}
@ -3771,7 +3784,7 @@ RPC.prototype.lockunspent = function lockunspent(args) {
RPC.prototype.move = function move(args) {
// Not implementing: stupid and deprecated.
Promise.reject(new Error('Not implemented.'));
return Promise.reject(new Error('Not implemented.'));
};
RPC.prototype._send = co(function* _send(account, address, amount, subtractFee) {
@ -4108,17 +4121,6 @@ RPC.prototype.setloglevel = function setloglevel(args) {
return Promise.resolve(null);
};
RPC.prototype.restartsync = function restartsync(args) {
if (args.help || args.length !== 0)
return Promise.reject(new RPCError('restartsync'));
this.pool.stopSync();
this.chain.synced = false;
this.pool.startSync();
return Promise.resolve(null);
};
/*
* Helpers
*/