mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 23:09:44 -04:00
Remove gArgs global from CreateChainParams to aid testing
This commit is contained in:
parent
e36aa351a3
commit
fa23308e9a
9 changed files with 34 additions and 33 deletions
|
@ -34,7 +34,8 @@ static void DeserializeAndCheckBlockTest(benchmark::Bench& bench)
|
||||||
char a = '\0';
|
char a = '\0';
|
||||||
stream.write(&a, 1); // Prevent compaction
|
stream.write(&a, 1); // Prevent compaction
|
||||||
|
|
||||||
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
|
ArgsManager bench_args;
|
||||||
|
const auto chainParams = CreateChainParams(bench_args, CBaseChainParams::MAIN);
|
||||||
|
|
||||||
bench.unit("block").run([&] {
|
bench.unit("block").run([&] {
|
||||||
CBlock block; // Note that CBlock caches its checked state, so we need to recreate it here
|
CBlock block; // Note that CBlock caches its checked state, so we need to recreate it here
|
||||||
|
|
|
@ -485,16 +485,16 @@ const CChainParams &Params() {
|
||||||
return *globalChainParams;
|
return *globalChainParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<const CChainParams> CreateChainParams(const std::string& chain)
|
std::unique_ptr<const CChainParams> CreateChainParams(const ArgsManager& args, const std::string& chain)
|
||||||
{
|
{
|
||||||
if (chain == CBaseChainParams::MAIN) {
|
if (chain == CBaseChainParams::MAIN) {
|
||||||
return std::unique_ptr<CChainParams>(new CMainParams());
|
return std::unique_ptr<CChainParams>(new CMainParams());
|
||||||
} else if (chain == CBaseChainParams::TESTNET) {
|
} else if (chain == CBaseChainParams::TESTNET) {
|
||||||
return std::unique_ptr<CChainParams>(new CTestNetParams());
|
return std::unique_ptr<CChainParams>(new CTestNetParams());
|
||||||
} else if (chain == CBaseChainParams::SIGNET) {
|
} else if (chain == CBaseChainParams::SIGNET) {
|
||||||
return std::unique_ptr<CChainParams>(new SigNetParams(gArgs));
|
return std::unique_ptr<CChainParams>(new SigNetParams(args));
|
||||||
} else if (chain == CBaseChainParams::REGTEST) {
|
} else if (chain == CBaseChainParams::REGTEST) {
|
||||||
return std::unique_ptr<CChainParams>(new CRegTestParams(gArgs));
|
return std::unique_ptr<CChainParams>(new CRegTestParams(args));
|
||||||
}
|
}
|
||||||
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
|
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
|
||||||
}
|
}
|
||||||
|
@ -502,5 +502,5 @@ std::unique_ptr<const CChainParams> CreateChainParams(const std::string& chain)
|
||||||
void SelectParams(const std::string& network)
|
void SelectParams(const std::string& network)
|
||||||
{
|
{
|
||||||
SelectBaseParams(network);
|
SelectBaseParams(network);
|
||||||
globalChainParams = CreateChainParams(network);
|
globalChainParams = CreateChainParams(gArgs, network);
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@ protected:
|
||||||
* @returns a CChainParams* of the chosen chain.
|
* @returns a CChainParams* of the chosen chain.
|
||||||
* @throws a std::runtime_error if the chain is not supported.
|
* @throws a std::runtime_error if the chain is not supported.
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<const CChainParams> CreateChainParams(const std::string& chain);
|
std::unique_ptr<const CChainParams> CreateChainParams(const ArgsManager& args, const std::string& chain);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the currently selected parameters. This won't change after app
|
* Return the currently selected parameters. This won't change after app
|
||||||
|
|
|
@ -380,10 +380,10 @@ void SetupServerArgs(NodeContext& node)
|
||||||
const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET);
|
const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET);
|
||||||
const auto signetBaseParams = CreateBaseChainParams(CBaseChainParams::SIGNET);
|
const auto signetBaseParams = CreateBaseChainParams(CBaseChainParams::SIGNET);
|
||||||
const auto regtestBaseParams = CreateBaseChainParams(CBaseChainParams::REGTEST);
|
const auto regtestBaseParams = CreateBaseChainParams(CBaseChainParams::REGTEST);
|
||||||
const auto defaultChainParams = CreateChainParams(CBaseChainParams::MAIN);
|
const auto defaultChainParams = CreateChainParams(argsman, CBaseChainParams::MAIN);
|
||||||
const auto testnetChainParams = CreateChainParams(CBaseChainParams::TESTNET);
|
const auto testnetChainParams = CreateChainParams(argsman, CBaseChainParams::TESTNET);
|
||||||
const auto signetChainParams = CreateChainParams(CBaseChainParams::SIGNET);
|
const auto signetChainParams = CreateChainParams(argsman, CBaseChainParams::SIGNET);
|
||||||
const auto regtestChainParams = CreateChainParams(CBaseChainParams::REGTEST);
|
const auto regtestChainParams = CreateChainParams(argsman, CBaseChainParams::REGTEST);
|
||||||
|
|
||||||
// Hidden Options
|
// Hidden Options
|
||||||
std::vector<std::string> hidden_args = {
|
std::vector<std::string> hidden_args = {
|
||||||
|
|
|
@ -94,12 +94,12 @@ void PaymentServer::ipcParseCommandLine(int argc, char* argv[])
|
||||||
SendCoinsRecipient r;
|
SendCoinsRecipient r;
|
||||||
if (GUIUtil::parseBitcoinURI(arg, &r) && !r.address.isEmpty())
|
if (GUIUtil::parseBitcoinURI(arg, &r) && !r.address.isEmpty())
|
||||||
{
|
{
|
||||||
auto tempChainParams = CreateChainParams(CBaseChainParams::MAIN);
|
auto tempChainParams = CreateChainParams(gArgs, CBaseChainParams::MAIN);
|
||||||
|
|
||||||
if (IsValidDestinationString(r.address.toStdString(), *tempChainParams)) {
|
if (IsValidDestinationString(r.address.toStdString(), *tempChainParams)) {
|
||||||
SelectParams(CBaseChainParams::MAIN);
|
SelectParams(CBaseChainParams::MAIN);
|
||||||
} else {
|
} else {
|
||||||
tempChainParams = CreateChainParams(CBaseChainParams::TESTNET);
|
tempChainParams = CreateChainParams(gArgs, CBaseChainParams::TESTNET);
|
||||||
if (IsValidDestinationString(r.address.toStdString(), *tempChainParams)) {
|
if (IsValidDestinationString(r.address.toStdString(), *tempChainParams)) {
|
||||||
SelectParams(CBaseChainParams::TESTNET);
|
SelectParams(CBaseChainParams::TESTNET);
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,7 +198,7 @@ void MinerTestingSetup::TestPackageSelection(const CChainParams& chainparams, co
|
||||||
BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||||
{
|
{
|
||||||
// Note that by default, these tests run with size accounting enabled.
|
// Note that by default, these tests run with size accounting enabled.
|
||||||
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
|
const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
|
||||||
const CChainParams& chainparams = *chainParams;
|
const CChainParams& chainparams = *chainParams;
|
||||||
CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
|
CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
|
||||||
std::unique_ptr<CBlockTemplate> pblocktemplate;
|
std::unique_ptr<CBlockTemplate> pblocktemplate;
|
||||||
|
|
|
@ -14,7 +14,7 @@ BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup)
|
||||||
/* Test calculation of next difficulty target with no constraints applying */
|
/* Test calculation of next difficulty target with no constraints applying */
|
||||||
BOOST_AUTO_TEST_CASE(get_next_work)
|
BOOST_AUTO_TEST_CASE(get_next_work)
|
||||||
{
|
{
|
||||||
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
|
const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
|
||||||
int64_t nLastRetargetTime = 1261130161; // Block #30240
|
int64_t nLastRetargetTime = 1261130161; // Block #30240
|
||||||
CBlockIndex pindexLast;
|
CBlockIndex pindexLast;
|
||||||
pindexLast.nHeight = 32255;
|
pindexLast.nHeight = 32255;
|
||||||
|
@ -26,7 +26,7 @@ BOOST_AUTO_TEST_CASE(get_next_work)
|
||||||
/* Test the constraint on the upper bound for next work */
|
/* Test the constraint on the upper bound for next work */
|
||||||
BOOST_AUTO_TEST_CASE(get_next_work_pow_limit)
|
BOOST_AUTO_TEST_CASE(get_next_work_pow_limit)
|
||||||
{
|
{
|
||||||
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
|
const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
|
||||||
int64_t nLastRetargetTime = 1231006505; // Block #0
|
int64_t nLastRetargetTime = 1231006505; // Block #0
|
||||||
CBlockIndex pindexLast;
|
CBlockIndex pindexLast;
|
||||||
pindexLast.nHeight = 2015;
|
pindexLast.nHeight = 2015;
|
||||||
|
@ -38,7 +38,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_pow_limit)
|
||||||
/* Test the constraint on the lower bound for actual time taken */
|
/* Test the constraint on the lower bound for actual time taken */
|
||||||
BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual)
|
BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual)
|
||||||
{
|
{
|
||||||
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
|
const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
|
||||||
int64_t nLastRetargetTime = 1279008237; // Block #66528
|
int64_t nLastRetargetTime = 1279008237; // Block #66528
|
||||||
CBlockIndex pindexLast;
|
CBlockIndex pindexLast;
|
||||||
pindexLast.nHeight = 68543;
|
pindexLast.nHeight = 68543;
|
||||||
|
@ -50,7 +50,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual)
|
||||||
/* Test the constraint on the upper bound for actual time taken */
|
/* Test the constraint on the upper bound for actual time taken */
|
||||||
BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual)
|
BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual)
|
||||||
{
|
{
|
||||||
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
|
const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
|
||||||
int64_t nLastRetargetTime = 1263163443; // NOTE: Not an actual block time
|
int64_t nLastRetargetTime = 1263163443; // NOTE: Not an actual block time
|
||||||
CBlockIndex pindexLast;
|
CBlockIndex pindexLast;
|
||||||
pindexLast.nHeight = 46367;
|
pindexLast.nHeight = 46367;
|
||||||
|
@ -61,7 +61,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_negative_target)
|
BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_negative_target)
|
||||||
{
|
{
|
||||||
const auto consensus = CreateChainParams(CBaseChainParams::MAIN)->GetConsensus();
|
const auto consensus = CreateChainParams(*m_node.args, CBaseChainParams::MAIN)->GetConsensus();
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
unsigned int nBits;
|
unsigned int nBits;
|
||||||
nBits = UintToArith256(consensus.powLimit).GetCompact(true);
|
nBits = UintToArith256(consensus.powLimit).GetCompact(true);
|
||||||
|
@ -71,7 +71,7 @@ BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_negative_target)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_overflow_target)
|
BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_overflow_target)
|
||||||
{
|
{
|
||||||
const auto consensus = CreateChainParams(CBaseChainParams::MAIN)->GetConsensus();
|
const auto consensus = CreateChainParams(*m_node.args, CBaseChainParams::MAIN)->GetConsensus();
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
unsigned int nBits = ~0x00800000;
|
unsigned int nBits = ~0x00800000;
|
||||||
hash.SetHex("0x1");
|
hash.SetHex("0x1");
|
||||||
|
@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_overflow_target)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_too_easy_target)
|
BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_too_easy_target)
|
||||||
{
|
{
|
||||||
const auto consensus = CreateChainParams(CBaseChainParams::MAIN)->GetConsensus();
|
const auto consensus = CreateChainParams(*m_node.args, CBaseChainParams::MAIN)->GetConsensus();
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
unsigned int nBits;
|
unsigned int nBits;
|
||||||
arith_uint256 nBits_arith = UintToArith256(consensus.powLimit);
|
arith_uint256 nBits_arith = UintToArith256(consensus.powLimit);
|
||||||
|
@ -92,7 +92,7 @@ BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_too_easy_target)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_biger_hash_than_target)
|
BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_biger_hash_than_target)
|
||||||
{
|
{
|
||||||
const auto consensus = CreateChainParams(CBaseChainParams::MAIN)->GetConsensus();
|
const auto consensus = CreateChainParams(*m_node.args, CBaseChainParams::MAIN)->GetConsensus();
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
unsigned int nBits;
|
unsigned int nBits;
|
||||||
arith_uint256 hash_arith = UintToArith256(consensus.powLimit);
|
arith_uint256 hash_arith = UintToArith256(consensus.powLimit);
|
||||||
|
@ -104,7 +104,7 @@ BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_biger_hash_than_target)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_zero_target)
|
BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_zero_target)
|
||||||
{
|
{
|
||||||
const auto consensus = CreateChainParams(CBaseChainParams::MAIN)->GetConsensus();
|
const auto consensus = CreateChainParams(*m_node.args, CBaseChainParams::MAIN)->GetConsensus();
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
unsigned int nBits;
|
unsigned int nBits;
|
||||||
arith_uint256 hash_arith{0};
|
arith_uint256 hash_arith{0};
|
||||||
|
@ -115,7 +115,7 @@ BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_zero_target)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test)
|
BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test)
|
||||||
{
|
{
|
||||||
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
|
const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
|
||||||
std::vector<CBlockIndex> blocks(10000);
|
std::vector<CBlockIndex> blocks(10000);
|
||||||
for (int i = 0; i < 10000; i++) {
|
for (int i = 0; i < 10000; i++) {
|
||||||
blocks[i].pprev = i ? &blocks[i - 1] : nullptr;
|
blocks[i].pprev = i ? &blocks[i - 1] : nullptr;
|
||||||
|
@ -135,9 +135,9 @@ BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sanity_check_chainparams(std::string chainName)
|
void sanity_check_chainparams(const ArgsManager& args, std::string chainName)
|
||||||
{
|
{
|
||||||
const auto chainParams = CreateChainParams(chainName);
|
const auto chainParams = CreateChainParams(args, chainName);
|
||||||
const auto consensus = chainParams->GetConsensus();
|
const auto consensus = chainParams->GetConsensus();
|
||||||
|
|
||||||
// hash genesis is correct
|
// hash genesis is correct
|
||||||
|
@ -164,22 +164,22 @@ void sanity_check_chainparams(std::string chainName)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(ChainParams_MAIN_sanity)
|
BOOST_AUTO_TEST_CASE(ChainParams_MAIN_sanity)
|
||||||
{
|
{
|
||||||
sanity_check_chainparams(CBaseChainParams::MAIN);
|
sanity_check_chainparams(*m_node.args, CBaseChainParams::MAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(ChainParams_REGTEST_sanity)
|
BOOST_AUTO_TEST_CASE(ChainParams_REGTEST_sanity)
|
||||||
{
|
{
|
||||||
sanity_check_chainparams(CBaseChainParams::REGTEST);
|
sanity_check_chainparams(*m_node.args, CBaseChainParams::REGTEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(ChainParams_TESTNET_sanity)
|
BOOST_AUTO_TEST_CASE(ChainParams_TESTNET_sanity)
|
||||||
{
|
{
|
||||||
sanity_check_chainparams(CBaseChainParams::TESTNET);
|
sanity_check_chainparams(*m_node.args, CBaseChainParams::TESTNET);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(ChainParams_SIGNET_sanity)
|
BOOST_AUTO_TEST_CASE(ChainParams_SIGNET_sanity)
|
||||||
{
|
{
|
||||||
sanity_check_chainparams(CBaseChainParams::SIGNET);
|
sanity_check_chainparams(*m_node.args, CBaseChainParams::SIGNET);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
@ -39,7 +39,7 @@ static void TestBlockSubsidyHalvings(int nSubsidyHalvingInterval)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(block_subsidy_test)
|
BOOST_AUTO_TEST_CASE(block_subsidy_test)
|
||||||
{
|
{
|
||||||
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
|
const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
|
||||||
TestBlockSubsidyHalvings(chainParams->GetConsensus()); // As in main
|
TestBlockSubsidyHalvings(chainParams->GetConsensus()); // As in main
|
||||||
TestBlockSubsidyHalvings(150); // As in regtest
|
TestBlockSubsidyHalvings(150); // As in regtest
|
||||||
TestBlockSubsidyHalvings(1000); // Just another interval
|
TestBlockSubsidyHalvings(1000); // Just another interval
|
||||||
|
@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE(block_subsidy_test)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(subsidy_limit_test)
|
BOOST_AUTO_TEST_CASE(subsidy_limit_test)
|
||||||
{
|
{
|
||||||
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
|
const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
|
||||||
CAmount nSum = 0;
|
CAmount nSum = 0;
|
||||||
for (int nHeight = 0; nHeight < 14000000; nHeight += 1000) {
|
for (int nHeight = 0; nHeight < 14000000; nHeight += 1000) {
|
||||||
CAmount nSubsidy = GetBlockSubsidy(nHeight, chainParams->GetConsensus());
|
CAmount nSubsidy = GetBlockSubsidy(nHeight, chainParams->GetConsensus());
|
||||||
|
|
|
@ -223,7 +223,7 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sanity checks of version bit deployments
|
// Sanity checks of version bit deployments
|
||||||
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
|
const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
|
||||||
const Consensus::Params &mainnetParams = chainParams->GetConsensus();
|
const Consensus::Params &mainnetParams = chainParams->GetConsensus();
|
||||||
for (int i=0; i<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
|
for (int i=0; i<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
|
||||||
uint32_t bitmask = VersionBitsMask(mainnetParams, static_cast<Consensus::DeploymentPos>(i));
|
uint32_t bitmask = VersionBitsMask(mainnetParams, static_cast<Consensus::DeploymentPos>(i));
|
||||||
|
@ -250,7 +250,7 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
|
||||||
{
|
{
|
||||||
// Check that ComputeBlockVersion will set the appropriate bit correctly
|
// Check that ComputeBlockVersion will set the appropriate bit correctly
|
||||||
// on mainnet.
|
// on mainnet.
|
||||||
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
|
const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
|
||||||
const Consensus::Params &mainnetParams = chainParams->GetConsensus();
|
const Consensus::Params &mainnetParams = chainParams->GetConsensus();
|
||||||
|
|
||||||
// Use the TESTDUMMY deployment for testing purposes.
|
// Use the TESTDUMMY deployment for testing purposes.
|
||||||
|
|
Loading…
Add table
Reference in a new issue