diff options
Diffstat (limited to 'src/rpc')
-rw-r--r-- | src/rpc/blockchain.cpp | 37 | ||||
-rw-r--r-- | src/rpc/mempool.cpp | 14 |
2 files changed, 23 insertions, 28 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 0f4941b40c..37a28e414a 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1455,7 +1455,7 @@ static RPCHelpMan getchaintips() } else if (block->nStatus & BLOCK_FAILED_MASK) { // This block or one of its ancestors is invalid. status = "invalid"; - } else if (!block->HaveTxsDownloaded()) { + } else if (!block->HaveNumChainTxs()) { // This block cannot be connected because full block data for it or one of its parents is missing. status = "headers-only"; } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) { @@ -2667,7 +2667,7 @@ UniValue CreateUTXOSnapshot( tip->nHeight, tip->GetBlockHash().ToString(), fs::PathToString(path), fs::PathToString(temppath))); - SnapshotMetadata metadata{tip->GetBlockHash(), maybe_stats->coins_count, tip->nChainTx}; + SnapshotMetadata metadata{tip->GetBlockHash(), maybe_stats->coins_count}; afile << metadata; @@ -2694,9 +2694,7 @@ UniValue CreateUTXOSnapshot( result.pushKV("base_height", tip->nHeight); result.pushKV("path", path.u8string()); result.pushKV("txoutset_hash", maybe_stats->hashSerialized.ToString()); - // Cast required because univalue doesn't have serialization specified for - // `unsigned int`, nChainTx's type. - result.pushKV("nchaintx", uint64_t{tip->nChainTx}); + result.pushKV("nchaintx", tip->nChainTx); return result; } @@ -2707,7 +2705,7 @@ static RPCHelpMan loadtxoutset() "Load the serialized UTXO set from disk.\n" "Once this snapshot is loaded, its contents will be " "deserialized into a second chainstate data structure, which is then used to sync to " - "the network's tip under a security model very much like `assumevalid`. " + "the network's tip. " "Meanwhile, the original chainstate will complete the initial block download process in " "the background, eventually validating up to the block that the snapshot is based upon.\n\n" @@ -2759,7 +2757,7 @@ static RPCHelpMan loadtxoutset() LogPrintf("[snapshot] waiting to see blockheader %s in headers chain before snapshot activation\n", base_blockhash.ToString()); - ChainstateManager& chainman = *node.chainman; + ChainstateManager& chainman = EnsureChainman(node); while (max_secs_to_wait_for_headers > 0) { snapshot_start_block = WITH_LOCK(::cs_main, @@ -2807,6 +2805,7 @@ const std::vector<RPCResult> RPCHelpForChainstate{ {RPCResult::Type::STR_HEX, "snapshot_blockhash", /*optional=*/true, "the base block of the snapshot this chainstate is based on, if any"}, {RPCResult::Type::NUM, "coins_db_cache_bytes", "size of the coinsdb cache"}, {RPCResult::Type::NUM, "coins_tip_cache_bytes", "size of the coinstip cache"}, + {RPCResult::Type::BOOL, "validated", "whether the chainstate is fully validated. True if all blocks in the chainstate were validated, false if the chain is based on a snapshot and the snapshot has not yet been validated."}, }; static RPCHelpMan getchainstates() @@ -2818,8 +2817,7 @@ return RPCHelpMan{ RPCResult{ RPCResult::Type::OBJ, "", "", { {RPCResult::Type::NUM, "headers", "the number of headers seen so far"}, - {RPCResult::Type::OBJ, "normal", /*optional=*/true, "fully validated chainstate containing blocks this node has validated starting from the genesis block", RPCHelpForChainstate}, - {RPCResult::Type::OBJ, "snapshot", /*optional=*/true, "only present if an assumeutxo snapshot is loaded. Partially validated chainstate containing blocks this node has validated starting from the snapshot. After the snapshot is validated (when the 'normal' chainstate advances far enough to validate it), this chainstate will replace and become the 'normal' chainstate.", RPCHelpForChainstate}, + {RPCResult::Type::ARR, "chainstates", "list of the chainstates ordered by work, with the most-work (active) chainstate last", {{RPCResult::Type::OBJ, "", "", RPCHelpForChainstate},}}, } }, RPCExamples{ @@ -2831,10 +2829,9 @@ return RPCHelpMan{ LOCK(cs_main); UniValue obj(UniValue::VOBJ); - NodeContext& node = EnsureAnyNodeContext(request.context); - ChainstateManager& chainman = *node.chainman; + ChainstateManager& chainman = EnsureAnyChainman(request.context); - auto make_chain_data = [&](const Chainstate& cs) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { + auto make_chain_data = [&](const Chainstate& cs, bool validated) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { AssertLockHeld(::cs_main); UniValue data(UniValue::VOBJ); if (!cs.m_chain.Tip()) { @@ -2852,20 +2849,18 @@ return RPCHelpMan{ if (cs.m_from_snapshot_blockhash) { data.pushKV("snapshot_blockhash", cs.m_from_snapshot_blockhash->ToString()); } + data.pushKV("validated", validated); return data; }; - if (chainman.GetAll().size() > 1) { - for (Chainstate* chainstate : chainman.GetAll()) { - obj.pushKV( - chainstate->m_from_snapshot_blockhash ? "snapshot" : "normal", - make_chain_data(*chainstate)); - } - } else { - obj.pushKV("normal", make_chain_data(chainman.ActiveChainstate())); - } obj.pushKV("headers", chainman.m_best_header ? chainman.m_best_header->nHeight : -1); + const auto& chainstates = chainman.GetAll(); + UniValue obj_chainstates{UniValue::VARR}; + for (Chainstate* cs : chainstates) { + obj_chainstates.push_back(make_chain_data(*cs, !cs->m_from_snapshot_blockhash || chainstates.size() == 1)); + } + obj.pushKV("chainstates", std::move(obj_chainstates)); return obj; } }; diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp index 705608bd47..136969eb87 100644 --- a/src/rpc/mempool.cpp +++ b/src/rpc/mempool.cpp @@ -819,11 +819,11 @@ static RPCHelpMan savemempool() static RPCHelpMan submitpackage() { return RPCHelpMan{"submitpackage", - "Submit a package of raw transactions (serialized, hex-encoded) to local node (-regtest only).\n" + "Submit a package of raw transactions (serialized, hex-encoded) to local node.\n" + "The package must consist of a child with its parents, and none of the parents may depend on one another.\n" "The package will be validated according to consensus and mempool policy rules. If all transactions pass, they will be accepted to mempool.\n" "This RPC is experimental and the interface may be unstable. Refer to doc/policy/packages.md for documentation on package policies.\n" - "Warning: until package relay is in use, successful submission does not mean the transaction will propagate to other nodes on the network.\n" - "Currently, each transaction is broadcasted individually after submission, which means they must meet other nodes' feerate requirements alone.\n" + "Warning: successful submission does not mean the transactions will propagate throughout the network.\n" , { {"package", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of raw transactions.", @@ -862,9 +862,6 @@ static RPCHelpMan submitpackage() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - if (Params().GetChainType() != ChainType::REGTEST) { - throw std::runtime_error("submitpackage is for regression testing (-regtest mode) only"); - } const UniValue raw_transactions = request.params[0].get_array(); if (raw_transactions.size() < 1 || raw_transactions.size() > MAX_PACKAGE_COUNT) { throw JSONRPCError(RPC_INVALID_PARAMETER, @@ -881,6 +878,9 @@ static RPCHelpMan submitpackage() } txns.emplace_back(MakeTransactionRef(std::move(mtx))); } + if (!IsChildWithParentsTree(txns)) { + throw JSONRPCTransactionError(TransactionError::INVALID_PACKAGE, "package topology disallowed. not child-with-parents or parents depend on each other."); + } NodeContext& node = EnsureAnyNodeContext(request.context); CTxMemPool& mempool = EnsureMemPool(node); @@ -983,7 +983,7 @@ void RegisterMempoolRPCCommands(CRPCTable& t) {"blockchain", &getrawmempool}, {"blockchain", &importmempool}, {"blockchain", &savemempool}, - {"hidden", &submitpackage}, + {"rawtransactions", &submitpackage}, }; for (const auto& c : commands) { t.appendCommand(c.name, &c); |