void test_ecc() { unsigned char r_buf[32]; memset(r_buf, 0, 32); random_init(); while (btc_ecc_verify_privatekey(r_buf) == 0) { random_bytes(r_buf, 32, 0); } memset(r_buf, 0xFF, 32); u_assert_int_eq(btc_ecc_verify_privatekey(r_buf), 0); //secp256k1 overflow uint8_t pub_key33[33], pub_key33_invalid[33], pub_key65[65], pub_key65_invalid[65]; memcpy(pub_key33, utils_hex_to_uint8("02fcba7ecf41bc7e1be4ee122d9d22e3333671eb0a3a87b5cdf099d59874e1940f"), 33); memcpy(pub_key33_invalid, utils_hex_to_uint8("999999999941bc7e1be4ee122d9d22e3333671eb0a3a87b5cdf099d59874e1940f"), 33); memcpy(pub_key65, utils_hex_to_uint8("044054fd18aeb277aeedea01d3f3986ff4e5be18092a04339dcf4e524e2c0a09746c7083ed2097011b1223a17a644e81f59aa3de22dac119fd980b36a8ff29a244"), 65); memcpy(pub_key65_invalid, utils_hex_to_uint8("044054fd18aeb277aeedea01d3f3986ff4e5be18092a04339dcf4e524e2c0a09746c7083ed2097011b1223a17a644e81f59aa3de22dac119fd980b39999f29a244"), 65); u_assert_int_eq(btc_ecc_verify_pubkey(pub_key33, 1), 1); u_assert_int_eq(btc_ecc_verify_pubkey(pub_key65, 0), 1); u_assert_int_eq(btc_ecc_verify_pubkey(pub_key33_invalid, 1), 0); u_assert_int_eq(btc_ecc_verify_pubkey(pub_key65_invalid, 0), 0); btc_key key; btc_privkey_init(&key); assert(btc_privkey_is_valid(&key) == 0); btc_privkey_gen(&key); uint8_t* hash = utils_hex_to_uint8((const char*)"26db47a48a10b9b0b697b793f5c0231aa35fe192c9d063d7b03a55e3c302850a"); unsigned char sig[74]; size_t outlen = 74; btc_key_sign_hash(&key, hash, sig, &outlen); uint8_t sigcomp[64]; unsigned char sigder[74]; size_t sigderlen = 74; u_assert_int_eq(btc_ecc_der_to_compact(sig, outlen, sigcomp), true); u_assert_int_eq(btc_ecc_compact_to_der_normalized(sigcomp, sigder, &sigderlen), true); u_assert_int_eq(outlen, sigderlen); u_assert_int_eq(memcmp(sig,sigder,sigderlen), 0); }
void test_logdb(logdb_log_db* (*new_func)()) { logdb_log_db *db; enum logdb_error error = 0; struct buffer key = {"key0", 4}; struct buffer value = {"val0", 4}; struct buffer key1; struct buffer value1; cstring *outtest; cstring *value_test; unsigned char testbin[4] = {0x00, 0x10, 0x20, 0x30}; struct buffer value0_new = {"dumb", 4}; struct buffer key2 = {"pkey", 4}; struct buffer value2; struct buffer smp_value; struct buffer smp_key; uint8_t txbin[10240]; uint8_t txbin_rev[10240]; char hexrev[98]; int outlenrev; long fsize; char *buf; char *wrk_buf; FILE *f; unsigned int i; value2.p = testbin; value2.len = 4; key1.p = (char *)key1str; key1.len = strlen(key1str); value1.p = (char *)value1str; value1.len = strlen(value1str); unlink(dbtmpfile); db = new_func(); u_assert_int_eq(logdb_load(db, "file_that_should_not_exists.dat", false, NULL), false); u_assert_int_eq(logdb_load(db, dbtmpfile, true, NULL), true); logdb_append(db, &key, &value); logdb_append(db, &key1, &value1); u_assert_int_eq(logdb_cache_size(db), 2); outtest = logdb_find_cache(db, &key1); u_assert_int_eq(strcmp(outtest->str, value1str),0); logdb_flush(db); logdb_free(db); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); u_assert_int_eq(logdb_count_keys(db), 2); value_test = logdb_find(db, &key1); u_assert_int_eq(strcmp(value_test->str, value1str), 0); value_test = logdb_find(db, &key); u_assert_int_eq(memcmp(value_test->str, value.p, value.len), 0); logdb_free(db); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); logdb_append(db, &key2, &value2); logdb_flush(db); logdb_free(db); /* check if private key is available */ db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); value_test = logdb_find(db, &key2); u_assert_int_eq(memcmp(value_test->str, value2.p, value2.len), 0); value_test = logdb_find(db, &key); u_assert_int_eq(memcmp(value_test->str, value.p, value.len), 0); /* delete a record */ logdb_delete(db, &key2); logdb_flush(db); logdb_free(db); /* find and check the deleted record */ db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); value_test = logdb_find(db, &key); u_assert_int_eq(memcmp(value_test->str, value.p, value.len), 0); value_test = logdb_find(db, &key2); u_assert_int_eq((int)value_test, 0); /* should be null */ /* overwrite a key */ logdb_append(db, &key, &value0_new); value_test = logdb_find(db, &key); u_assert_int_eq(memcmp(value_test->str, value0_new.p, value0_new.len), 0); logdb_flush(db); logdb_free(db); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); value_test = logdb_find(db, &key); u_assert_int_eq(memcmp(value_test->str, value0_new.p, value0_new.len), 0); logdb_flush(db); logdb_free(db); /* simulate corruption */ f = fopen(dbtmpfile, "rb"); fseek(f, 0, SEEK_END); fsize = ftell(f); fseek(f, 0, SEEK_SET); buf = malloc(fsize + 1); fread(buf, fsize, 1, f); fclose(f); /* ---------------------------------------------------- */ wrk_buf = safe_malloc(fsize + 1); memcpy(wrk_buf, buf, fsize); wrk_buf[0] = 0x88; /* wrong header */ unlink(dbtmpfile); f = fopen(dbtmpfile, "wb"); fwrite(wrk_buf, 1, fsize, f); fclose(f); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), false); u_assert_int_eq(error, LOGDB_ERROR_WRONG_FILE_FORMAT); logdb_free(db); /* ---------------------------------------------------- */ memcpy(wrk_buf, buf, fsize); wrk_buf[66] = 0x00; /* wrong checksum hash */ unlink(dbtmpfile); f = fopen(dbtmpfile, "wb"); fwrite(wrk_buf, 1, fsize, f); fclose(f); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), false); u_assert_int_eq(error, LOGDB_ERROR_CHECKSUM); logdb_free(db); /* ---------------------------------------------------- */ memcpy(wrk_buf, buf, fsize); wrk_buf[42] = 0xFF; /* wrong value length */ unlink(dbtmpfile); f = fopen(dbtmpfile, "wb"); fwrite(wrk_buf, 1, fsize, f); fclose(f); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), false); u_assert_int_eq(error, LOGDB_ERROR_DATASTREAM_ERROR); logdb_free(db); free(buf); free(wrk_buf); /* --- large db test */ unlink(dbtmpfile); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, true, NULL), true); for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); smp_key.p = hashbin; smp_key.len = outlen; outlen = sizeof(tx->hextx) / 2; utils_hex_to_bin(tx->hextx, txbin, strlen(tx->hextx), &outlen); smp_value.p = txbin; smp_value.len = outlen; logdb_append(db, &smp_key, &smp_value); } u_assert_int_eq(logdb_count_keys(db), (sizeof(sampledata) / sizeof(sampledata[0]))); /* check all records */ for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); smp_key.p = hashbin; smp_key.len = outlen; outtest = logdb_find(db, &smp_key); outlen = sizeof(tx->hextx) / 2; utils_hex_to_bin(tx->hextx, txbin, strlen(tx->hextx), &outlen); u_assert_int_eq(outlen, outtest->len); } logdb_flush(db); logdb_free(db); db = new_func(); error = 0; u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), true); u_assert_int_eq(logdb_count_keys(db), (sizeof(sampledata) / sizeof(sampledata[0]))); /* check all records */ for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); memcpy(hexrev, tx->txhash, sizeof(tx->txhash)); utils_reverse_hex(hexrev, strlen(tx->txhash)); outlenrev = sizeof(tx->txhash) / 2; utils_hex_to_bin(hexrev, txbin_rev, strlen(hexrev), &outlenrev); smp_key.p = hashbin; smp_key.len = outlen; outtest = logdb_find(db, &smp_key); outlen = strlen(tx->hextx) / 2; utils_hex_to_bin(tx->hextx, txbin, strlen(tx->hextx), &outlen); u_assert_int_eq(outlen, outtest->len); /* hash transaction data and check hashes */ if (strlen(tx->hextx) > 2) { uint8_t tx_hash_check[SHA256_DIGEST_LENGTH]; sha256_Raw(txbin, outlen, tx_hash_check); sha256_Raw(tx_hash_check, 32, tx_hash_check); u_assert_int_eq(memcmp(tx_hash_check, txbin_rev, SHA256_DIGEST_LENGTH), 0); } } /* check all records */ for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); smp_key.p = hashbin; smp_key.len = outlen; logdb_delete(db, &smp_key); } u_assert_int_eq(logdb_count_keys(db), 0); logdb_flush(db); logdb_free(db); db = new_func(); error = 0; u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), true); u_assert_int_eq(error, LOGDB_SUCCESS); u_assert_int_eq(logdb_count_keys(db), 0); for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); smp_key.p = hashbin; smp_key.len = outlen; outlen = sizeof(tx->hextx) / 2; utils_hex_to_bin(tx->hextx, txbin, strlen(tx->hextx), &outlen); smp_value.p = txbin; smp_value.len = outlen; logdb_append(db, &smp_key, &smp_value); } logdb_flush(db); logdb_free(db); db = new_func(); error = 0; u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), true); u_assert_int_eq(error, LOGDB_SUCCESS); u_assert_int_eq(logdb_count_keys(db), (sizeof(sampledata) / sizeof(sampledata[0]))); logdb_flush(db); logdb_free(db); db = new_func(); error = 0; u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), true); u_assert_int_eq(error, LOGDB_SUCCESS); u_assert_int_eq(logdb_count_keys(db), (sizeof(sampledata) / sizeof(sampledata[0]))); for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); smp_key.p = hashbin; smp_key.len = outlen; outlen = sizeof(tx->hextx) / 2; utils_hex_to_bin(tx->hextx, txbin, strlen(tx->hextx), &outlen); smp_value.p = txbin; smp_value.len = outlen; logdb_append(db, &smp_key, &smp_value); } logdb_flush(db); logdb_free(db); }
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); }
void test_logdb(logdb_log_db* (*new_func)()) { logdb_log_db *db; enum logdb_error error = 0; cstring *key;// key= {"key0", 4}; cstring *value;// = {"val0", 4}; cstring *key1; cstring *value1; cstring *outtest; cstring *value_test; unsigned char testbin[4] = {0x00, 0x10, 0x20, 0x30}; cstring *value0;// = {"dumb", 4}; cstring *key2;// = {"pkey", 4}; cstring *value2; cstring *smp_value; cstring *smp_key; uint8_t txbin[10240]; uint8_t txbin_rev[10240]; char hexrev[98]; int outlenrev; long fsize; char *buf; char *wrk_buf; FILE *f; unsigned int i; char bufs[300][65]; rb_red_blk_node *nodetest; unsigned int cnt = 0; logdb_record* rec; key = cstr_new("key0"); value = cstr_new("val0"); value0 = cstr_new("dumb"); value1 = cstr_new_sz(10); value2 = cstr_new_sz(10); key1 = cstr_new_sz(10); key2 = cstr_new("key2"); cstr_append_buf(value2, testbin, sizeof(testbin)); cstr_append_buf(value2, testbin, sizeof(testbin)); cstr_append_buf(key1, key1str, strlen(key1str)); cstr_append_buf(value1, value1str, strlen(value1str)); unlink(dbtmpfile); db = new_func(); u_assert_int_eq(logdb_load(db, "file_that_should_not_exists.dat", false, NULL), false); u_assert_int_eq(logdb_load(db, dbtmpfile, true, NULL), true); logdb_append(db, NULL, key, value); logdb_append(db, NULL, key1, value1); u_assert_int_eq(logdb_cache_size(db), 2); outtest = logdb_find_cache(db, key1); u_assert_int_eq(strcmp(outtest->str, value1str),0); logdb_flush(db); logdb_free(db); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); u_assert_int_eq(logdb_count_keys(db), 2); value_test = logdb_find(db, key1); u_assert_int_eq(strcmp(value_test->str, value1str), 0); value_test = logdb_find(db, key); u_assert_int_eq(memcmp(value_test->str, value->str, value->len), 0); logdb_free(db); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); logdb_append(db, NULL, key2, value2); logdb_flush(db); logdb_free(db); /* check if private key is available */ db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); value_test = logdb_find(db, key2); u_assert_int_eq(memcmp(value_test->str, value2->str, value2->len), 0); value_test = logdb_find(db, key); u_assert_int_eq(memcmp(value_test->str, value->str, value->len), 0); /* delete a record */ logdb_delete(db, NULL, key2); logdb_flush(db); logdb_free(db); /* find and check the deleted record */ db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); value_test = logdb_find(db, key); u_assert_int_eq(memcmp(value_test->str, value->str, value->len), 0); value_test = logdb_find(db, key2); u_assert_int_eq((int)value_test, 0); /* should be null */ /* overwrite a key */ logdb_append(db, NULL, key, value0); value_test = logdb_find(db, key); u_assert_int_eq(memcmp(value_test->str, value0->str, value0->len), 0); logdb_flush(db); logdb_free(db); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); value_test = logdb_find(db, key); u_assert_int_eq(memcmp(value_test->str, value0->str, value0->len), 0); logdb_flush(db); logdb_free(db); /* simulate corruption */ f = fopen(dbtmpfile, "rb"); fseek(f, 0, SEEK_END); fsize = ftell(f); fseek(f, 0, SEEK_SET); buf = malloc(fsize + 1); fread(buf, fsize, 1, f); fclose(f); /* ---------------------------------------------------- */ wrk_buf = safe_malloc(fsize + 1); memcpy(wrk_buf, buf, fsize); wrk_buf[0] = 0x88; /* wrong header */ unlink(dbtmpfile); f = fopen(dbtmpfile, "wb"); fwrite(wrk_buf, 1, fsize, f); fclose(f); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), false); u_assert_int_eq(error, LOGDB_ERROR_WRONG_FILE_FORMAT); logdb_free(db); /* ---------------------------------------------------- */ memcpy(wrk_buf, buf, fsize); wrk_buf[66] = 0x00; /* wrong checksum hash */ unlink(dbtmpfile); f = fopen(dbtmpfile, "wb"); fwrite(wrk_buf, 1, fsize, f); fclose(f); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), false); u_assert_int_eq(error, LOGDB_ERROR_CHECKSUM); logdb_free(db); /* ---------------------------------------------------- */ memcpy(wrk_buf, buf, fsize); wrk_buf[42] = 0xFF; /* wrong value length */ unlink(dbtmpfile); f = fopen(dbtmpfile, "wb"); fwrite(wrk_buf, 1, fsize, f); fclose(f); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), false); u_assert_int_eq(error, LOGDB_ERROR_DATASTREAM_ERROR); logdb_free(db); free(buf); free(wrk_buf); /* --- large db test */ unlink(dbtmpfile); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, true, NULL), true); smp_key = cstr_new_sz(100); smp_value = cstr_new_sz(100); for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); cstr_erase(smp_key, 0, smp_key->len); cstr_append_buf(smp_key, hashbin, outlen); outlen = sizeof(tx->hextx) / 2; utils_hex_to_bin(tx->hextx, txbin, strlen(tx->hextx), &outlen); cstr_erase(smp_value, 0, smp_value->len); cstr_append_buf(smp_value, txbin, outlen); logdb_append(db, NULL, smp_key, smp_value); } u_assert_int_eq(logdb_count_keys(db), (sizeof(sampledata) / sizeof(sampledata[0]))); /* check all records */ for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); cstr_erase(smp_key, 0, smp_key->len); cstr_append_buf(smp_key, hashbin, outlen); outtest = logdb_find(db, smp_key); outlen = sizeof(tx->hextx) / 2; utils_hex_to_bin(tx->hextx, txbin, strlen(tx->hextx), &outlen); u_assert_int_eq(outlen, outtest->len); } logdb_flush(db); logdb_free(db); db = new_func(); error = 0; u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), true); u_assert_int_eq(logdb_count_keys(db), (sizeof(sampledata) / sizeof(sampledata[0]))); /* check all records */ for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); memcpy(hexrev, tx->txhash, sizeof(tx->txhash)); utils_reverse_hex(hexrev, strlen(tx->txhash)); outlenrev = sizeof(tx->txhash) / 2; utils_hex_to_bin(hexrev, txbin_rev, strlen(hexrev), &outlenrev); cstr_erase(smp_key, 0, smp_key->len); cstr_append_buf(smp_key, hashbin, outlen); outtest = logdb_find(db, smp_key); outlen = strlen(tx->hextx) / 2; utils_hex_to_bin(tx->hextx, txbin, strlen(tx->hextx), &outlen); u_assert_int_eq(outlen, outtest->len); /* hash transaction data and check hashes */ if (strlen(tx->hextx) > 2) { uint8_t tx_hash_check[SHA256_DIGEST_LENGTH]; sha256_Raw(txbin, outlen, tx_hash_check); sha256_Raw(tx_hash_check, 32, tx_hash_check); u_assert_int_eq(memcmp(tx_hash_check, txbin_rev, SHA256_DIGEST_LENGTH), 0); } } /* check all records */ for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); cstr_erase(smp_key, 0, smp_key->len); cstr_append_buf(smp_key, hashbin, outlen); logdb_delete(db, NULL, smp_key); } u_assert_int_eq(logdb_count_keys(db), 0); logdb_flush(db); logdb_free(db); db = new_func(); error = 0; u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), true); u_assert_int_eq(error, LOGDB_SUCCESS); u_assert_int_eq(logdb_count_keys(db), 0); for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); cstr_erase(smp_key, 0, smp_key->len); cstr_append_buf(smp_key, hashbin, outlen); outlen = sizeof(tx->hextx) / 2; utils_hex_to_bin(tx->hextx, txbin, strlen(tx->hextx), &outlen); cstr_erase(smp_value, 0, smp_value->len); cstr_append_buf(smp_value, txbin, outlen); logdb_append(db, NULL, smp_key, smp_value); } logdb_flush(db); logdb_free(db); db = new_func(); error = 0; u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), true); u_assert_int_eq(error, LOGDB_SUCCESS); u_assert_int_eq(logdb_count_keys(db), (sizeof(sampledata) / sizeof(sampledata[0]))); logdb_flush(db); logdb_free(db); db = new_func(); error = 0; u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), true); u_assert_int_eq(error, LOGDB_SUCCESS); u_assert_int_eq(logdb_count_keys(db), (sizeof(sampledata) / sizeof(sampledata[0]))); if(new_func == logdb_rbtree_new) { logdb_rbtree_db* handle = (logdb_rbtree_db *)db->cb_ctx; size_t size = rbtree_count(handle->tree); nodetest = NULL; while ((nodetest = rbtree_enumerate_next(handle->tree))) { rec = (logdb_record *)nodetest->info; utils_bin_to_hex((unsigned char *)rec->key->str, rec->key->len, bufs[cnt]); for(i = 0; i < cnt; i++) { u_assert_int_eq(strcmp(bufs[i], bufs[cnt]) != 0, 1); } cnt++; } u_assert_int_eq(size, cnt); } for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); cstr_erase(smp_key, 0, smp_key->len); cstr_append_buf(smp_key, hashbin, outlen); outlen = sizeof(tx->hextx) / 2; utils_hex_to_bin(tx->hextx, txbin, strlen(tx->hextx), &outlen); cstr_erase(smp_value, 0, smp_value->len); cstr_append_buf(smp_value, txbin, outlen); logdb_append(db, NULL, smp_key, smp_value); } logdb_flush(db); logdb_free(db); /* test switch mem mapper after initialitaion. */ db = logdb_new(); logdb_set_memmapper(db, &logdb_rbtree_mapper, NULL); logdb_flush(db); logdb_free(db); unlink(dbtmpfile); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, true, NULL), true); // create transaction, don't store logdb_txn* txn = logdb_txn_new(); logdb_append(db, txn, key, value); logdb_append(db, txn, key1, value1); u_assert_int_eq(logdb_cache_size(db), 0); logdb_txn_free(txn); logdb_flush(db); logdb_free(db); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); // db should still be empty u_assert_int_eq(logdb_count_keys(db), 0); // create transaction, store it this time txn = logdb_txn_new(); logdb_append(db, txn, key, value); logdb_append(db, txn, key1, value1); logdb_txn_commit(db, txn); u_assert_int_eq(logdb_cache_size(db), 2); logdb_txn_free(txn); logdb_flush(db); logdb_free(db); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); // now we should have the two persisted items from the txn u_assert_int_eq(logdb_count_keys(db), 2); logdb_flush(db); logdb_free(db); cstr_free(key, true); cstr_free(value, true); cstr_free(value0, true); cstr_free(value1, true); cstr_free(value2, true); cstr_free(key1, true); cstr_free(key2, true); cstr_free(smp_key, true); cstr_free(smp_value, true); }