Skip to content

Commit 1ed0dc9

Browse files
authored
Merge pull request #1731 from evoskuil/master
Add mutable chain_state field and const get/set for header/block.
2 parents 963a84b + c279464 commit 1ed0dc9

4 files changed

Lines changed: 68 additions & 31 deletions

File tree

include/bitcoin/system/chain/block.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define LIBBITCOIN_SYSTEM_CHAIN_BLOCK_HPP
2121

2222
#include <memory>
23+
#include <bitcoin/system/chain/chain_state.hpp>
2324
#include <bitcoin/system/chain/context.hpp>
2425
#include <bitcoin/system/chain/header.hpp>
2526
#include <bitcoin/system/chain/input.hpp>
@@ -105,15 +106,20 @@ class BC_API block
105106
bool is_malleable64() const NOEXCEPT;
106107
bool is_malleated64() const NOEXCEPT;
107108

108-
/// Cache setters/getters, not thread safe.
109+
/// Cache and metadata.
109110
/// -----------------------------------------------------------------------
111+
/// getters/setters, const/mutable, not thread safe.
110112

111113
/// Cache (overrides hash() computation).
112114
void set_hashes(const data_chunk& data) NOEXCEPT;
113115

114116
/// Reference used to avoid copy, sets cache if not set.
115117
const hash_digest& get_hash() const NOEXCEPT;
116118

119+
/// Set/get chain_state associated with the block.header, may be nullptr.
120+
void set_state(const chain_state::cptr& state) const NOEXCEPT;
121+
const chain_state::cptr& get_state() const NOEXCEPT;
122+
117123
/// Set/get memory allocation.
118124
void set_allocation(size_t allocation) const NOEXCEPT;
119125
size_t get_allocation() const NOEXCEPT;

include/bitcoin/system/chain/header.hpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,18 +96,23 @@ class BC_API header
9696
uint32_t nonce() const NOEXCEPT;
9797

9898
/// Computed properties.
99-
hash_digest hash() const NOEXCEPT;
10099
uint256_t proof() const NOEXCEPT;
100+
hash_digest hash() const NOEXCEPT;
101101

102-
/// Cache setters/getters, not thread safe.
102+
/// Cache and metadata.
103103
/// -----------------------------------------------------------------------
104+
/// getters/setters, const/mutable, not thread safe.
104105

105-
/// Cache (overrides hash() computation).
106+
/// Set to avoid hash() re-computation.
106107
void set_hash(const hash_digest& hash) const NOEXCEPT;
107108

108109
/// Reference used to avoid copy, sets cache if not set.
109110
const hash_digest& get_hash() const NOEXCEPT;
110111

112+
/// Set/get chain_state associated with the header, may be nullptr.
113+
void set_state(const chain_state::cptr& state) const NOEXCEPT;
114+
const chain_state::cptr& get_state() const NOEXCEPT;
115+
111116
/// Validation.
112117
/// -----------------------------------------------------------------------
113118
/// Checkpoints and previous_block_hash are chain validation (not here).
@@ -153,6 +158,9 @@ class BC_API header
153158

154159
// Identity hash caching.
155160
mutable std::optional<hash_digest> hash_{};
161+
162+
// Chain state caching.
163+
mutable chain_state::cptr state_{};
156164
};
157165

158166
typedef std_vector<header> headers;

src/chain/block.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,16 @@ void block::set_hashes(const data_chunk& data) NOEXCEPT
326326
}
327327
}
328328

329+
const chain_state::cptr& block::get_state() const NOEXCEPT
330+
{
331+
return header_->get_state();
332+
}
333+
334+
void block::set_state(const chain_state::cptr& state) const NOEXCEPT
335+
{
336+
header_->set_state(state);
337+
}
338+
329339
// static/private
330340
block::sizes block::serialized_size(const transaction_cptrs& txs) NOEXCEPT
331341
{

src/chain/header.cpp

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,35 @@ uint32_t header::nonce() const NOEXCEPT
218218
return nonce_;
219219
}
220220

221-
void header::set_hash(const hash_digest& hash) const NOEXCEPT
221+
// static/computed
222+
uint256_t header::proof(uint32_t bits) NOEXCEPT
222223
{
223-
hash_ = hash;
224+
auto target = compact::expand(bits);
225+
226+
//*************************************************************************
227+
// CONSENSUS: bits may be overflowed, which is guarded here.
228+
// A target of zero is disallowed so is useful as a sentinel value.
229+
//*************************************************************************
230+
if (is_zero(target))
231+
return target;
232+
233+
//*************************************************************************
234+
// CONSENSUS: If target is (2^256)-1, division would fail, however compact
235+
// compression is lossy, and therefore unable to produce negative one.
236+
//*************************************************************************
237+
238+
// We need to compute 2**256 / (target + 1), but we can't represent 2**256
239+
// as it's too large for uint256. However as 2**256 is at least as large as
240+
// target + 1, it is equal to ((2**256 - target - 1) / (target + 1)) + 1, or
241+
// (~target / (target + 1)) + 1.
242+
return ++(~target / (target + one));
243+
}
244+
245+
// computed
246+
uint256_t header::proof() const NOEXCEPT
247+
{
248+
// Returns zero if bits_ mantissa is less than one or bits_ is overflowed.
249+
return proof(bits_);
224250
}
225251

226252
// computed
@@ -240,6 +266,14 @@ hash_digest header::hash() const NOEXCEPT
240266
return digest;
241267
}
242268

269+
// Cache and metadata.
270+
// ----------------------------------------------------------------------------
271+
272+
void header::set_hash(const hash_digest& hash) const NOEXCEPT
273+
{
274+
hash_ = hash;
275+
}
276+
243277
const hash_digest& header::get_hash() const NOEXCEPT
244278
{
245279
if (!hash_)
@@ -248,35 +282,14 @@ const hash_digest& header::get_hash() const NOEXCEPT
248282
return *hash_;
249283
}
250284

251-
// static
252-
uint256_t header::proof(uint32_t bits) NOEXCEPT
285+
const chain_state::cptr& header::get_state() const NOEXCEPT
253286
{
254-
auto target = compact::expand(bits);
255-
256-
//*************************************************************************
257-
// CONSENSUS: bits may be overflowed, which is guarded here.
258-
// A target of zero is disallowed so is useful as a sentinel value.
259-
//*************************************************************************
260-
if (is_zero(target))
261-
return target;
262-
263-
//*************************************************************************
264-
// CONSENSUS: If target is (2^256)-1, division would fail, however compact
265-
// compression is lossy, and therefore unable to produce negative one.
266-
//*************************************************************************
267-
268-
// We need to compute 2**256 / (target + 1), but we can't represent 2**256
269-
// as it's too large for uint256. However as 2**256 is at least as large as
270-
// target + 1, it is equal to ((2**256 - target - 1) / (target + 1)) + 1, or
271-
// (~target / (target + 1)) + 1.
272-
return ++(~target / (target + one));
287+
return state_;
273288
}
274289

275-
// computed
276-
uint256_t header::proof() const NOEXCEPT
290+
void header::set_state(const chain_state::cptr& state) const NOEXCEPT
277291
{
278-
// Returns zero if bits_ mantissa is less than one or bits_ is overflowed.
279-
return proof(bits_);
292+
state_ = state;
280293
}
281294

282295
// Check.

0 commit comments

Comments
 (0)