mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 10:38:42 +01:00
Merge #21121: [test] Small unit test improvements, including helper to make mempool transaction
1363b6c27d
[doc / util] Use comments to clarify time unit for int64_t type. (Amiti Uttarwar)47a7a1687d
[util] Introduce a SetMockTime that takes chrono time (Amiti Uttarwar)df6a5fc1df
[util] Change GetMockTime to return chrono type instead of int (Amiti Uttarwar)a2d908e1da
[test] Throw error instead of segfaulting in failure scenario (Amiti Uttarwar)9a3bbe8fc5
[test] Introduce a unit test helper to create a valid mempool transaction. (Amiti Uttarwar) Pull request description: Some miscellaneous improvements that came up when working on #21061 - The first commit is a helper to make valid mempool transactions & submit via ATMP. Introducing in this PR, using in #21061. - The second commit is a small improvement in `miner_tests.cpp` that uses `BOOST_REQUIRE_EQUAL` to properly terminate the program instead of segfaulting in the failure scenario where the blocks do not include the expected number of transactions. - The third commit changes the function signature of `GetMockTime()` to return a chrono type. - The fourth & fifth commit overload `SetMockTime` to also accept chrono type, and adds documentation to indicate that the `int64_t` function signature is deprecated. ACKs for top commit: vasild: ACK1363b6c27d
Tree-SHA512: c72574d73668ea04ee4c33858f8de68b368780f445e05afb569aaf8564093f8112259b3afe93cf6dc2ee12a1ab5af1130ac73c16416132c1ba2851c054a67d78
This commit is contained in:
commit
569b5ba1dc
@ -203,9 +203,9 @@ std::string BCLog::Logger::LogTimestampStr(const std::string& str)
|
|||||||
strStamped.pop_back();
|
strStamped.pop_back();
|
||||||
strStamped += strprintf(".%06dZ", nTimeMicros%1000000);
|
strStamped += strprintf(".%06dZ", nTimeMicros%1000000);
|
||||||
}
|
}
|
||||||
int64_t mocktime = GetMockTime();
|
std::chrono::seconds mocktime = GetMockTime();
|
||||||
if (mocktime) {
|
if (mocktime > 0s) {
|
||||||
strStamped += " (mocktime: " + FormatISO8601DateTime(mocktime) + ")";
|
strStamped += " (mocktime: " + FormatISO8601DateTime(count_seconds(mocktime)) + ")";
|
||||||
}
|
}
|
||||||
strStamped += ' ' + str;
|
strStamped += ' ' + str;
|
||||||
} else
|
} else
|
||||||
|
@ -123,6 +123,7 @@ void MinerTestingSetup::TestPackageSelection(const CChainParams& chainparams, co
|
|||||||
m_node.mempool->addUnchecked(entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
|
m_node.mempool->addUnchecked(entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
|
||||||
|
|
||||||
std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
|
std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
|
||||||
|
BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 4);
|
||||||
BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashParentTx);
|
BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashParentTx);
|
||||||
BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashHighFeeTx);
|
BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashHighFeeTx);
|
||||||
BOOST_CHECK(pblocktemplate->block.vtx[3]->GetHash() == hashMediumFeeTx);
|
BOOST_CHECK(pblocktemplate->block.vtx[3]->GetHash() == hashMediumFeeTx);
|
||||||
@ -157,6 +158,7 @@ void MinerTestingSetup::TestPackageSelection(const CChainParams& chainparams, co
|
|||||||
hashLowFeeTx = tx.GetHash();
|
hashLowFeeTx = tx.GetHash();
|
||||||
m_node.mempool->addUnchecked(entry.Fee(feeToUse+2).FromTx(tx));
|
m_node.mempool->addUnchecked(entry.Fee(feeToUse+2).FromTx(tx));
|
||||||
pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
|
pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
|
||||||
|
BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 6);
|
||||||
BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashFreeTx);
|
BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashFreeTx);
|
||||||
BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashLowFeeTx);
|
BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashLowFeeTx);
|
||||||
|
|
||||||
@ -191,6 +193,7 @@ void MinerTestingSetup::TestPackageSelection(const CChainParams& chainparams, co
|
|||||||
tx.vout[0].nValue = 100000000 - 10000; // 10k satoshi fee
|
tx.vout[0].nValue = 100000000 - 10000; // 10k satoshi fee
|
||||||
m_node.mempool->addUnchecked(entry.Fee(10000).FromTx(tx));
|
m_node.mempool->addUnchecked(entry.Fee(10000).FromTx(tx));
|
||||||
pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
|
pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
|
||||||
|
BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 9);
|
||||||
BOOST_CHECK(pblocktemplate->block.vtx[8]->GetHash() == hashLowFeeTx2);
|
BOOST_CHECK(pblocktemplate->block.vtx[8]->GetHash() == hashLowFeeTx2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,6 +260,55 @@ CBlock TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransa
|
|||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CMutableTransaction TestChain100Setup::CreateValidMempoolTransaction(CTransactionRef input_transaction,
|
||||||
|
int input_vout,
|
||||||
|
int input_height,
|
||||||
|
CKey input_signing_key,
|
||||||
|
CScript output_destination,
|
||||||
|
CAmount output_amount)
|
||||||
|
{
|
||||||
|
// Transaction we will submit to the mempool
|
||||||
|
CMutableTransaction mempool_txn;
|
||||||
|
|
||||||
|
// Create an input
|
||||||
|
COutPoint outpoint_to_spend(input_transaction->GetHash(), input_vout);
|
||||||
|
CTxIn input(outpoint_to_spend);
|
||||||
|
mempool_txn.vin.push_back(input);
|
||||||
|
|
||||||
|
// Create an output
|
||||||
|
CTxOut output(output_amount, output_destination);
|
||||||
|
mempool_txn.vout.push_back(output);
|
||||||
|
|
||||||
|
// Sign the transaction
|
||||||
|
// - Add the signing key to a keystore
|
||||||
|
FillableSigningProvider keystore;
|
||||||
|
keystore.AddKey(input_signing_key);
|
||||||
|
// - Populate a CoinsViewCache with the unspent output
|
||||||
|
CCoinsView coins_view;
|
||||||
|
CCoinsViewCache coins_cache(&coins_view);
|
||||||
|
AddCoins(coins_cache, *input_transaction.get(), input_height);
|
||||||
|
// - Use GetCoin to properly populate utxo_to_spend,
|
||||||
|
Coin utxo_to_spend;
|
||||||
|
assert(coins_cache.GetCoin(outpoint_to_spend, utxo_to_spend));
|
||||||
|
// - Then add it to a map to pass in to SignTransaction
|
||||||
|
std::map<COutPoint, Coin> input_coins;
|
||||||
|
input_coins.insert({outpoint_to_spend, utxo_to_spend});
|
||||||
|
// - Default signature hashing type
|
||||||
|
int nHashType = SIGHASH_ALL;
|
||||||
|
std::map<int, std::string> input_errors;
|
||||||
|
assert(SignTransaction(mempool_txn, &keystore, input_coins, nHashType, input_errors));
|
||||||
|
|
||||||
|
// Add transaction to the mempool
|
||||||
|
{
|
||||||
|
LOCK(cs_main);
|
||||||
|
const MempoolAcceptResult result = AcceptToMemoryPool(*m_node.mempool.get(), MakeTransactionRef(mempool_txn), /* bypass_limits */ false);
|
||||||
|
assert(result.m_result_type == MempoolAcceptResult::ResultType::VALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mempool_txn;
|
||||||
|
}
|
||||||
|
|
||||||
TestChain100Setup::~TestChain100Setup()
|
TestChain100Setup::~TestChain100Setup()
|
||||||
{
|
{
|
||||||
gArgs.ForceSetArg("-segwitheight", "0");
|
gArgs.ForceSetArg("-segwitheight", "0");
|
||||||
|
@ -123,6 +123,23 @@ struct TestChain100Setup : public RegTestingSetup {
|
|||||||
//! Mine a series of new blocks on the active chain.
|
//! Mine a series of new blocks on the active chain.
|
||||||
void mineBlocks(int num_blocks);
|
void mineBlocks(int num_blocks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a transaction and submit to the mempool.
|
||||||
|
*
|
||||||
|
* @param input_transaction The transaction to spend
|
||||||
|
* @param input_vout The vout to spend from the input_transaction
|
||||||
|
* @param input_height The height of the block that included the input_transaction
|
||||||
|
* @param input_signing_key The key to spend the input_transaction
|
||||||
|
* @param output_destination Where to send the output
|
||||||
|
* @param output_amount How much to send
|
||||||
|
*/
|
||||||
|
CMutableTransaction CreateValidMempoolTransaction(CTransactionRef input_transaction,
|
||||||
|
int input_vout,
|
||||||
|
int input_height,
|
||||||
|
CKey input_signing_key,
|
||||||
|
CScript output_destination,
|
||||||
|
CAmount output_amount = CAmount(1 * COIN));
|
||||||
|
|
||||||
~TestChain100Setup();
|
~TestChain100Setup();
|
||||||
|
|
||||||
bool m_deterministic;
|
bool m_deterministic;
|
||||||
|
@ -53,9 +53,14 @@ void SetMockTime(int64_t nMockTimeIn)
|
|||||||
nMockTime.store(nMockTimeIn, std::memory_order_relaxed);
|
nMockTime.store(nMockTimeIn, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t GetMockTime()
|
void SetMockTime(std::chrono::seconds mock_time_in)
|
||||||
{
|
{
|
||||||
return nMockTime.load(std::memory_order_relaxed);
|
nMockTime.store(mock_time_in.count(), std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::chrono::seconds GetMockTime()
|
||||||
|
{
|
||||||
|
return std::chrono::seconds(nMockTime.load(std::memory_order_relaxed));
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t GetTimeMillis()
|
int64_t GetTimeMillis()
|
||||||
|
@ -43,10 +43,19 @@ int64_t GetTimeMicros();
|
|||||||
/** Returns the system time (not mockable) */
|
/** Returns the system time (not mockable) */
|
||||||
int64_t GetSystemTimeInSeconds(); // Like GetTime(), but not mockable
|
int64_t GetSystemTimeInSeconds(); // Like GetTime(), but not mockable
|
||||||
|
|
||||||
/** For testing. Set e.g. with the setmocktime rpc, or -mocktime argument */
|
/**
|
||||||
|
* DEPRECATED
|
||||||
|
* Use SetMockTime with chrono type
|
||||||
|
*
|
||||||
|
* @param[in] nMockTimeIn Time in seconds.
|
||||||
|
*/
|
||||||
void SetMockTime(int64_t nMockTimeIn);
|
void SetMockTime(int64_t nMockTimeIn);
|
||||||
|
|
||||||
|
/** For testing. Set e.g. with the setmocktime rpc, or -mocktime argument */
|
||||||
|
void SetMockTime(std::chrono::seconds mock_time_in);
|
||||||
|
|
||||||
/** For testing */
|
/** For testing */
|
||||||
int64_t GetMockTime();
|
std::chrono::seconds GetMockTime();
|
||||||
|
|
||||||
/** Return system time (or mocked time, if set) */
|
/** Return system time (or mocked time, if set) */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
Loading…
Reference in New Issue
Block a user