From c8b2ab7e3b5e96a1e2d734d7ac3597312354e9df Mon Sep 17 00:00:00 2001
From: "alexey.stratulat" <alexey.stratulat@demlabs.net>
Date: Wed, 16 Nov 2022 15:44:12 +0000
Subject: [PATCH] Backport 7253

---
 modules/chain/dap_chain_ledger.c         | 29 ++++++++++++++++++++++++
 modules/chain/include/dap_chain_ledger.h |  4 ++++
 2 files changed, 33 insertions(+)

diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c
index 737ce807c5..0600225077 100644
--- a/modules/chain/dap_chain_ledger.c
+++ b/modules/chain/dap_chain_ledger.c
@@ -210,6 +210,11 @@ typedef struct dap_ledger_cache_str_item {
     bool found;
 } dap_ledger_cache_str_item_t;
 
+typedef struct dap_chain_ledger_tx_notifier {
+    dap_chain_ledger_tx_add_notify_t callback;
+    void *arg;
+} dap_chain_ledger_tx_notifier_t;
+
 // dap_ledget_t private section
 typedef struct dap_ledger_private {
     dap_chain_net_t * net;
@@ -3776,6 +3781,11 @@ static inline int s_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d
     HASH_ADD_INORDER(hh, l_ledger_priv->ledger_items, tx_hash_fast, sizeof(dap_chain_hash_fast_t),
                          l_tx_item, s_sort_ledger_tx_item); // tx_hash_fast: name of key field
     if(a_safe_call) pthread_rwlock_unlock(&l_ledger_priv->ledger_rwlock);
+    // Callable callback
+    for (dap_list_t *notifier = a_ledger->tx_add_notifiers; notifier != NULL; notifier = notifier->next) {
+        dap_chain_ledger_tx_notifier_t *l_notify = (dap_chain_ledger_tx_notifier_t *)notifier->data;
+        l_notify->callback(l_notify->arg, a_ledger, l_tx_item->tx);
+    }
     // Count TPS
     clock_gettime(CLOCK_REALTIME, &l_ledger_priv->tps_end_time);
     l_ledger_priv->tps_count++;
@@ -4719,3 +4729,22 @@ dap_list_t *dap_chain_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledg
     }
     return l_list_used_out;
 }
+
+void dap_chain_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_ledger_tx_add_notify_t a_callback, void *a_arg) {
+    if (!a_ledger) {
+        log_it(L_ERROR, "NULL ledger passed to dap_chain_ledger_tx_add_notify()");
+        return;
+    }
+    if (!a_callback) {
+        log_it(L_ERROR, "NULL callback passed to dap_chain_ledger_tx_add_notify()");
+        return;
+    }
+    dap_chain_ledger_tx_notifier_t *l_notifier = DAP_NEW(dap_chain_ledger_tx_notifier_t);
+    if (!l_notifier){
+        log_it(L_ERROR, "Can't allocate memory for notifier in dap_chain_ledger_tx_add_notify()");
+        return;
+    }
+    l_notifier->callback = a_callback;
+    l_notifier->arg = a_arg;
+    a_ledger->tx_add_notifiers = dap_list_append(a_ledger->tx_add_notifiers, l_notifier);
+}
diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h
index d53d545289..55b33eed08 100644
--- a/modules/chain/include/dap_chain_ledger.h
+++ b/modules/chain/include/dap_chain_ledger.h
@@ -38,12 +38,14 @@
 
 typedef struct dap_ledger {
     char *net_name;
+    dap_list_t *tx_add_notifiers;
     void *_internal;
 } dap_ledger_t;
 
 typedef bool (* dap_chain_ledger_verificator_callback_t)(dap_ledger_t * a_ledger, dap_hash_fast_t *a_tx_out_hash,  dap_chain_tx_out_cond_t *a_tx_out_cond,
                                                          dap_chain_datum_tx_t *a_tx_in, bool a_owner);
 typedef bool (*dap_chain_ledger_verificator_callback_out_t)(dap_ledger_t* a_ledger, dap_chain_datum_tx_t* a_tx, dap_chain_tx_out_cond_t* a_cond);
+typedef void (* dap_chain_ledger_tx_add_notify_t)(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx);
 
 typedef struct dap_chain_net dap_chain_net_t;
 
@@ -248,3 +250,5 @@ int dap_chain_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype,
 dap_list_t * dap_chain_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse);
 
 //bool dap_chain_ledger_fee_verificator(dap_ledger_t* a_ledger, dap_chain_tx_out_cond_t* a_cond, dap_chain_datum_tx_t* a_tx, bool a_owner);
+
+void dap_chain_ledger_tx_add_notify(dap_ledger_t *a_ledger, dap_chain_ledger_tx_add_notify_t a_callback, void *a_arg);
-- 
GitLab