rpc: improve gbt proposal and capabilities handling.

This commit is contained in:
Christopher Jeffrey 2017-03-15 04:49:54 -07:00
parent dc6b7b1f10
commit 5ee8a9b306
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 97 additions and 13 deletions

View File

@ -32,6 +32,7 @@ var Validator = require('../utils/validator');
var RPCBase = require('./rpcbase');
var pkg = require('../pkg');
var RPCError = RPCBase.RPCError;
var errs = RPCBase.errors;
var MAGIC_STRING = RPCBase.MAGIC_STRING;
/**
@ -1061,7 +1062,9 @@ RPC.prototype.getBlockTemplate = co(function* getBlockTemplate(args, help) {
var capabilities = valid.array('capabilities');
var version = valid.u32('maxversion', -1);
var coinbase = false;
var i, cap, block, value, txn;
var txnCap = false;
var valueCap = false;
var i, capability, block;
if (help || args.length > 1)
throw new RPCError('getblocktemplate ( "jsonrequestobject" )');
@ -1075,7 +1078,18 @@ RPC.prototype.getBlockTemplate = co(function* getBlockTemplate(args, help) {
block = Block.fromRaw(data);
return yield this.addBlock(block);
if (block.prevBlock !== this.chain.tip.hash)
return 'inconclusive-not-best-prevblk';
try {
yield this.chain.verifyBlock(block);
} catch (e) {
if (e.type === 'VerifyError')
return e.reason;
throw e;
}
return null;
}
if (rules)
@ -1083,21 +1097,29 @@ RPC.prototype.getBlockTemplate = co(function* getBlockTemplate(args, help) {
if (capabilities) {
for (i = 0; i < capabilities.length; i++) {
cap = capabilities[i];
switch (cap) {
capability = capabilities[i];
if (typeof capability !== 'string')
throw new RPCError('Capability must be a string.');
switch (capability) {
case 'coinbasetxn':
txn = true;
txnCap = true;
break;
case 'coinbasevalue':
value = true;
// Prefer value if they support it.
valueCap = true;
break;
case 'coinbase/append':
break;
}
}
if (txn)
if (txnCap && !valueCap) {
if (this.miner.addresses.length === 0)
throw new RPCError('No addresses available for coinbase.');
coinbase = true;
}
}
if (!this.network.selfConnect) {
@ -1224,10 +1246,8 @@ RPC.prototype._createTemplate = co(function* _createTemplate(version, coinbase,
weightlimit: undefined,
longpollid: this.chain.tip.rhash() + util.pad32(this.totalTX()),
submitold: false,
coinbaseaux: {
flags: attempt.coinbaseFlags.toString('hex')
},
coinbasevalue: attempt.getReward(),
coinbaseaux: undefined,
coinbasevalue: undefined,
coinbasetxn: undefined,
default_witness_commitment: undefined,
transactions: txs
@ -1243,11 +1263,16 @@ RPC.prototype._createTemplate = co(function* _createTemplate(version, coinbase,
if (coinbase) {
tx = attempt.toCoinbase();
// We don't include the commitment
// output (see bip145).
if (attempt.witness) {
// We don't include the commitment
// output (see bip145).
output = tx.outputs.pop();
assert(output.script.isCommitment());
// Also not including the witness nonce.
tx.inputs[0].witness.length = 0;
tx.inputs[0].witness.compile();
tx.refresh();
}
@ -1260,6 +1285,11 @@ RPC.prototype._createTemplate = co(function* _createTemplate(version, coinbase,
sigops: tx.getSigopsCost() / scale | 0,
weight: tx.getWeight()
};
} else {
json.coinbaseaux = {
flags: attempt.coinbaseFlags.toString('hex')
};
json.coinbasevalue = attempt.getReward();
}
if (rules && rules.indexOf('segwit') !== -1)

View File

@ -33,6 +33,60 @@ function RPCBase() {
util.inherits(RPCBase, EventEmitter);
/**
* RPC errors.
* @enum {Number}
* @default
*/
RPCBase.errors = {
// Standard JSON-RPC 2.0 errors
INVALID_REQUEST: -32600,
METHOD_NOT_FOUND: -32601,
INVALID_PARAMS: -32602,
INTERNAL_ERROR: -32603,
PARSE_ERROR: -32700,
// General application defined errors
MISC_ERROR: -1,
FORBIDDEN_BY_SAFE_MODE: -2,
TYPE_ERROR: -3,
INVALID_ADDRESS_OR_KEY: -5,
OUT_OF_MEMORY: -7,
INVALID_PARAMETER: -8,
DATABASE_ERROR: -20,
DESERIALIZATION_ERROR: -22,
VERIFY_ERROR: -25,
VERIFY_REJECTED: -26,
VERIFY_ALREADY_IN_CHAIN: -27,
IN_WARMUP: -28,
// Aliases for backward compatibility
TRANSACTION_ERROR: -25,
TRANSACTION_REJECTED: -26,
TRANSACTION_ALREADY_IN_CHAIN: -27,
// P2P client errors
CLIENT_NOT_CONNECTED: -9,
CLIENT_IN_INITIAL_DOWNLOAD: -10,
CLIENT_NODE_ALREADY_ADDED: -23,
CLIENT_NODE_NOT_ADDED: -24,
CLIENT_NODE_NOT_CONNECTED: -29,
CLIENT_INVALID_IP_OR_SUBNET: -30,
CLIENT_P2P_DISABLED: -31,
// Wallet errors
WALLET_ERROR: -4,
WALLET_INSUFFICIENT_FUNDS: -6,
WALLET_INVALID_ACCOUNT_NAME: -11,
WALLET_KEYPOOL_RAN_OUT: -12,
WALLET_UNLOCK_NEEDED: -13,
WALLET_PASSPHRASE_INCORRECT: -14,
WALLET_WRONG_ENC_STATE: -15,
WALLET_ENCRYPTION_FAILED: -16,
WALLET_ALREADY_UNLOCKED: -17
};
/**
* Magic string for signing.
* @const {String}