22// Distributed under the MIT software license, see the accompanying
33// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44
5+ #include < chainparams.h>
56#include < index/txindex.h>
67#include < init.h>
78#include < tinyformat.h>
1011#include < validation.h>
1112#include < warnings.h>
1213
14+ constexpr int64_t SYNC_LOG_INTERVAL = 30 ; // seconds
15+ constexpr int64_t SYNC_LOCATOR_WRITE_INTERVAL = 30 ; // seconds
16+
1317template <typename ... Args>
1418static void FatalError (const char * fmt, const Args&... args)
1519{
@@ -47,6 +51,75 @@ bool TxIndex::Init()
4751 return true ;
4852}
4953
54+ static const CBlockIndex* NextSyncBlock (const CBlockIndex* pindex_prev)
55+ {
56+ AssertLockHeld (cs_main);
57+
58+ if (!pindex_prev) {
59+ return chainActive.Genesis ();
60+ }
61+
62+ const CBlockIndex* pindex = chainActive.Next (pindex_prev);
63+ if (pindex) {
64+ return pindex;
65+ }
66+
67+ return chainActive.Next (chainActive.FindFork (pindex_prev));
68+ }
69+
70+ void TxIndex::ThreadSync ()
71+ {
72+ const CBlockIndex* pindex = m_best_block_index.load ();
73+ if (!m_synced) {
74+ auto & consensus_params = Params ().GetConsensus ();
75+
76+ int64_t last_log_time = 0 ;
77+ int64_t last_locator_write_time = 0 ;
78+ while (true ) {
79+ {
80+ LOCK (cs_main);
81+ const CBlockIndex* pindex_next = NextSyncBlock (pindex);
82+ if (!pindex_next) {
83+ WriteBestBlock (pindex);
84+ m_best_block_index = pindex;
85+ m_synced = true ;
86+ break ;
87+ }
88+ pindex = pindex_next;
89+ }
90+
91+ int64_t current_time = GetTime ();
92+ if (last_log_time + SYNC_LOG_INTERVAL < current_time) {
93+ LogPrintf (" Syncing txindex with block chain from height %d\n " , pindex->nHeight );
94+ last_log_time = current_time;
95+ }
96+
97+ if (last_locator_write_time + SYNC_LOCATOR_WRITE_INTERVAL < current_time) {
98+ WriteBestBlock (pindex);
99+ last_locator_write_time = current_time;
100+ }
101+
102+ CBlock block;
103+ if (!ReadBlockFromDisk (block, pindex, consensus_params)) {
104+ FatalError (" %s: Failed to read block %s from disk" ,
105+ __func__, pindex->GetBlockHash ().ToString ());
106+ return ;
107+ }
108+ if (!WriteBlock (block, pindex)) {
109+ FatalError (" %s: Failed to write block %s to tx index database" ,
110+ __func__, pindex->GetBlockHash ().ToString ());
111+ return ;
112+ }
113+ }
114+ }
115+
116+ if (pindex) {
117+ LogPrintf (" txindex is enabled at height %d\n " , pindex->nHeight );
118+ } else {
119+ LogPrintf (" txindex is enabled\n " );
120+ }
121+ }
122+
50123bool TxIndex::WriteBlock (const CBlock& block, const CBlockIndex* pindex)
51124{
52125 CDiskTxPos pos (pindex->GetBlockPos (), GetSizeOfCompactSize (block.vtx .size ()));
@@ -59,6 +132,15 @@ bool TxIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
59132 return m_db->WriteTxs (vPos);
60133}
61134
135+ bool TxIndex::WriteBestBlock (const CBlockIndex* block_index)
136+ {
137+ LOCK (cs_main);
138+ if (!m_db->WriteBestBlock (chainActive.GetLocator (block_index))) {
139+ return error (" %s: Failed to write locator to disk" , __func__);
140+ }
141+ return true ;
142+ }
143+
62144void TxIndex::BlockConnected (const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex,
63145 const std::vector<CTransactionRef>& txn_conflicted)
64146{
@@ -149,9 +231,16 @@ void TxIndex::Start()
149231 FatalError (" %s: txindex failed to initialize" , __func__);
150232 return ;
151233 }
234+
235+ m_thread_sync = std::thread (&TraceThread<std::function<void ()>>, " txindex" ,
236+ std::bind (&TxIndex::ThreadSync, this ));
152237}
153238
154239void TxIndex::Stop ()
155240{
156241 UnregisterValidationInterface (this );
242+
243+ if (m_thread_sync.joinable ()) {
244+ m_thread_sync.join ();
245+ }
157246}
0 commit comments