diff --git a/CMakeLists.txt b/CMakeLists.txt
index ec2db312c5a007120fefa8ed4b235c90037289d7..630925c807c9cf73aae30d3f80b7c5c6d34d7a99 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,6 +26,7 @@ set(DAP_CHAIN_HEADERS
         dap_chain_ops.h
         dap_chain.h
         dap_chain_mine.h
+        dap_chain_mine_task.h
         dap_chain_block.h
         dap_chain_block_cache.h
         dap_chain_internal.h
diff --git a/dap_chain.c b/dap_chain.c
index 377c127d9d22f57798df24a93baf5101c5274131..d27eefa61e10bbb5dad123deb9d06d7fa1e4b205 100644
--- a/dap_chain.c
+++ b/dap_chain.c
@@ -57,7 +57,7 @@ dap_chain_t * dap_chain_open(const char * a_file_storage,const char * a_file_cac
 {
     dap_chain_t * l_chain = DAP_NEW_Z(dap_chain_t);
 
-    l_chain->difficulty = 4;
+    l_chain->difficulty = 2;
 
     DAP_CHAIN_INTERNAL_LOCAL_NEW(l_chain);
 
diff --git a/dap_chain_block.c b/dap_chain_block.c
index 8d7e38d5a4bffa8dbc69e75834a6eebb845f7182..87d6562de41c06a7c0a6b6ac96caab968919f7cf 100644
--- a/dap_chain_block.c
+++ b/dap_chain_block.c
@@ -44,6 +44,7 @@ dap_chain_block_t * dap_chain_block_new(dap_chain_hash_t * a_prev_block )
     }else{
         l_block->header.signature = DAP_CHAIN_BLOCK_SIGNATURE;
         l_block->header.version = 1;
+        l_block->header.timestamp = time(NULL);
         if( a_prev_block ){
             memcpy(&l_block->header.prev_block,a_prev_block,sizeof(l_block->header.prev_block));
         }else{
diff --git a/dap_chain_block.h b/dap_chain_block.h
index b639db986016b903acd20ab58339e0149dd99a13..9676d15ba283b06f402674dc01c6f18b2872e6d8 100644
--- a/dap_chain_block.h
+++ b/dap_chain_block.h
@@ -67,3 +67,4 @@ static inline void dap_chain_block_hash_calc(dap_chain_block_t * a_block, dap_ch
     dap_hash(a_block,a_block->header.size,a_hash->data,
              sizeof(a_hash->data),DAP_HASH_TYPE_SLOW_0);
 }
+
diff --git a/dap_chain_block_cache.c b/dap_chain_block_cache.c
index f3857d5d11b1660c5ea1721ef929409a200bf77e..0ffb6a62aa146ed2c1dee8f3736ee234ec852166 100644
--- a/dap_chain_block_cache.c
+++ b/dap_chain_block_cache.c
@@ -36,9 +36,9 @@ void dap_chain_block_cache_dump(dap_chain_block_cache_t * a_block_cache)
     if ( a_block_cache ) {
         dap_chain_block_t * l_block = a_block_cache->block;
         if( l_block ){
-            char * l_hash_str = dap_chain_hash_to_str(&a_block_cache->block_hash);
-            char * l_prev_hash_str = dap_chain_hash_to_str(&l_block->header.prev_block);
-            char * l_root_sections_str = dap_chain_hash_to_str(&l_block->header.root_sections);
+            char * l_hash_str = dap_chain_hash_to_str_new(&a_block_cache->block_hash);
+            char * l_prev_hash_str = dap_chain_hash_to_str_new(&l_block->header.prev_block);
+            char * l_root_sections_str = dap_chain_hash_to_str_new(&l_block->header.root_sections);
             log_it(L_INFO, "  **  block_hash        %s",l_hash_str);
             log_it(L_INFO, "  **    version         %d",l_block->header.version);
             log_it(L_INFO, "  **    timestamp       %s",  ctime(  (time_t*) &l_block->header.timestamp) );
diff --git a/dap_chain_block_cache.h b/dap_chain_block_cache.h
index f258da4634c3994524033ff7082bf940f2839493..1947bab6ec5c28814ec12aae988db78345c6d39e 100644
--- a/dap_chain_block_cache.h
+++ b/dap_chain_block_cache.h
@@ -29,7 +29,7 @@ typedef struct dap_chain_block_cache{
     dap_chain_hash_t block_hash;
     uint32_t sections_size;
 
-    uint64_t block_mine_time;
+    double block_mine_time;
     dap_chain_block_t * block;
 } dap_chain_block_cache_t;
 
diff --git a/dap_chain_common.c b/dap_chain_common.c
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..28f6c9fb0b751aabe544501a2f1b0e0d84f6213d 100644
--- a/dap_chain_common.c
+++ b/dap_chain_common.c
@@ -0,0 +1,26 @@
+#include <string.h>
+#include "dap_common.h"
+#include "dap_chain_common.h"
+
+#define LOG_TAG "dap_chain_common"
+
+/**
+ * @brief dap_chain_hash_to_str
+ * @param a_hash
+ * @param a_str
+ * @param a_str_max
+ * @return
+ */
+size_t dap_chain_hash_to_str(dap_chain_hash_t * a_hash, char * a_str, size_t a_str_max)
+{
+    const size_t c_hash_str_size = sizeof(*a_hash)*2 +1 /*trailing zero*/ +2 /* heading 0x */  ;
+    if (a_str_max < c_hash_str_size ){
+        log_it(L_ERROR,"String for hash too small, need %u but have only %u",c_hash_str_size,a_str_max);
+    }
+    size_t i;
+    snprintf(a_str,3,"0x");
+    for (i = 0; i< sizeof(a_hash->data); ++i)
+        snprintf(a_str+i*2+2,3,"%02x",a_hash->data[i]);
+    a_str[c_hash_str_size]='\0';
+    return  strlen(a_str);
+}
diff --git a/dap_chain_common.h b/dap_chain_common.h
index 0e3df1b81972eb8bd34e71147aae2fe0b511c3f8..6cc1da25c34c10903d1e9f488987e8144ff4819b 100644
--- a/dap_chain_common.h
+++ b/dap_chain_common.h
@@ -29,7 +29,7 @@
 #include "dap_common.h"
 #include "dap_math_ops.h"
 
-#define DAP_CHAIN_HASH_SIZE 64
+#define DAP_CHAIN_HASH_SIZE 32
 #define DAP_CHAIN_ADDR_HASH_SIZE 32
 
 typedef union dap_chain_hash{
@@ -56,19 +56,18 @@ typedef struct dap_chain_addr{
     uint64_t checksum;
 } dap_chain_addr_t;
 
+size_t dap_chain_hash_to_str(dap_chain_hash_t * a_hash, char * a_str, size_t a_str_max);
+
 /**
  * @brief dap_chain_hash_to_str
  * @param a_hash
  * @return
  */
-static inline char * dap_chain_hash_to_str(dap_chain_hash_t * a_hash)
+static inline char * dap_chain_hash_to_str_new(dap_chain_hash_t * a_hash)
 {
     const size_t c_hash_str_size = sizeof(*a_hash)*2 +1 /*trailing zero*/ +2 /* heading 0x */  ;
     char * ret = DAP_NEW_Z_SIZE(char, c_hash_str_size);
-    size_t i;
-    snprintf(ret,2,"0x");
-    for (i = 0; i< sizeof(a_hash->data); ++i)
-        snprintf(ret+i+2,2,"%02x",a_hash->data[i]);
+    dap_chain_hash_to_str(a_hash,ret,c_hash_str_size);
     return ret;
 }
 
diff --git a/dap_chain_mine.c b/dap_chain_mine.c
index a5ab4339cb7e571191bce236e6d3f5bd1b675c57..9c992241b18cccd020564a36eb3604234a994dc6 100644
--- a/dap_chain_mine.c
+++ b/dap_chain_mine.c
@@ -1,44 +1,292 @@
-#include <time.h>
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <kahovski@gmail.com>
+ * DeM Labs Inc.   https://demlabs.net
+ * DeM Labs Open source community https://github.com/demlabsinc
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#else
+#define _GNU_SOURCE
+#endif
+
+#include <sys/time.h>
+#include <unistd.h>
+#include <sched.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <inttypes.h>
+#include <errno.h>
+
 #include "dap_common.h"
 #include "dap_chain_block.h"
+#include <pthread.h>
 #include "dap_chain_mine.h"
+#include "dap_chain_mine_task.h"
 
 #define LOG_TAG "dap_chain_mine"
 
+int get_cpu_count()
+{
+    long nprocs = -1;
+    long nprocs_max = -1;
+#ifdef _WIN32
+  #ifndef _SC_NPROCESSORS_ONLN
+    SYSTEM_INFO info;
+    GetSystemInfo(&info);
+    #define sysconf(a) info.dwNumberOfProcessors
+    #define _SC_NPROCESSORS_ONLN
+  #endif
+#endif
+#ifdef _SC_NPROCESSORS_ONLN
+    nprocs = sysconf(_SC_NPROCESSORS_ONLN);
+    if (nprocs < 1) {
+      log_it(L_ERROR, "Could not determine number of CPUs online: %s ", strerror (errno));
+      return -1;
+    }
+    nprocs_max = sysconf(_SC_NPROCESSORS_CONF);
+    if (nprocs_max < 1){
+      log_it(L_ERROR, "Could not determine number of CPUs configured: %s",strerror (errno));
+      return -2;
+    }
+    log_it(L_INFO, "%ld of %ld processors online",nprocs, nprocs_max);
+    return nprocs;
+  #else
+    log_it(L_ERROR, "Could not determine number of CPUs");
+    return -3;
+  #endif
+}
+
 /**
- * @brief dap_chain_mine_block
- * @param a_block_cache
+ * @brief s_mine_thread
+ * @param a_arg
  * @return
  */
-int dap_chain_mine_block(dap_chain_block_cache_t * a_block_cache, bool a_mine_gold_only)
+static void * s_mine_thread(void * a_arg)
 {
+    dap_chain_mine_task_t * l_task =  (dap_chain_mine_task_t *) a_arg;
     dap_chain_hash_t l_hash;
-    dap_chain_block_t * l_block = a_block_cache->block;
-    dap_chain_hash_kind_t l_hash_kind;
-    uint64_t l_difficulty = l_block->header.difficulty;
-    time_t l_tm_start = time(NULL);
-    uint64_t l_hash_count = 0;
-    do{
-        l_block->header.nonce++;
-        log_it(L_DEBUG,"nonce %llu",l_block->header.nonce);
-        dap_chain_block_hash_calc(l_block,&l_hash);
+    dap_chain_hash_kind_t l_hash_kind = HASH_USELESS;
+    uint64_t l_difficulty = l_task->block->header.difficulty;
+    uint_fast64_t l_nonce;
+    uint_fast64_t l_hash_count = 0;
+    log_it(L_INFO, "Th#%u:  started",l_task->id);
+
+    // Set CPU affininty and nice level
+#ifndef NO_POSIX_SHED
+    uint32_t l_cpu_count = get_cpu_count();
+    cpu_set_t mask;
+    CPU_ZERO(&mask);
+    CPU_SET( l_task->id % l_cpu_count , &mask);
+
+    if ( pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &mask) != 0 ){
+        log_it(L_CRITICAL, "Error pthread_setaffinity_np() You really have %d or more core in CPU?", l_task->id % l_cpu_count );
+        abort();
+    }else
+        log_it(L_DEBUG, "set affinity to CPU %u", l_task->id % l_cpu_count );
+
+#else
+#warning "No SHED affinity, mining could be uneffective"
+#endif
+    // Set thread priority
+    struct sched_param l_prio_param;
+    int l_prio_policy=SCHED_RR;
+    l_prio_param.__sched_priority= 99;
+    pthread_t self_id= pthread_self();
+    if( pthread_setschedparam(self_id,l_prio_policy,&l_prio_param)== 0 ){
+        log_it(L_DEBUG, "Set priority Round-Robin 99 lvl");
+    }else
+        log_it(L_WARNING, "Can't set priority to Round-Robin 99 lvl");
+
+    for( l_nonce = l_task->nonce_from ; l_nonce < l_task->nonce_to; ++l_nonce ){
+        //log_it(L_DEBUG, "Th#%u: nonce = %llu hash_count = %llu", l_task->id,  l_task->block->header.nonce,
+        //       l_hash_count);
+        l_task->block->header.nonce = l_nonce;
+        dap_chain_block_hash_calc(l_task->block,&l_hash);
         l_hash_count++;
+
+        char l_hash_str[140];
+        dap_chain_hash_to_str(&l_hash,l_hash_str,sizeof (l_hash_str) );
+        //log_it(L_DEBUG, "Th#%u: block hash %s ",l_task->id, l_hash_str);
+
+        // Update task structure every 10 hashes to prevent often context switch
+        if (l_hash_count % 10 == 0){ // TODO Make automatic growing value, depending from hash rate
+            atomic_uint_fast64_t l_hash_count_atomic = ATOMIC_VAR_INIT(l_hash_count);
+            atomic_exchange(&l_task->hash_count, l_hash_count_atomic);
+
+            if( atomic_load(& l_task->tasks->is_mined) ){
+                log_it(L_INFO, "Th#%u: Stop the process", l_task->id);
+                break;
+            }
+        }
+
         l_hash_kind = dap_chain_hash_kind_check(&l_hash,l_difficulty );
-        if(l_block->header.nonce = 0x0fffffffffffffff )
-            break;
-        if (a_mine_gold_only){
-            if (  l_hash_kind != HASH_GOLD ){
-                continue;
+        if (l_task->gold_only){
+            if (  l_hash_kind == HASH_GOLD ){
+                char l_hash_str[140];
+                dap_chain_hash_to_str(&l_hash,l_hash_str,sizeof (l_hash_str) );
+                log_it(L_INFO, "Th#%u: !!! Mined GOLD token !!! block hash %s ",l_task->id, l_hash_str);
+                break;
             }
+        }else if (  l_hash_kind != HASH_USELESS ){
+            char l_hash_str[140];
+            dap_chain_hash_to_str(&l_hash,l_hash_str,sizeof (l_hash_str) );
+            log_it(L_INFO, "Th#%u: !!! Mined SILVER token !!! block hash %s", l_task->id, l_hash_str);
+            break;
         }
-    }while (  l_hash_kind == HASH_USELESS );
-    time_t l_tm_end = time(NULL);
-    if ( l_hash_kind == HASH_GOLD ){
-        log_it(L_INFO, " !!! Mined GOLD token !!!");
-    }else if ( l_hash_kind == HASH_SILVER ) {
-        log_it(L_INFO, " !!! Mined SILVER token !!!");
-    }
-    log_it(L_DEBUG, "Mining time: %lu seconds, %llu hashes, %llu H/s ", l_tm_end - l_tm_start,l_hash_count,
-            l_hash_count / (l_tm_end - l_tm_start));
-    return l_hash_kind != HASH_USELESS;
+    }
+
+    if ( l_hash_kind != HASH_USELESS ){
+        log_it(L_INFO, "Th#%u: !!! Mined nonce = %" PRIuFAST64 " on try %" PRIuFAST64,l_nonce, l_hash_count );
+        atomic_bool l_is_mined_atomic = ATOMIC_VAR_INIT(true);
+        atomic_uint_fast64_t l_mined_nonce_atomic = ATOMIC_VAR_INIT(l_nonce);
+
+        memcpy(&l_task->tasks->mined_hash,&l_hash, sizeof(l_task->tasks->mined_hash) );
+
+        atomic_exchange(&l_task->tasks->is_mined, l_is_mined_atomic );
+        atomic_exchange(&l_task->tasks->mined_nonce ,l_mined_nonce_atomic);
+    }else
+        log_it(L_DEBUG, "Th#%u: Mined nothing");
+
+    DAP_DELETE(l_task->block);
+    return NULL;
 }
+
+static void * s_stats_thread(void * a_arg)
+{
+    dap_chain_mine_tasks_t * l_tasks =  (dap_chain_mine_tasks_t *) a_arg;
+
+    struct dap_chain_mine_task_result * l_result = DAP_NEW_Z(struct dap_chain_mine_task_result);
+    struct timespec l_tm_start;
+    struct timespec l_tm_end ;
+    clock_gettime(CLOCK_MONOTONIC_RAW,&l_tm_start);
+    uint64_t l_tm_diff;
+    double l_tm_diff_secs;
+
+    while(true){
+        uint_fast64_t l_hash_count_total = 0;
+        uint64_t i;
+        log_it(L_DEBUG, "Statistic:");
+
+        for( i = 0; i<l_tasks->tasks_count ; ++i){
+            //log_it(L_DEBUG, "Thread #%u:  hash_count = %llu", i, atomic_load(&l_tasks->task[i].hash_count));
+            l_hash_count_total += atomic_load(& l_tasks->task[i].hash_count );
+        }
+
+        clock_gettime(CLOCK_MONOTONIC_RAW,&l_tm_end);
+        l_tm_diff =  (l_tm_end.tv_sec - l_tm_start.tv_sec) * 1000000 +  (l_tm_end.tv_nsec - l_tm_start.tv_nsec)/ 1000;
+        l_tm_diff_secs = ( (double) l_tm_diff)/ 1000000.0;
+
+        log_it(L_INFO, "Mining time: %04.03lf seconds, %llu hashes, %.03lf H/s ", l_tm_diff_secs
+               , l_hash_count_total ,
+                ( (double) l_hash_count_total) /  ((double) l_tm_diff_secs ) );
+        if(atomic_load(&l_tasks->is_mined) ){
+            l_result->success = true;
+            l_result->nonce = atomic_load(&l_tasks->mined_nonce);
+            memcpy(&l_result->mined_hash, &l_tasks->mined_hash, sizeof(l_tasks->mined_hash) );
+            l_result->mined_time = l_tm_diff;
+            l_result->hashrate_middle = ( (double) l_hash_count_total) /  ((double) l_tm_diff_secs ) ;
+            break;
+        }
+        sleep(2);
+    }
+    return l_result;
+}
+
+
+/**
+ * @brief dap_chain_mine_block
+ * @param a_block_cache
+ * @return
+ */
+int dap_chain_mine_block(dap_chain_block_cache_t * a_block_cache, bool a_mine_gold_only, uint32_t a_threads)
+{
+    pthread_t stats_pid;
+    struct dap_chain_mine_task_result * l_result = NULL;
+    dap_chain_mine_tasks_t * l_tasks = DAP_NEW_Z ( dap_chain_mine_tasks_t);
+
+    uint32_t i;
+
+    if( a_threads == 0 ){
+        int rval=  get_cpu_count();
+        if(rval<0 )
+            return -4;
+        else
+            a_threads = rval;
+    }
+
+    l_tasks->task = DAP_NEW_Z_SIZE( struct dap_chain_mine_task, (sizeof(struct dap_chain_mine_task)*a_threads+16) );
+    l_tasks->tasks_count = a_threads;
+    l_tasks->is_mined = ATOMIC_VAR_INIT(false);
+    l_tasks->mined_nonce = ATOMIC_VAR_INIT(0);
+    l_tasks->block_cache = a_block_cache;
+    uint64_t l_nonce_task_length = UINT64_MAX / a_threads;
+    for(i = 0; i< a_threads; i++){ // Creates mining threads
+        dap_chain_mine_task_t *l_task = &l_tasks->task[i];
+        l_task->tasks = l_tasks;
+        l_task->id = i;
+        l_task->hash_count = ATOMIC_VAR_INIT(0);
+        // Each thread has its own copy of the block for mining
+        l_task->block = DAP_NEW_Z_SIZE(dap_chain_block_t,a_block_cache->block->header.size);
+        memcpy(l_task->block, a_block_cache->block,a_block_cache->block->header.size );
+        // spread nonce between threads
+        l_task->nonce_from = i *l_nonce_task_length;
+        l_task->nonce_to =  (i==a_threads-1)? UINT64_MAX: (i+1)*l_nonce_task_length;
+        pthread_create(& l_task->task_pid ,NULL,s_mine_thread, l_task);
+    }
+    // Create statistic collector thread
+    pthread_create(&stats_pid,NULL,s_stats_thread, l_tasks);
+
+    // Join to it, waiting for results
+    pthread_join(stats_pid,(void**) &l_result);
+    log_it(L_DEBUG,"Finishing mining threads, free memory...");
+    for(i = 0; i< a_threads; i++){ // Creates mining threads
+        pthread_join(l_tasks->task[i].task_pid,NULL);
+    }
+
+    DAP_DELETE(l_tasks->task);
+    //}
+    DAP_DELETE (l_tasks);
+    if(l_result){
+        if(l_result->success){
+            log_it(L_INFO,"Mined nonce = 0x%016x Hashrate  %.03lf H/s",l_result->nonce, l_result->hashrate_middle);
+            a_block_cache->block->header.nonce = l_result->nonce;
+            a_block_cache->block_mine_time = l_result->mined_time;
+            memcpy(&a_block_cache->block_hash, &l_result->mined_hash,sizeof(l_result->mined_hash));
+            DAP_DELETE(l_result);
+            return 0;
+        }else{
+            log_it(L_INFO,"Minded nothing");
+            DAP_DELETE(l_result);
+            return 1;
+        }
+    }else{
+        log_it(L_ERROR,"No result! Its NULL!");
+        return -2;
+    }
+
+
+}
+
+
diff --git a/dap_chain_mine.h b/dap_chain_mine.h
index cb5edfcc707155363f315c34590a92e4b1243754..71d1d590b4a4454fd0e0266d2124f228ff8a9d3a 100644
--- a/dap_chain_mine.h
+++ b/dap_chain_mine.h
@@ -27,4 +27,4 @@
 #include "dap_chain_block_cache.h"
 
 
-int dap_chain_mine_block(dap_chain_block_cache_t * a_block_cache, bool a_mine_gold_only);
+int dap_chain_mine_block(dap_chain_block_cache_t * a_block_cache, bool a_mine_gold_only, uint32_t a_threads);
diff --git a/dap_chain_mine_task.h b/dap_chain_mine_task.h
new file mode 100644
index 0000000000000000000000000000000000000000..2fbe03fabad40216783e457d81123a9e3db272e7
--- /dev/null
+++ b/dap_chain_mine_task.h
@@ -0,0 +1,62 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <kahovski@gmail.com>
+ * DeM Labs Inc.   https://demlabs.net
+ * DeM Labs Open source community https://github.com/demlabsinc
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#pragma once
+#include <stdint.h>
+#include <stddef.h>
+#include <stdatomic.h>
+#include "dap_chain_common.h"
+#include "dap_chain_block.h"
+#include "dap_chain_block_cache.h"
+
+typedef struct dap_chain_mine_task
+{
+    uint32_t id;
+    pthread_t task_pid;
+    uint64_t nonce_from;
+    uint64_t nonce_to;
+    atomic_uint_fast64_t hash_count;
+    bool gold_only;
+    dap_chain_block_t * block;
+    struct  dap_chain_mine_tasks * tasks;
+} dap_chain_mine_task_t;
+
+typedef struct  dap_chain_mine_tasks{
+    atomic_bool is_mined;
+    uint32_t tasks_count;
+    atomic_uint_fast64_t mined_nonce;
+    struct  dap_chain_mine_task * task;
+    dap_chain_hash_t mined_hash;
+    double hashrate_prev[10];
+    double hashrate_avg;
+    dap_chain_block_cache_t * block_cache;
+} dap_chain_mine_tasks_t;
+
+struct dap_chain_mine_task_result
+{
+    bool success;
+    uint64_t nonce;
+    double mined_time;
+    double hashrate_middle;
+    dap_chain_hash_t mined_hash;
+};