diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f609957bf45507a18126924caf1ab523f0a341e..b540a7b4228959c80f88b90401f6ac48dbadd42a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,7 @@ add_subdirectory(modules/cellframe-sdk/chain) add_subdirectory(modules/cellframe-sdk/app-cli) add_subdirectory(modules/cellframe-sdk/wallet) add_subdirectory(modules/cellframe-sdk/type/dag) +add_subdirectory(modules/cellframe-sdk/consensus/dag_poa) target_compile_options(dap_chain_common_python_module PRIVATE "-fpic") target_compile_options(dap_python_module PRIVATE "-fpic" ) @@ -189,6 +190,7 @@ target_link_libraries(${PROJECT_NAME} cellframe-sdk dap_python_module dap_chain_wallet_python_module dap_server_json_rpc_python_module dap_chain_service_datum_python + dap_chain_cs_dag_poa_python_module ${PYTHON_LIBRARIES} ) diff --git a/CellFrame/python-cellframe.c b/CellFrame/python-cellframe.c index 8626cf823f1bab682c034b4ba5f9bf1a740d60b0..0a84ad0bbf10a07c750ffb755c08998d1a0ee14c 100644 --- a/CellFrame/python-cellframe.c +++ b/CellFrame/python-cellframe.c @@ -443,6 +443,9 @@ PyMODINIT_FUNC PyInit_libCellFrame(void){ PyType_Ready(&DapChainNetSrvPriceObject_DapChainNetSrvPriceObjectType) < 0 || PyType_Ready(&DapChainNetSrvPriceUnitUIDObject_DapChainNetSrvPriceUnitUIDObjectType) < 0 || // ============= + // === Chain cs dag poa + PyType_Ready(&DapChainCsDagPoaObject_DapChainCsDagPoaObjectType) < 0 || + // ============= PyType_Ready(&DapChainGDBObject_DapChainGDBType) < 0 || @@ -554,6 +557,9 @@ PyMODINIT_FUNC PyInit_libCellFrame(void){ PyModule_AddObject(module, "ChainNetSrvUID", (PyObject*)&DapChainNetSrvUIDObject_DapChainNetSrvUIDObjectType); PyModule_AddObject(module, "ChainNetSrvPriceUnitUID", (PyObject*)&DapChainNetSrvPriceUnitUIDObject_DapChainNetSrvPriceUnitUIDObjectType); // ============= + // === Chain cs dag poa + PyModule_AddObject(module, "ChainCsDagPoa", (PyObject*)&DapChainCsDagPoaObject_DapChainCsDagPoaObjectType); + // ============= PyModule_AddObject(module, "ChainGDB", (PyObject*)&DapChainGDBObject_DapChainGDBType); PyModule_AddObject(module, "ChainWallet", (PyObject*)&DapChainWallet_dapChainWalletType); diff --git a/include/python-cellframe.h b/include/python-cellframe.h index f58c434cecb227773d5d0d9d12a37535b8da6fe6..9450c99e5a33c5f2efc0a263e01b64768f1093e0 100644 --- a/include/python-cellframe.h +++ b/include/python-cellframe.h @@ -44,6 +44,9 @@ #include "wrapping_dap_chain_net_srv_common.h" #include "wrapping_dap_chain_net_srv_order.h" // ============ +// === Chain cs dag poa === +#include "wrapping_dap_chain_cs_dag_poa.h" +// ============ #include "wrapping_http.h" diff --git a/modules/cellframe-sdk/chain/include/libdap-chain-python.h b/modules/cellframe-sdk/chain/include/libdap-chain-python.h index dceaefd8b0dea3756456dc5d1c9d0978af890780..cc9dddbec124a8e5042c990b3277afc4892839c5 100644 --- a/modules/cellframe-sdk/chain/include/libdap-chain-python.h +++ b/modules/cellframe-sdk/chain/include/libdap-chain-python.h @@ -41,6 +41,7 @@ PyObject *dap_chain_python_atom_iter_get_first(PyObject *self, PyObject *args); PyObject *dap_chain_python_atom_get_datums(PyObject *self, PyObject *args); PyObject *dap_chain_python_atom_iter_get_next(PyObject *self, PyObject *args); PyObject *dap_chain_python_atom_iter_get_dag(PyObject *self, PyObject *args); +PyObject *dap_chain_python_add_mempool_notify_callback(PyObject *self, PyObject *args); extern PyTypeObject dapChainObject_dapChainType; diff --git a/modules/cellframe-sdk/chain/src/libdap-chain-python.c b/modules/cellframe-sdk/chain/src/libdap-chain-python.c index 639f98097d32995fabb8166d819e115ea48f0e2f..9b7f14ef8ecc3bc1cf68d80de644de8c4f28c26e 100644 --- a/modules/cellframe-sdk/chain/src/libdap-chain-python.c +++ b/modules/cellframe-sdk/chain/src/libdap-chain-python.c @@ -22,6 +22,7 @@ static PyMethodDef DapChainMethods[] = { {"atomGetDatums", (PyCFunction) dap_chain_python_atom_get_datums, METH_VARARGS, ""}, {"atomIterGetNext", (PyCFunction)dap_chain_python_atom_iter_get_next, METH_VARARGS, ""}, {"getDag", (PyCFunction)dap_chain_python_atom_iter_get_dag, METH_NOARGS}, + {"addMempoolNotify", (PyCFunction)dap_chain_python_add_mempool_notify_callback, METH_VARARGS, ""}, //{"close", (PyCFunction)dap_chain_close_py, METH_NOARGS, ""}, {NULL, NULL, 0, NULL} }; @@ -230,3 +231,50 @@ PyObject *dap_chain_python_atom_iter_get_dag(PyObject *self, PyObject *args){ obj_dag->dag = DAP_CHAIN_CS_DAG(((PyDapChainObject*)self)->chain_t); return (PyObject*)obj_dag; } + +typedef struct _wrapping_chain_mempool_notify_callback{ + PyObject *func; + PyObject *arg; +}_wrapping_chain_mempool_notify_callback_t; + +void _wrapping_dap_chain_mempool_notify_handler(void * a_arg, const char a_op_code, const char * a_group, + const char * a_key, const void * a_value, const size_t a_value_len){ + if (!a_arg){ + return; + } + _wrapping_chain_mempool_notify_callback_t *l_callback = (_wrapping_chain_mempool_notify_callback_t*)a_arg; + PyObject *l_value = Py_None; + if (a_value_len != 0) { + l_value = PyBytes_FromStringAndSize(a_value, (Py_ssize_t)a_value_len); + } + char l_op_code[2]; + l_op_code[0] = a_op_code; + l_op_code[1] = '\0'; + PyObject *l_args = Py_BuildValue("sssOO", l_op_code, a_group, a_key, l_value, l_callback->arg); + PyGILState_STATE state = PyGILState_Ensure(); + PyEval_CallObject(l_callback->func, l_args); + Py_DECREF(l_args); + PyGILState_Release(state); +} + +PyObject *dap_chain_python_add_mempool_notify_callback(PyObject *self, PyObject *args){ + dap_chain_t *l_chain = ((PyDapChainObject*)self)->chain_t; + PyObject *obj_func; + PyObject *obj_arg; + if (!PyArg_ParseTuple(args, "OO", &obj_func, &obj_arg)){ + PyErr_SetString(PyExc_AttributeError, "Argument must be callable"); + return NULL; + } + if (!PyCallable_Check(obj_func)){ + PyErr_SetString(PyExc_AttributeError, "Invalid first parameter passed to function. The first " + "argument must be an instance of an object of type Chain. "); + return NULL; + } + _wrapping_chain_mempool_notify_callback_t *l_callback = DAP_NEW(_wrapping_chain_mempool_notify_callback_t); + l_callback->func = obj_func; + l_callback->arg = obj_arg; + Py_INCREF(obj_func); + Py_INCREF(obj_arg); + dap_chain_add_mempool_notify_callback(l_chain, _wrapping_dap_chain_mempool_notify_handler, l_callback); + return Py_None; +} diff --git a/modules/cellframe-sdk/consensus/dag_poa/CMakeLists.txt b/modules/cellframe-sdk/consensus/dag_poa/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..7793c0120d5e94b808e48456fe481b65a5ccf6cf --- /dev/null +++ b/modules/cellframe-sdk/consensus/dag_poa/CMakeLists.txt @@ -0,0 +1,219 @@ +project(dap_chain_cs_dag_poa_python_module C) +cmake_minimum_required(VERSION 3.0) + +set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_COLOR_MAKEFILE ON) +set(CMAKE_C_STANDARD 11) +add_definitions("-fpic") + +if(UNIX) + add_definitions("-DDAP_OS_UNIX") +endif() + +if (NOT (${SUBMODULES_NO_BUILD} MATCHES ON)) + set (SUBMODULES_NO_BUILD ON) + if (NOT (TARGET dap_core)) + add_subdirectory(libdap) + target_compile_options( + dap_core PRIVATE + "-fpic" + ) + endif() + if (NOT (TARGET dap_crypto)) + add_subdirectory(libdap-crypto) + target_compile_options( + dap_crypto PRIVATE + "-fpic" + ) + endif() + if (NOT (TARGET dap_chain_common)) + add_subdirectory(libdap-chain-common) + target_compile_options( + dap_chain_common PRIVATE + "-fpic" + ) + endif() + #if (NOT (TARGET dap_chain_coommon)) + # add_subdirectory(libdap-chain-common) + # target_compile_options( + # dap_chain_common PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_chain)) + # add_subdirectory(libdap-chain) + # target_compile_options( + # dap_chain PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_chain_crypto)) + # add_subdirectory(libdap-chain-crypto) + # target_compile_options( + # dap_chain_crypto PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_chain_mempool)) + # add_subdirectory(libdap-chain-mempool) + # target_compile_options( + # dap_chain_mempool PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_chain_net)) + # add_subdirectory(libdap-chain-net) + # target_compile_options( + # dap_chain_net PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_server_core)) + # add_subdirectory(libdap-server-core) + # target_compile_options( + # dap_server_core PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_chain_global_db)) + # add_subdirectory(libdap-chain-global-db) + # target_compile_options( + # dap_chain_global_db PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_client)) + # add_subdirectory(libdap-client) + # target_compile_options( + # dap_client PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET libdap-server)) + # add_subdirectory(libdap-server) + # # target_compile_options( + # # libdap-server PRIVATE + # # "-fpic" + # # ) + #endif() + #if (NOT (TARGET dap_stream)) + # add_subdirectory(libdap-stream) + # target_compile_options( + # dap_stream PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_stream_ch)) + # add_subdirectory(libdap-stream-ch) + # target_compile_options( + # dap_stream_ch PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_stream_ch_chain)) + # add_subdirectory(libdap-stream-ch-chain) + # target_compile_options( + # dap_stream_ch_chain PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_stream_ch_chain_net)) + # add_subdirectory(libdap-stream-ch-chain-net) + # target_compile_options( + # dap_stream_ch_chain_net PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_udp_server)) + # add_subdirectory(libdap-server-udp) + # target_compile_options( + # dap_udp_server PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_chain_wallet)) + # add_subdirectory(libdap-chain-wallet) + # target_compile_options( + # dap_chain_wallet PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_chain_net_srv)) + # add_subdirectory(libdap-chain-net-srv) + # target_compile_options( + # dap_chain_net_srv PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_server_http_db_auth)) + # add_subdirectory(libdap-server-http-db-auth) + # target_compile_options( + # dap_server_http_db_auth PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_chain_gdb)) + # add_subdirectory(libdap-chain-gdb) + # target_compile_options( + # dap_chain_gdb PRIVATE + # "-fpic" + # ) + #endif() + # if (NOT (TARGET dap_chain_net_srv_vpn)) + # add_subdirectory(libdap-chain-net-srv-vpn) + # target_compile_options( + # dap_chain_net_srv_vpn PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET dap_server_http_db)) + # add_subdirectory(libdap-server-http-db) + # target_compile_options( + # dap_server_http_db PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET (dap_python_module))) + # add_subdirectory(libdap-python) + # target_compile_options( + # dap_python_module PRIVATE + # "-fpic" + # ) + #endif() + #if (NOT (TARGET (dap_chain_python_module))) + # add_subdirectory(libdap-chain-python) + # target_compile_options( + # dap_chain_python_module PRIVATE + # "-fpic" + # ) + #endif() + if (NOT (TARGET (dap_crypto_python_module))) + add_subdirectory(libdap-crypto-python) + target_compile_options( + dap_crypto_python_module PRIVATE + "-fpic" + ) + endif() +endif() + + +file(GLOB CHAIN_COMMON_PYTHON_SRCS src/*.c) +file(GLOB CHAIN_COMMON_PYTHON_HEADERS include/*.h) + +set(Python_ADDITIONAL_VERSIONS 3.7 3.6 3.5 3.4) +find_package (PythonLibs REQUIRED) +include_directories(${PYTHON_INCLUDE_DIR} include/) + +add_library(${PROJECT_NAME} STATIC ${CHAIN_COMMON_PYTHON_SRCS} ${CHAIN_COMMON_PYTHON_HEADERS}) + +target_link_libraries(${PROJECT_NAME}) + +target_link_libraries(${PROJECT_NAME} dap_chain_common + dap_core + dap_crypto + dap_crypto_python_module + dap_chain_python_module + dap_chain_cs_dag_poa) + +target_include_directories(${PROJECT_NAME} PUBLIC include/ ) + diff --git a/modules/cellframe-sdk/consensus/dag_poa/include/wrapping_dap_chain_cs_dag_poa.h b/modules/cellframe-sdk/consensus/dag_poa/include/wrapping_dap_chain_cs_dag_poa.h new file mode 100644 index 0000000000000000000000000000000000000000..84b73c8d7e0dbf405ef1a81fd41ac507bb051e58 --- /dev/null +++ b/modules/cellframe-sdk/consensus/dag_poa/include/wrapping_dap_chain_cs_dag_poa.h @@ -0,0 +1,12 @@ +#include "Python.h" +#include "dap_chain_cs_dag_poa.h" +#include "libdap-chain-python.h" +#include "wrapping_dap_chain_cs_dag_event.h" + +typedef struct PyDapChainCsDagPoa{ + PyObject_HEAD +}PyDapChainCsDagPoaObject; + +PyObject* wrapping_dap_chain_cs_dag_poa_presign_callback_set(PyObject *self, PyObject *args); + +extern PyTypeObject DapChainCsDagPoaObject_DapChainCsDagPoaObjectType; diff --git a/modules/cellframe-sdk/consensus/dag_poa/src/wrapping_dap_chain_cs_dag_poa.c b/modules/cellframe-sdk/consensus/dag_poa/src/wrapping_dap_chain_cs_dag_poa.c new file mode 100644 index 0000000000000000000000000000000000000000..fde8c3cd4a9369983556d78567e6d4775e0585d0 --- /dev/null +++ b/modules/cellframe-sdk/consensus/dag_poa/src/wrapping_dap_chain_cs_dag_poa.c @@ -0,0 +1,114 @@ +#include "wrapping_dap_chain_cs_dag_poa.h" + +#define LOG_TAG "wrapping_dao_chain_cs_dag_poa" + +PyMethodDef DapChainCsDagPoaMethods[] = { + {"setPresign", (PyCFunction)wrapping_dap_chain_cs_dag_poa_presign_callback_set, METH_VARARGS | METH_STATIC, ""}, + {NULL, NULL, 0, NULL} +}; + +PyTypeObject DapChainCsDagPoaObject_DapChainCsDagPoaObjectType = { + PyVarObject_HEAD_INIT(NULL, 0) + "CellFrame.ChainCsDagPoa", /* tp_name */ + sizeof(PyDapChainCsDagPoaObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Chain net object", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + DapChainCsDagPoaMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +typedef struct _wrapping_dap_chain_cs_dag_poa_callback{ + PyObject *func; + PyObject *arg; +}_wrapping_dap_chain_cs_dag_poa_callback_t; + +int _wrapping_callback_handler(dap_chain_t *a_chain, dap_chain_cs_dag_event_t *a_event, size_t a_event_size, void* a_arg){ + if(!a_arg){ + log_it(L_ERROR, "The Python function cannot be run because the argument passed is not a function. "); + return -1; + } + _wrapping_dap_chain_cs_dag_poa_callback_t *l_callback = (_wrapping_dap_chain_cs_dag_poa_callback_t*)a_arg; + + PyGILState_STATE state = PyGILState_Ensure(); + PyDapChainObject *l_obj_chain = PyObject_New(PyDapChainObject, &dapChainObject_dapChainType); + l_obj_chain->chain_t = a_chain; + PyDapChainCsDagEventObject *l_obj_event = PyObject_New(PyDapChainCsDagEventObject, &DapChainCsDagEvent_DapChainCsDagEventType); + l_obj_event->event = a_event; + l_obj_event->event_size = a_event_size; + PyObject *argv = Py_BuildValue("OOO", l_obj_chain, l_obj_event, l_callback->arg); + PyObject *res = PyEval_CallObject(l_callback->func, argv); + Py_XDECREF(argv); + PyGILState_Release(state); + if (!res){ + if (PyLong_AsLong(res)){ + int l_res = _PyLong_AsInt(res); + return l_res; + } else { + log_it(L_ERROR, "Python function was executed but returned not a number."); + return -3; + } + }else{ + log_it(L_ERROR, "An error occurred while executing a Python function. "); + return -2; + } +} + +PyObject* wrapping_dap_chain_cs_dag_poa_presign_callback_set(PyObject *self, PyObject *args){ + (void)self; + PyObject *obj_chain; + PyObject *obj_func; + PyObject *obj_arg; + if (!PyArg_ParseTuple(args, "OOO", &obj_chain, &obj_func, &obj_arg)){ + PyErr_SetString(PyExc_AttributeError, "Argument must be callable"); + return NULL; + } + if (!PyDapChain_Check(obj_chain)){ + PyErr_SetString(PyExc_AttributeError, "Invalid first parameter passed to function. The first " + "argument must be an instance of an object of type Chain. "); + return NULL; + } + if (!PyCallable_Check(obj_func)){ + PyErr_SetString(PyExc_AttributeError, "The second argument is not correct. This function must " + "accept a function that will be called from the callback. "); + return NULL; + } + _wrapping_dap_chain_cs_dag_poa_callback_t *l_callback = DAP_NEW(_wrapping_dap_chain_cs_dag_poa_callback_t); + l_callback->func = obj_func; + l_callback->arg = obj_arg; + Py_INCREF(obj_func); + Py_INCREF(obj_arg); + dap_chain_cs_dag_poa_presign_callback_set(((PyDapChainObject*)obj_chain)->chain_t, _wrapping_callback_handler, l_callback); + return Py_None; +}