MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / SanityCheck

Method SanityCheck

src/txgraph.cpp:2836–2907  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2834}
2835
2836void GenericClusterImpl::SanityCheck(const TxGraphImpl& graph, int level) const
2837{
2838 // There must be an m_mapping for each m_depgraph position (including holes).
2839 assert(m_depgraph.PositionRange() == m_mapping.size());
2840 // The linearization for this Cluster must contain every transaction once.
2841 assert(m_depgraph.TxCount() == m_linearization.size());
2842 // Unless a split is to be applied, the cluster cannot have any holes.
2843 if (!NeedsSplitting()) {
2844 assert(m_depgraph.Positions() == SetType::Fill(m_depgraph.TxCount()));
2845 }
2846
2847 // Compute the chunking of m_linearization.
2848 auto linchunking = ChunkLinearizationInfo(m_depgraph, m_linearization);
2849 unsigned chunk_num{0};
2850
2851 // Verify m_linearization.
2852 SetType m_done;
2853 LinearizationIndex linindex{0};
2854 DepGraphIndex chunk_pos{0}; //!< position within the current chunk
2855 assert(m_depgraph.IsAcyclic());
2856 if (m_linearization.empty()) return;
2857 FeeFrac equal_feerate_prefix = linchunking[chunk_num].feerate;
2858 for (auto lin_pos : m_linearization) {
2859 assert(lin_pos < m_mapping.size());
2860 const auto& entry = graph.m_entries[m_mapping[lin_pos]];
2861 // Check that the linearization is topological.
2862 m_done.Set(lin_pos);
2863 if (IsTopological()) {
2864 assert(m_done.IsSupersetOf(m_depgraph.Ancestors(lin_pos)));
2865 }
2866 // Check that the Entry has a locator pointing back to this Cluster & position within it.
2867 assert(entry.m_locator[level].cluster == this);
2868 assert(entry.m_locator[level].index == lin_pos);
2869 // For main-level entries, check linearization position and chunk feerate.
2870 if (level == 0 && IsAcceptable()) {
2871 assert(entry.m_main_lin_index == linindex);
2872 ++linindex;
2873 if (!linchunking[chunk_num].transactions[lin_pos]) {
2874 // First transaction of a new chunk.
2875 ++chunk_num;
2876 assert(chunk_num < linchunking.size());
2877 chunk_pos = 0;
2878 if (ByRatio{linchunking[chunk_num].feerate} < ByRatio{equal_feerate_prefix}) {
2879 equal_feerate_prefix = linchunking[chunk_num].feerate;
2880 } else {
2881 assert(ByRatio{linchunking[chunk_num].feerate} == ByRatio{equal_feerate_prefix});
2882 equal_feerate_prefix += linchunking[chunk_num].feerate;
2883 }
2884 }
2885 assert(entry.m_main_chunk_feerate == linchunking[chunk_num].feerate);
2886 assert(entry.m_main_equal_feerate_chunk_prefix_size == equal_feerate_prefix.size);
2887 // Verify that an entry in the chunk index exists for every chunk-ending transaction.
2888 ++chunk_pos;
2889 if (graph.m_main_clusterset.m_to_remove.empty()) {
2890 bool is_chunk_end = (chunk_pos == linchunking[chunk_num].transactions.Count());
2891 assert((entry.m_main_chunkindex_iterator != graph.m_main_chunkindex.end()) == is_chunk_end);
2892 if (is_chunk_end) {
2893 auto& chunk_data = *entry.m_main_chunkindex_iterator;

Callers

nothing calls this directly

Calls 15

ChunkLinearizationInfoFunction · 0.85
PositionRangeMethod · 0.80
TxCountMethod · 0.80
IsAcyclicMethod · 0.80
IsPresentMethod · 0.80
IsMissingMethod · 0.80
IsRemovedMethod · 0.80
GetLevelMethod · 0.80
NeedsSplittingMethod · 0.80
TotalMemoryUsageMethod · 0.80
sizeMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected