ethash_full_t ethash_full_new_internal( char const* dirname, ethash_h256_t const seed_hash, uint64_t full_size, ethash_light_t const light, ethash_callback_t callback ) { struct ethash_full* ret; FILE *f = NULL; ret = calloc(sizeof(*ret), 1); if (!ret) { return NULL; } ret->file_size = (size_t)full_size; switch (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, false)) { case ETHASH_IO_FAIL: goto fail_free_full; case ETHASH_IO_MEMO_MATCH: if (!ethash_mmap(ret, f)) { goto fail_close_file; } return ret; case ETHASH_IO_MEMO_SIZE_MISMATCH: // if a DAG of same filename but unexpected size is found, silently force new file creation if (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, true) != ETHASH_IO_MEMO_MISMATCH) { goto fail_free_full; } // fallthrough to the mismatch case here, DO NOT go through match case ETHASH_IO_MEMO_MISMATCH: if (!ethash_mmap(ret, f)) { goto fail_close_file; } break; } if (!ethash_compute_full_data(ret->data, full_size, light, callback)) { goto fail_free_full_data; } // after the DAG has been filled then we finalize it by writting the magic number at the beginning if (fseek(f, 0, SEEK_SET) != 0) { goto fail_free_full_data; } uint64_t const magic_num = ETHASH_DAG_MAGIC_NUM; if (fwrite(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) { goto fail_free_full_data; } fflush(f); // make sure the magic number IS there return ret; fail_free_full_data: // could check that munmap(..) == 0 but even if it did not can't really do anything here munmap(ret->data, (size_t)full_size); fail_close_file: fclose(ret->file); fail_free_full: free(ret); return NULL; }
static PyObject * calc_dataset_bytes(PyObject *self, PyObject *args) { char *cache_bytes; unsigned long full_size; int cache_size; if (!PyArg_ParseTuple(args, "k" PY_STRING_FORMAT, &full_size, &cache_bytes, &cache_size)) return 0; if (full_size % MIX_WORDS != 0) { char error_message[1024]; sprintf(error_message, "The size of data set must be a multiple of %i bytes (was %lu)", MIX_WORDS, full_size); PyErr_SetString(PyExc_ValueError, error_message); return 0; } if (cache_size % HASH_BYTES != 0) { char error_message[1024]; sprintf(error_message, "The size of the cache must be a multiple of %i bytes (was %i)", HASH_BYTES, cache_size); PyErr_SetString(PyExc_ValueError, error_message); return 0; } ethash_params params; params.cache_size = (size_t) cache_size; params.full_size = (size_t) full_size; ethash_cache cache; cache.mem = (void *) cache_bytes; void *mem = malloc(params.full_size); ethash_compute_full_data(mem, ¶ms, &cache); PyObject * val = Py_BuildValue(PY_STRING_FORMAT, (char *) mem, full_size); free(mem); return val; }
ethash_full_t ethash_full_new(ethash_params const* params, ethash_cache const* cache, ethash_callback_t callback) { struct ethash_full *ret; ret = calloc(sizeof(*ret), 1); if (!ret) { return NULL; } ret->cache = (ethash_cache*)cache; ret->data = malloc((size_t)params->full_size); if (!ret->data) { goto fail_free_full; } if (!ethash_compute_full_data(ret->data, params, cache)) { goto fail_free_full_data; } ret->callback = callback; return ret; fail_free_full_data: free(ret->data); fail_free_full: free(ret); return NULL; }