bool version::from_data(reader& source) { reset(); value = source.read_4_bytes_little_endian(); services = source.read_8_bytes_little_endian(); timestamp = source.read_8_bytes_little_endian(); auto result = static_cast<bool>(source); if (result) result = address_me.from_data(source, false); if (result && (value >= 106)) { result = address_you.from_data(source, false); nonce = source.read_8_bytes_little_endian(); user_agent = source.read_string(); if (value >= 209) start_height = source.read_4_bytes_little_endian(); // The satoshi client treats 209 as the "initial protocol version" // and disconnects peers below 31800 (for getheaders support). if (value >= 70001) relay = (source.read_byte() != 0); result &= source; } if (!result) reset(); return result; }
bool operation::from_data(reader& source) { reset(); const auto byte = source.read_byte(); auto result = static_cast<bool>(source); auto op_code = static_cast<opcode>(byte); if (byte == 0 && op_code != opcode::zero) return false; code = ((0 < byte && byte <= 75) ? opcode::special : op_code); if (operation::must_read_data(code)) { uint32_t size; read_opcode_data_size(size, code, byte, source); data = source.read_data(size); result = (source && (data.size() == size)); } 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 header::from_data(uint32_t version, reader& source) { if (!chain::header::from_data(source)) return false; // The header message must trail a zero byte (yes, it's stoopid). // bitcoin.org/en/developer-reference#headers if (version != version::level::canonical && source.read_byte() != 0x00) source.invalidate(); if (!source) reset(); return source; }
bool send_compact::from_data(uint32_t version, reader& source) { reset(); const auto mode = source.read_byte(); if (mode > 1) source.invalidate(); high_bandwidth_mode_ = (mode == 1); this->version_ = source.read_8_bytes_little_endian(); if (version < send_compact::version_minimum) source.invalidate(); if (!source) reset(); return source; }
bool operation::read_opcode_data_size(uint32_t& count, opcode code, uint8_t raw_byte, reader& source) { switch (code) { case opcode::special: count = raw_byte; return true; case opcode::pushdata1: count = source.read_byte(); return true; case opcode::pushdata2: count = source.read_2_bytes_little_endian(); return true; case opcode::pushdata4: count = source.read_4_bytes_little_endian(); return true; default: return false; } }
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; }
bool filter_load::from_data(reader& source) { bool result = false; reset(); uint64_t filter_size = source.read_variable_uint_little_endian(); result = source; if (result) { filter = source.read_data(filter_size); hash_functions = source.read_4_bytes_little_endian(); tweak = source.read_4_bytes_little_endian(); flags = source.read_byte(); result = source && (filter.size() == filter_size); } if (!result) reset(); return result; }