* Serialize the UTXO set to a file for loading elsewhere. * * @see SnapshotMetadata */
| 2949 | * @see SnapshotMetadata |
| 2950 | */ |
| 2951 | static RPCHelpMan dumptxoutset() |
| 2952 | { |
| 2953 | return RPCHelpMan{ |
| 2954 | "dumptxoutset", |
| 2955 | "Write the serialized UTXO set to disk.", |
| 2956 | { |
| 2957 | {"path", RPCArg::Type::STR, RPCArg::Optional::NO, "Path to the output file. If relative, will be prefixed by datadir."}, |
| 2958 | }, |
| 2959 | RPCResult{ |
| 2960 | RPCResult::Type::OBJ, "", "", |
| 2961 | { |
| 2962 | {RPCResult::Type::NUM, "coins_written", "the number of coins written in the snapshot"}, |
| 2963 | {RPCResult::Type::STR_HEX, "base_hash", "the hash of the base of the snapshot"}, |
| 2964 | {RPCResult::Type::NUM, "base_height", "the height of the base of the snapshot"}, |
| 2965 | {RPCResult::Type::STR, "path", "the absolute path that the snapshot was written to"}, |
| 2966 | {RPCResult::Type::STR_HEX, "txoutset_hash", "the hash of the UTXO set contents"}, |
| 2967 | {RPCResult::Type::NUM, "nchaintx", "the number of transactions in the chain up to and including the base block"}, |
| 2968 | } |
| 2969 | }, |
| 2970 | RPCExamples{ |
| 2971 | HelpExampleCli("dumptxoutset", "utxo.dat") |
| 2972 | }, |
| 2973 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 2974 | { |
| 2975 | const ArgsManager& args{EnsureAnyArgsman(request.context)}; |
| 2976 | const fs::path path = fsbridge::AbsPathJoin(args.GetDataDirNet(), fs::u8path(request.params[0].get_str())); |
| 2977 | // Write to a temporary path and then move into `path` on completion |
| 2978 | // to avoid confusion due to an interruption. |
| 2979 | const fs::path temppath = fsbridge::AbsPathJoin(args.GetDataDirNet(), fs::u8path(request.params[0].get_str() + ".incomplete")); |
| 2980 | |
| 2981 | if (fs::exists(path)) { |
| 2982 | throw JSONRPCError( |
| 2983 | RPC_INVALID_PARAMETER, |
| 2984 | path.u8string() + " already exists. If you are sure this is what you want, " |
| 2985 | "move it out of the way first"); |
| 2986 | } |
| 2987 | |
| 2988 | FILE* file{fsbridge::fopen(temppath, "wb")}; |
| 2989 | CAutoFile afile{file, SER_DISK, CLIENT_VERSION}; |
| 2990 | NodeContext& node = EnsureAnyNodeContext(request.context); |
| 2991 | UniValue result = CreateUTXOSnapshot( |
| 2992 | node, node.chainman->ActiveChainstate(), afile, path, temppath); |
| 2993 | fs::rename(temppath, path); |
| 2994 | |
| 2995 | result.pushKV("path", path.u8string()); |
| 2996 | return result; |
| 2997 | }, |
| 2998 | }; |
| 2999 | } |
| 3000 | |
| 3001 | UniValue CreateUTXOSnapshot( |
| 3002 | NodeContext& node, |
nothing calls this directly
no test coverage detected