mirror of https://github.com/ethereum/go-ethereum
parent
387f6bba3e
commit
95711bc2dd
@ -0,0 +1,17 @@ |
|||||||
|
include setup.py |
||||||
|
|
||||||
|
# C sources |
||||||
|
include src/libethash/internal.c |
||||||
|
include src/libethash/sha3.c |
||||||
|
include src/libethash/util.c |
||||||
|
include src/python/core.c |
||||||
|
|
||||||
|
# Headers |
||||||
|
include src/libethash/compiler.h |
||||||
|
include src/libethash/data_sizes.h |
||||||
|
include src/libethash/endian.h |
||||||
|
include src/libethash/ethash.h |
||||||
|
include src/libethash/fnv.h |
||||||
|
include src/libethash/internal.h |
||||||
|
include src/libethash/sha3.h |
||||||
|
include src/libethash/util.h |
@ -1,3 +1,6 @@ |
|||||||
.PHONY: clean |
.PHONY: clean test |
||||||
|
test: |
||||||
|
./test/test.sh
|
||||||
|
|
||||||
clean: |
clean: |
||||||
rm -rf *.so pyethash.egg-info/ build/ test/python/python-virtual-env/ test/c/build/ pyethash/*.{so,pyc}
|
rm -rf *.so pyethash.egg-info/ build/ test/python/python-virtual-env/ test/c/build/ pyethash.so test/python/*.pyc dist/ MANIFEST
|
||||||
|
@ -1,2 +0,0 @@ |
|||||||
pyethash.egg-info/ |
|
||||||
*.so |
|
@ -1,3 +0,0 @@ |
|||||||
import pyethash.core |
|
||||||
core = pyethash.core |
|
||||||
EPOCH_LENGTH = 30000 |
|
@ -1,21 +1,33 @@ |
|||||||
#!/usr/bin/env python |
#!/usr/bin/env python |
||||||
from distutils.core import setup, Extension |
from distutils.core import setup, Extension |
||||||
|
|
||||||
pyethash_core = Extension('pyethash.core', |
pyethash = Extension('pyethash', |
||||||
sources = [ |
sources = [ |
||||||
'src/python/core.c', |
'src/python/core.c', |
||||||
'src/libethash/util.c', |
'src/libethash/util.c', |
||||||
'src/libethash/internal.c', |
'src/libethash/internal.c', |
||||||
'src/libethash/sha3.c' |
'src/libethash/sha3.c'], |
||||||
|
depends = [ |
||||||
|
'src/libethash/ethash.h', |
||||||
|
'src/libethash/compiler.h', |
||||||
|
'src/libethash/data_sizes.h', |
||||||
|
'src/libethash/endian.h', |
||||||
|
'src/libethash/ethash.h', |
||||||
|
'src/libethash/fnv.h', |
||||||
|
'src/libethash/internal.h', |
||||||
|
'src/libethash/sha3.h', |
||||||
|
'src/libethash/util.h' |
||||||
], |
], |
||||||
extra_compile_args = ["-std=gnu99"]) |
extra_compile_args = ["-Isrc/", "-std=gnu99", "-Wall"]) |
||||||
|
|
||||||
setup ( |
setup ( |
||||||
name = 'pyethash', |
name = 'pyethash', |
||||||
author = "Matthew Wampler-Doty", |
author = "Matthew Wampler-Doty", |
||||||
author_email = "matthew.wampler.doty@gmail.com", |
author_email = "matthew.wampler.doty@gmail.com", |
||||||
license = 'GPL', |
license = 'GPL', |
||||||
version = '1.0', |
version = '23', |
||||||
|
url = 'https://github.com/ethereum/ethash', |
||||||
|
download_url = 'https://github.com/ethereum/ethash/tarball/v23', |
||||||
description = 'Python wrappers for ethash, the ethereum proof of work hashing function', |
description = 'Python wrappers for ethash, the ethereum proof of work hashing function', |
||||||
ext_modules = [pyethash_core], |
ext_modules = [pyethash], |
||||||
) |
) |
||||||
|
29
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/CMakeLists.txt
generated
vendored
29
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/CMakeLists.txt
generated
vendored
59
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.cpp
generated
vendored
59
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.cpp
generated
vendored
1
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.h
generated
vendored
1
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.h
generated
vendored
8
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3_cryptopp.cpp
generated
vendored
8
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3_cryptopp.cpp
generated
vendored
@ -1,64 +1,305 @@ |
|||||||
#include <Python.h> |
#include <Python.h> |
||||||
#include <alloca.h> |
#include <alloca.h> |
||||||
#include <stdint.h> |
#include <stdint.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <time.h> |
||||||
#include "../libethash/ethash.h" |
#include "../libethash/ethash.h" |
||||||
|
|
||||||
static PyObject* |
#define MIX_WORDS (MIX_BYTES/4) |
||||||
get_cache_size(PyObject* self, PyObject* args) |
|
||||||
{ |
static PyObject * |
||||||
|
get_cache_size(PyObject *self, PyObject *args) { |
||||||
unsigned long block_number; |
unsigned long block_number; |
||||||
if (!PyArg_ParseTuple(args, "k", &block_number)) |
if (!PyArg_ParseTuple(args, "k", &block_number)) |
||||||
return 0; |
return 0; |
||||||
|
if (block_number >= EPOCH_LENGTH * 2048) { |
||||||
|
char error_message[1024]; |
||||||
|
sprintf(error_message, "Block number must be less than %i (was %lu)", EPOCH_LENGTH * 2048, block_number); |
||||||
|
|
||||||
|
PyErr_SetString(PyExc_ValueError, error_message); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
return Py_BuildValue("i", ethash_get_cachesize(block_number)); |
return Py_BuildValue("i", ethash_get_cachesize(block_number)); |
||||||
} |
} |
||||||
|
|
||||||
static PyObject* |
static PyObject * |
||||||
get_full_size(PyObject* self, PyObject* args) |
get_full_size(PyObject *self, PyObject *args) { |
||||||
{ |
|
||||||
unsigned long block_number; |
unsigned long block_number; |
||||||
if (!PyArg_ParseTuple(args, "k", &block_number)) |
if (!PyArg_ParseTuple(args, "k", &block_number)) |
||||||
return 0; |
return 0; |
||||||
|
if (block_number >= EPOCH_LENGTH * 2048) { |
||||||
|
char error_message[1024]; |
||||||
|
sprintf(error_message, "Block number must be less than %i (was %lu)", EPOCH_LENGTH * 2048, block_number); |
||||||
|
|
||||||
|
PyErr_SetString(PyExc_ValueError, error_message); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
return Py_BuildValue("i", ethash_get_datasize(block_number)); |
return Py_BuildValue("i", ethash_get_datasize(block_number)); |
||||||
} |
} |
||||||
|
|
||||||
|
|
||||||
static PyObject* |
static PyObject * |
||||||
mkcache(PyObject* self, PyObject* args) |
mkcache_bytes(PyObject *self, PyObject *args) { |
||||||
{ |
char *seed; |
||||||
char * seed; |
|
||||||
unsigned long cache_size; |
unsigned long cache_size; |
||||||
int seed_len; |
int seed_len; |
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "ks#", &cache_size, &seed, &seed_len)) |
if (!PyArg_ParseTuple(args, "ks#", &cache_size, &seed, &seed_len)) |
||||||
return 0; |
return 0; |
||||||
|
|
||||||
|
if (seed_len != 32) { |
||||||
|
char error_message[1024]; |
||||||
|
sprintf(error_message, "Seed must be 32 bytes long (was %i)", seed_len); |
||||||
|
|
||||||
if (seed_len != 32) |
PyErr_SetString(PyExc_ValueError, error_message); |
||||||
{ |
return 0; |
||||||
PyErr_SetString(PyExc_ValueError, |
|
||||||
"Seed must be 32 bytes long"); |
|
||||||
return 0; |
|
||||||
} |
} |
||||||
|
|
||||||
printf("cache size: %lu\n", cache_size); |
|
||||||
ethash_params params; |
ethash_params params; |
||||||
params.cache_size = (size_t) cache_size; |
params.cache_size = (size_t) cache_size; |
||||||
ethash_cache cache; |
ethash_cache cache; |
||||||
cache.mem = alloca(cache_size); |
cache.mem = malloc(cache_size); |
||||||
ethash_mkcache(&cache, ¶ms, (uint8_t *) seed); |
ethash_mkcache(&cache, ¶ms, (uint8_t *) seed); |
||||||
return PyString_FromStringAndSize(cache.mem, cache_size); |
PyObject * val = Py_BuildValue("s#", cache.mem, cache_size); |
||||||
|
free(cache.mem); |
||||||
|
return val; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
static PyObject * |
||||||
|
calc_dataset_bytes(PyObject *self, PyObject *args) { |
||||||
|
char *cache_bytes; |
||||||
|
unsigned long full_size; |
||||||
|
int cache_size; |
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "ks#", &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("s#", (char *) mem, full_size); |
||||||
|
free(mem); |
||||||
|
return val; |
||||||
|
} |
||||||
|
|
||||||
|
// hashimoto_light(full_size, cache, header, nonce)
|
||||||
|
static PyObject * |
||||||
|
hashimoto_light(PyObject *self, PyObject *args) { |
||||||
|
char *cache_bytes, *header; |
||||||
|
unsigned long full_size; |
||||||
|
unsigned long long nonce; |
||||||
|
int cache_size, header_size; |
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "ks#s#K", &full_size, &cache_bytes, &cache_size, &header, &header_size, &nonce)) |
||||||
|
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; |
||||||
|
} |
||||||
|
|
||||||
|
if (header_size != 32) { |
||||||
|
char error_message[1024]; |
||||||
|
sprintf(error_message, "Seed must be 32 bytes long (was %i)", header_size); |
||||||
|
PyErr_SetString(PyExc_ValueError, error_message); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
ethash_return_value out; |
||||||
|
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; |
||||||
|
ethash_light(&out, &cache, ¶ms, (uint8_t *) header, nonce); |
||||||
|
return Py_BuildValue("{s:s#,s:s#}", |
||||||
|
"mix digest", out.mix_hash, 32, |
||||||
|
"result", out.result, 32); |
||||||
|
} |
||||||
|
|
||||||
|
// hashimoto_full(dataset, header, nonce)
|
||||||
|
static PyObject * |
||||||
|
hashimoto_full(PyObject *self, PyObject *args) { |
||||||
|
char *full_bytes, *header; |
||||||
|
unsigned long long nonce; |
||||||
|
int full_size, header_size; |
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "s#s#K", &full_bytes, &full_size, &header, &header_size, &nonce)) |
||||||
|
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 %i)", MIX_WORDS, full_size); |
||||||
|
PyErr_SetString(PyExc_ValueError, error_message); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
if (header_size != 32) { |
||||||
|
char error_message[1024]; |
||||||
|
sprintf(error_message, "Header must be 32 bytes long (was %i)", header_size); |
||||||
|
PyErr_SetString(PyExc_ValueError, error_message); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
ethash_return_value out; |
||||||
|
ethash_params params; |
||||||
|
params.full_size = (size_t) full_size; |
||||||
|
ethash_full(&out, (void *) full_bytes, ¶ms, (uint8_t *) header, nonce); |
||||||
|
return Py_BuildValue("{s:s#, s:s#}", |
||||||
|
"mix digest", out.mix_hash, 32, |
||||||
|
"result", out.result, 32); |
||||||
} |
} |
||||||
|
|
||||||
|
// mine(dataset_bytes, header, difficulty_bytes)
|
||||||
|
static PyObject * |
||||||
|
mine(PyObject *self, PyObject *args) { |
||||||
|
char *full_bytes, *header, *difficulty; |
||||||
|
srand(time(0)); |
||||||
|
uint64_t nonce = ((uint64_t) rand()) << 32 | rand(); |
||||||
|
int full_size, header_size, difficulty_size; |
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "s#s#s#", &full_bytes, &full_size, &header, &header_size, &difficulty, &difficulty_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 %i)", MIX_WORDS, full_size); |
||||||
|
PyErr_SetString(PyExc_ValueError, error_message); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
if (header_size != 32) { |
||||||
|
char error_message[1024]; |
||||||
|
sprintf(error_message, "Header must be 32 bytes long (was %i)", header_size); |
||||||
|
PyErr_SetString(PyExc_ValueError, error_message); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
if (difficulty_size != 32) { |
||||||
|
char error_message[1024]; |
||||||
|
sprintf(error_message, "Difficulty must be an array of 32 bytes (only had %i)", difficulty_size); |
||||||
|
PyErr_SetString(PyExc_ValueError, error_message); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
ethash_return_value out; |
||||||
|
ethash_params params; |
||||||
|
params.full_size = (size_t) full_size; |
||||||
|
|
||||||
|
// TODO: Multi threading?
|
||||||
|
do { |
||||||
|
ethash_full(&out, (void *) full_bytes, ¶ms, (const uint8_t *) header, nonce++); |
||||||
|
// TODO: disagrees with the spec https://github.com/ethereum/wiki/wiki/Ethash#mining
|
||||||
|
} while (!ethash_check_difficulty(out.result, (const uint8_t *) difficulty)); |
||||||
|
|
||||||
|
return Py_BuildValue("{s:s#, s:s#, s:K}", |
||||||
|
"mix digest", out.mix_hash, 32, |
||||||
|
"result", out.result, 32, |
||||||
|
"nonce", nonce); |
||||||
|
} |
||||||
|
|
||||||
|
//get_seedhash(block_number)
|
||||||
|
static PyObject * |
||||||
|
get_seedhash(PyObject *self, PyObject *args) { |
||||||
|
unsigned long block_number; |
||||||
|
if (!PyArg_ParseTuple(args, "k", &block_number)) |
||||||
|
return 0; |
||||||
|
if (block_number >= EPOCH_LENGTH * 2048) { |
||||||
|
char error_message[1024]; |
||||||
|
sprintf(error_message, "Block number must be less than %i (was %lu)", EPOCH_LENGTH * 2048, block_number); |
||||||
|
|
||||||
|
PyErr_SetString(PyExc_ValueError, error_message); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
uint8_t seedhash[32]; |
||||||
|
ethash_get_seedhash(seedhash, block_number); |
||||||
|
return Py_BuildValue("s#", (char *) seedhash, 32); |
||||||
|
} |
||||||
|
|
||||||
static PyMethodDef CoreMethods[] = |
static PyMethodDef PyethashMethods[] = |
||||||
{ |
{ |
||||||
{"get_cache_size", get_cache_size, METH_VARARGS, "Get the cache size for a given block number"}, |
{"get_cache_size", get_cache_size, METH_VARARGS, |
||||||
{"get_full_size", get_full_size, METH_VARARGS, "Get the full size for a given block number"}, |
"get_cache_size(block_number)\n\n" |
||||||
{"mkcache", mkcache, METH_VARARGS, "Makes the cache for given parameters and seed hash"}, |
"Get the cache size for a given block number\n" |
||||||
{NULL, NULL, 0, NULL} |
"\nExample:\n" |
||||||
}; |
">>> get_cache_size(0)\n" |
||||||
|
"1048384"}, |
||||||
|
{"get_full_size", get_full_size, METH_VARARGS, |
||||||
|
"get_full_size(block_number)\n\n" |
||||||
|
"Get the full size for a given block number\n" |
||||||
|
"\nExample:\n" |
||||||
|
">>> get_full_size(0)\n" |
||||||
|
"1073739904" |
||||||
|
}, |
||||||
|
{"get_seedhash", get_seedhash, METH_VARARGS, |
||||||
|
"get_seedhash(block_number)\n\n" |
||||||
|
"Gets the seedhash for a block."}, |
||||||
|
{"mkcache_bytes", mkcache_bytes, METH_VARARGS, |
||||||
|
"mkcache_bytes(size, header)\n\n" |
||||||
|
"Makes a byte array for the cache for given cache size and seed hash\n" |
||||||
|
"\nExample:\n" |
||||||
|
">>> pyethash.mkcache_bytes( 1024, \"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\").encode('hex')" |
||||||
|
"\"2da2b506f21070e1143d908e867962486d6b0a02e31d468fd5e3a7143aafa76a14201f63374314e2a6aaf84ad2eb57105dea3378378965a1b3873453bb2b78f9a8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995ca8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995ca8620b2ebeca41fbc773bb837b5e724d6eb2de570d99858df0d7d97067fb8103b21757873b735097b35d3bea8fd1c359a9e8a63c1540c76c9784cf8d975e995c259440b89fa3481c2c33171477c305c8e1e421f8d8f6d59585449d0034f3e421808d8da6bbd0b6378f567647cc6c4ba6c434592b198ad444e7284905b7c6adaf70bf43ec2daa7bd5e8951aa609ab472c124cf9eba3d38cff5091dc3f58409edcc386c743c3bd66f92408796ee1e82dd149eaefbf52b00ce33014a6eb3e50625413b072a58bc01da28262f42cbe4f87d4abc2bf287d15618405a1fe4e386fcdafbb171064bd99901d8f81dd6789396ce5e364ac944bbbd75a7827291c70b42d26385910cd53ca535ab29433dd5c5714d26e0dce95514c5ef866329c12e958097e84462197c2b32087849dab33e88b11da61d52f9dbc0b92cc61f742c07dbbf751c49d7678624ee60dfbe62e5e8c47a03d8247643f3d16ad8c8e663953bcda1f59d7e2d4a9bf0768e789432212621967a8f41121ad1df6ae1fa78782530695414c6213942865b2730375019105cae91a4c17a558d4b63059661d9f108362143107babe0b848de412e4da59168cce82bfbff3c99e022dd6ac1e559db991f2e3f7bb910cefd173e65ed00a8d5d416534e2c8416ff23977dbf3eb7180b75c71580d08ce95efeb9b0afe904ea12285a392aff0c8561ff79fca67f694a62b9e52377485c57cc3598d84cac0a9d27960de0cc31ff9bbfe455acaa62c8aa5d2cce96f345da9afe843d258a99c4eaf3650fc62efd81c7b81cd0d534d2d71eeda7a6e315d540b4473c80f8730037dc2ae3e47b986240cfc65ccc565f0d8cde0bc68a57e39a271dda57440b3598bee19f799611d25731a96b5dbbbefdff6f4f656161462633030d62560ea4e9c161cf78fc96a2ca5aaa32453a6c5dea206f766244e8c9d9a8dc61185ce37f1fc804459c5f07434f8ecb34141b8dcae7eae704c950b55556c5f40140c3714b45eddb02637513268778cbf937a33e4e33183685f9deb31ef54e90161e76d969587dd782eaa94e289420e7c2ee908517f5893a26fdb5873d68f92d118d4bcf98d7a4916794d6ab290045e30f9ea00ca547c584b8482b0331ba1539a0f2714fddc3a0b06b0cfbb6a607b8339c39bcfd6640b1f653e9d70ef6c985b\""}, |
||||||
|
{"calc_dataset_bytes", calc_dataset_bytes, METH_VARARGS, |
||||||
|
"calc_dataset_bytes(full_size, cache_bytes)\n\n" |
||||||
|
"Makes a byte array for the dataset for a given size given cache bytes"}, |
||||||
|
{"hashimoto_light", hashimoto_light, METH_VARARGS, |
||||||
|
"hashimoto_light(full_size, cache_bytes, header, nonce)\n\n" |
||||||
|
"Runs the hashimoto hashing function just using cache bytes. Takes an int (full_size), byte array (cache_bytes), another byte array (header), and an int (nonce). Returns an object containing the mix digest, and hash result."}, |
||||||
|
{"hashimoto_full", hashimoto_full, METH_VARARGS, |
||||||
|
"hashimoto_full(dataset_bytes, header, nonce)\n\n" |
||||||
|
"Runs the hashimoto hashing function using the dataset bytes. Useful for testing. Returns an object containing the mix digest (byte array), and hash result (another byte array)."}, |
||||||
|
{"mine", mine, METH_VARARGS, |
||||||
|
"mine(dataset_bytes, header, difficulty_bytes)\n\n" |
||||||
|
"Mine for an adequate header. Returns an object containing the mix digest (byte array), hash result (another byte array) and nonce (an int)."}, |
||||||
|
{NULL, NULL, 0, NULL} |
||||||
|
}; |
||||||
|
|
||||||
PyMODINIT_FUNC |
PyMODINIT_FUNC |
||||||
initcore(void) |
initpyethash(void) { |
||||||
{ |
PyObject *module = Py_InitModule("pyethash", PyethashMethods); |
||||||
(void) Py_InitModule("core", CoreMethods); |
// Following Spec: https://github.com/ethereum/wiki/wiki/Ethash#definitions
|
||||||
|
PyModule_AddIntConstant(module, "REVISION", (long) REVISION); |
||||||
|
PyModule_AddIntConstant(module, "DATASET_BYTES_INIT", (long) DATASET_BYTES_INIT); |
||||||
|
PyModule_AddIntConstant(module, "DATASET_BYTES_GROWTH", (long) DATASET_BYTES_GROWTH); |
||||||
|
PyModule_AddIntConstant(module, "CACHE_BYTES_INIT", (long) CACHE_BYTES_INIT); |
||||||
|
PyModule_AddIntConstant(module, "CACHE_BYTES_GROWTH", (long) CACHE_BYTES_GROWTH); |
||||||
|
PyModule_AddIntConstant(module, "EPOCH_LENGTH", (long) EPOCH_LENGTH); |
||||||
|
PyModule_AddIntConstant(module, "MIX_BYTES", (long) MIX_BYTES); |
||||||
|
PyModule_AddIntConstant(module, "HASH_BYTES", (long) HASH_BYTES); |
||||||
|
PyModule_AddIntConstant(module, "DATASET_PARENTS", (long) DATASET_PARENTS); |
||||||
|
PyModule_AddIntConstant(module, "CACHE_ROUNDS", (long) CACHE_ROUNDS); |
||||||
|
PyModule_AddIntConstant(module, "ACCESSES", (long) ACCESSES); |
||||||
} |
} |
||||||
|
@ -0,0 +1,82 @@ |
|||||||
|
package ethashTest |
||||||
|
|
||||||
|
import ( |
||||||
|
"bytes" |
||||||
|
"crypto/rand" |
||||||
|
"encoding/hex" |
||||||
|
"log" |
||||||
|
"math/big" |
||||||
|
"testing" |
||||||
|
|
||||||
|
"github.com/ethereum/ethash" |
||||||
|
"github.com/ethereum/go-ethereum/core" |
||||||
|
"github.com/ethereum/go-ethereum/ethdb" |
||||||
|
) |
||||||
|
|
||||||
|
func TestEthash(t *testing.T) { |
||||||
|
seedHash := make([]byte, 32) |
||||||
|
_, err := rand.Read(seedHash) |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
|
||||||
|
db, err := ethdb.NewMemDatabase() |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
|
||||||
|
blockProcessor, err := core.NewCanonical(5, db) |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
|
||||||
|
log.Println("Block Number: ", blockProcessor.ChainManager().CurrentBlock().Number()) |
||||||
|
|
||||||
|
e := ethash.New(blockProcessor.ChainManager()) |
||||||
|
|
||||||
|
miningHash := make([]byte, 32) |
||||||
|
if _, err := rand.Read(miningHash); err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
diff := big.NewInt(10000) |
||||||
|
log.Println("difficulty", diff) |
||||||
|
|
||||||
|
nonce := uint64(0) |
||||||
|
|
||||||
|
ghash_full := e.FullHash(nonce, miningHash) |
||||||
|
log.Printf("ethash full (on nonce): %x %x\n", ghash_full, nonce) |
||||||
|
|
||||||
|
ghash_light := e.LightHash(nonce, miningHash) |
||||||
|
log.Printf("ethash light (on nonce): %x %x\n", ghash_light, nonce) |
||||||
|
|
||||||
|
if bytes.Compare(ghash_full, ghash_light) != 0 { |
||||||
|
t.Errorf("full: %x, light: %x", ghash_full, ghash_light) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func TestGetSeedHash(t *testing.T) { |
||||||
|
seed0, err := ethash.GetSeedHash(0) |
||||||
|
if err != nil { |
||||||
|
t.Errorf("Failed to get seedHash for block 0: %v", err) |
||||||
|
} |
||||||
|
if bytes.Compare(seed0, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) != 0 { |
||||||
|
log.Printf("seedHash for block 0 should be 0s, was: %v\n", seed0) |
||||||
|
} |
||||||
|
seed1, err := ethash.GetSeedHash(30000) |
||||||
|
if err != nil { |
||||||
|
t.Error(err) |
||||||
|
} |
||||||
|
|
||||||
|
// From python:
|
||||||
|
// > from pyethash import get_seedhash
|
||||||
|
// > get_seedhash(30000)
|
||||||
|
expectedSeed1, err := hex.DecodeString("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563") |
||||||
|
if err != nil { |
||||||
|
t.Error(err) |
||||||
|
} |
||||||
|
|
||||||
|
if bytes.Compare(seed1, expectedSeed1) != 0 { |
||||||
|
log.Printf("seedHash for block 1 should be: %v,\nactual value: %v\n", expectedSeed1, seed1) |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
# Strict mode |
||||||
|
set -e |
||||||
|
|
||||||
|
SOURCE="${BASH_SOURCE[0]}" |
||||||
|
while [ -h "$SOURCE" ]; do |
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" |
||||||
|
SOURCE="$(readlink "$SOURCE")" |
||||||
|
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" |
||||||
|
done |
||||||
|
TEST_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" |
||||||
|
|
||||||
|
export GOPATH=${HOME}/.go |
||||||
|
export PATH=$PATH:$GOPATH/bin |
||||||
|
echo "# getting go dependencies (can take some time)..." |
||||||
|
cd ${TEST_DIR}/../.. && go get |
||||||
|
cd ${GOPATH}/src/github.com/ethereum/go-ethereum |
||||||
|
git checkout poc-9 |
||||||
|
cd ${TEST_DIR} && go test |
@ -1,2 +1,3 @@ |
|||||||
pyethereum==0.7.522 |
pyethereum==0.7.522 |
||||||
nose==1.3.4 |
nose==1.3.4 |
||||||
|
pysha3==0.3 |
104
Godeps/_workspace/src/github.com/ethereum/ethash/test/python/test_pyethash.py
generated
vendored
104
Godeps/_workspace/src/github.com/ethereum/ethash/test/python/test_pyethash.py
generated
vendored
Loading…
Reference in new issue