logdb_record* logdb_record_new() { logdb_record* record; record = calloc(1, sizeof(*record)); record->key = cstr_new_sz(32); record->value = cstr_new_sz(128); record->written = false; record->mode = RECORD_TYPE_WRITE; return record; }
void bp_tx_sighash(bu256_t *hash, const cstring *scriptCode, const struct bp_tx *txTo, unsigned int nIn, int nHashType) { if (nIn >= txTo->vin->len) { // nIn out of range bu256_set_u64(hash, 1); return; } // Check for invalid use of SIGHASH_SINGLE if ((nHashType & 0x1f) == SIGHASH_SINGLE) { if (nIn >= txTo->vout->len) { // nOut out of range bu256_set_u64(hash, 1); return; } } cstring *s = cstr_new_sz(512); // Serialize only the necessary parts of the transaction being signed bp_tx_sigserializer(s, scriptCode, txTo, nIn, nHashType); ser_s32(s, nHashType); bu_Hash((unsigned char *) hash, s->str, s->len); cstr_free(s, true); }
cstring *message_str(const unsigned char netmagic[4], const char *command_, const void *data, uint32_t data_len) { cstring *s = cstr_new_sz(P2P_HDR_SZ + data_len); /* network identifier (magic number) */ cstr_append_buf(s, netmagic, 4); /* command string */ char command[12] = {}; strncpy(command, command_, 12); cstr_append_buf(s, command, 12); /* data length */ uint32_t data_len_le = htole32(data_len); cstr_append_buf(s, &data_len_le, 4); /* data checksum */ unsigned char md32[4]; bu_Hash4(md32, data, data_len); cstr_append_buf(s, &md32[0], 4); /* data payload */ if (data_len > 0) cstr_append_buf(s, data, data_len); return s; }
static void test_privkey_valid_enc(const char *base58_str, cstring *payload, bool compress, bool is_testnet) { assert(payload != NULL); cstring *pl = cstr_new_sz(payload->len + 1); cstr_append_buf(pl, payload->str, payload->len); if (compress) cstr_append_c(pl, 1); cstring *b58 = base58_encode_check( is_testnet ? PRIVKEY_ADDRESS_TEST : PRIVKEY_ADDRESS, true, pl->str, pl->len); assert(b58 != NULL); if (strcmp(b58->str, base58_str)) { fprintf(stderr, "base58: have %s, expected %s\n", b58->str, base58_str); assert(!strcmp(b58->str, base58_str)); } cstr_free(b58, true); cstr_free(pl, true); cstr_free(payload, true); }
static void test_privkey_valid_dec(const char *base58_str, cstring *payload, bool compress, bool is_testnet) { assert(payload != NULL); cstring *pl = cstr_new_sz(payload->len + 1); cstr_append_buf(pl, payload->str, payload->len); if (compress) cstr_append_c(pl, 1); unsigned char addrtype; cstring *dec = base58_decode_check(&addrtype, base58_str); assert(dec != NULL); if (is_testnet) assert(addrtype == PRIVKEY_ADDRESS_TEST); else assert(addrtype == PRIVKEY_ADDRESS); if (compress) { assert(dec->len == 33); assert(dec->str[32] == 1); } else assert(dec->len == 32); assert(dec->len == pl->len); assert(memcmp(dec->str, pl->str, pl->len) == 0); cstr_free(dec, true); cstr_free(pl, true); cstr_free(payload, true); }
cstring *ser_wallet(const struct wallet *wlt) { struct bp_key *key; cstring *rs = cstr_new_sz(20 * 1024); /* * ser "root" record */ { cstring *s_root = ser_wallet_root(wlt); cstring *recdata = message_str(wlt->chain->netmagic, "root", s_root->str, s_root->len); cstr_append_buf(rs, recdata->str, recdata->len); cstr_free(recdata, true); cstr_free(s_root, true); } /* ser "privkey" records */ wallet_for_each_key(wlt, key) { void *privkey = NULL; size_t pk_len = 0; bp_privkey_get(key, &privkey, &pk_len); cstring *recdata = message_str(wlt->chain->netmagic, "privkey", privkey, pk_len); free(privkey); cstr_append_buf(rs, recdata->str, recdata->len); cstr_free(recdata, true); }
void btc_node_send_version(btc_node *node) { if (!node) return; /* get new string buffer */ cstring *version_msg_cstr = cstr_new_sz(256); /* copy socket_addr to p2p addr */ btc_p2p_address fromAddr; btc_p2p_address_init(&fromAddr); btc_p2p_address toAddr; btc_p2p_address_init(&toAddr); btc_addr_to_p2paddr(&node->addr, &toAddr); /* create a version message struct */ btc_p2p_version_msg version_msg; memset(&version_msg, 0, sizeof(version_msg)); /* create a serialized version message */ btc_p2p_msg_version_init(&version_msg, &fromAddr, &toAddr, node->nodegroup->clientstr); btc_p2p_msg_version_ser(&version_msg, version_msg_cstr); /* create p2p message */ cstring *p2p_msg = btc_p2p_message_new(node->nodegroup->chainparams->netmagic, BTC_MSG_VERSION, version_msg_cstr->str, version_msg_cstr->len); /* send message */ btc_node_send(node, p2p_msg); /* cleanup */ cstr_free(version_msg_cstr, true); cstr_free(p2p_msg, true); }
cstring* cstr_new(const char* init_str) { if (!init_str || !*init_str) return cstr_new_sz(0); size_t slen = strlen(init_str); return cstr_new_buf(init_str, slen); }
cstring *ser_msg_getblocks(const struct msg_getblocks *gb) { cstring *s = cstr_new_sz(256); ser_bp_locator(s, &gb->locator); ser_u256(s, &gb->hash_stop); return s; }
static cstring *ser_blkinfo(const struct blkinfo *bi) { cstring *rs = cstr_new_sz(sizeof(*bi)); ser_u256(rs, &bi->hash); ser_bp_block(rs, &bi->hdr); return rs; }
void btc_tx_hash(const btc_tx* tx, uint8_t* hashout) { cstring* txser = cstr_new_sz(1024); btc_tx_serialize(txser, tx); sha256_Raw((const uint8_t*)txser->str, txser->len, hashout); sha256_Raw(hashout, 32, hashout); cstr_free(txser, true); }
cstring* cstr_new_buf(const void* buf, size_t sz) { cstring* s = cstr_new_sz(sz); if (!s) return NULL; memcpy(s->str, buf, sz); s->len = sz; s->str[s->len] = 0; return s; }
static void output_data_hex(void) { size_t alloc_len = opt_hexdata ? strlen(opt_hexdata) : 512; cstring *s = cstr_new_sz(alloc_len); ser_bp_tx(s, &tx); char hexstr[(s->len * 2) + 1]; encode_hex(hexstr, s->str, s->len); printf("%s\n", hexstr); cstr_free(s, true); }
btc_bool btc_tx_add_p2sh_hash160_out(btc_tx* tx, int64_t amount, uint8_t* hash160) { btc_tx_out* tx_out = btc_tx_out_new(); tx_out->script_pubkey = cstr_new_sz(1024); btc_script_build_p2sh(tx_out->script_pubkey, hash160); tx_out->value = amount; vector_add(tx->vout, tx_out); return true; }
void btc_tx_out_copy(btc_tx_out* dest, const btc_tx_out* src) { dest->value = src->value; if (!src->script_pubkey) dest->script_pubkey = NULL; else { dest->script_pubkey = cstr_new_sz(src->script_pubkey->len); cstr_append_buf(dest->script_pubkey, src->script_pubkey->str, src->script_pubkey->len); } }
void btc_tx_in_copy(btc_tx_in* dest, const btc_tx_in* src) { memcpy(&dest->prevout, &src->prevout, sizeof(dest->prevout)); dest->sequence = src->sequence; if (!src->script_sig) dest->script_sig = NULL; else { dest->script_sig = cstr_new_sz(src->script_sig->len); cstr_append_buf(dest->script_sig, src->script_sig->str, src->script_sig->len); } }
static void test_txout(const struct bitc_txout *txout) { struct const_buffer buf = { txout->scriptPubKey->str, txout->scriptPubKey->len }; struct bscript_parser bsp; struct bscript_op op; clist *ops = NULL; /* * parse script */ bsp_start(&bsp, &buf); while (bsp_getop(&op, &bsp)) { struct bscript_op *op_p; op_p = memdup(&op, sizeof(op)); ops = clist_append(ops, op_p); } assert(!bsp.error); /* * build script */ clist *tmp = ops; cstring *s = cstr_new_sz(256); while (tmp) { struct bscript_op *op_p; op_p = tmp->data; tmp = tmp->next; if (is_bsp_pushdata(op_p->op)) { bsp_push_data(s, op_p->data.p, op_p->data.len); } else { bsp_push_op(s, op_p->op); } } clist_free_ext(ops, free); /* byte-compare original and newly created scripts */ assert(cstr_equal(s, txout->scriptPubKey)); cstr_free(s, true); }
btc_node* btc_node_new() { btc_node* node; node = calloc(1, sizeof(*node)); node->version_handshake = false; node->state = 0; node->nonce = 0; node->services = 0; node->lastping = 0; node->time_started_con = 0; node->recvBuffer = cstr_new_sz(P2P_MESSAGE_CHUNK_SIZE); return node; }
static cstring *ser_wallet_root(const struct wallet *wlt) { cstring *rs = cstr_new_sz(8); ser_u32(rs, wlt->version); ser_bytes(rs, &wlt->chain->netmagic[0], 4); const uint32_t n_settings = 1; ser_varlen(rs, n_settings); ser_str(rs, "def_acct", 64); ser_varstr(rs, wlt->def_acct); return rs; }
cstring *ser_msg_version(const struct msg_version *mv) { cstring *s = cstr_new_sz(256); ser_u32(s, mv->nVersion); ser_u64(s, mv->nServices); ser_s64(s, mv->nTime); ser_bp_addr(s, MIN_PROTO_VERSION, &mv->addrTo); ser_bp_addr(s, MIN_PROTO_VERSION, &mv->addrFrom); ser_u64(s, mv->nonce); ser_str(s, mv->strSubVer, sizeof(mv->strSubVer)); ser_u32(s, mv->nStartingHeight); return s; }
static bool ser_peerman(struct peer_manager *peers, int fd, const struct chain_info *chain) { /* write "magic number" (constant first file record) */ cstring *rec = message_str(chain->netmagic, "magic.peers", NULL, 0); unsigned int rec_len = rec->len; ssize_t wrc = write(fd, rec->str, rec_len); cstr_free(rec, true); if (wrc != rec_len) return false; if (debugging) fprintf(stderr, "peerman: %zu peers to write\n", clist_length(peers->addrlist)); /* write peer list */ clist *tmp = peers->addrlist; while (tmp) { struct peer *peer; peer = tmp->data; tmp = tmp->next; cstring *msg_data = cstr_new_sz(sizeof(struct peer)); ser_peer(msg_data, CADDR_TIME_VERSION, peer); rec = message_str(chain->netmagic, "peer", msg_data->str, msg_data->len); rec_len = rec->len; wrc = write(fd, rec->str, rec_len); cstr_free(rec, true); cstr_free(msg_data, true); if (wrc != rec_len) return false; } return true; }
cstring *base58_encode_check(unsigned char addrtype, bool have_addrtype, const void *data, size_t data_len) { cstring *s = cstr_new_sz(data_len + 1 + 4); if (have_addrtype) cstr_append_c(s, addrtype); cstr_append_buf(s, data, data_len); unsigned char md32[4]; bu_Hash4(md32, s->str, s->len); cstr_append_buf(s, md32, 4); cstring *s_enc = base58_encode(s->str, s->len); cstr_free(s, true); return s_enc; }
static void runtest (void) { unsigned char md1[SHA256_DIGEST_LENGTH]; unsigned char md2[SHA256_DIGEST_LENGTH]; sha256_Raw((unsigned char *)data1, strlen(data1), md1); sha256_Raw((unsigned char *)data2, strlen(data2), md2); struct bloom bloom; assert(bloom_init(&bloom, 1000, 0.001) == true); bloom_insert(&bloom, md1, sizeof(md1)); assert(bloom_contains(&bloom, md1, sizeof(md1)) == true); assert(bloom_contains(&bloom, md2, sizeof(md2)) == false); cstring *ser = cstr_new_sz(1024); ser_bloom(ser, &bloom); struct bloom bloom2; __bloom_init(&bloom2); struct const_buffer buf = { ser->str, ser->len }; assert(deser_bloom(&bloom2, &buf) == true); assert(bloom.nHashFuncs == bloom2.nHashFuncs); assert(bloom.vData->len == bloom2.vData->len); assert(memcmp(bloom.vData->str, bloom2.vData->str, bloom2.vData->len) == 0); assert(bloom_contains(&bloom2, md1, sizeof(md1)) == true); assert(bloom_contains(&bloom2, md2, sizeof(md2)) == false); bloom_free(&bloom2); bloom_free(&bloom); cstr_free(ser, true); }
static void string_find_del(cstring *s, const struct buffer *buf) { /* wrap buffer in a script */ cstring *script = cstr_new_sz(buf->len + 8); bsp_push_data(script, buf->p, buf->len); /* search for script, as a substring of 's' */ void *p; unsigned int sublen = script->len; while ((p = memmem(s->str, s->len, script->str, sublen)) != NULL) { void *begin = s->str; void *end = begin + s->len; void *tail = p + sublen; unsigned int tail_len = end - tail; unsigned int new_len = s->len - sublen; memmove(p, tail, tail_len); cstr_resize(s, new_len); } cstr_free(script, true); }
void logdb_write_record(logdb_log_db* db, logdb_record *rec) { SHA256_CTX ctx = db->hashctx; SHA256_CTX ctx_final; uint8_t hash[SHA256_DIGEST_LENGTH]; /* serialize record to buffer */ cstring *serbuf = cstr_new_sz(1024); logdb_record_ser(rec, serbuf); /* create hash of the body */ sha256_Raw((const uint8_t*)serbuf->str, serbuf->len, hash); /* write record header */ assert(fwrite(record_magic, 8, 1, db->file) == 1); sha256_Update(&ctx, record_magic, 8); /* write partial hash as body checksum&indicator (body start) */ assert(fwrite(hash, db->hashlen, 1, db->file) == 1); sha256_Update(&ctx, hash, db->hashlen); /* write the body */ fwrite(serbuf->str, serbuf->len, 1, db->file); sha256_Update(&ctx, (uint8_t *)serbuf->str, serbuf->len); /* write partial hash as body checksum&indicator (body end) */ assert(fwrite(hash, db->hashlen, 1, db->file) == 1); sha256_Update(&ctx, hash, db->hashlen); cstr_free(serbuf, true); ctx_final = ctx; sha256_Final(hash, &ctx_final); assert(fwrite(hash, db->hashlen, 1, db->file) == 1); db->hashctx = ctx; }
void test_serialize() { char hex0[] = "28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c1"; char hex1[] = "28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c2"; char hex2[] = "28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c3"; uint8_t* hash0 = malloc(32); uint8_t* hash1 = malloc(32); uint8_t* hash2 = malloc(32); memcpy(hash0, utils_hex_to_uint8(hex0), 32); memcpy(hash1, utils_hex_to_uint8(hex1), 32); memcpy(hash2, utils_hex_to_uint8(hex2), 32); vector* vec = vector_new(5, free); vector_add(vec, hash0); vector_add(vec, hash1); vector_add(vec, hash2); cstring* s = cstr_new_sz(200); ser_u256_vector(s, vec); vector_free(vec, true); vector* vec2 = vector_new(0, NULL); struct const_buffer buf = {s->str, s->len}; deser_u256_vector(&vec2, &buf); vector_free(vec2, true); cstr_free(s, true); cstring* s2 = cstr_new_sz(200); ser_u16(s2, 0xAAFF); ser_u32(s2, 0xDDBBAAFF); ser_u64(s2, 0x99FF99FFDDBBAAFF); ser_varlen(s2, 10); ser_varlen(s2, 1000); ser_varlen(s2, 100000000); ser_str(s2, "test", 4); cstring* s3 = cstr_new("foo"); ser_varstr(s2, s3); cstr_free(s3, true); // ser_varlen(s2, (uint64_t)0x9999999999999999); // uint64 varlen is not supported right now struct const_buffer buf2 = {s2->str, s2->len}; uint16_t num0; deser_u16(&num0, &buf2); assert(num0 == 43775); //0xAAFF uint32_t num1; deser_u32(&num1, &buf2); assert(num1 == 3720063743); //0xDDBBAAFF uint64_t num2; deser_u64(&num2, &buf2); assert(num2 == 0x99FF99FFDDBBAAFF); //0x99FF99FFDDBBAAFF uint32_t num3; deser_varlen(&num3, &buf2); assert(num3 == 10); deser_varlen(&num3, &buf2); assert(num3 == 1000); deser_varlen(&num3, &buf2); assert(num3 == 100000000); char strbuf[255]; deser_str(strbuf, &buf2, 255); assert(strncmp(strbuf, "test", 4) == 0); cstring* deser_test = cstr_new_sz(0); deser_varstr(&deser_test, &buf2); assert(strncmp(deser_test->str, "foo", 3) == 0); cstr_free(deser_test, true); cstr_free(s2, true); }
bool bp_script_sign(struct bp_keystore *ks, const cstring *fromPubKey, const struct bp_tx *txTo, unsigned int nIn, int nHashType) { if (!txTo || !txTo->vin || nIn >= txTo->vin->len) return false; struct bp_txin *txin = parr_idx(txTo->vin, nIn); /* get signature hash */ bu256_t hash; bp_tx_sighash(&hash, fromPubKey, txTo, nIn, nHashType); /* match fromPubKey against templates, to find what pubkey[hashes] * are required for signing */ struct bscript_addr addrs; if (!bsp_addr_parse(&addrs, fromPubKey->str, fromPubKey->len)) return false; cstring *scriptSig = cstr_new_sz(64); bool rc = false; bu160_t key_id; struct buffer *kbuf; /* sign, based on script template matched above */ switch (addrs.txtype) { case TX_PUBKEY: kbuf = addrs.pub->data; bu_Hash160((unsigned char *)&key_id, kbuf->p, kbuf->len); if (!sign1(&key_id, ks, &hash, nHashType, scriptSig)) goto out; break; case TX_PUBKEYHASH: kbuf = addrs.pubhash->data; memcpy(&key_id, kbuf->p, kbuf->len); if (!sign1(&key_id, ks, &hash, nHashType, scriptSig)) goto out; if (!bkeys_pubkey_append(ks, &key_id, scriptSig)) goto out; break; case TX_SCRIPTHASH: /* TODO; not supported yet */ case TX_MULTISIG: goto out; case TX_NONSTANDARD: /* unknown script type, cannot sign */ goto out; } if (txin->scriptSig) cstr_free(txin->scriptSig, true); txin->scriptSig = scriptSig; scriptSig = NULL; rc = true; out: if (scriptSig) cstr_free(scriptSig, true); bsp_addr_free(&addrs); return rc; }
void test_protocol() { /* get new string buffer */ cstring *version_msg_cstr = cstr_new_sz(256); cstring *inv_msg_cstr = cstr_new_sz(256); struct sockaddr_in test_sa, test_sa_check; memset(&test_sa, 0, sizeof(test_sa)); memset(&test_sa_check, 0, sizeof(test_sa_check)); test_sa.sin_family = AF_INET; struct sockaddr_in6 test_sa6, test_sa6_check; test_sa6.sin6_family = AF_INET6; test_sa6.sin6_port = htons(1024); evutil_inet_pton(AF_INET, "10.0.0.1", &test_sa.sin_addr); // store IP in antelope char i6buf[1024]; memset(&i6buf, 0, 1024); evutil_inet_pton(AF_INET6, "::1", &test_sa6.sin6_addr); btc_p2p_address ipv6Test; btc_p2p_address_init(&ipv6Test); btc_addr_to_p2paddr((struct sockaddr *)&test_sa6, &ipv6Test); btc_p2paddr_to_addr(&ipv6Test, (struct sockaddr *)&test_sa6_check); memset(&i6buf, 0, 1024); u_assert_int_eq(test_sa6.sin6_port, test_sa6_check.sin6_port); /* copy socket_addr to p2p addr */ btc_p2p_address fromAddr; btc_p2p_address_init(&fromAddr); btc_p2p_address toAddr; btc_p2p_address_init(&toAddr); btc_addr_to_p2paddr((struct sockaddr *)&test_sa, &toAddr); btc_p2paddr_to_addr(&toAddr, (struct sockaddr *)&test_sa_check); u_assert_int_eq(test_sa.sin_port, test_sa_check.sin_port); evutil_inet_ntop(AF_INET, &test_sa_check.sin_addr, i6buf, 1024); u_assert_str_eq(i6buf, "10.0.0.1"); /* create a inv message struct */ btc_p2p_inv_msg inv_msg, inv_msg_check; memset(&inv_msg, 0, sizeof(inv_msg)); uint256 hash = {0}; btc_p2p_msg_inv_init(&inv_msg, 1, hash); btc_p2p_msg_inv_ser(&inv_msg, inv_msg_cstr); struct const_buffer buf_inv = {inv_msg_cstr->str, inv_msg_cstr->len}; u_assert_int_eq(btc_p2p_msg_inv_deser(&inv_msg_check, &buf_inv), true); u_assert_int_eq(inv_msg_check.type, 1); u_assert_mem_eq(inv_msg_check.hash, inv_msg.hash, sizeof(inv_msg.hash)); cstr_free(inv_msg_cstr, true); /* create a version message struct */ btc_p2p_version_msg version_msg; memset(&version_msg, 0, sizeof(version_msg)); /* create a serialized version message */ btc_p2p_msg_version_init(&version_msg, &fromAddr, &toAddr, "client", false); btc_p2p_msg_version_ser(&version_msg, version_msg_cstr); /* create p2p message */ cstring *p2p_msg = btc_p2p_message_new((unsigned const char *)&btc_chainparams_main.netmagic, BTC_MSG_VERSION, version_msg_cstr->str, version_msg_cstr->len); struct const_buffer buf = {p2p_msg->str, p2p_msg->len}; btc_p2p_msg_hdr hdr; btc_p2p_deser_msghdr(&hdr, &buf); u_assert_mem_eq(hdr.netmagic, &btc_chainparams_main.netmagic, 4); u_assert_str_eq(hdr.command, BTC_MSG_VERSION); u_assert_int_eq(hdr.data_len, version_msg_cstr->len); u_assert_int_eq(buf.len, hdr.data_len); u_assert_int_eq(buf.len, hdr.data_len); u_assert_mem_eq(buf.p, version_msg_cstr->str, hdr.data_len); btc_p2p_version_msg v_msg_check; u_assert_int_eq(btc_p2p_msg_version_deser(&v_msg_check, &buf), true); u_assert_int_eq(v_msg_check.version, BTC_PROTOCOL_VERSION); u_assert_str_eq(v_msg_check.useragent, "client"); u_assert_int_eq(v_msg_check.start_height, 0); cstr_free(p2p_msg, true); cstr_free(version_msg_cstr, true); /* getheaders */ uint256 genesis_hash = {0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xd6, 0x68, 0x9c, 0x08, 0x5a, 0xe1, 0x65, 0x83, 0x1e, 0x93, 0x4f, 0xf7, 0x63, 0xae, 0x46, 0xa2, 0xa6, 0xc1, 0x72, 0xb3, 0xf1, 0xb6, 0x0a, 0x8c, 0xe2, 0x6f}; vector *blocklocators = vector_new(1, NULL); vector_add(blocklocators, genesis_hash); cstring *getheader_msg = cstr_new_sz(256); btc_p2p_msg_getheaders(blocklocators, NULL, getheader_msg); p2p_msg = btc_p2p_message_new((unsigned const char *)&btc_chainparams_main.netmagic, BTC_MSG_GETHEADERS, getheader_msg->str, getheader_msg->len); buf.p = p2p_msg->str; buf.len = p2p_msg->len; btc_p2p_deser_msghdr(&hdr, &buf); u_assert_str_eq(hdr.command, BTC_MSG_GETHEADERS); u_assert_int_eq(hdr.data_len, getheader_msg->len); uint256 hashstop_check; vector *blocklocators_check = vector_new(1, free); btc_p2p_deser_msg_getheaders(blocklocators_check, hashstop_check, &buf); u_assert_mem_eq(NULLHASH, hashstop_check, sizeof(hashstop_check)); uint8_t *hash_loc_0 = vector_idx(blocklocators_check, 0); u_assert_mem_eq(genesis_hash, hash_loc_0, sizeof(genesis_hash)); /* cleanup */ cstr_free(getheader_msg, true); vector_free(blocklocators, true); vector_free(blocklocators_check, true); cstr_free(p2p_msg, true); }
static void runtest(const char *json_fn_base, const char *ser_fn_base) { char *fn = test_filename(json_fn_base); json_t *meta = read_json(fn); assert(json_is_object(meta)); char *ser_fn = test_filename(ser_fn_base); void *data = NULL; size_t data_len = 0; bool rc = bu_read_file(ser_fn, &data, &data_len, 100 * 1024 * 1024); assert(rc); const char *hashstr = json_string_value(json_object_get(meta, "hash")); assert(hashstr != NULL); unsigned int size = json_integer_value(json_object_get(meta, "size")); assert(data_len == size); struct bp_tx tx; bp_tx_init(&tx); struct const_buffer buf = { data, data_len }; rc = deser_bp_tx(&tx, &buf); assert(rc); cstring *gs = cstr_new_sz(10000); ser_bp_tx(gs, &tx); if (gs->len != data_len) { fprintf(stderr, "gs->len %ld, data_len %lu\n", (long)gs->len, data_len); assert(gs->len == data_len); } assert(memcmp(gs->str, data, data_len) == 0); bp_tx_calc_sha256(&tx); char hexstr[BU256_STRSZ]; bu256_hex(hexstr, &tx.sha256); if (strcmp(hexstr, hashstr)) { fprintf(stderr, "tx: wanted hash %s,\n got hash %s\n", hashstr, hexstr); assert(!strcmp(hexstr, hashstr)); } assert(tx.vin->len == 1); assert(tx.vout->len == 2); struct bp_tx tx_copy; bp_tx_init(&tx_copy); bp_tx_copy(&tx_copy, &tx); bp_tx_calc_sha256(&tx_copy); assert(bu256_equal(&tx_copy.sha256, &tx.sha256) == true); bp_tx_free(&tx); bp_tx_free(&tx_copy); cstr_free(gs, true); free(data); free(fn); free(ser_fn); json_decref(meta); }
static void runtest(const char *json_fn_base, const char *ser_fn_base) { char *fn = test_filename(json_fn_base); json_t *meta = read_json(fn); assert(json_is_object(meta)); char *ser_fn = test_filename(ser_fn_base); int fd = file_seq_open(ser_fn); if (fd < 0) { perror(ser_fn); exit(1); } struct p2p_message msg = {}; bool read_ok = false; bool rc = fread_message(fd, &msg, &read_ok); assert(rc); assert(read_ok); assert(!strncmp(msg.hdr.command, "block", 12)); close(fd); const char *hashstr = json_string_value(json_object_get(meta, "hash")); assert(hashstr != NULL); unsigned int size = json_integer_value(json_object_get(meta, "size")); assert((24 + msg.hdr.data_len) == size); struct bp_block block; bp_block_init(&block); struct const_buffer buf = { msg.data, msg.hdr.data_len }; rc = deser_bp_block(&block, &buf); assert(rc); cstring *gs = cstr_new_sz(100000); ser_bp_block(gs, &block); if (gs->len != msg.hdr.data_len) { fprintf(stderr, "gs->len %ld, msg.hdr.data_len %u\n", (long)gs->len, msg.hdr.data_len); assert(gs->len == msg.hdr.data_len); } assert(memcmp(gs->str, msg.data, msg.hdr.data_len) == 0); bp_block_calc_sha256(&block); char hexstr[BU256_STRSZ]; bu256_hex(hexstr, &block.sha256); if (strcmp(hexstr, hashstr)) { fprintf(stderr, "block: wanted hash %s,\n got hash %s\n", hashstr, hexstr); assert(!strcmp(hexstr, hashstr)); } rc = bp_block_valid(&block); assert(rc); bp_block_free(&block); cstr_free(gs, true); free(msg.data); free(fn); free(ser_fn); json_decref(meta); }