From f877aaaf16e40254bf685b4195b809138501feab Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Mon, 20 Oct 2014 04:18:00 +0000 Subject: [PATCH] Bugfix: submitblock: Use a temporary CValidationState to determine accurately the outcome of ProcessBlock, now that it no longer does the full block validity check --- src/rpcmining.cpp | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index c767835a27..a6494163aa 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -526,6 +526,24 @@ Value getblocktemplate(const Array& params, bool fHelp) return result; } +class submitblock_StateCatcher : public CValidationInterface +{ +public: + uint256 hash; + bool found; + CValidationState state; + + submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), found(false), state() {}; + +protected: + virtual void BlockChecked(const CBlock& block, const CValidationState& stateIn) { + if (block.GetHash() != hash) + return; + found = true; + state = stateIn; + }; +}; + Value submitblock(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) @@ -558,8 +576,22 @@ Value submitblock(const Array& params, bool fHelp) } CValidationState state; + submitblock_StateCatcher sc(pblock.GetHash()); + RegisterValidationInterface(&sc); bool fAccepted = ProcessBlock(state, NULL, &pblock); - if (!fAccepted) + UnregisterValidationInterface(&sc); + if (fAccepted) + { + if (!sc.found) + return "inconclusive"; + state = sc.state; + } + if (state.IsError()) + { + std::string strRejectReason = state.GetRejectReason(); + throw JSONRPCError(RPC_MISC_ERROR, strRejectReason); + } + if (state.IsInvalid()) return "rejected"; // TODO: report validation state return Value::null;