Changeset View
Changeset View
Standalone View
Standalone View
src/test/miner_tests.cpp
| Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | void TestPackageSelection(Config &config, CScript scriptPubKey, | ||||
| tx.vin.resize(1); | tx.vin.resize(1); | ||||
| tx.vin[0].scriptSig = CScript() << OP_1; | tx.vin[0].scriptSig = CScript() << OP_1; | ||||
| tx.vin[0].prevout.hash = txFirst[0]->GetId(); | tx.vin[0].prevout.hash = txFirst[0]->GetId(); | ||||
| tx.vin[0].prevout.n = 0; | tx.vin[0].prevout.n = 0; | ||||
| tx.vout.resize(1); | tx.vout.resize(1); | ||||
| tx.vout[0].nValue = Amount(5000000000LL - 1000); | tx.vout[0].nValue = Amount(5000000000LL - 1000); | ||||
| // This tx has a low fee: 1000 satoshis. | // This tx has a low fee: 1000 satoshis. | ||||
| // Save this txid for later use. | // Save this txid for later use. | ||||
| uint256 hashParentTx = tx.GetId(); | TxId parentTxId = tx.GetId(); | ||||
| mempool.addUnchecked(hashParentTx, | mempool.addUnchecked(parentTxId, | ||||
| entry.Fee(Amount(1000)) | entry.Fee(Amount(1000)) | ||||
| .Time(GetTime()) | .Time(GetTime()) | ||||
| .SpendsCoinbase(true) | .SpendsCoinbase(true) | ||||
| .FromTx(tx)); | .FromTx(tx)); | ||||
| // This tx has a medium fee: 10000 satoshis. | // This tx has a medium fee: 10000 satoshis. | ||||
| tx.vin[0].prevout.hash = txFirst[1]->GetId(); | tx.vin[0].prevout.hash = txFirst[1]->GetId(); | ||||
| tx.vout[0].nValue = Amount(5000000000LL - 10000); | tx.vout[0].nValue = Amount(5000000000LL - 10000); | ||||
| uint256 hashMediumFeeTx = tx.GetId(); | TxId mediumFeeTxId = tx.GetId(); | ||||
| mempool.addUnchecked(hashMediumFeeTx, | mempool.addUnchecked(mediumFeeTxId, | ||||
| entry.Fee(Amount(10000)) | entry.Fee(Amount(10000)) | ||||
| .Time(GetTime()) | .Time(GetTime()) | ||||
| .SpendsCoinbase(true) | .SpendsCoinbase(true) | ||||
| .FromTx(tx)); | .FromTx(tx)); | ||||
| // This tx has a high fee, but depends on the first transaction. | // This tx has a high fee, but depends on the first transaction. | ||||
| tx.vin[0].prevout.hash = hashParentTx; | tx.vin[0].prevout.hash = parentTxId; | ||||
| // 50k satoshi fee. | // 50k satoshi fee. | ||||
| tx.vout[0].nValue = Amount(5000000000LL - 1000 - 50000); | tx.vout[0].nValue = Amount(5000000000LL - 1000 - 50000); | ||||
| uint256 hashHighFeeTx = tx.GetId(); | TxId highFeeTxId = tx.GetId(); | ||||
| mempool.addUnchecked(hashHighFeeTx, | mempool.addUnchecked(highFeeTxId, | ||||
| entry.Fee(Amount(50000)) | entry.Fee(Amount(50000)) | ||||
| .Time(GetTime()) | .Time(GetTime()) | ||||
| .SpendsCoinbase(false) | .SpendsCoinbase(false) | ||||
| .FromTx(tx)); | .FromTx(tx)); | ||||
| std::unique_ptr<CBlockTemplate> pblocktemplate = | std::unique_ptr<CBlockTemplate> pblocktemplate = | ||||
| BlockAssembler(config).CreateNewBlock(scriptPubKey); | BlockAssembler(config).CreateNewBlock(scriptPubKey); | ||||
| BOOST_CHECK(pblocktemplate->block.vtx[1]->GetId() == hashParentTx); | BOOST_CHECK(pblocktemplate->block.vtx[1]->GetId() == parentTxId); | ||||
| BOOST_CHECK(pblocktemplate->block.vtx[2]->GetId() == hashHighFeeTx); | BOOST_CHECK(pblocktemplate->block.vtx[2]->GetId() == highFeeTxId); | ||||
| BOOST_CHECK(pblocktemplate->block.vtx[3]->GetId() == hashMediumFeeTx); | BOOST_CHECK(pblocktemplate->block.vtx[3]->GetId() == mediumFeeTxId); | ||||
| // Test that a package below the block min tx fee doesn't get included | // Test that a package below the block min tx fee doesn't get included | ||||
| tx.vin[0].prevout.hash = hashHighFeeTx; | tx.vin[0].prevout.hash = highFeeTxId; | ||||
| // 0 fee. | // 0 fee. | ||||
| tx.vout[0].nValue = Amount(5000000000LL - 1000 - 50000); | tx.vout[0].nValue = Amount(5000000000LL - 1000 - 50000); | ||||
| uint256 hashFreeTx = tx.GetId(); | TxId freeTxId = tx.GetId(); | ||||
| mempool.addUnchecked(hashFreeTx, entry.Fee(Amount(0)).FromTx(tx)); | mempool.addUnchecked(freeTxId, entry.Fee(Amount(0)).FromTx(tx)); | ||||
| size_t freeTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); | size_t freeTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); | ||||
| // Calculate a fee on child transaction that will put the package just | // Calculate a fee on child transaction that will put the package just | ||||
| // below the block min tx fee (assuming 1 child tx of the same size). | // below the block min tx fee (assuming 1 child tx of the same size). | ||||
| Amount feeToUse = blockMinFeeRate.GetFee(2 * freeTxSize) - Amount(1); | Amount feeToUse = blockMinFeeRate.GetFee(2 * freeTxSize) - Amount(1); | ||||
| tx.vin[0].prevout.hash = hashFreeTx; | tx.vin[0].prevout.hash = freeTxId; | ||||
| tx.vout[0].nValue = Amount(5000000000LL - 1000 - 50000) - feeToUse; | tx.vout[0].nValue = Amount(5000000000LL - 1000 - 50000) - feeToUse; | ||||
| uint256 hashLowFeeTx = tx.GetId(); | TxId lowFeeTxId = tx.GetId(); | ||||
| mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse).FromTx(tx)); | mempool.addUnchecked(lowFeeTxId, entry.Fee(feeToUse).FromTx(tx)); | ||||
| pblocktemplate = BlockAssembler(config).CreateNewBlock(scriptPubKey); | pblocktemplate = BlockAssembler(config).CreateNewBlock(scriptPubKey); | ||||
| // Verify that the free tx and the low fee tx didn't get selected. | // Verify that the free tx and the low fee tx didn't get selected. | ||||
| for (size_t i = 0; i < pblocktemplate->block.vtx.size(); ++i) { | for (const auto &txn : pblocktemplate->block.vtx) { | ||||
| BOOST_CHECK(pblocktemplate->block.vtx[i]->GetId() != hashFreeTx); | BOOST_CHECK(txn->GetId() != freeTxId); | ||||
| BOOST_CHECK(pblocktemplate->block.vtx[i]->GetId() != hashLowFeeTx); | BOOST_CHECK(txn->GetId() != lowFeeTxId); | ||||
| } | } | ||||
| // Test that packages above the min relay fee do get included, even if one | // Test that packages above the min relay fee do get included, even if one | ||||
| // of the transactions is below the min relay fee. Remove the low fee | // of the transactions is below the min relay fee. Remove the low fee | ||||
| // transaction and replace with a higher fee transaction | // transaction and replace with a higher fee transaction | ||||
| mempool.removeRecursive(CTransaction(tx)); | mempool.removeRecursive(CTransaction(tx)); | ||||
| // Now we should be just over the min relay fee. | // Now we should be just over the min relay fee. | ||||
| tx.vout[0].nValue -= Amount(2); | tx.vout[0].nValue -= Amount(2); | ||||
| hashLowFeeTx = tx.GetId(); | lowFeeTxId = tx.GetId(); | ||||
| mempool.addUnchecked(hashLowFeeTx, | mempool.addUnchecked(lowFeeTxId, | ||||
| entry.Fee(feeToUse + Amount(2)).FromTx(tx)); | entry.Fee(feeToUse + Amount(2)).FromTx(tx)); | ||||
| pblocktemplate = BlockAssembler(config).CreateNewBlock(scriptPubKey); | pblocktemplate = BlockAssembler(config).CreateNewBlock(scriptPubKey); | ||||
| BOOST_CHECK(pblocktemplate->block.vtx[4]->GetId() == hashFreeTx); | BOOST_CHECK(pblocktemplate->block.vtx[4]->GetId() == freeTxId); | ||||
| BOOST_CHECK(pblocktemplate->block.vtx[5]->GetId() == hashLowFeeTx); | BOOST_CHECK(pblocktemplate->block.vtx[5]->GetId() == lowFeeTxId); | ||||
| // Test that transaction selection properly updates ancestor fee | // Test that transaction selection properly updates ancestor fee | ||||
| // calculations as ancestor transactions get included in a block. Add a | // calculations as ancestor transactions get included in a block. Add a | ||||
| // 0-fee transaction that has 2 outputs. | // 0-fee transaction that has 2 outputs. | ||||
| tx.vin[0].prevout.hash = txFirst[2]->GetId(); | tx.vin[0].prevout.hash = txFirst[2]->GetId(); | ||||
| tx.vout.resize(2); | tx.vout.resize(2); | ||||
| tx.vout[0].nValue = Amount(5000000000LL - 100000000); | tx.vout[0].nValue = Amount(5000000000LL - 100000000); | ||||
| // 1BCC output. | // 1BCC output. | ||||
| tx.vout[1].nValue = Amount(100000000); | tx.vout[1].nValue = Amount(100000000); | ||||
| uint256 hashFreeTx2 = tx.GetId(); | TxId freeTxId2 = tx.GetId(); | ||||
| mempool.addUnchecked(hashFreeTx2, | mempool.addUnchecked(freeTxId2, | ||||
| entry.Fee(Amount(0)).SpendsCoinbase(true).FromTx(tx)); | entry.Fee(Amount(0)).SpendsCoinbase(true).FromTx(tx)); | ||||
| // This tx can't be mined by itself. | // This tx can't be mined by itself. | ||||
| tx.vin[0].prevout.hash = hashFreeTx2; | tx.vin[0].prevout.hash = freeTxId2; | ||||
| tx.vout.resize(1); | tx.vout.resize(1); | ||||
| feeToUse = blockMinFeeRate.GetFee(freeTxSize); | feeToUse = blockMinFeeRate.GetFee(freeTxSize); | ||||
| tx.vout[0].nValue = Amount(5000000000LL) - Amount(100000000) - feeToUse; | tx.vout[0].nValue = Amount(5000000000LL) - Amount(100000000) - feeToUse; | ||||
| uint256 hashLowFeeTx2 = tx.GetId(); | TxId lowFeeTxId2 = tx.GetId(); | ||||
| mempool.addUnchecked(hashLowFeeTx2, | mempool.addUnchecked(lowFeeTxId2, | ||||
| entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx)); | entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx)); | ||||
| pblocktemplate = BlockAssembler(config).CreateNewBlock(scriptPubKey); | pblocktemplate = BlockAssembler(config).CreateNewBlock(scriptPubKey); | ||||
| // Verify that this tx isn't selected. | // Verify that this tx isn't selected. | ||||
| for (size_t i = 0; i < pblocktemplate->block.vtx.size(); ++i) { | for (const auto &txn : pblocktemplate->block.vtx) { | ||||
| BOOST_CHECK(pblocktemplate->block.vtx[i]->GetId() != hashFreeTx2); | BOOST_CHECK(txn->GetId() != freeTxId2); | ||||
| BOOST_CHECK(pblocktemplate->block.vtx[i]->GetId() != hashLowFeeTx2); | BOOST_CHECK(txn->GetId() != lowFeeTxId2); | ||||
| } | } | ||||
| // This tx will be mineable, and should cause hashLowFeeTx2 to be selected | // This tx will be mineable, and should cause lowFeeTxId2 to be selected | ||||
| // as well. | // as well. | ||||
| tx.vin[0].prevout.n = 1; | tx.vin[0].prevout.n = 1; | ||||
| // 10k satoshi fee. | // 10k satoshi fee. | ||||
| tx.vout[0].nValue = Amount(100000000 - 10000); | tx.vout[0].nValue = Amount(100000000 - 10000); | ||||
| mempool.addUnchecked(tx.GetId(), entry.Fee(Amount(10000)).FromTx(tx)); | mempool.addUnchecked(tx.GetId(), entry.Fee(Amount(10000)).FromTx(tx)); | ||||
| pblocktemplate = BlockAssembler(config).CreateNewBlock(scriptPubKey); | pblocktemplate = BlockAssembler(config).CreateNewBlock(scriptPubKey); | ||||
| BOOST_CHECK(pblocktemplate->block.vtx[8]->GetId() == hashLowFeeTx2); | BOOST_CHECK(pblocktemplate->block.vtx[8]->GetId() == lowFeeTxId2); | ||||
| } | } | ||||
| void TestCoinbaseMessageEB(uint64_t eb, std::string cbmsg) { | void TestCoinbaseMessageEB(uint64_t eb, std::string cbmsg) { | ||||
| GlobalConfig config; | GlobalConfig config; | ||||
| config.SetMaxBlockSize(eb); | config.SetMaxBlockSize(eb); | ||||
| CScript scriptPubKey = | CScript scriptPubKey = | ||||
| ▲ Show 20 Lines • Show All 579 Lines • Show Last 20 Lines | |||||