Add more fs::path operator/ and operator+ overloads to prevent unsafe string->path conversions on Windows that would cause strings to be decoded according to the current Windows locale & code page instead of the correct string encoding. Update application code to deal with loss of implicit string->path conversions by calling fs::u8path or fs::PathFromString explicitly, or by just changing variable types from std::string to fs::path to avoid conversions altoghther, or make them happen earlier. In all cases, there's no change in behavior either (1) because strings only contained ASCII characters and would be decoded the same regardless of what encoding was used, or (2) because of the 1:1 mapping between paths and strings using the PathToString and PathFromString functions. Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
56 lines
1.8 KiB
C++
56 lines
1.8 KiB
C++
// Copyright (c) 2021 The Bitcoin Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
//
|
|
#ifndef BITCOIN_TEST_UTIL_CHAINSTATE_H
|
|
#define BITCOIN_TEST_UTIL_CHAINSTATE_H
|
|
|
|
#include <clientversion.h>
|
|
#include <fs.h>
|
|
#include <node/context.h>
|
|
#include <node/utxo_snapshot.h>
|
|
#include <rpc/blockchain.h>
|
|
#include <validation.h>
|
|
|
|
#include <univalue.h>
|
|
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
const auto NoMalleation = [](CAutoFile& file, node::SnapshotMetadata& meta){};
|
|
|
|
/**
|
|
* Create and activate a UTXO snapshot, optionally providing a function to
|
|
* malleate the snapshot.
|
|
*/
|
|
template<typename F = decltype(NoMalleation)>
|
|
static bool
|
|
CreateAndActivateUTXOSnapshot(node::NodeContext& node, const fs::path root, F malleation = NoMalleation)
|
|
{
|
|
// Write out a snapshot to the test's tempdir.
|
|
//
|
|
int height;
|
|
WITH_LOCK(::cs_main, height = node.chainman->ActiveHeight());
|
|
fs::path snapshot_path = root / fs::u8path(tfm::format("test_snapshot.%d.dat", height));
|
|
FILE* outfile{fsbridge::fopen(snapshot_path, "wb")};
|
|
CAutoFile auto_outfile{outfile, SER_DISK, CLIENT_VERSION};
|
|
|
|
UniValue result = CreateUTXOSnapshot(
|
|
node, node.chainman->ActiveChainstate(), auto_outfile, snapshot_path, snapshot_path);
|
|
BOOST_TEST_MESSAGE(
|
|
"Wrote UTXO snapshot to " << fs::PathToString(snapshot_path.make_preferred()) << ": " << result.write());
|
|
|
|
// Read the written snapshot in and then activate it.
|
|
//
|
|
FILE* infile{fsbridge::fopen(snapshot_path, "rb")};
|
|
CAutoFile auto_infile{infile, SER_DISK, CLIENT_VERSION};
|
|
node::SnapshotMetadata metadata;
|
|
auto_infile >> metadata;
|
|
|
|
malleation(auto_infile, metadata);
|
|
|
|
return node.chainman->ActivateSnapshot(auto_infile, metadata, /*in_memory=*/true);
|
|
}
|
|
|
|
|
|
#endif // BITCOIN_TEST_UTIL_CHAINSTATE_H
|