// Optimize reads by short-circuiting what is unnecessary. // Invalid returns are conflated with skipped, but are store only. bool stealth_record::from_data(reader& source, size_t start_height, const binary& filter) { height_ = source.read_4_bytes_little_endian(); if (height_ < start_height) { reset(); source.skip(serialized_size(false) - sizeof(uint32_t)); return false; } prefix_ = source.read_4_bytes_little_endian(); if (!filter.is_prefix_of(prefix_)) { reset(); source.skip(serialized_size(false) - 2 * sizeof(uint32_t)); return false; } unsigned_ephemeral_ = source.read_hash(); public_key_hash_ = source.read_short_hash(); transaction_hash_ = source.read_hash(); if (!source) reset(); return source; }
bool stealth_record::from_data(reader& source, bool wire) { if (!wire) return from_data(source, 0, {}); reset(); unsigned_ephemeral_ = source.read_hash(); public_key_hash_ = source.read_short_hash(); transaction_hash_ = source.read_hash(); if (!source) reset(); return source; }
bool block_transactions::from_data(uint32_t version, reader& source) { reset(); block_hash_ = source.read_hash(); const auto count = source.read_size_little_endian(); // Guard against potential for arbitrary memory allocation. if (count > max_block_size) source.invalidate(); else transactions_.resize(count); // Order is required. for (auto& tx: transactions_) if (!tx.from_data(source, true)) break; if (version < block_transactions::version_minimum) source.invalidate(); if (!source) reset(); return source; }
bool point::from_data(reader& source, bool wire) { reset(); valid_ = true; hash_ = source.read_hash(); if (wire) { index_ = source.read_4_bytes_little_endian(); } else { index_ = source.read_2_bytes_little_endian(); // Convert 16 bit sentinel to 32 bit sentinel. if (index_ == max_uint16) index_ = null_index; } if (!source) reset(); return source; }
bool merkle_block::from_data(reader& source) { reset(); bool result = header.from_data(source, true); uint64_t hash_count = 0; if (result) { hash_count = source.read_variable_uint_little_endian(); result = source; } for (uint64_t i = 0; (i < hash_count) && result; ++i) { hashes.push_back(source.read_hash()); result = source; } if (result) { auto size = source.read_variable_uint_little_endian(); BITCOIN_ASSERT(size <= bc::max_size_t); const auto flag_count = static_cast<size_t>(size); flags = source.read_data(flag_count); result = source && (flags.size() == flag_count); } if (!result) reset(); return result; }
// Avoid point reuse due to affect on store tx serialization. bool payment_record::from_data(reader& source, bool wire) { valid_ = true; output_ = (source.read_byte() == 1); if (wire) { height_ = source.read_4_bytes_little_endian(); link_ = unlinked; hash_ = source.read_hash(); index_ = source.read_4_bytes_little_endian(); } else { height_ = 0; link_ = source.read_8_bytes_little_endian(); hash_ = null_hash; index_ = source.read_2_bytes_little_endian(); // Convert 16 bit sentinel to 32 bit sentinel. if (index_ == max_uint16) index_ = point::null_index; } data_ = source.read_8_bytes_little_endian(); if (!source) reset(); return source; }
bool point::from_data(reader& source) { auto result = true; reset(); hash = source.read_hash(); index = source.read_4_bytes_little_endian(); result = source; if (!result) reset(); return result; }
bool reject::from_data(reader& source) { bool result = 0; reset(); message = source.read_string(); code = error_code_from_byte(source.read_byte()); reason = source.read_string(); if ((message == chain::block::command) || (message == chain::transaction::command)) { data = source.read_hash(); } result = source; if (!result) reset(); return result; }