1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
crate::ix!();

/**
  | Access to the block database (blocks/index/)
  |
  */
pub struct BlockTreeDB {
    base: DBWrapper,
}

impl BlockTreeDB {
    
    pub fn write_batch_sync(&mut self, 
        file_info:   &Vec<(i32,*const BlockFileInfo)>,
        n_last_file: i32,
        blockinfo:   &Vec<*const BlockIndex>) -> bool {
        
        todo!();
        /*
            CDBBatch batch(*this);
        for (std::vector<std::pair<int, const BlockFileInfo*> >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) {
            batch.Write(std::make_pair(DB_BLOCK_FILES, it->first), *it->second);
        }
        batch.Write(DB_LAST_BLOCK, nLastFile);
        for (std::vector<const BlockIndex*>::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) {
            batch.Write(std::make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()), CDiskBlockIndex(*it));
        }
        return WriteBatch(batch, true);
        */
    }
    
    pub fn write_flag(&mut self, 
        name:  &String,
        value: bool) -> bool {
        
        todo!();
        /*
            return Write(std::make_pair(DB_FLAG, name), fValue ? uint8_t{'1'} : uint8_t{'0'});
        */
    }
    
    pub fn read_flag(&mut self, 
        name:  &String,
        value: &mut bool) -> bool {
        
        todo!();
        /*
            uint8_t ch;
        if (!Read(std::make_pair(DB_FLAG, name), ch))
            return false;
        fValue = ch == uint8_t{'1'};
        return true;
        */
    }
    
    pub fn load_block_index_guts(&mut self, 
        consensus_params:   &ChainConsensusParams,
        insert_block_index: fn(_0: &u256) -> *mut BlockIndex) -> bool {
        
        todo!();
        /*
            std::unique_ptr<CDBIterator> pcursor(NewIterator());

        pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, uint256()));

        // Load m_block_index
        while (pcursor->Valid()) {
            if (ShutdownRequested()) return false;
            std::pair<uint8_t, uint256> key;
            if (pcursor->GetKey(key) && key.first == DB_BLOCK_INDEX) {
                CDiskBlockIndex diskindex;
                if (pcursor->GetValue(diskindex)) {
                    // Construct block index object
                    BlockIndex* pindexNew = insertBlockIndex(diskindex.GetBlockHash());
                    pindexNew->pprev          = insertBlockIndex(diskindex.hashPrev);
                    pindexNew->nHeight        = diskindex.nHeight;
                    pindexNew->nFile          = diskindex.nFile;
                    pindexNew->nDataPos       = diskindex.nDataPos;
                    pindexNew->nUndoPos       = diskindex.nUndoPos;
                    pindexNew->nVersion       = diskindex.nVersion;
                    pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
                    pindexNew->nTime          = diskindex.nTime;
                    pindexNew->nBits          = diskindex.nBits;
                    pindexNew->nNonce         = diskindex.nNonce;
                    pindexNew->nStatus        = diskindex.nStatus;
                    pindexNew->nTx            = diskindex.nTx;

                    if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, consensusParams))
                        return error("%s: CheckProofOfWork failed: %s", __func__, pindexNew->ToString());

                    pcursor->Next();
                } else {
                    return error("%s: failed to read value", __func__);
                }
            } else {
                break;
            }
        }

        return true;
        */
    }

    pub fn new(
        n_cache_size: usize,
        memory:       Option<bool>,
        wipe:         Option<bool>) -> Self {
        let memory: bool = memory.unwrap_or(false);
        let wipe:   bool = wipe.unwrap_or(false);
    
        todo!();
        /*


            : CDBWrapper(gArgs.GetDataDirNet() / "blocks" / "index", nCacheSize, fMemory, fWipe)
        */
    }
    
    pub fn read_block_file_info(&mut self, 
        n_file: i32,
        info:   &mut BlockFileInfo) -> bool {
        
        todo!();
        /*
            return Read(std::make_pair(DB_BLOCK_FILES, nFile), info);
        */
    }
    
    pub fn write_reindexing(&mut self, reindexing: bool) -> bool {
        
        todo!();
        /*
            if (fReindexing)
            return Write(DB_REINDEX_FLAG, uint8_t{'1'});
        else
            return Erase(DB_REINDEX_FLAG);
        */
    }
    
    pub fn read_reindexing(&mut self, reindexing: &mut bool)  {
        
        todo!();
        /*
            fReindexing = Exists(DB_REINDEX_FLAG);
        */
    }
    
    pub fn read_last_block_file(&mut self, n_file: &mut i32) -> bool {
        
        todo!();
        /*
            return Read(DB_LAST_BLOCK, nFile);
        */
    }
}