/* Deserialize a block structure from a flat array. */ static void block_deserialize(struct block *b, unsigned char buf[SERIALIZED_BLOCK_LEN]) { const unsigned char *p, *endp; unsigned char uint32_buf[4]; p = buf; endp = buf + SERIALIZED_BLOCK_LEN; deserialize(&p, endp, b->prev_block_hash, sizeof(b->prev_block_hash)); deserialize(&p, endp, uint32_buf, sizeof(uint32_buf)); b->height = deserialize_uint32(uint32_buf); deserialize(&p, endp, uint32_buf, sizeof(uint32_buf)); b->nonce = deserialize_uint32(uint32_buf); deserialize(&p, endp, uint32_buf, sizeof(uint32_buf)); b->reward_tx.height = deserialize_uint32(uint32_buf); deserialize(&p, endp, b->reward_tx.prev_transaction_hash, sizeof(b->reward_tx.prev_transaction_hash)); deserialize(&p, endp, b->reward_tx.dest_pubkey.x, sizeof(b->reward_tx.dest_pubkey.x)); deserialize(&p, endp, b->reward_tx.dest_pubkey.y, sizeof(b->reward_tx.dest_pubkey.y)); deserialize(&p, endp, b->reward_tx.src_signature.r, sizeof(b->reward_tx.src_signature.r)); deserialize(&p, endp, b->reward_tx.src_signature.s, sizeof(b->reward_tx.src_signature.s)); deserialize(&p, endp, uint32_buf, sizeof(uint32_buf)); b->normal_tx.height = deserialize_uint32(uint32_buf); deserialize(&p, endp, b->normal_tx.prev_transaction_hash, sizeof(b->normal_tx.prev_transaction_hash)); deserialize(&p, endp, b->normal_tx.dest_pubkey.x, sizeof(b->normal_tx.dest_pubkey.x)); deserialize(&p, endp, b->normal_tx.dest_pubkey.y, sizeof(b->normal_tx.dest_pubkey.y)); deserialize(&p, endp, b->normal_tx.src_signature.r, sizeof(b->normal_tx.src_signature.r)); deserialize(&p, endp, b->normal_tx.src_signature.s, sizeof(b->normal_tx.src_signature.s)); if (p != endp) abort(); }
int deserialize_blockheader(struct buff *buf, btc_block_header *hdr) { int res; res = deserialize_uint32(buf, &hdr->version); res |= deserialize_uint256(buf, &hdr->prevBlock); res |= deserialize_uint256(buf, &hdr->merkleRoot); res |= deserialize_uint32(buf, &hdr->timestamp); res |= deserialize_uint32(buf, &hdr->bits); res |= deserialize_uint32(buf, &hdr->nonce); return res; }
bool deserialize_data(const char *p_stream, uint32_t p_stream_size, uint32_t &r_offset, void *&r_data, uint32_t &r_size) { uint32_t t_size = 0, t_data_size = 0; bool t_success = true; void *t_data = nil; t_success = deserialize_uint32(p_stream, p_stream_size, r_offset, t_data_size); if (t_success) { if (t_data_size == 0) { r_size = 0; return true; } if (r_data == nil) { t_size = t_data_size; MCMemoryAllocate(t_size, t_data); } else { t_size = r_size; t_data = r_data; } t_success = (t_data != nil && t_data_size <= t_size); } if (t_success) { MCMemoryCopy(t_data, p_stream + r_offset, t_data_size); r_data = t_data; r_size = t_size; r_offset += t_data_size; } return t_success; }
int deserialize_varint(struct buff *buf, uint64 *val) { int res; uint8 c; res = deserialize_uint8(buf, &c); if (res) { return res; } if (c < 253) { *val = c; } else if (c == 253) { uint16 len16 = 0; res = deserialize_uint16(buf, &len16); *val = len16; } else if (c == 254) { uint32 len32 = 0; res = deserialize_uint32(buf, &len32); *val = len32; } else { uint64 len64 = 0; res = deserialize_uint64(buf, &len64); *val = len64; } return res; }
int deserialize_inv(struct buff *buf, btc_msg_inv *inv) { int res; res = deserialize_uint32(buf, &inv->type); if (res) { return res; } return deserialize_bytes(buf, &inv->hash, sizeof inv->hash); }
int deserialize_version(struct buff *buf, btc_msg_version *v) { int res; memset(v, 0, sizeof *v); res = deserialize_uint32(buf, &v->version); res |= deserialize_uint64(buf, &v->services); res |= deserialize_uint64(buf, &v->time); res |= deserialize_addr(BTC_PROTO_MIN, buf, &v->addrTo); res |= deserialize_addr(BTC_PROTO_MIN, buf, &v->addrFrom); res |= deserialize_uint64(buf, &v->nonce); res |= deserialize_str(buf, v->strVersion, sizeof v->strVersion); res |= deserialize_uint32(buf, &v->startingHeight); if (v->version >= BTC_PROTO_FILTERING && buff_space_left(buf) > 0) { res |= deserialize_uint8(buf, &v->relayTx); } else { v->relayTx = 1; } ASSERT(buff_space_left(buf) == 0); return res; }
int deserialize_addr(uint32 protversion, struct buff *buf, btc_msg_address *addr) { int res = 0; addr->time = 0; if (protversion >= BTC_PROTO_ADDR_W_TIME) { res = deserialize_uint32(buf, &addr->time); } res |= deserialize_uint64(buf, &addr->services); res |= deserialize_bytes(buf, addr->ip, ARRAYSIZE(addr->ip)); res |= deserialize_uint16(buf, &addr->port); return res; }
int deserialize_tx(struct buff *buf, btc_msg_tx *tx) { uint64 i; int res; res = deserialize_uint32(buf, &tx->version); res |= deserialize_varint(buf, &tx->in_count); tx->tx_in = safe_malloc(tx->in_count * sizeof *tx->tx_in); for (i = 0; i < tx->in_count; i++) { res |= deserialize_uint256(buf, &tx->tx_in[i].prevTxHash); res |= deserialize_uint32(buf, &tx->tx_in[i].prevTxOutIdx); res |= deserialize_varint(buf, &tx->tx_in[i].scriptLength); tx->tx_in[i].scriptSig = safe_malloc(tx->tx_in[i].scriptLength); res |= deserialize_bytes(buf, tx->tx_in[i].scriptSig, tx->tx_in[i].scriptLength); res |= deserialize_uint32(buf, &tx->tx_in[i].sequence); } res |= deserialize_varint(buf, &tx->out_count); tx->tx_out = safe_malloc(tx->out_count * sizeof *tx->tx_out); for (i = 0; i < tx->out_count; i++) { res |= deserialize_uint64(buf, &tx->tx_out[i].value); res |= deserialize_varint(buf, &tx->tx_out[i].scriptLength); tx->tx_out[i].scriptPubKey = safe_malloc(tx->tx_out[i].scriptLength); res |= deserialize_bytes(buf, tx->tx_out[i].scriptPubKey, tx->tx_out[i].scriptLength); } res |= deserialize_uint32(buf, &tx->lock_time); ASSERT_NOT_TESTED(buff_space_left(buf) == 0); return res; }
static bool script_parse_one_op(struct buff *buf, struct script_inst *inst, bool *error) { uint8 opcode; size_t len; int res; ASSERT(buf); ASSERT(inst); ASSERT(error); *error = 0; if (buff_space_left(buf) == 0) { /* done ! */ return 0; } res = deserialize_uint8(buf, &opcode); if (res) { goto error; } inst->opcode = opcode; if (opcode < OP_PUSHDATA1) { len = opcode; } else if (opcode == OP_PUSHDATA1) { uint8 len8; res = deserialize_uint8(buf, &len8); if (res) { goto error; } len = len8; } else if (opcode == OP_PUSHDATA2) { uint16 len16; res = deserialize_uint16(buf, &len16); if (res) { goto error; } len = len16; } else if (opcode == OP_PUSHDATA4) { uint32 len32; res = deserialize_uint32(buf, &len32); if (res) { goto error; } len = len32; } else { /* * opcode with no data. */ inst->data = NULL; inst->len = 0; return 1; } inst->data = buff_curptr(buf); inst->len = len; res = buff_skip(buf, len); if (res) { goto error; } return 1; error: *error = 1; return 0; }