Changeset View
Standalone View
src/test/policyestimator_tests.cpp
Show First 20 Lines • Show All 244 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) { | ||||
for (int i = 1; i < 10; i++) { | for (int i = 1; i < 10; i++) { | ||||
BOOST_CHECK(mpool.estimateSmartFee(i).GetFeePerK() >= | BOOST_CHECK(mpool.estimateSmartFee(i).GetFeePerK() >= | ||||
mpool.estimateFee(i).GetFeePerK()); | mpool.estimateFee(i).GetFeePerK()); | ||||
BOOST_CHECK(mpool.estimateSmartFee(i).GetFeePerK() >= | BOOST_CHECK(mpool.estimateSmartFee(i).GetFeePerK() >= | ||||
mpool.GetMinFee(1).GetFeePerK()); | mpool.GetMinFee(1).GetFeePerK()); | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(MempoolMinimumFeeEstimate) { | |||||
CTxMemPool mpool; | |||||
TestMemPoolEntryHelper entry; | |||||
// Create a transaction template | |||||
CScript garbage; | |||||
for (unsigned int i = 0; i < 128; i++) { | |||||
garbage.push_back('X'); | |||||
} | |||||
CMutableTransaction tx; | |||||
tx.vin.resize(1); | |||||
tx.vin[0].scriptSig = garbage; | |||||
tx.vout.resize(1); | |||||
tx.vout[0].nValue = Amount::zero(); | |||||
// Create a fake block | |||||
std::vector<CTransactionRef> block; | |||||
int blocknum = 0; | |||||
// Loop through 200 blocks adding trasnsactions so we have a estimateFee | |||||
jasonbcox: trasnsactions -> transactions | |||||
// that is calculable. | |||||
while (blocknum < 200) { | |||||
for (int64_t j = 0; j < 100; j++) { | |||||
// make transaction unique | |||||
tx.vin[0].nSequence = 10000 * blocknum + j; | |||||
TxId txid = tx.GetId(); | |||||
mpool.addUnchecked( | |||||
txid, | |||||
entry.Fee((j + 1) * DEFAULT_BLOCK_MIN_TX_FEE_PER_KB) | |||||
.Time(GetTime()) | |||||
.Priority(0) | |||||
.Height(blocknum) | |||||
.FromTx(tx, &mpool)); | |||||
CTransactionRef ptx = mpool.get(txid); | |||||
block.push_back(ptx); | |||||
} | |||||
mpool.removeForBlock(block, ++blocknum); | |||||
block.clear(); | |||||
} | |||||
// Check that the estimate is above the rolling minimum fee. This should | |||||
// be true since we have not trimmed the mempool. | |||||
BOOST_CHECK(CFeeRate(Amount::zero()) == mpool.estimateFee(1)); | |||||
BOOST_CHECK(mpool.GetMinFee(1) <= mpool.estimateFee(2)); | |||||
BOOST_CHECK(mpool.GetMinFee(1) <= mpool.estimateFee(3)); | |||||
BOOST_CHECK(mpool.GetMinFee(1) <= mpool.estimateFee(4)); | |||||
BOOST_CHECK(mpool.GetMinFee(1) <= mpool.estimateFee(5)); | |||||
jasonbcoxUnsubmitted Not Done Inline Actionsuse a for-loop jasonbcox: use a for-loop | |||||
schancelUnsubmitted Done Inline ActionsNo, then you need crap to figure out which iteration broke. schancel: No, then you need crap to figure out which iteration broke. | |||||
jasonbcoxUnsubmitted Not Done Inline ActionsA simple print statement will make this easily debuggable: for (numBlocks ...) { LogPrint("Verifying estimateFee for %s blocks", numBlocks); BOOST_CHECK(mpool.GetMinFee(1) <= mpool.estimateFee(numBlocks)); } jasonbcox: A simple print statement will make this easily debuggable:
```
for (numBlocks ...) {… | |||||
schancelUnsubmitted Done Inline ActionsCongrats, you saved 0 lines of code. schancel: Congrats, you saved 0 lines of code. | |||||
schancelUnsubmitted Done Inline ActionsI don't agree, and I don't like you blocking me landing code over nits. schancel: I don't agree, and I don't like you blocking me landing code over nits. | |||||
jasonbcoxUnsubmitted Not Done Inline ActionsI don't consider this a nit. Bugs arising from copy-pasted code is a well understood phenomenon. Number of lines of code is mostly irrelevant here. jasonbcox: I don't consider this a nit. Bugs arising from copy-pasted code is a well understood… | |||||
deadalnixUnsubmitted Not Done Inline ActionsI don't think any of you have a very strong case here. As @jasonbcox points out, it's not about line of code - the goal never was to produce a test case as compact as possible. But some level of code repetition in tests can actually be beneficial. See: https://evgenii.com/blog/code-duplication-in-unit-tests/ It wouldn't be outside of tests, but testing code is somewhat different than regular code. I often make the mistake myself of making my test code too dry. deadalnix: I don't think any of you have a very strong case here. As @jasonbcox points out, it's not about… | |||||
// Check that estimateFee returns the minimum rolling fee even when the | |||||
// mempool grows very quickly and no blocks have been mined. | |||||
// Add a bunch of low fee transactions which are not in the mempool | |||||
// And have zero fees. | |||||
CMutableTransaction mtx; | |||||
tx.vin.resize(1); | |||||
tx.vin[0].scriptSig = garbage; | |||||
tx.vout.resize(1); | |||||
block.clear(); | |||||
// Add tons of transactions to the mempool, | |||||
// but don't mine them. | |||||
for (int64_t i = 0; i < 10000; i++) { | |||||
// Mutate the hash | |||||
tx.vin[0].nSequence = 10000 * blocknum + i; | |||||
// Add new transaction to the mempool with a increasing fee | |||||
// The average should end up as 1/2 * 100 * | |||||
// DEFAULT_BLOCK_MIN_TX_FEE_PER_KB | |||||
mpool.addUnchecked(tx.GetId(), | |||||
entry.Fee((i + 1) * DEFAULT_BLOCK_MIN_TX_FEE_PER_KB) | |||||
.Time(GetTime()) | |||||
.Priority(0) | |||||
.Height(blocknum) | |||||
.FromTx(tx, &mpool)); | |||||
} | |||||
// Trim to size. GetMinFee should be more than 1000 * | |||||
// DEFAULT_BLOCK_MIN_TX_FEE_PER_KB But the estimateFee should be | |||||
// unchanged. | |||||
mpool.TrimToSize(1); | |||||
BOOST_CHECK(mpool.GetMinFee(1) >= | |||||
CFeeRate(10000 * DEFAULT_BLOCK_MIN_TX_FEE_PER_KB, | |||||
jasonbcoxUnsubmitted Not Done Inline ActionsComment says 1000. this is 10000. which is correct? jasonbcox: Comment says 1000. this is 10000. which is correct? | |||||
CTransaction(tx).GetTotalSize())); | |||||
for (int i = 1; i < 10; i++) { | |||||
BOOST_CHECK_MESSAGE(mpool.estimateFee(i) == mpool.GetMinFee(1), | |||||
"Confirm blocks has failed on iteration " << i); | |||||
} | |||||
} | |||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |
trasnsactions -> transactions