static struct tx_ser_key * txdb_deserialize_tx_key(const void *key, size_t klen) { struct tx_ser_key *tx; char hashStr[80]; bool s; int n; ASSERT(key); tx = safe_calloc(1, sizeof *tx); n = sscanf(key, "/tx/%010llu/%s", &tx->seq, hashStr); ASSERT(n == 2); s = uint256_from_str(hashStr, &tx->txHash); ASSERT(s); return tx; }
int blockstore_init(struct config *config, struct blockstore **blockStore) { struct blockstore *bs; char *file; bool s; int res; int i; *blockStore = NULL; file = blockstore_get_filename(config); Log(LGPFX" Using headers at '%s.\n", file); if (!file_exists(file)) { Log(LGPFX" file '%s' does not exist. Creating..\n", file); res = file_create(file); if (res) { Warning(LGPFX" failed to create file: %s\n", strerror(res)); free(file); return res; } res = file_chmod(file, 0600); if (res != 0) { Warning(LGPFX" failed to chmod 0600 '%s': %s\n", file, strerror(res)); free(file); return res; } } bs = safe_calloc(1, sizeof *bs); bs->height = -1; bs->hash_blk = hashtable_create(); bs->hash_orphans = hashtable_create(); const struct block_cpt_entry_str *arrayStr; struct block_cpt_entry *array; int n; if (btc->testnet) { n = ARRAYSIZE(cpt_testnet); array = block_cpt_testnet; arrayStr = cpt_testnet; } else { n = ARRAYSIZE(cpt_main); array = block_cpt_main; arrayStr = cpt_main; } for (i = 0; i < n; i++) { array[i].height = arrayStr[i].height; s = uint256_from_str(arrayStr[i].hashStr, &array[i].hash); ASSERT(s); } memcpy(&bs->genesis_hash.data, &array[0].hash.data, sizeof bs->genesis_hash); Log(LGPFX" Genesis: %s\n", arrayStr[0].hashStr); res = blockset_open(bs, file); free(file); if (res != 0) { goto exit; } Log(LGPFX" loaded %d headers.\n", bs->height + 1); *blockStore = bs; return 0; exit: blockstore_exit(bs); return res; }