| 1419 | } |
| 1420 | |
| 1421 | static RPCHelpMan combineblocksigs() |
| 1422 | { |
| 1423 | return RPCHelpMan{"combineblocksigs", |
| 1424 | "\nMerges signatures on a block proposal\n", |
| 1425 | { |
| 1426 | {"blockhex", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex-encoded block from getnewblockhex"}, |
| 1427 | {"signatures", RPCArg::Type::ARR, RPCArg::Optional::NO, "A json array of pubkey/signature pairs", |
| 1428 | { |
| 1429 | {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", |
| 1430 | { |
| 1431 | {"pubkey", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The pubkey for the signature in hex"}, |
| 1432 | {"sig", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A signature (in the form of a hex-encoded scriptSig)"}, |
| 1433 | }, |
| 1434 | }, |
| 1435 | }, |
| 1436 | }, |
| 1437 | {"witnessScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED_NAMED_ARG, "The hex-encoded witnessScript for the signblockscript"}, |
| 1438 | }, |
| 1439 | RPCResult{ |
| 1440 | RPCResult::Type::OBJ, "", "", |
| 1441 | { |
| 1442 | {RPCResult::Type::STR_HEX, "hex", "the signed block"}, |
| 1443 | {RPCResult::Type::BOOL, "complete", "whether the block is complete"}, |
| 1444 | } |
| 1445 | }, |
| 1446 | RPCExamples{ |
| 1447 | HelpExampleCli("combineblocksigs", "<hex> '[{\"pubkey\":\"hex\",\"sig\":\"hex\"}, ...]'"), |
| 1448 | }, |
| 1449 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 1450 | { |
| 1451 | if (!g_signed_blocks) { |
| 1452 | throw JSONRPCError(RPC_MISC_ERROR, "Signed blocks are not active for this network."); |
| 1453 | } |
| 1454 | |
| 1455 | CBlock block; |
| 1456 | if (!DecodeHexBlk(block, request.params[0].get_str())) |
| 1457 | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); |
| 1458 | |
| 1459 | bool is_dynafed = !block.m_dynafed_params.IsNull(); |
| 1460 | |
| 1461 | const Consensus::Params& params = Params().GetConsensus(); |
| 1462 | const UniValue& sigs = request.params[1].get_array(); |
| 1463 | FillableSigningProvider keystore; |
| 1464 | SignatureData sig_data; |
| 1465 | SimpleSignatureCreator signature_creator(block.GetHash(), is_dynafed ? SIGHASH_ALL : 0); |
| 1466 | for (unsigned int i = 0; i < sigs.size(); i++) { |
| 1467 | UniValue pubkey_sig = sigs[i]; |
| 1468 | const std::string& pubkey_str = pubkey_sig["pubkey"].get_str(); |
| 1469 | const std::string& sig_str = pubkey_sig["sig"].get_str(); |
| 1470 | if (!IsHex(sig_str) || !IsHex(pubkey_str)) { |
| 1471 | continue; |
| 1472 | } |
| 1473 | std::vector<unsigned char> pubkey_bytes = ParseHex(pubkey_str); |
| 1474 | std::vector<unsigned char> sig_bytes = ParseHex(sig_str); |
| 1475 | CPubKey pubkey(pubkey_bytes.begin(), pubkey_bytes.end()); |
| 1476 | if (!pubkey.IsFullyValid()) { |
| 1477 | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Bad pubkey"); |
| 1478 | } |
nothing calls this directly
no test coverage detected