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_block(struct buff *buf, btc_msg_block *blk) { uint64 i; int res; res = deserialize_blockheader(buf, &blk->header); btcmsg_print_header(&blk->header); res |= deserialize_varint(buf, &blk->txCount); Warning("numTx=%llu\n", blk->txCount); blk->tx = safe_malloc(blk->txCount * sizeof *blk->tx); for (i = 0; i < blk->txCount; i++) { res |= deserialize_tx(buf, blk->tx + i); } Warning("sz: %zu vs %zu\n", buff_curlen(buf), buff_maxlen(buf)); ASSERT(buff_space_left(buf) == 0); 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 struct tx_ser_data * txdb_deserialize_tx_data(const void *val, size_t vlen) { struct tx_ser_data *tx; struct buff buf; ASSERT(val); buff_init(&buf, (void *)val, vlen); tx = safe_malloc(sizeof *tx); deserialize_uint256(&buf, &tx->blkHash); deserialize_uint64(&buf, &tx->timestamp); deserialize_varint(&buf, &tx->len); tx->buf = safe_calloc(1, tx->len + 1); deserialize_bytes(&buf, tx->buf, tx->len); ASSERT(buff_space_left(&buf) == 0); return tx; }
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; }