This file is indexed.

/usr/include/bitcoin/blockchain/leveldb_blockchain.hpp is in libbitcoin-dev 2.0-2.2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/*
 * Copyright (c) 2011-2013 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * libbitcoin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) 
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef LIBBITCOIN_BLOCKCHAIN_LEVELDB_BLOCKCHAIN_HPP
#define LIBBITCOIN_BLOCKCHAIN_LEVELDB_BLOCKCHAIN_HPP

#include <bitcoin/blockchain/blockchain.hpp>

#include <boost/interprocess/sync/file_lock.hpp>
#include <leveldb/db.h>

#include <bitcoin/blockchain/organizer.hpp>
#include <bitcoin/utility/subscriber.hpp>
#include <bitcoin/threadpool.hpp>

namespace libbitcoin {

class leveldb_common;
typedef std::shared_ptr<leveldb_common> leveldb_common_ptr;

class leveldb_blockchain
  : public blockchain
{
public:
    // Used by internal components so need public definition here
    typedef subscriber<
        const std::error_code&, size_t, const block_list&, const block_list&>
            reorganize_subscriber_type;

    typedef std::function<void (const std::error_code)> start_handler;

    leveldb_blockchain(threadpool& pool);
    ~leveldb_blockchain();

    // Non-copyable
    leveldb_blockchain(const leveldb_blockchain&) = delete;
    void operator=(const leveldb_blockchain&) = delete;

    void start(const std::string& prefix, start_handler handle_start);
    void stop();

    void store(const block_type& block,
        store_block_handler handle_store);
    void import(const block_type& block, size_t height,
        import_block_handler handle_import);

    // fetch block header by height
    void fetch_block_header(size_t height,
        fetch_handler_block_header handle_fetch);
    // fetch block header by hash
    void fetch_block_header(const hash_digest& block_hash,
        fetch_handler_block_header handle_fetch);
    // fetch transaction hashes in block by height
    void fetch_block_transaction_hashes(size_t height,
        fetch_handler_block_transaction_hashes handle_fetch);
    // fetch transaction hashes in block by hash
    void fetch_block_transaction_hashes(const hash_digest& block_hash,
        fetch_handler_block_transaction_hashes handle_fetch);
    // fetch height of block by hash
    void fetch_block_height(const hash_digest& block_hash,
        fetch_handler_block_height handle_fetch);
    // fetch height of latest block
    void fetch_last_height(fetch_handler_last_height handle_fetch);
    // fetch transaction by hash
    void fetch_transaction(const hash_digest& transaction_hash,
        fetch_handler_transaction handle_fetch);
    // fetch height and offset within block of transaction by hash
    void fetch_transaction_index(const hash_digest& transaction_hash,
        fetch_handler_transaction_index handle_fetch);
    // fetch spend of an output point
    void fetch_spend(const output_point& outpoint,
        fetch_handler_spend handle_fetch);
    // fetch outputs, values and spends for an address.
    void fetch_history(const payment_address& address,
        fetch_handler_history handle_fetch, size_t from_height=0);

    void subscribe_reorganize(reorganize_handler handle_reorganize);

private:
    typedef std::atomic<size_t> seqlock_type;
    typedef std::unique_ptr<leveldb::DB> database_ptr;
    typedef std::unique_ptr<leveldb::Comparator> comparator_ptr;

    typedef std::function<bool (size_t)> perform_read_functor;

    bool initialize(const std::string& prefix);

    void begin_write();

    template <typename Handler, typename... Args>
    void finish_write(Handler handler, Args&&... args)
    {
        ++seqlock_;
        // seqlock is now even again.
        BITCOIN_ASSERT(seqlock_ % 2 == 0);
        handler(std::forward<Args>(args)...);
    }

    void do_store(const block_type& block,
        store_block_handler handle_store);
    void do_import(const block_type& block, size_t height,
        import_block_handler handle_import);

    // Uses sequence looks to try to read shared data.
    // Try to initiate asynchronous read operation. If it fails then
    // sleep for a small amount of time and then retry read operation.
    void fetch(perform_read_functor perform_read);

    template <typename Handler, typename... Args>
    bool finish_fetch(size_t slock, Handler handler, Args&&... args)
    {
        if (slock != seqlock_)
            return false;
        handler(std::forward<Args>(args)...);
        return true;
    }

    bool fetch_block_header_by_height(size_t height, 
        fetch_handler_block_header handle_fetch, size_t slock);
    bool fetch_block_header_by_hash(const hash_digest& block_hash, 
        fetch_handler_block_header handle_fetch, size_t slock);
    bool do_fetch_block_height(const hash_digest& block_hash,
        fetch_handler_block_height handle_fetch, size_t slock);
    bool do_fetch_last_height(
        fetch_handler_last_height handle_fetch, size_t slock);
    bool do_fetch_transaction(const hash_digest& transaction_hash,
        fetch_handler_transaction handle_fetch, size_t slock);
    bool do_fetch_transaction_index(const hash_digest& transaction_hash,
        fetch_handler_transaction_index handle_fetch, size_t slock);
    bool do_fetch_spend(const output_point& outpoint,
        fetch_handler_spend handle_fetch, size_t slock);
    bool do_fetch_history(const payment_address& address,
        fetch_handler_history handle_fetch, size_t from_height, size_t slock);

    io_service& ios_;
    // Queue for writes to the blockchain.
    async_strand strand_;
    // Queue for serializing reorganization handler calls.
    async_strand reorg_strand_;
    // Lock the database directory with a file lock.
    boost::interprocess::file_lock flock_;
    // seqlock used for writes.
    seqlock_type seqlock_;

    // Comparator to order blocks by height logically.
    // Otherwise the last block in the database
    // might not be the largest height in our blockchain.
    comparator_ptr height_comparator_;
    leveldb::Options open_options_;


    // Blocks indexed by height.
    //   block height -> block header + list(tx_hashes)
    database_ptr db_block_;
    // Block heights indexed by hash (a secondary lookup table).
    //   block hash -> block height
    database_ptr db_block_hash_;
    // Transactions indexed by hash.
    //   tx hash -> tx height + tx index + tx
    database_ptr db_tx_;
    // Lookup whether an output point is spent.
    // Value is the input point spend.
    //   outpoint -> inpoint spend
    database_ptr db_spend_;

    // Address to list of output points + values
    database_ptr db_credit_;
    // Address to list of spend input points.
    database_ptr db_debit_;

    leveldb_common_ptr common_;
    // Organize stuff
    orphans_pool_ptr orphans_;
    chain_keeper_ptr chain_;
    organizer_ptr organize_;

    reorganize_subscriber_type::ptr reorganize_subscriber_;
};

} // namespace libbitcoin

#endif