rpc: some refactoring.

This commit is contained in:
Christopher Jeffrey 2017-01-12 12:41:33 -08:00
parent 7396e08f16
commit 002718206a
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 108 additions and 76 deletions

View File

@ -71,6 +71,8 @@ function RPC(node) {
util.inherits(RPC, EventEmitter); util.inherits(RPC, EventEmitter);
RPC.magic = 'Bitcoin Signed Message:\n';
RPC.prototype.execute = function execute(json) { RPC.prototype.execute = function execute(json) {
switch (json.method) { switch (json.method) {
case 'stop': case 'stop':
@ -502,12 +504,17 @@ RPC.prototype.getnettotals = co(function* getnettotals(args) {
RPC.prototype.getpeerinfo = co(function* getpeerinfo(args) { RPC.prototype.getpeerinfo = co(function* getpeerinfo(args) {
var peers = []; var peers = [];
var id = 0; var id = 0;
var peer; var peer, offset;
if (args.help || args.length !== 0) if (args.help || args.length !== 0)
throw new RPCError('getpeerinfo'); throw new RPCError('getpeerinfo');
for (peer = this.pool.peers.head(); peer; peer = peer.next) { for (peer = this.pool.peers.head(); peer; peer = peer.next) {
offset = this.network.time.known[peer.hostname];
if (offset == null)
offset = 0;
peers.push({ peers.push({
id: id++, id: id++,
addr: peer.hostname, addr: peer.hostname,
@ -518,15 +525,17 @@ RPC.prototype.getpeerinfo = co(function* getpeerinfo(args) {
bytessent: peer.socket.bytesWritten, bytessent: peer.socket.bytesWritten,
bytesrecv: peer.socket.bytesRead, bytesrecv: peer.socket.bytesRead,
conntime: peer.ts !== 0 ? util.now() - peer.ts : 0, conntime: peer.ts !== 0 ? util.now() - peer.ts : 0,
timeoffset: peer.version ? peer.version.ts - util.now() : 0, timeoffset: offset,
pingtime: peer.lastPing !== -1 ? peer.lastPing / 1000 : 0, pingtime: peer.lastPong !== -1
minping: peer.minPing !== -1 ? peer.minPing / 1000 : 0, ? (peer.lastPong - peer.lastPing) / 1000
: -1,
minping: peer.minPing !== -1 ? peer.minPing / 1000 : -1,
version: peer.version ? peer.version.version : 0, version: peer.version ? peer.version.version : 0,
subver: peer.version ? peer.version.agent : '', subver: peer.version ? peer.version.agent : '',
inbound: !peer.outbound, inbound: !peer.outbound,
startingheight: peer.version ? peer.version.height : -1, startingheight: peer.version ? peer.version.height : -1,
banscore: peer.banScore, banscore: peer.banScore,
inflight: [], inflight: peer.requestMap.keys().map(util.revHex),
whitelisted: false whitelisted: false
}); });
} }
@ -667,8 +676,8 @@ RPC.prototype.getblockchaininfo = co(function* getblockchaininfo(args) {
return { return {
chain: 'main', chain: 'main',
blocks: this.chain.height, blocks: this.chain.height,
headers: this.chain.bestHeight, headers: this.chain.height,
bestblockhash: util.revHex(this.chain.tip.hash), bestblockhash: this.chain.tip.rhash(),
difficulty: this._getDifficulty(), difficulty: this._getDifficulty(),
mediantime: yield this.chain.tip.getMedianTimeAsync(), mediantime: yield this.chain.tip.getMedianTimeAsync(),
verificationprogress: this.chain.getProgress(), verificationprogress: this.chain.getProgress(),
@ -780,7 +789,7 @@ RPC.prototype._txToJSON = function _txToJSON(tx, entry) {
if (tx.isCoinbase()) { if (tx.isCoinbase()) {
out.coinbase = input.script.toJSON(); out.coinbase = input.script.toJSON();
} else { } else {
out.txid = util.revHex(input.prevout.hash); out.txid = input.prevout.rhash();
out.vout = input.prevout.index; out.vout = input.prevout.index;
out.scriptSig = { out.scriptSig = {
asm: input.script.toASM(), asm: input.script.toASM(),
@ -805,27 +814,34 @@ RPC.prototype._txToJSON = function _txToJSON(tx, entry) {
blockhash: entry ? entry.rhash() : null, blockhash: entry ? entry.rhash() : null,
confirmations: conf, confirmations: conf,
time: entry ? entry.ts : 0, time: entry ? entry.ts : 0,
blocktime: entry ? entry.ts : 0 blocktime: entry ? entry.ts : 0,
hex: undefined
}; };
}; };
RPC.prototype._scriptToJSON = function scriptToJSON(script, hex) { RPC.prototype._scriptToJSON = function scriptToJSON(script, hex) {
var out = {}; var type = script.getType();
var type, address; var address = script.getAddress();
var out;
out.asm = script.toASM(); out = {
asm: script.toASM(),
hex: undefined,
type: Script.typesByVal[type],
reqSigs: 1,
addresses: []
};
if (hex) if (hex)
out.hex = script.toJSON(); out.hex = script.toJSON();
type = script.getType(); if (script.isMultisig())
out.type = Script.typesByVal[type]; out.reqSigs = script.getSmall(0);
out.reqSigs = script.isMultisig() ? script.getSmall(0) : 1; if (address) {
address = address.toBase58(this.network);
address = script.getAddress(); out.addresses.push(address);
}
out.addresses = address ? [address.toBase58(this.network)] : [];
return out; return out;
}; };
@ -881,7 +897,7 @@ RPC.prototype._headerToJSON = co(function* _headerToJSON(entry) {
var nextHash = yield this.chain.db.getNextHash(entry.hash); var nextHash = yield this.chain.db.getNextHash(entry.hash);
return { return {
hash: util.revHex(entry.hash), hash: entry.rhash(),
confirmations: this.chain.height - entry.height + 1, confirmations: this.chain.height - entry.height + 1,
height: entry.height, height: entry.height,
version: entry.version, version: entry.version,
@ -904,7 +920,7 @@ RPC.prototype._blockToJSON = co(function* _blockToJSON(entry, block, txDetails)
var nextHash = yield this.chain.db.getNextHash(entry.hash); var nextHash = yield this.chain.db.getNextHash(entry.hash);
return { return {
hash: util.revHex(entry.hash), hash: entry.rhash(),
confirmations: this.chain.height - entry.height + 1, confirmations: this.chain.height - entry.height + 1,
strippedsize: block.getBaseSize(), strippedsize: block.getBaseSize(),
size: block.getSize(), size: block.getSize(),
@ -990,6 +1006,7 @@ RPC.prototype.getmempoolinfo = co(function* getmempoolinfo(args) {
}); });
RPC.prototype.getmempoolancestors = co(function* getmempoolancestors(args) { RPC.prototype.getmempoolancestors = co(function* getmempoolancestors(args) {
var out = [];
var i, hash, verbose, entry, entries; var i, hash, verbose, entry, entries;
if (args.help || args.length < 1 || args.length > 2) if (args.help || args.length < 1 || args.length > 2)
@ -1014,17 +1031,22 @@ RPC.prototype.getmempoolancestors = co(function* getmempoolancestors(args) {
entries = this.mempool.getAncestors(entry.tx); entries = this.mempool.getAncestors(entry.tx);
if (verbose) { if (verbose) {
for (i = 0; i < entries.length; i++) for (i = 0; i < entries.length; i++) {
entries[i] = this._entryToJSON(entries[i]); entry = entries[i];
out.push(this._entryToJSON(entry));
}
} else { } else {
for (i = 0; i < entries.length; i++) for (i = 0; i < entries.length; i++) {
entries[i] = entries[i].tx.txid(); entry = entries[i];
out.push(entry.tx.txid());
}
} }
return entries; return out;
}); });
RPC.prototype.getmempooldescendants = co(function* getmempooldescendants(args) { RPC.prototype.getmempooldescendants = co(function* getmempooldescendants(args) {
var out = [];
var i, hash, verbose, entry, entries; var i, hash, verbose, entry, entries;
if (args.help || args.length < 1 || args.length > 2) if (args.help || args.length < 1 || args.length > 2)
@ -1049,14 +1071,18 @@ RPC.prototype.getmempooldescendants = co(function* getmempooldescendants(args) {
entries = this.mempool.getDescendants(entry.tx); entries = this.mempool.getDescendants(entry.tx);
if (verbose) { if (verbose) {
for (i = 0; i < entries.length; i++) for (i = 0; i < entries.length; i++) {
entries[i] = this._entryToJSON(entries[i]); entry = entries[i];
out.push(this._entryToJSON(entry));
}
} else { } else {
for (i = 0; i < entries.length; i++) for (i = 0; i < entries.length; i++) {
entries[i] = entries[i].tx.txid(); entry = entries[i];
out.push(entry.tx.txid());
}
} }
return entries; return out;
}); });
RPC.prototype.getmempoolentry = co(function* getmempoolentry(args) { RPC.prototype.getmempoolentry = co(function* getmempoolentry(args) {
@ -1237,7 +1263,8 @@ RPC.prototype.gettxoutproof = co(function* gettxoutproof(args) {
throw new RPCError('Block not found.'); throw new RPCError('Block not found.');
for (i = 0; i < txids.length; i++) { for (i = 0; i < txids.length; i++) {
if (!block.hasTX(txids[i])) txid = txids[i];
if (!block.hasTX(txid))
throw new RPCError('Block does not contain all txids.'); throw new RPCError('Block does not contain all txids.');
} }
@ -1247,7 +1274,7 @@ RPC.prototype.gettxoutproof = co(function* gettxoutproof(args) {
}); });
RPC.prototype.verifytxoutproof = co(function* verifytxoutproof(args) { RPC.prototype.verifytxoutproof = co(function* verifytxoutproof(args) {
var res = []; var out = [];
var i, block, hash, entry; var i, block, hash, entry;
if (args.help || args.length !== 1) if (args.help || args.length !== 1)
@ -1256,7 +1283,7 @@ RPC.prototype.verifytxoutproof = co(function* verifytxoutproof(args) {
block = MerkleBlock.fromRaw(toString(args[0]), 'hex'); block = MerkleBlock.fromRaw(toString(args[0]), 'hex');
if (!block.verify()) if (!block.verify())
return res; return out;
entry = yield this.chain.db.getEntry(block.hash('hex')); entry = yield this.chain.db.getEntry(block.hash('hex'));
@ -1265,10 +1292,10 @@ RPC.prototype.verifytxoutproof = co(function* verifytxoutproof(args) {
for (i = 0; i < block.matches.length; i++) { for (i = 0; i < block.matches.length; i++) {
hash = block.matches[i]; hash = block.matches[i];
res.push(util.revHex(hash)); out.push(util.revHex(hash));
} }
return res; return out;
}); });
RPC.prototype.gettxoutsetinfo = co(function* gettxoutsetinfo(args) { RPC.prototype.gettxoutsetinfo = co(function* gettxoutsetinfo(args) {
@ -1768,22 +1795,25 @@ RPC.prototype._bindChain = function _bindChain() {
RPC.prototype._getAttempt = co(function* _getAttempt(update) { RPC.prototype._getAttempt = co(function* _getAttempt(update) {
var attempt = this.attempt; var attempt = this.attempt;
var block;
this._bindChain(); this._bindChain();
if (attempt) { if (attempt) {
block = attempt.block;
if (update) { if (update) {
attempt.updateNonce(); attempt.updateNonce();
this.coinbase[attempt.block.merkleRoot] = attempt.coinbase.clone(); this.coinbase[block.merkleRoot] = attempt.coinbase.clone();
} }
return attempt; return attempt;
} }
attempt = yield this.miner.createBlock(); attempt = yield this.miner.createBlock();
block = attempt.block;
this.attempt = attempt; this.attempt = attempt;
this.start = util.now(); this.start = util.now();
this.coinbase[attempt.block.merkleRoot] = attempt.coinbase.clone(); this.coinbase[block.merkleRoot] = attempt.coinbase.clone();
return attempt; return attempt;
}); });
@ -2042,13 +2072,10 @@ RPC.prototype.createrawtransaction = co(function* createrawtransaction(args) {
throw new RPCError('Invalid parameter'); throw new RPCError('Invalid parameter');
} }
input = new Input({ input = new Input();
prevout: { input.prevout.hash = hash;
hash: util.revHex(hash), input.prevout.index = index;
index: index input.sequence = sequence;
},
sequence: sequence
});
tx.inputs.push(input); tx.inputs.push(input);
} }
@ -2062,10 +2089,9 @@ RPC.prototype.createrawtransaction = co(function* createrawtransaction(args) {
if (key === 'data') { if (key === 'data') {
value = new Buffer(value, 'hex'); value = new Buffer(value, 'hex');
output = new Output({ output = new Output();
value: 0, output.value = 0;
script: Script.fromNulldata(value) output.script.fromNulldata(value);
});
tx.outputs.push(output); tx.outputs.push(output);
continue; continue;
} }
@ -2078,10 +2104,9 @@ RPC.prototype.createrawtransaction = co(function* createrawtransaction(args) {
addrs[b58] = true; addrs[b58] = true;
output = new Output({ output = new Output();
value: toSatoshi(value), output.value = toSatoshi(value);
address: address output.script.fromAddress(address);
});
tx.outputs.push(output); tx.outputs.push(output);
} }
@ -2101,7 +2126,7 @@ RPC.prototype.decoderawtransaction = co(function* decoderawtransaction(args) {
}); });
RPC.prototype.decodescript = co(function* decodescript(args) { RPC.prototype.decodescript = co(function* decodescript(args) {
var data, script, hash, address; var data, script, address;
if (args.help || args.length !== 1) if (args.help || args.length !== 1)
throw new RPCError('decodescript "hex"'); throw new RPCError('decodescript "hex"');
@ -2112,8 +2137,7 @@ RPC.prototype.decodescript = co(function* decodescript(args) {
if (data.length > 0) if (data.length > 0)
script.fromRaw(new Buffer(data, 'hex')); script.fromRaw(new Buffer(data, 'hex'));
hash = crypto.hash160(script.toRaw()); address = Address.fromScripthash(script.hash160());
address = Address.fromHash(hash, Script.types.SCRIPTHASH);
script = this._scriptToJSON(script); script = this._scriptToJSON(script);
script.p2sh = address.toBase58(this.network); script.p2sh = address.toBase58(this.network);
@ -2217,7 +2241,7 @@ RPC.prototype._signrawtransaction = co(function* signrawtransaction(wallet, tx,
for (i = 0; i < prevout.length; i++) { for (i = 0; i < prevout.length; i++) {
prev = prevout[i]; prev = prevout[i];
if (!(prev && typeof prev === 'object')) if (!prev || typeof prev !== 'object')
throw new RPCError('Invalid parameter'); throw new RPCError('Invalid parameter');
hash = toHash(prev.txid); hash = toHash(prev.txid);
@ -2255,6 +2279,7 @@ RPC.prototype._signrawtransaction = co(function* signrawtransaction(wallet, tx,
if (key) { if (key) {
key.script = redeem; key.script = redeem;
key.witness = script.isWitnessScripthash(); key.witness = script.isWitnessScripthash();
key.refresh();
break; break;
} }
} }
@ -2386,21 +2411,22 @@ RPC.prototype._createRedeem = co(function* _createRedeem(args) {
*/ */
RPC.prototype.createmultisig = co(function* createmultisig(args) { RPC.prototype.createmultisig = co(function* createmultisig(args) {
var script; var script, address;
if (args.help || args.length < 2 || args.length > 2) if (args.help || args.length < 2 || args.length > 2)
throw new RPCError('createmultisig nrequired ["key",...]'); throw new RPCError('createmultisig nrequired ["key",...]');
script = yield this._createRedeem(args); script = yield this._createRedeem(args);
address = script.getAddress();
return { return {
address: script.getAddress().toBase58(this.network), address: adddress.toBase58(this.network),
redeemScript: script.toJSON() redeemScript: script.toJSON()
}; };
}); });
RPC.prototype.createwitnessaddress = co(function* createwitnessaddress(args) { RPC.prototype.createwitnessaddress = co(function* createwitnessaddress(args) {
var raw, script, program; var raw, script, program, address;
if (args.help || args.length !== 1) if (args.help || args.length !== 1)
throw new RPCError('createwitnessaddress "script"'); throw new RPCError('createwitnessaddress "script"');
@ -2408,16 +2434,17 @@ RPC.prototype.createwitnessaddress = co(function* createwitnessaddress(args) {
raw = toString(args[1]); raw = toString(args[1]);
script = Script.fromRaw(raw, 'hex'); script = Script.fromRaw(raw, 'hex');
program = script.forWitness(); program = script.forWitness();
address = program.getAddress();
return { return {
address: program.getAddress().toBase58(this.network), address: address.toBase58(this.network),
witnessScript: program.toJSON() witnessScript: program.toJSON()
}; };
}); });
RPC.prototype.validateaddress = co(function* validateaddress(args) { RPC.prototype.validateaddress = co(function* validateaddress(args) {
var wallet = this.wallet; var wallet = this.wallet;
var b58, address, json, path; var b58, address, json, path, script;
if (args.help || args.length !== 1) if (args.help || args.length !== 1)
throw new RPCError('validateaddress "bitcoinaddress"'); throw new RPCError('validateaddress "bitcoinaddress"');
@ -2433,13 +2460,16 @@ RPC.prototype.validateaddress = co(function* validateaddress(args) {
} }
path = yield wallet.getPath(address); path = yield wallet.getPath(address);
script = Script.fromAddress(address);
json = { json = {
isvalid: true, isvalid: true,
address: address.toBase58(this.network), address: address.toBase58(this.network),
scriptPubKey: Script.fromAddress(address).toJSON(), scriptPubKey: script.toJSON(),
ismine: path ? true : false, ismine: path ? true : false,
iswatchonly: path ? wallet.watchOnly : false iswatchonly: path ? wallet.watchOnly : false,
account: undefined,
hdkeypath: undefined
}; };
if (!path) if (!path)
@ -2451,10 +2481,8 @@ RPC.prototype.validateaddress = co(function* validateaddress(args) {
return json; return json;
}); });
RPC.magic = 'Bitcoin Signed Message:\n';
RPC.prototype.verifymessage = co(function* verifymessage(args) { RPC.prototype.verifymessage = co(function* verifymessage(args) {
var address, sig, msg, key; var address, sig, msg, hash, key;
if (args.help || args.length !== 3) if (args.help || args.length !== 3)
throw new RPCError('verifymessage "bitcoinaddress" "signature" "message"'); throw new RPCError('verifymessage "bitcoinaddress" "signature" "message"');
@ -2463,9 +2491,9 @@ RPC.prototype.verifymessage = co(function* verifymessage(args) {
sig = toString(args[1]); sig = toString(args[1]);
msg = toString(args[2]); msg = toString(args[2]);
address = Address.getHash(address); hash = Address.getHash(address);
if (!address) if (!hash)
throw new RPCError('Invalid address.'); throw new RPCError('Invalid address.');
sig = new Buffer(sig, 'base64'); sig = new Buffer(sig, 'base64');
@ -2479,7 +2507,7 @@ RPC.prototype.verifymessage = co(function* verifymessage(args) {
key = crypto.hash160(key); key = crypto.hash160(key);
return crypto.ccmp(key, address); return crypto.ccmp(key, hash);
}); });
RPC.prototype.signmessagewithprivkey = co(function* signmessagewithprivkey(args) { RPC.prototype.signmessagewithprivkey = co(function* signmessagewithprivkey(args) {
@ -2635,6 +2663,8 @@ RPC.prototype.setmocktime = co(function* setmocktime(args) {
if (ts < 0) if (ts < 0)
throw new RPCError('Invalid parameter.'); throw new RPCError('Invalid parameter.');
this.network.time.offset = 0;
delta = this.network.now() - ts; delta = this.network.now() - ts;
this.network.time.offset = -delta; this.network.time.offset = -delta;
@ -2833,7 +2863,7 @@ RPC.prototype.getaccount = co(function* getaccount(args) {
RPC.prototype.getaddressesbyaccount = co(function* getaddressesbyaccount(args) { RPC.prototype.getaddressesbyaccount = co(function* getaddressesbyaccount(args) {
var wallet = this.wallet; var wallet = this.wallet;
var i, path, account, addrs, paths; var i, path, account, address, addrs, paths;
if (args.help || args.length !== 1) if (args.help || args.length !== 1)
throw new RPCError('getaddressesbyaccount "account"'); throw new RPCError('getaddressesbyaccount "account"');
@ -2849,7 +2879,8 @@ RPC.prototype.getaddressesbyaccount = co(function* getaddressesbyaccount(args) {
for (i = 0; i < paths.length; i++) { for (i = 0; i < paths.length; i++) {
path = paths[i]; path = paths[i];
addrs.push(path.toAddress().toBase58(this.network)); address = path.toAddress();
addrs.push(address.toBase58(this.network));
} }
return addrs; return addrs;
@ -3346,7 +3377,7 @@ RPC.prototype.listlockunspent = co(function* listlockunspent(args) {
for (i = 0; i < outpoints.length; i++) { for (i = 0; i < outpoints.length; i++) {
outpoint = outpoints[i]; outpoint = outpoints[i];
out.push({ out.push({
txid: util.revHex(outpoint.hash), txid: outpoint.rhash(),
vout: outpoint.index vout: outpoint.index
}); });
} }
@ -3401,9 +3432,10 @@ RPC.prototype._listReceived = co(function* _listReceived(minconf, empty, account
for (i = 0; i < paths.length; i++) { for (i = 0; i < paths.length; i++) {
path = paths[i]; path = paths[i];
address = path.toAddress();
map[path.hash] = { map[path.hash] = {
involvesWatchonly: wallet.watchOnly, involvesWatchonly: wallet.watchOnly,
address: path.toAddress().toBase58(this.network), address: address.toBase58(this.network),
account: path.name, account: path.name,
amount: 0, amount: 0,
confirmations: -1, confirmations: -1,
@ -3713,7 +3745,7 @@ RPC.prototype.listunspent = co(function* listunspent(args) {
ring = yield wallet.getKey(hash); ring = yield wallet.getKey(hash);
out.push({ out.push({
txid: util.revHex(coin.hash), txid: coin.rhash(),
vout: coin.index, vout: coin.index,
address: address ? address.toBase58(this.network) : null, address: address ? address.toBase58(this.network) : null,
account: ring ? ring.name : undefined, account: ring ? ring.name : undefined,

View File

@ -634,7 +634,6 @@ HTTPServer.prototype._init = function _init() {
res.send(200, { res.send(200, {
version: pkg.version, version: pkg.version,
agent: this.pool.userAgent,
network: this.network.type, network: this.network.type,
chain: { chain: {
height: this.chain.height, height: this.chain.height,
@ -644,6 +643,7 @@ HTTPServer.prototype._init = function _init() {
pool: { pool: {
host: this.pool.address.host, host: this.pool.address.host,
port: this.pool.address.port, port: this.pool.address.port,
agent: this.pool.userAgent,
services: this.pool.address.services.toString(2), services: this.pool.address.services.toString(2),
outbound: this.pool.peers.outbound, outbound: this.pool.peers.outbound,
inbound: this.pool.peers.inbound inbound: this.pool.peers.inbound