rpc: improve gbt proposal and capabilities handling.
This commit is contained in:
parent
dc6b7b1f10
commit
5ee8a9b306
@ -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)
|
||||
|
||||
@ -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}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user