From 4084bb5fe972f0e1cdc65518031f2c51b818186b Mon Sep 17 00:00:00 2001 From: Matthew Wampler-Doty Date: Thu, 5 Mar 2015 09:04:09 -0500 Subject: [PATCH] Chipping away at python --- Makefile | 3 +- pyethash/__init__.py | 3 ++ setup.cfg | 8 ---- setup.py | 12 ++++-- src/python/core.c | 75 +++++++++++++++++++++++++++++------- test/python/test.sh | 8 ++-- test/python/test_pyethash.py | 22 +++++++++-- 7 files changed, 96 insertions(+), 35 deletions(-) delete mode 100644 setup.cfg diff --git a/Makefile b/Makefile index e1cda496..e2630581 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,3 @@ +.PHONY: clean clean: - rm -rf *.so pyethash.egg-info/ build/ test/python/python-virtual-env/ test/c/build/ pythethash/core.so + rm -rf *.so pyethash.egg-info/ build/ test/python/python-virtual-env/ test/c/build/ pyethash/*.{so,pyc} diff --git a/pyethash/__init__.py b/pyethash/__init__.py index e69de29b..fca037db 100644 --- a/pyethash/__init__.py +++ b/pyethash/__init__.py @@ -0,0 +1,3 @@ +import pyethash.core +core = pyethash.core +EPOCH_LENGTH = 30000 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 12bf26e3..00000000 --- a/setup.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[nosetests] -verbosity=1 -detailed-errors=1 -with-coverage=1 -cover-package=nose -debug=nose.loader -pdb=1 -pdb-failures=1 diff --git a/setup.py b/setup.py index b96d8769..96108d31 100755 --- a/setup.py +++ b/setup.py @@ -9,8 +9,12 @@ 'src/libethash/sha3.c' ]) -setup (name = 'pyethash', - version = '1.0', - description = 'Python wrappers for ethash, the ethereum proof of work hashing function', - ext_modules = [pyethash_core], +setup ( + name = 'pyethash', + author = "Matthew Wampler-Doty", + author_email = "matthew.wampler.doty@gmail.com", + license = 'GPL', + version = '1.0', + description = 'Python wrappers for ethash, the ethereum proof of work hashing function', + ext_modules = [pyethash_core], ) diff --git a/src/python/core.c b/src/python/core.c index 2992231b..1486a10e 100644 --- a/src/python/core.c +++ b/src/python/core.c @@ -1,32 +1,79 @@ #include +#include +#include #include "../libethash/ethash.h" - + static PyObject* get_params(PyObject* self, PyObject* args) { unsigned long block_number; ethash_params p; - + if (!PyArg_ParseTuple(args, "k", &block_number)) - Py_RETURN_NONE; + return 0; ethash_params_init(&p, block_number); - - printf("\nBlock number: %lu\n", block_number); - printf("DAG Size: %lu\n", p.full_size); - printf("Cache Size: %lu\n", p.cache_size); - - return Py_BuildValue("{sisi}", - "DAG Size", p.full_size, - "Cache Size", p.cache_size); + + // TODO: Do I memory leak? + return Py_BuildValue("{sisi}", + "DAG Size", p.full_size, + "Cache Size", p.cache_size); +} + +static PyObject* +get_cache(PyObject* self, PyObject* args) +{ + PyObject * py_params = 0; + uint8_t * seed; + int seed_len; + + if (!PyArg_ParseTuple(args, "Os#", &py_params, &seed, &seed_len)) + return 0; + + printf("Seed length: %i\n", seed_len); + if (!PyDict_Check(py_params)) + { + PyErr_SetString( PyExc_TypeError, + "Parameters must be a dictionary"); + return 0; + } + + PyObject * dag_size_obj = PyDict_GetItemString(py_params, "DAG Size"); + if ( !PyInt_Check(dag_size_obj)) + { + PyErr_SetString( PyExc_TypeError, + "The DAG size must be an integer"); + return 0; + } + + PyObject * cache_size_obj = PyDict_GetItemString(py_params, "Cache Size"); + if ( !PyInt_Check(cache_size_obj)) + { + PyErr_SetString( PyExc_TypeError, + "The cache size must be an integer"); + return 0; + } + + const unsigned long cache_size = PyInt_AsUnsignedLongMask(cache_size_obj); + const unsigned long dag_size = PyInt_AsUnsignedLongMask(dag_size_obj); + printf("cache size: %lu\n", cache_size); + printf("dag size: %lu\n", dag_size); + ethash_params params; + params.cache_size = cache_size; + params.full_size = dag_size; + ethash_cache cache; + cache.mem = alloca(cache_size); + Py_RETURN_NONE; } - + + static PyMethodDef CoreMethods[] = { - {"get_params", get_params, METH_VARARGS, "Gets the parameters for a given block"}, + {"get_params", get_params, METH_VARARGS, "Gets the parameters for a given block number"}, + {"get_cache", get_cache, METH_VARARGS, "Gets the cache for given parameters and seed hash"}, {NULL, NULL, 0, NULL} }; - + PyMODINIT_FUNC initcore(void) { diff --git a/test/python/test.sh b/test/python/test.sh index 7bd06646..ac828d5b 100755 --- a/test/python/test.sh +++ b/test/python/test.sh @@ -11,10 +11,10 @@ while [ -h "$SOURCE" ]; do done TEST_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" -rm -rf $TEST_DIR/python-virtual-env -virtualenv --system-site-packages $TEST_DIR/python-virtual-env > /dev/null -source $TEST_DIR/python-virtual-env/bin/activate -pip install -r $TEST_DIR/requirements.txt > /dev/null +#rm -rf $TEST_DIR/python-virtual-env +#virtualenv --system-site-packages $TEST_DIR/python-virtual-env > /dev/null +source $TEST_DIR/python-virtual-env/bin/activate +#pip install -r $TEST_DIR/requirements.txt > /dev/null pip install -e $TEST_DIR/../.. cd $TEST_DIR nosetests --with-doctest -v diff --git a/test/python/test_pyethash.py b/test/python/test_pyethash.py index cb1f182f..1740c197 100644 --- a/test/python/test_pyethash.py +++ b/test/python/test_pyethash.py @@ -1,9 +1,23 @@ -import pyethash.core +import pyethash -def test_get_params(): +def test_get_params_not_null(): block_num = 123456 out = pyethash.core.get_params(block_num) assert out != None -if __name__ == '__main__': - test_me() +def test_get_params_based_on_EPOCH(): + block_num = 123456 + out1 = pyethash.core.get_params(block_num) + out2 = pyethash.core.get_params((block_num // pyethash.EPOCH_LENGTH) * pyethash.EPOCH_LENGTH) + assert out1["DAG Size"] == out2["DAG Size"] + assert out1["Cache Size"] == out2["Cache Size"] + +def test_get_params_returns_different_values_based_on_different_block_input(): + out1 = pyethash.core.get_params(123456) + out2 = pyethash.core.get_params(12345) + assert out1["DAG Size"] != out2["DAG Size"] + assert out1["Cache Size"] != out2["Cache Size"] + +def test_get_cache_smoke_test(): + params = pyethash.core.get_params(123456, bytes("~~~~~")) + assert pyethash.core.get_cache(params) != None