Add a wrapper to the C lib to the spec folder

This commit is contained in:
mratsim 2018-02-23 16:43:37 +01:00
parent f11a6a2cde
commit 118da2ea29
2 changed files with 155 additions and 1 deletions

152
spec/internal.nim Normal file
View File

@ -0,0 +1,152 @@
# GPLv3 license
# Nim wrapper for libethash
{.compile: "internal.c".}
{.compile: "sha3.c".}
{.compile: "io_posix.c".}
{.compile: "io.c".}
const
ETHASH_REVISION* = 23
ETHASH_DATASET_BYTES_INIT* = 1073741824
ETHASH_DATASET_BYTES_GROWTH* = 8388608
ETHASH_CACHE_BYTES_INIT* = 1073741824
ETHASH_CACHE_BYTES_GROWTH* = 131072
ETHASH_EPOCH_LENGTH* = 30000
ETHASH_MIX_BYTES* = 128
ETHASH_HASH_BYTES* = 64
ETHASH_DATASET_PARENTS* = 256
ETHASH_CACHE_ROUNDS* = 3
ETHASH_ACCESSES* = 64
ETHASH_DAG_MAGIC_NUM_SIZE* = 8
ETHASH_DAG_MAGIC_NUM* = 0xFEE1DEADBADDCAFE'i64
## / Type of a seedhash/blockhash e.t.c.
type
ethash_h256_t* {.bycopy, importc.} = object
b*: array[32, uint8]
const
ENABLE_SSE* = 0
const
NODE_WORDS* = (64 div 4)
MIX_WORDS* = (ETHASH_MIX_BYTES div 4)
MIX_NODES* = (MIX_WORDS div NODE_WORDS)
type
node* {.bycopy, importc.} = object {.union.}
bytes*: array[NODE_WORDS * 4, uint8]
words*: array[NODE_WORDS, uint32]
double_words*: array[NODE_WORDS div 2, uint64]
ethash_callback_t* {.importc.}= proc (a2: cuint): cint
ethash_return_value_t* {.bycopy.} = object
result*: ethash_h256_t
mix_hash*: ethash_h256_t
success*: bool
proc ethash_h256_get*(hash: ptr ethash_h256_t; i: cuint): uint8 {.inline, importc.} =
return hash.b[i]
proc ethash_h256_set*(hash: ptr ethash_h256_t; i: cuint; v: uint8) {.inline, importc.} =
hash.b[i] = v
proc ethash_h256_reset*(hash: ptr ethash_h256_t) {.inline, importc.} =
hash[] = ethash_h256_t()
## *
## Difficulty quick check for POW preverification
##
## @param header_hash The hash of the header
## @param nonce The block's nonce
## @param mix_hash The mix digest hash
## @param boundary The boundary is defined as (2^256 / difficulty)
## @return true for succesful pre-verification and false otherwise
##
proc ethash_quick_check_difficulty*(header_hash: ptr ethash_h256_t; nonce: uint64;
mix_hash: ptr ethash_h256_t;
boundary: ptr ethash_h256_t): bool {.importc.}
type
ethash_light* {.bycopy, importc.} = object
cache*: pointer
cache_size*: uint64
block_number*: uint64
ethash_light_t = ptr ethash_light
## *
## Allocate and initialize a new ethash_light handler. Internal version
##
## @param cache_size The size of the cache in bytes
## @param seed Block seedhash to be used during the computation of the
## cache nodes
## @return Newly allocated ethash_light handler or NULL in case of
## ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes()
##
proc ethash_light_new_internal*(cache_size: uint64; seed: ptr ethash_h256_t): ethash_light_t {.importc.}
## *
## Calculate the light client data. Internal version.
##
## @param light The light client handler
## @param full_size The size of the full data in bytes.
## @param header_hash The header hash to pack into the mix
## @param nonce The nonce to pack into the mix
## @return The resulting hash.
##
proc ethash_light_compute_internal*(light: ethash_light_t; full_size: uint64;
header_hash: ethash_h256_t; nonce: uint64): ethash_return_value_t {.importc.}
type
ethash_full* {.bycopy.} = object
file*: ptr FILE
file_size*: uint64
data*: ptr node
ethash_full_t = ptr ethash_full
## *
## Allocate and initialize a new ethash_full handler. Internal version.
##
## @param dirname The directory in which to put the DAG file.
## @param seedhash The seed hash of the block. Used in the DAG file naming.
## @param full_size The size of the full data in bytes.
## @param cache A cache object to use that was allocated with @ref ethash_cache_new().
## Iff this function succeeds the ethash_full_t will take memory
## memory ownership of the cache and free it at deletion. If
## not then the user still has to handle freeing of the cache himself.
## @param callback A callback function with signature of @ref ethash_callback_t
## It accepts an unsigned with which a progress of DAG calculation
## can be displayed. If all goes well the callback should return 0.
## If a non-zero value is returned then DAG generation will stop.
## @return Newly allocated ethash_full handler or NULL in case of
## ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data()
##
proc ethash_full_new_internal*(dirname: cstring; seed_hash: ethash_h256_t;
full_size: uint64; light: ethash_light_t;
callback: ethash_callback_t): ethash_full_t {.importc.}
proc ethash_calculate_dag_item*(ret: ptr node; node_index: uint32;
cache: ethash_light_t){.importc.}
proc ethash_quick_hash*(return_hash: ptr ethash_h256_t;
header_hash: ptr ethash_h256_t; nonce: uint64;
mix_hash: ptr ethash_h256_t){.importc.}
proc ethash_get_datasize*(block_number: uint64): uint64 {.importc.}
proc ethash_get_cachesize*(block_number: uint64): uint64 {.importc.}
## *
## Compute the memory data for a full node's memory
##
## @param mem A pointer to an ethash full's memory
## @param full_size The size of the full data in bytes
## @param cache A cache object to use in the calculation
## @param callback The callback function. Check @ref ethash_full_new() for details.
## @return true if all went fine and false for invalid parameters
##
proc ethash_compute_full_data*(mem: pointer; full_size: uint64;
light: ethash_light_t; callback: ethash_callback_t): bool {.importc.}

View File

@ -7,6 +7,8 @@ type U512* = array[16, uint32]
## A very simple type alias to `xor` Hash[512] with normal integers
## and be able to do sha3_512 which only accepts arrays
# TODO delete this
proc toU512*(x: Natural): U512 {.inline, noSideEffect.}=
when system.cpuEndian == littleEndian:
result[0] = x.uint32
@ -102,7 +104,7 @@ proc toByteArrayBE*[T: SomeInteger](num: T): ByteArrayBE[T.sizeof] {.noSideEffec
# but in case of bigEndian, casting is much faster.
const N = T.sizeof
for i in 0 ..< N:
result[i] = byte(num shr uint((N-1-i) * 8))
result[i] = byte(num shr T((N-1-i) * 8))
proc toByteArrayBE*(x: U512): ByteArrayBE[64] {.inline, noSideEffect, noInit.}=
cast[type result](x)