| 1053 | } |
| 1054 | |
| 1055 | static RPCHelpMan submitheader() |
| 1056 | { |
| 1057 | return RPCHelpMan{"submitheader", |
| 1058 | "\nDecode the given hexdata as a header and submit it as a candidate chain tip if valid." |
| 1059 | "\nThrows when the header is invalid.\n", |
| 1060 | { |
| 1061 | {"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block header data"}, |
| 1062 | }, |
| 1063 | RPCResult{ |
| 1064 | RPCResult::Type::NONE, "", "None"}, |
| 1065 | RPCExamples{ |
| 1066 | HelpExampleCli("submitheader", "\"aabbcc\"") + |
| 1067 | HelpExampleRpc("submitheader", "\"aabbcc\"") |
| 1068 | }, |
| 1069 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 1070 | { |
| 1071 | CBlockHeader h; |
| 1072 | if (!DecodeHexBlockHeader(h, request.params[0].get_str())) { |
| 1073 | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block header decode failed"); |
| 1074 | } |
| 1075 | ChainstateManager& chainman = EnsureAnyChainman(request.context); |
| 1076 | { |
| 1077 | LOCK(cs_main); |
| 1078 | if (!chainman.m_blockman.LookupBlockIndex(h.hashPrevBlock)) { |
| 1079 | throw JSONRPCError(RPC_VERIFY_ERROR, "Must submit previous header (" + h.hashPrevBlock.GetHex() + ") first"); |
| 1080 | } |
| 1081 | } |
| 1082 | |
| 1083 | BlockValidationState state; |
| 1084 | chainman.ProcessNewBlockHeaders({h}, state, Params()); |
| 1085 | if (state.IsValid()) return NullUniValue; |
| 1086 | if (state.IsError()) { |
| 1087 | throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString()); |
| 1088 | } |
| 1089 | throw JSONRPCError(RPC_VERIFY_ERROR, state.GetRejectReason()); |
| 1090 | }, |
| 1091 | }; |
| 1092 | } |
| 1093 | |
| 1094 | static RPCHelpMan estimatesmartfee() |
| 1095 | { |
nothing calls this directly
no test coverage detected