| 1541 | } |
| 1542 | |
| 1543 | static RPCHelpMan consumecompactsketch() |
| 1544 | { |
| 1545 | return RPCHelpMan{"consumecompactsketch", |
| 1546 | "\nTakes hex representation of a proposed compact block sketch and fills it in\n" |
| 1547 | "using mempool. Returns the block if complete, and a list\n" |
| 1548 | "of missing transaction indices serialized as a native structure." |
| 1549 | "NOTE: The latest instance of this call will have a partially filled block\n" |
| 1550 | "cached in memory to be used in `consumegetblocktxn` to finalize the block.\n", |
| 1551 | { |
| 1552 | {"sketch", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Hex string of compact block sketch."}, |
| 1553 | }, |
| 1554 | RPCResult{ |
| 1555 | RPCResult::Type::OBJ, "", "", |
| 1556 | { |
| 1557 | {RPCResult::Type::STR_HEX, "blockhex", "The filled block hex. Only returns when block is final"}, |
| 1558 | {RPCResult::Type::STR_HEX, "block_tx_req", "The serialized structure of missing transaction indices, given to serving node"}, |
| 1559 | {RPCResult::Type::STR_HEX, "found_tranasctions", "The serialized list of found transactions to be used in finalizecompactblock"}, |
| 1560 | }, |
| 1561 | }, |
| 1562 | RPCExamples{ |
| 1563 | HelpExampleCli("consumecompactsketch", "<sketch>"), |
| 1564 | }, |
| 1565 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 1566 | { |
| 1567 | UniValue ret(UniValue::VOBJ); |
| 1568 | |
| 1569 | std::vector<unsigned char> compact_block_bytes(ParseHex(request.params[0].get_str())); |
| 1570 | CDataStream ssBlock(compact_block_bytes, SER_NETWORK, PROTOCOL_VERSION); |
| 1571 | CBlockHeaderAndShortTxIDs cmpctblock; |
| 1572 | ssBlock >> cmpctblock; |
| 1573 | |
| 1574 | const NodeContext& node = EnsureAnyNodeContext(request.context); |
| 1575 | LOCK(node.mempool->cs); |
| 1576 | PartiallyDownloadedBlock partialBlock(node.mempool.get()); |
| 1577 | const std::vector<std::pair<uint256, CTransactionRef>> dummy; |
| 1578 | ReadStatus status = partialBlock.InitData(cmpctblock, dummy); |
| 1579 | if (status != READ_STATUS_OK) { |
| 1580 | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Compact block decode failed"); |
| 1581 | } |
| 1582 | |
| 1583 | BlockTransactionsRequest req; |
| 1584 | std::vector<CTransactionRef> found(partialBlock.GetAvailableTx()); |
| 1585 | for (size_t i = 0; i < cmpctblock.BlockTxCount(); i++) { |
| 1586 | if (!partialBlock.IsTxAvailable(i)) { |
| 1587 | req.indexes.push_back(i); |
| 1588 | } |
| 1589 | } |
| 1590 | |
| 1591 | CDataStream ssReq(SER_NETWORK, PROTOCOL_VERSION); |
| 1592 | ssReq << req; |
| 1593 | |
| 1594 | if (req.indexes.empty()) { |
| 1595 | std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>(); |
| 1596 | std::vector<CTransactionRef> dummy; |
| 1597 | ReadStatus status = partialBlock.FillBlock(*pblock, dummy, false /* don't get pow */); |
| 1598 | if (status == READ_STATUS_INVALID) { |
| 1599 | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Bogus crap sketch."); |
| 1600 | } else if (status == READ_STATUS_FAILED) { |
nothing calls this directly
no test coverage detected