Bitcoin Core
31.1.0
P2P Digital Currency
Toggle main menu visibility
Loading...
Searching...
No Matches
src
test
disconnected_transactions.cpp
Go to the documentation of this file.
1
// Copyright (c) 2023-present The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
//
5
#include <boost/test/unit_test.hpp>
6
#include <
core_memusage.h
>
7
#include <
kernel/disconnected_transactions.h
>
8
#include <
test/util/setup_common.h
>
9
10
BOOST_FIXTURE_TEST_SUITE
(disconnected_transactions,
TestChain100Setup
)
11
12
13
BOOST_AUTO_TEST_CASE
(disconnectpool_memory_limits)
14
{
15
// Use the coinbase transactions from TestChain100Setup. It doesn't matter whether these
16
// transactions would realistically be in a block together, they just need distinct txids and
17
// uniform size for this test to work.
18
std::vector<CTransactionRef> block_vtx(m_coinbase_txns);
19
BOOST_CHECK_EQUAL
(block_vtx.size(), 100);
20
21
// Roughly estimate sizes to sanity check that DisconnectedBlockTransactions::DynamicMemoryUsage
22
// is within an expected range.
23
24
// Overhead for the hashmap depends on number of buckets
25
std::unordered_map<Txid, CTransaction*, SaltedTxidHasher> temp_map;
26
temp_map.reserve(1);
27
const
size_t
MAP_1{
memusage::DynamicUsage
(temp_map)};
28
temp_map.reserve(100);
29
const
size_t
MAP_100{
memusage::DynamicUsage
(temp_map)};
30
31
const
size_t
TX_USAGE{
RecursiveDynamicUsage
(block_vtx.front())};
32
for
(
const
auto
& tx : block_vtx)
33
BOOST_CHECK_EQUAL
(
RecursiveDynamicUsage
(tx), TX_USAGE);
34
35
// Our overall formula is unordered map overhead + usage per entry.
36
// Implementations may vary, but we're trying to guess the usage of data structures.
37
const
size_t
ENTRY_USAGE_ESTIMATE{
38
TX_USAGE
39
// list entry: 2 pointers (next pointer and prev pointer) + element itself
40
+
memusage::MallocUsage
((2 *
sizeof
(
void
*)) +
sizeof
(
decltype
(block_vtx)::value_type))
41
// unordered map: 1 pointer for the hashtable + key and value
42
+
memusage::MallocUsage
(
sizeof
(
void
*) +
sizeof
(
decltype
(temp_map)::key_type)
43
+
sizeof
(
decltype
(temp_map)::value_type))};
44
45
// DisconnectedBlockTransactions that's just big enough for 1 transaction.
46
{
47
DisconnectedBlockTransactions
disconnectpool{MAP_1 + ENTRY_USAGE_ESTIMATE};
48
// Add just 2 (and not all 100) transactions to keep the unordered map's hashtable overhead
49
// to a minimum and avoid all (instead of all but 1) transactions getting evicted.
50
std::vector<CTransactionRef> two_txns({block_vtx.at(0), block_vtx.at(1)});
51
auto
evicted_txns{disconnectpool.
AddTransactionsFromBlock
(two_txns)};
52
BOOST_CHECK
(disconnectpool.
DynamicMemoryUsage
() <= MAP_1 + ENTRY_USAGE_ESTIMATE);
53
54
// Only 1 transaction can be kept
55
BOOST_CHECK_EQUAL
(1, evicted_txns.size());
56
// Transactions are added from back to front and eviction is FIFO.
57
BOOST_CHECK_EQUAL
(block_vtx.at(1), evicted_txns.front());
58
59
disconnectpool.
clear
();
60
}
61
62
// DisconnectedBlockTransactions with a comfortable maximum memory usage so that nothing is evicted.
63
// Record usage so we can check size limiting in the next test.
64
size_t
usage_full{0};
65
{
66
const
size_t
USAGE_100_OVERESTIMATE{MAP_100 + ENTRY_USAGE_ESTIMATE * 100};
67
DisconnectedBlockTransactions
disconnectpool{USAGE_100_OVERESTIMATE};
68
auto
evicted_txns{disconnectpool.
AddTransactionsFromBlock
(block_vtx)};
69
BOOST_CHECK_EQUAL
(evicted_txns.size(), 0);
70
BOOST_CHECK
(disconnectpool.
DynamicMemoryUsage
() <= USAGE_100_OVERESTIMATE);
71
72
usage_full = disconnectpool.
DynamicMemoryUsage
();
73
74
disconnectpool.
clear
();
75
}
76
77
// DisconnectedBlockTransactions that's just a little too small for all of the transactions.
78
{
79
const
size_t
MAX_MEMUSAGE_99{usage_full -
sizeof
(
void
*)};
80
DisconnectedBlockTransactions
disconnectpool{MAX_MEMUSAGE_99};
81
auto
evicted_txns{disconnectpool.
AddTransactionsFromBlock
(block_vtx)};
82
BOOST_CHECK
(disconnectpool.
DynamicMemoryUsage
() <= MAX_MEMUSAGE_99);
83
84
// Only 1 transaction needed to be evicted
85
BOOST_CHECK_EQUAL
(1, evicted_txns.size());
86
87
// Transactions are added from back to front and eviction is FIFO.
88
// The last transaction of block_vtx should be the first to be evicted.
89
BOOST_CHECK_EQUAL
(block_vtx.back(), evicted_txns.front());
90
91
disconnectpool.
clear
();
92
}
93
}
94
95
BOOST_AUTO_TEST_SUITE_END
()
DisconnectedBlockTransactions
DisconnectedBlockTransactions.
Definition
disconnected_transactions.h:39
DisconnectedBlockTransactions::clear
void clear()
Definition
disconnected_transactions.cpp:78
DisconnectedBlockTransactions::DynamicMemoryUsage
size_t DynamicMemoryUsage() const
Definition
disconnected_transactions.cpp:44
DisconnectedBlockTransactions::AddTransactionsFromBlock
std::vector< CTransactionRef > AddTransactionsFromBlock(const std::vector< CTransactionRef > &vtx)
Add transactions from the block, iterating through vtx in reverse order.
Definition
disconnected_transactions.cpp:49
core_memusage.h
RecursiveDynamicUsage
static size_t RecursiveDynamicUsage(const CScript &script)
Definition
core_memusage.h:12
BOOST_FIXTURE_TEST_SUITE
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END
BOOST_AUTO_TEST_SUITE_END()
disconnected_transactions.h
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(ipc_tests)
Definition
ipc_tests.cpp:13
memusage::DynamicUsage
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
Definition
memusage.h:31
memusage::MallocUsage
static size_t MallocUsage(size_t alloc)
Compute the total memory used by allocating alloc bytes.
Definition
memusage.h:52
BOOST_CHECK_EQUAL
#define BOOST_CHECK_EQUAL(v1, v2)
Definition
object.cpp:17
BOOST_CHECK
#define BOOST_CHECK(expr)
Definition
object.cpp:16
setup_common.h
TestChain100Setup
Testing fixture that pre-creates a 100-block REGTEST-mode block chain.
Definition
setup_common.h:146
Generated on
for Bitcoin Core by
1.17.0