| 984 | }; |
| 985 | |
| 986 | static RPCHelpMan submitblock() |
| 987 | { |
| 988 | // We allow 2 arguments for compliance with BIP22. Argument 2 is ignored. |
| 989 | return RPCHelpMan{"submitblock", |
| 990 | "\nAttempts to submit new block to network.\n" |
| 991 | "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n", |
| 992 | { |
| 993 | {"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block data to submit"}, |
| 994 | {"dummy", RPCArg::Type::STR, RPCArg::DefaultHint{"ignored"}, "dummy value, for compatibility with BIP22. This value is ignored."}, |
| 995 | }, |
| 996 | { |
| 997 | RPCResult{"If the block was accepted", RPCResult::Type::NONE, "", ""}, |
| 998 | RPCResult{"Otherwise", RPCResult::Type::STR, "", "According to BIP22"}, |
| 999 | }, |
| 1000 | RPCExamples{ |
| 1001 | HelpExampleCli("submitblock", "\"mydata\"") |
| 1002 | + HelpExampleRpc("submitblock", "\"mydata\"") |
| 1003 | }, |
| 1004 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 1005 | { |
| 1006 | std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>(); |
| 1007 | CBlock& block = *blockptr; |
| 1008 | if (!DecodeHexBlk(block, request.params[0].get_str())) { |
| 1009 | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); |
| 1010 | } |
| 1011 | |
| 1012 | if (block.vtx.empty() || !block.vtx[0]->IsCoinBase()) { |
| 1013 | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block does not start with a coinbase"); |
| 1014 | } |
| 1015 | |
| 1016 | ChainstateManager& chainman = EnsureAnyChainman(request.context); |
| 1017 | uint256 hash = block.GetHash(); |
| 1018 | { |
| 1019 | LOCK(cs_main); |
| 1020 | const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash); |
| 1021 | if (pindex) { |
| 1022 | if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) { |
| 1023 | return "duplicate"; |
| 1024 | } |
| 1025 | if (pindex->nStatus & BLOCK_FAILED_MASK) { |
| 1026 | return "duplicate-invalid"; |
| 1027 | } |
| 1028 | } |
| 1029 | } |
| 1030 | |
| 1031 | { |
| 1032 | LOCK(cs_main); |
| 1033 | const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock); |
| 1034 | if (pindex) { |
| 1035 | UpdateUncommittedBlockStructures(block, pindex, Params().GetConsensus()); |
| 1036 | } |
| 1037 | } |
| 1038 | |
| 1039 | bool new_block; |
| 1040 | auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash()); |
| 1041 | RegisterSharedValidationInterface(sc); |
| 1042 | bool accepted = chainman.ProcessNewBlock(Params(), blockptr, /*force_processing=*/true, /*new_block=*/&new_block); |
| 1043 | UnregisterSharedValidationInterface(sc); |
nothing calls this directly
no test coverage detected