Browse Source

Merge #10146: Better error handling for submitblock

30f30c0 Add braces to submitblock per current style. (Gregory Maxwell)
4f15ea1 Check transaction count early in submitblock. (Gregory Maxwell)
ada0caa Make GetWitnessCommitmentIndex callable on blocks without a coinbase txn. (Gregory Maxwell)

Tree-SHA512: 02dcd337ad9cdd8e4fa6a42c009d016026d1229c193676ed6fcc9ce55e924fedec57f516ac1e95c3db0985243ba908307338ce783a70416cb292bed881002bfc
0.15
Wladimir J. van der Laan 7 years ago
parent
commit
72bc7e1303
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 25
      src/rpc/mining.cpp
  2. 8
      src/validation.cpp

25
src/rpc/mining.cpp

@ -720,7 +720,7 @@ protected:
UniValue submitblock(const JSONRPCRequest& request) UniValue submitblock(const JSONRPCRequest& request)
{ {
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
throw std::runtime_error( throw std::runtime_error(
"submitblock \"hexdata\" ( \"jsonparametersobject\" )\n" "submitblock \"hexdata\" ( \"jsonparametersobject\" )\n"
"\nAttempts to submit new block to network.\n" "\nAttempts to submit new block to network.\n"
@ -738,11 +738,17 @@ UniValue submitblock(const JSONRPCRequest& request)
+ HelpExampleCli("submitblock", "\"mydata\"") + HelpExampleCli("submitblock", "\"mydata\"")
+ HelpExampleRpc("submitblock", "\"mydata\"") + HelpExampleRpc("submitblock", "\"mydata\"")
); );
}
std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>(); std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>();
CBlock& block = *blockptr; CBlock& block = *blockptr;
if (!DecodeHexBlk(block, request.params[0].get_str())) if (!DecodeHexBlk(block, request.params[0].get_str())) {
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
}
if (block.vtx.empty() || !block.vtx[0]->IsCoinBase()) {
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block does not start with a coinbase");
}
uint256 hash = block.GetHash(); uint256 hash = block.GetHash();
bool fBlockPresent = false; bool fBlockPresent = false;
@ -751,10 +757,12 @@ UniValue submitblock(const JSONRPCRequest& request)
BlockMap::iterator mi = mapBlockIndex.find(hash); BlockMap::iterator mi = mapBlockIndex.find(hash);
if (mi != mapBlockIndex.end()) { if (mi != mapBlockIndex.end()) {
CBlockIndex *pindex = mi->second; CBlockIndex *pindex = mi->second;
if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
return "duplicate"; return "duplicate";
if (pindex->nStatus & BLOCK_FAILED_MASK) }
if (pindex->nStatus & BLOCK_FAILED_MASK) {
return "duplicate-invalid"; return "duplicate-invalid";
}
// Otherwise, we might only have the header - process the block before returning // Otherwise, we might only have the header - process the block before returning
fBlockPresent = true; fBlockPresent = true;
} }
@ -772,14 +780,15 @@ UniValue submitblock(const JSONRPCRequest& request)
RegisterValidationInterface(&sc); RegisterValidationInterface(&sc);
bool fAccepted = ProcessNewBlock(Params(), blockptr, true, NULL); bool fAccepted = ProcessNewBlock(Params(), blockptr, true, NULL);
UnregisterValidationInterface(&sc); UnregisterValidationInterface(&sc);
if (fBlockPresent) if (fBlockPresent) {
{ if (fAccepted && !sc.found) {
if (fAccepted && !sc.found)
return "duplicate-inconclusive"; return "duplicate-inconclusive";
}
return "duplicate"; return "duplicate";
} }
if (!sc.found) if (!sc.found) {
return "inconclusive"; return "inconclusive";
}
return BIP22ValidationResult(sc.state); return BIP22ValidationResult(sc.state);
} }

8
src/validation.cpp

@ -2901,9 +2901,11 @@ bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& pa
static int GetWitnessCommitmentIndex(const CBlock& block) static int GetWitnessCommitmentIndex(const CBlock& block)
{ {
int commitpos = -1; int commitpos = -1;
for (size_t o = 0; o < block.vtx[0]->vout.size(); o++) { if (!block.vtx.empty()) {
if (block.vtx[0]->vout[o].scriptPubKey.size() >= 38 && block.vtx[0]->vout[o].scriptPubKey[0] == OP_RETURN && block.vtx[0]->vout[o].scriptPubKey[1] == 0x24 && block.vtx[0]->vout[o].scriptPubKey[2] == 0xaa && block.vtx[0]->vout[o].scriptPubKey[3] == 0x21 && block.vtx[0]->vout[o].scriptPubKey[4] == 0xa9 && block.vtx[0]->vout[o].scriptPubKey[5] == 0xed) { for (size_t o = 0; o < block.vtx[0]->vout.size(); o++) {
commitpos = o; if (block.vtx[0]->vout[o].scriptPubKey.size() >= 38 && block.vtx[0]->vout[o].scriptPubKey[0] == OP_RETURN && block.vtx[0]->vout[o].scriptPubKey[1] == 0x24 && block.vtx[0]->vout[o].scriptPubKey[2] == 0xaa && block.vtx[0]->vout[o].scriptPubKey[3] == 0x21 && block.vtx[0]->vout[o].scriptPubKey[4] == 0xa9 && block.vtx[0]->vout[o].scriptPubKey[5] == 0xed) {
commitpos = o;
}
} }
} }
return commitpos; return commitpos;

Loading…
Cancel
Save