From e2cb0b6ec0393f43e18645dab742b69a0c3469e8 Mon Sep 17 00:00:00 2001
From: Dmtiriy Gerasimov <naeper@demlabs.net>
Date: Mon, 8 Apr 2019 14:56:14 +0700
Subject: [PATCH] [*] DAG callbacks

---
 .gitignore               |   0
 CMakeLists.txt           |   0
 LICENSE                  |   0
 README.md                |   0
 dap_chain_cs_dag.c       | 178 ++++++++++++++++++++++++++++++++++-----
 dap_chain_cs_dag.h       |   0
 dap_chain_cs_dag_event.c |   2 +-
 dap_chain_cs_dag_event.h |  39 ++++++++-
 8 files changed, 192 insertions(+), 27 deletions(-)
 mode change 100644 => 100755 .gitignore
 mode change 100644 => 100755 CMakeLists.txt
 mode change 100644 => 100755 LICENSE
 mode change 100644 => 100755 README.md
 mode change 100644 => 100755 dap_chain_cs_dag.c
 mode change 100644 => 100755 dap_chain_cs_dag.h
 mode change 100644 => 100755 dap_chain_cs_dag_event.c
 mode change 100644 => 100755 dap_chain_cs_dag_event.h

diff --git a/.gitignore b/.gitignore
old mode 100644
new mode 100755
diff --git a/CMakeLists.txt b/CMakeLists.txt
old mode 100644
new mode 100755
diff --git a/LICENSE b/LICENSE
old mode 100644
new mode 100755
diff --git a/README.md b/README.md
old mode 100644
new mode 100755
diff --git a/dap_chain_cs_dag.c b/dap_chain_cs_dag.c
old mode 100644
new mode 100755
index 5da2f0c3db..d81c67255a
--- a/dap_chain_cs_dag.c
+++ b/dap_chain_cs_dag.c
@@ -22,20 +22,46 @@
     along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include <stdint.h>
+#include <uthash.h>
+
 #include "dap_common.h"
 #include "dap_chain_cs_dag.h"
 
 #define LOG_TAG "dap_chain_cs_dag"
 
+typedef struct dap_chain_cs_dag_event_item {
+    dap_chain_hash_fast_t hash;
+    dap_chain_cs_dag_event_t *event;
+    UT_hash_handle hh;
+} dap_chain_cs_dag_event_item_t;
+
 typedef struct dap_chain_cs_dag_pvt {
-    uint8_t padding;
+    dap_chain_cs_dag_event_item_t * events;
+    dap_chain_cs_dag_event_item_t * events_round_new;
+    dap_chain_cs_dag_event_item_t * events_round_prev_lasts;
 } dap_chain_cs_dag_pvt_t;
 
 #define PVT(a) ((dap_chain_cs_dag_pvt_t *) a->_pvt )
 
-static int s_chain_callback_element_add(dap_chain_t * a_chain, void * a_data, size_t a_data_size);// Accept new element in chain
-static int s_chain_callback_element_get_first(dap_chain_t * a_chain, void ** a_data, size_t * a_data_size ); // Get the fisrt element from chain
-static int s_chain_callback_element_get_next( dap_chain_t * a_chain, void ** a_data, size_t * a_data_size ); // Get the next element from chain from the current one
+// Atomic element organization callbacks
+static int s_chain_callback_atom_add(dap_chain_t * a_chain, dap_chain_atom_t *);// Accept new event in dag
+static int s_chain_callback_atom_verify(dap_chain_t * a_chain, dap_chain_atom_t *);// Verify new event in dag
+static size_t s_chain_callback_atom_get_size(dap_chain_atom_t *);// Get dag event size
+static size_t s_chain_callback_atom_get_static_hdr_size(dap_chain_t *);// Get dag event header size
+
+static dap_chain_atom_iter_t* s_chain_callback_atom_iter_create(dap_chain_t * a_chain ); // Get the fisrt event from dag
+static dap_chain_atom_t* s_chain_callback_atom_iter_get_first( dap_chain_atom_iter_t * a_atom_iter ); // Get the fisrt event from dag
+static dap_chain_atom_t* s_chain_callback_atom_iter_get_next( dap_chain_atom_iter_t * a_atom_iter ); // Get the next event from dag
+static void s_chain_callback_atom_iter_delete(dap_chain_atom_iter_t * a_atom_iter ); // Get the fisrt event from dag
+
+// Datum ops
+
+static dap_chain_datum_iter_t* s_chain_callback_datum_iter_create(dap_chain_t * a_chain );
+static void s_chain_callback_datum_iter_delete(dap_chain_datum_iter_t * a_iter );
+static dap_chain_datum_t* s_chain_callback_datum_iter_get_first( dap_chain_datum_iter_t * a_datum_iter ); // Get the fisrt datum from dag
+static dap_chain_datum_t* s_chain_callback_datum_iter_get_next( dap_chain_datum_iter_t * a_datum_iter ); // Get the next datum from dag
+
+
 
 /**
  * @brief dap_chain_cs_dag_init
@@ -43,6 +69,8 @@ static int s_chain_callback_element_get_next( dap_chain_t * a_chain, void ** a_d
  */
 int dap_chain_cs_dag_init()
 {
+    dap_chain_class_add( "dag", dap_chain_cs_dag_new );
+
     return 0;
 }
 
@@ -66,9 +94,25 @@ void dap_chain_cs_dag_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg)
     l_chain_cs_dag->chain = a_chain;
 
     a_chain->callback_delete = dap_chain_cs_dag_delete;
-    a_chain->callback_element_add = s_chain_callback_element_add; // Accept new element in chain
-    a_chain->callback_element_get_first = s_chain_callback_element_get_first; // Get the fisrt element from chain
-    a_chain->callback_element_get_next = s_chain_callback_element_get_next; // Get the next element from chain from the current one
+
+    // Atom element callbacks
+    a_chain->callback_atom_add = s_chain_callback_atom_add ;  // Accept new element in chain
+    a_chain->callback_atom_verify = s_chain_callback_atom_add ;  // Verify new element in chain
+    a_chain->callback_atom_get_size = s_chain_callback_atom_get_size; // Get dag event size
+    a_chain->callback_atom_get_static_hdr_size = s_chain_callback_atom_get_static_hdr_size; // Get dag event hdr size
+
+    a_chain->callback_atom_iter_create = s_chain_callback_atom_iter_create;
+    a_chain->callback_atom_iter_delete = s_chain_callback_atom_iter_delete;
+    a_chain->callback_atom_iter_get_first = s_chain_callback_atom_iter_get_first; // Get the fisrt element from chain
+    a_chain->callback_atom_iter_get_next = s_chain_callback_atom_iter_get_next; // Get the next element from chain from the current one
+
+    // Datum operations callbacks
+    a_chain->callback_datum_iter_create = s_chain_callback_datum_iter_create; // Datum iterator create
+    a_chain->callback_datum_iter_delete = s_chain_callback_datum_iter_delete; // Datum iterator delete
+    a_chain->callback_datum_iter_get_first = s_chain_callback_datum_iter_get_first; // Get the fisrt datum from chain
+    a_chain->callback_datum_iter_get_next = s_chain_callback_datum_iter_get_next; // Get the next datum from chain from the current one
+
+    // Others
     a_chain->_inheritor = l_chain_cs_dag;
 
     log_it (L_NOTICE, "DAG chain initialized");
@@ -92,36 +136,124 @@ void dap_chain_cs_dag_delete(dap_chain_t * a_chain)
 }
 
 /**
- * @brief s_chain_callback_element_add Accept new element in chain
- * @param a_chain
- * @param a_data
- * @param a_data_size
+ * @brief s_chain_callback_atom_add Accept new event in dag
+ * @param a_chain DAG object
+ * @param a_atom
+ * @return 0 if verified and added well, otherwise if not
  */
-static int s_chain_callback_element_add(dap_chain_t * a_chain, void * a_data, size_t a_data_size)
+static int s_chain_callback_atom_add(dap_chain_t * a_chain, dap_chain_atom_t * a_atom)
 {
     return -1; // TODO
 }
 
+
 /**
- * @brief s_chain_callback_element_get_first Get the fisrt element from chain
+ * @brief s_chain_callback_atom_verify Verify atomic element
  * @param a_chain
- * @param a_data
- * @param a_data_size
- * @return 0 if ok
+ * @param a_atom
+ * @return
  */
-static int s_chain_callback_element_get_first(dap_chain_t * a_chain, void ** a_data, size_t * a_data_size )
+static int s_chain_callback_atom_verify(dap_chain_t * a_chain, dap_chain_atom_t *  a_atom)
 {
     return -1; // TODO
 }
 
 /**
- * @brief s_chain_callback_element_get_next Get the next element from chain from the current one
+ * @brief s_chain_callback_atom_get_size Get size of atomic element
+ * @param a_atom
+ * @return
+ */
+static size_t s_chain_callback_atom_get_size(dap_chain_atom_t * a_atom)
+{
+    return dap_chain_cs_dag_event_calc_size( (dap_chain_cs_dag_event_t * ) a_atom);
+}
+
+/**
+ * @brief s_chain_callback_atom_get_static_hdr_size
  * @param a_chain
- * @param a_data
- * @param a_data_size
- * @return 0 if ok
+ * @return
  */
-static int s_chain_callback_element_get_next( dap_chain_t * a_chain, void ** a_data, size_t * a_data_size )
+static size_t s_chain_callback_atom_get_static_hdr_size(dap_chain_t * a_chain)
 {
-    return -1; // TODO
+   return sizeof (dap_chain_class_dag_event_hdr_t);
+}
+
+/**
+ * @brief s_chain_callback_atom_iter_create Create atomic element iterator
+ * @param a_chain
+ * @return
+ */
+static dap_chain_atom_iter_t* s_chain_callback_atom_iter_create(dap_chain_t * a_chain )
+{
+    return NULL; // TODO
+}
+
+/**
+ * @brief s_chain_callback_atom_iter_get_first Get the first dag event
+ * @param a_atom_iter
+ * @return
+ */
+static dap_chain_atom_t* s_chain_callback_atom_iter_get_first(dap_chain_atom_iter_t * a_atom_iter )
+{
+    return NULL; // TODO
+}
+
+/**
+ * @brief s_chain_callback_atom_iter_get_next Get the next dag event
+ * @param a_atom_iter
+ * @return
+ */
+static dap_chain_atom_t* s_chain_callback_atom_iter_get_next( dap_chain_atom_iter_t * a_atom_iter )
+{
+    return NULL; // TODO
+}
+
+/**
+ * @brief s_chain_callback_atom_iter_delete Delete dag event iterator
+ * @param a_atom_iter
+ */
+static void s_chain_callback_atom_iter_delete(dap_chain_atom_iter_t * a_atom_iter )
+{
+    // TODO
+}
+
+
+
+/**
+ * @brief s_chain_callback_datum_iter_create Create datum iterator
+ * @param a_chain
+ * @return
+ */
+static dap_chain_datum_iter_t* s_chain_callback_datum_iter_create(dap_chain_t * a_chain )
+{
+    return NULL; // TODO
+}
+
+/**
+ * @brief s_chain_callback_datum_iter_get_first Get the first datum
+ * @param a_datum_iter
+ * @return
+ */
+static dap_chain_datum_t* s_chain_callback_datum_iter_get_first(dap_chain_datum_iter_t * a_datum_iter )
+{
+    return NULL; // TODO
+}
+
+/**
+ * @brief s_chain_callback_datum_iter_get_next Get the next dag event datum
+ * @param a_datum_iter
+ * @return
+ */
+static dap_chain_datum_t* s_chain_callback_datum_iter_get_next( dap_chain_datum_iter_t * a_datum_iter )
+{
+    return NULL; // TODO
+}
+
+/**
+ * @brief s_chain_callback_datum_iter_delete Delete dag event datum iterator
+ * @param a_datum_iter
+ */
+static void s_chain_callback_datum_iter_delete(dap_chain_datum_iter_t * a_datum_iter )
+{
+    // TODO
 }
diff --git a/dap_chain_cs_dag.h b/dap_chain_cs_dag.h
old mode 100644
new mode 100755
diff --git a/dap_chain_cs_dag_event.c b/dap_chain_cs_dag_event.c
old mode 100644
new mode 100755
index 94aa4ade1f..a8d39c0a45
--- a/dap_chain_cs_dag_event.c
+++ b/dap_chain_cs_dag_event.c
@@ -25,8 +25,8 @@
 #include "dap_common.h"
 #include "dap_enc_key.h"
 
+#include "dap_hash.h"
 #include "dap_chain_sign.h"
-
 #include "dap_chain_datum.h"
 #include "dap_chain_cs_dag.h"
 #include "dap_chain_cs_dag_event.h"
diff --git a/dap_chain_cs_dag_event.h b/dap_chain_cs_dag_event.h
old mode 100644
new mode 100755
index 0d02264a61..6edecd6426
--- a/dap_chain_cs_dag_event.h
+++ b/dap_chain_cs_dag_event.h
@@ -27,16 +27,19 @@
 #include "dap_chain_common.h"
 #include "dap_chain_datum.h"
 #include "dap_chain_sign.h"
+#include "dap_hash.h"
 
 typedef struct dap_chain_cs_dag dap_chain_cs_dag_t;
 
-typedef struct dap_chain_cs_dag_event {
-    struct {
+typedef struct dap_chain_class_dag_event_hdr {
         uint8_t version;
         uint64_t timestamp;
         uint16_t hash_count; // Number of hashes
         uint16_t signs_count; // Number of signs nested with event
-    } header;
+} dap_chain_class_dag_event_hdr_t;
+
+typedef struct dap_chain_cs_dag_event {
+    dap_chain_class_dag_event_hdr_t header;
     uint8_t hashes_n_signs_n_datum[]; // Hashes, signes and datum
 } dap_chain_cs_dag_event_t;
 
@@ -49,3 +52,33 @@ void dap_chain_cs_dag_event_delete(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_
 
 dap_chain_datum_t* dap_chain_cs_dag_event_get_datum(dap_chain_cs_dag_event_t * a_event);
 dap_chain_sign_t * dap_chain_cs_dag_event_get_sign( dap_chain_cs_dag_event_t * a_event, uint16_t a_sign_number);
+
+/**
+ * @brief dap_chain_cs_dag_event_calc_size
+ * @param a_event
+ * @return
+ */
+static inline size_t dap_chain_cs_dag_event_calc_size(dap_chain_cs_dag_event_t * a_event)
+{
+    size_t l_hashes_size = a_event->header.hash_count*sizeof(dap_chain_hash_fast_t);
+    uint8_t * l_signs = a_event->hashes_n_signs_n_datum
+            +l_hashes_size;
+    uint16_t l_signs_offset = 0;
+    uint16_t l_signs_passed;
+    for ( l_signs_passed=0;  l_signs_passed < a_event->header.signs_count; l_signs_passed++){
+        dap_chain_sign_t * l_sign = (dap_chain_sign_t *) l_signs+l_signs_offset;
+        l_signs_offset+=l_sign->header.sign_pkey_size+l_sign->header.sign_size+sizeof(l_sign->header);
+    }
+    dap_chain_datum_t * l_datum = (dap_chain_datum_t*)  l_signs+l_signs_offset;
+    return sizeof( a_event->header ) + l_hashes_size +l_signs_offset +l_datum->header.data_size;
+}
+
+/**
+ * @brief dap_chain_cs_dag_event_calc_hash
+ * @param a_event
+ * @param a_event_hash
+ */
+static inline void dap_chain_cs_dag_event_calc_hash(dap_chain_cs_dag_event_t * a_event,dap_chain_hash_fast_t * a_event_hash)
+{
+    dap_hash_fast(a_event, dap_chain_cs_dag_event_calc_size (a_event) , a_event_hash);
+}
-- 
GitLab