diff --git a/include/cosigner/asymmetric_eddsa_cosigner_server.h b/include/cosigner/asymmetric_eddsa_cosigner_server.h index 3c5a703..d831f7f 100644 --- a/include/cosigner/asymmetric_eddsa_cosigner_server.h +++ b/include/cosigner/asymmetric_eddsa_cosigner_server.h @@ -3,6 +3,7 @@ #include "asymmetric_eddsa_cosigner.h" #include "crypto/commitments/commitments.h" #include "crypto/ed25519_algebra/ed25519_algebra.h" +#include "cosigner/timing_map.h" #include #include @@ -84,8 +85,7 @@ class asymmetric_eddsa_cosigner_server : public asymmetric_eddsa_cosigner void commit_to_Rs(const std::string& txid, uint64_t id, const std::vector& Rs, eddsa_commitment& commitment); signing_persistency& _signing_persistency; - std::mutex _timing_map_lock; - std::map _timing_map; + TimingMap _timing_map; }; } diff --git a/include/cosigner/cmp_ecdsa_online_signing_service.h b/include/cosigner/cmp_ecdsa_online_signing_service.h index 93981ce..17c1e6c 100644 --- a/include/cosigner/cmp_ecdsa_online_signing_service.h +++ b/include/cosigner/cmp_ecdsa_online_signing_service.h @@ -1,8 +1,8 @@ #pragma once #include "cosigner/cmp_ecdsa_signing_service.h" +#include "cosigner/timing_map.h" -#include namespace fireblocks { @@ -44,7 +44,7 @@ class cmp_ecdsa_online_signing_service final : public cmp_ecdsa_signing_service virtual void delete_signing_data(const std::string& txid) = 0; }; - cmp_ecdsa_online_signing_service(platform_service& service, const cmp_key_persistency& key_persistency, signing_persistency& persistency) : cmp_ecdsa_signing_service(service, key_persistency), _signing_persistency(persistency) {} + cmp_ecdsa_online_signing_service(platform_service& service, const cmp_key_persistency& key_persistency, signing_persistency& persistency); void start_signing(const std::string& key_id, const std::string& txid, cosigner_sign_algorithm algorithm, const signing_data& data, const std::string& metadata_json, const std::set& players, const std::set& players_ids, std::vector& mta_requests); uint64_t mta_response(const std::string& txid, const std::map>& requests, uint32_t version, cmp_mta_responses& response); @@ -57,8 +57,7 @@ class cmp_ecdsa_online_signing_service final : public cmp_ecdsa_signing_service private: signing_persistency& _signing_persistency; - std::mutex _timing_map_lock; - std::map _timing_map; + TimingMap _timing_map; }; } diff --git a/include/cosigner/eddsa_online_signing_service.h b/include/cosigner/eddsa_online_signing_service.h index 2d47168..7d47962 100644 --- a/include/cosigner/eddsa_online_signing_service.h +++ b/include/cosigner/eddsa_online_signing_service.h @@ -1,6 +1,7 @@ #pragma once #include "cosigner/types.h" +#include "cosigner/timing_map.h" #include #include @@ -51,7 +52,7 @@ class eddsa_online_signing_service final virtual void delete_signing_data(const std::string& txid) = 0; }; - eddsa_online_signing_service(platform_service& service, const cmp_key_persistency& key_persistency, signing_persistency& preprocessing_persistency) : _service(service), _key_persistency(key_persistency), _signing_persistency(preprocessing_persistency) {} + eddsa_online_signing_service(platform_service& service, const cmp_key_persistency& key_persistency, signing_persistency& preprocessing_persistency); void start_signing(const std::string& key_id, const std::string& txid, const signing_data& data, const std::string& metadata_json, const std::set& players, const std::set& players_ids, std::vector& commitments); uint64_t store_commitments(const std::string& txid, const std::map>& commitments, uint32_t version, std::vector& R); uint64_t broadcast_si(const std::string& txid, const std::map>& Rs, std::vector& si); @@ -67,8 +68,7 @@ class eddsa_online_signing_service final const cmp_key_persistency& _key_persistency; signing_persistency& _signing_persistency; - std::mutex _timing_map_lock; - std::map _timing_map; + TimingMap _timing_map; static const std::unique_ptr _ed25519; }; diff --git a/include/cosigner/timing_map.h b/include/cosigner/timing_map.h new file mode 100644 index 0000000..9216171 --- /dev/null +++ b/include/cosigner/timing_map.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include +#include "cosigner/platform_service.h" +namespace fireblocks +{ +namespace common +{ +namespace cosigner +{ + +class TimingMap final +{ +public: + TimingMap(platform_service& platform_service); + ~TimingMap() = default; + + TimingMap(const TimingMap&) = delete; + TimingMap(TimingMap&&) = delete; + TimingMap& operator=(const TimingMap&) = delete; + TimingMap& operator=(TimingMap&&) = delete; + + void insert(const std::string& key); + const std::optional extract(const std::string& key); + void erase(const std::string& key); + +private: + const std::optional extract_impl(const std::string& key); + std::mutex _lock; + std::map _data; + platform_service& _time_service; +}; + +} +} +} \ No newline at end of file diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 4abd15f..7e18909 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -24,6 +24,7 @@ set(COSIGNER_FILES cosigner/eddsa_online_signing_service.cpp cosigner/mta.cpp cosigner/utils.cpp + cosigner/timing_map.cpp logging/logging_t.c ) diff --git a/src/common/Makefile b/src/common/Makefile index d1eb327..4b70784 100644 --- a/src/common/Makefile +++ b/src/common/Makefile @@ -19,7 +19,7 @@ C_Objects := $(C_Files:.c=.o) Cpp_Files := cosigner/cosigner_exception.cpp cosigner/cmp_setup_service.cpp cosigner/cmp_offline_refresh_service.cpp cosigner/utils.cpp \ cosigner/cmp_ecdsa_signing_service.cpp cosigner/cmp_ecdsa_online_signing_service.cpp cosigner/cmp_ecdsa_offline_signing_service.cpp cosigner/mta.cpp \ cosigner/eddsa_online_signing_service.cpp cosigner/asymmetric_eddsa_cosigner.cpp cosigner/asymmetric_eddsa_cosigner_server.cpp cosigner/asymmetric_eddsa_cosigner_client.cpp \ - blockchain/mpc/hd_derive.cpp + blockchain/mpc/hd_derive.cpp cosigner/timing_map.cpp Cpp_Objects := $(Cpp_Files:.cpp=.o) diff --git a/src/common/cosigner/asymmetric_eddsa_cosigner_server.cpp b/src/common/cosigner/asymmetric_eddsa_cosigner_server.cpp index 7560933..36faf34 100644 --- a/src/common/cosigner/asymmetric_eddsa_cosigner_server.cpp +++ b/src/common/cosigner/asymmetric_eddsa_cosigner_server.cpp @@ -28,7 +28,7 @@ class ed25519_scalar_cleaner asymmetric_eddsa_cosigner_server::asymmetric_eddsa_cosigner_server(platform_service& cosigner_service, const cmp_key_persistency& key_persistency, signing_persistency& signing_persistency) : - asymmetric_eddsa_cosigner(cosigner_service, key_persistency), _signing_persistency(signing_persistency) {} + asymmetric_eddsa_cosigner(cosigner_service, key_persistency), _signing_persistency(signing_persistency), _timing_map(cosigner_service) {} void asymmetric_eddsa_cosigner_server::store_presigning_data(const std::string& key_id, const std::string& request_id, uint32_t start_index, uint32_t count, uint32_t total_count, const std::set& players_ids, uint64_t sender, const std::vector& R_commitments) @@ -129,10 +129,7 @@ void asymmetric_eddsa_cosigner_server::eddsa_sign_offline(const std::string& key throw cosigner_exception(cosigner_exception::INVALID_PARAMETERS); } - { - std::lock_guard lg(_timing_map_lock); - _timing_map[txid] = _service.now_msec(); - } + _timing_map.insert(txid); uint64_t my_id = _service.get_id_from_keyid(key_id); @@ -440,18 +437,15 @@ uint64_t asymmetric_eddsa_cosigner_server::broadcast_si(const std::string& txid, { _signing_persistency.delete_signing_data(txid); - std::lock_guard time_lock(_timing_map_lock); - auto timing_it = _timing_map.find(txid); - if (timing_it == _timing_map.end()) + const std::optional diff = _timing_map.extract(txid); + if (!diff) { LOG_WARN("transaction %s is missing from timing map??", txid.c_str()); - LOG_INFO("Finished signing trnsaction %s", txid.c_str()); + LOG_INFO("Finished signing transaction %s", txid.c_str()); } else { - uint64_t diff = (_service.now_msec() - timing_it->second); - _timing_map.erase(timing_it); - LOG_INFO("Finished signing %lu blocks for transaction %s (tenant %s) in %" PRIu64 "ms", data.signers_ids.size(), txid.c_str(), _service.get_current_tenantid().c_str(), diff); + LOG_INFO("Finished signing %lu blocks for transaction %s (tenant %s) in %" PRIu64 "ms", data.signers_ids.size(), txid.c_str(), _service.get_current_tenantid().c_str(), *diff); } } else @@ -541,18 +535,15 @@ uint64_t asymmetric_eddsa_cosigner_server::get_eddsa_signature(const std::string _signing_persistency.delete_signing_data(txid); - std::lock_guard time_lock(_timing_map_lock); - auto timing_it = _timing_map.find(txid); - if (timing_it == _timing_map.end()) + const std::optional diff = _timing_map.extract(txid); + if (!diff) { LOG_WARN("transaction %s is missing from timing map??", txid.c_str()); - LOG_INFO("Finished signing trnsaction %s", txid.c_str()); + LOG_INFO("Finished signing transaction %s", txid.c_str()); } else { - uint64_t diff = (_service.now_msec() - timing_it->second); - _timing_map.erase(timing_it); - LOG_INFO("Finished signing %lu blocks for transaction %s (tenant %s) in %" PRIu64 "ms", sigs.size(), txid.c_str(), _service.get_current_tenantid().c_str(), diff); + LOG_INFO("Finished signing %lu blocks for transaction %s (tenant %s) in %" PRIu64 "ms", sigs.size(), txid.c_str(), _service.get_current_tenantid().c_str(), *diff); } return my_id; diff --git a/src/common/cosigner/cmp_ecdsa_online_signing_service.cpp b/src/common/cosigner/cmp_ecdsa_online_signing_service.cpp index b178a99..72c8f2e 100644 --- a/src/common/cosigner/cmp_ecdsa_online_signing_service.cpp +++ b/src/common/cosigner/cmp_ecdsa_online_signing_service.cpp @@ -49,6 +49,12 @@ static inline const char* to_string(cosigner_sign_algorithm algorithm) } } +cmp_ecdsa_online_signing_service::cmp_ecdsa_online_signing_service(platform_service& service, const cmp_key_persistency& key_persistency, signing_persistency& persistency): + cmp_ecdsa_signing_service(service, key_persistency), + _signing_persistency(persistency), + _timing_map(service) {} + + void cmp_ecdsa_online_signing_service::start_signing(const std::string& key_id, const std::string& txid, cosigner_sign_algorithm algorithm, const signing_data& data, const std::string& metadata_json, const std::set& players, const std::set& players_ids, std::vector& mta_requests) { LOG_INFO("Entering txid = %s", txid.c_str()); @@ -95,10 +101,7 @@ void cmp_ecdsa_online_signing_service::start_signing(const std::string& key_id, _service.start_signing(key_id, txid, data, metadata_json, players); #ifdef MOBILE - { - std::lock_guard lg(_timing_map_lock); - _timing_map[txid] = _service.now_msec(); - } + _timing_map.insert(txid); #endif LOG_INFO("Starting signing process keyid = %s, txid = %s", key_id.c_str(), txid.c_str()); @@ -156,10 +159,7 @@ uint64_t cmp_ecdsa_online_signing_service::mta_response(const std::string& txid, } #ifndef MOBILE - { - std::lock_guard lg(_timing_map_lock); - _timing_map[txid] = _service.now_msec(); - } + _timing_map.insert(txid); #endif ack_mta_request(metadata.sig_data.size(), requests, metadata.signers_ids, metadata.ack); @@ -467,18 +467,15 @@ uint64_t cmp_ecdsa_online_signing_service::get_cmp_signature(const std::string& _signing_persistency.delete_signing_data(txid); - std::lock_guard time_lock(_timing_map_lock); - auto timing_it = _timing_map.find(txid); - if (timing_it == _timing_map.end()) + const std::optional diff = _timing_map.extract(txid); + if (!diff) { LOG_WARN("transaction %s is missing from timing map??", txid.c_str()); LOG_INFO("Finished signing transaction %s", txid.c_str()); } else { - uint64_t diff = (_service.now_msec() - timing_it->second); - _timing_map.erase(timing_it); - LOG_INFO("Finished signing %lu blocks for transaction %s (tenant %s) in %" PRIu64 "ms", full_sig.size(), txid.c_str(), _service.get_current_tenantid().c_str(), diff); + LOG_INFO("Finished signing %lu blocks for transaction %s (tenant %s) in %" PRIu64 "ms", full_sig.size(), txid.c_str(), _service.get_current_tenantid().c_str(), *diff); } return my_id; diff --git a/src/common/cosigner/eddsa_online_signing_service.cpp b/src/common/cosigner/eddsa_online_signing_service.cpp index 87fd5f3..4f4ba57 100644 --- a/src/common/cosigner/eddsa_online_signing_service.cpp +++ b/src/common/cosigner/eddsa_online_signing_service.cpp @@ -30,6 +30,13 @@ static inline const char* to_string(cosigner_sign_algorithm algorithm) const std::unique_ptr eddsa_online_signing_service::_ed25519(elliptic_curve256_new_ed25519_algebra(), elliptic_curve256_algebra_ctx_free); +eddsa_online_signing_service::eddsa_online_signing_service(platform_service& service, const cmp_key_persistency& key_persistency, signing_persistency& preprocessing_persistency): + _service(service), + _key_persistency(key_persistency), + _signing_persistency(preprocessing_persistency), + _timing_map(service) {} + + void eddsa_online_signing_service::start_signing(const std::string& key_id, const std::string& txid, const signing_data& data, const std::string& metadata_json, const std::set& players, const std::set& players_ids, std::vector& commitments) { (void)players; // UNUSED @@ -63,10 +70,7 @@ void eddsa_online_signing_service::start_signing(const std::string& key_id, cons _service.start_signing(key_id, txid, data, metadata_json, players); #ifdef MOBILE - { - std::lock_guard lg(_timing_map_lock); - _timing_map[txid] = _service.now_msec(); - } + _timing_map.insert(txid); #endif size_t blocks = data.blocks.size(); @@ -133,10 +137,7 @@ uint64_t eddsa_online_signing_service::store_commitments(const std::string& txid verify_tenant_id(_service, _key_persistency, data.key_id); #ifndef MOBILE - { - std::lock_guard lg(_timing_map_lock); - _timing_map[txid] = _service.now_msec(); - } + _timing_map.insert(txid); #endif @@ -381,18 +382,15 @@ uint64_t eddsa_online_signing_service::get_eddsa_signature(const std::string& tx _signing_persistency.delete_signing_data(txid); - std::lock_guard time_lock(_timing_map_lock); - auto timing_it = _timing_map.find(txid); - if (timing_it == _timing_map.end()) + const std::optional diff = _timing_map.extract(txid); + if (!diff) { LOG_WARN("transaction %s is missing from timing map??", txid.c_str()); - LOG_INFO("Finished signing trnsaction %s", txid.c_str()); + LOG_INFO("Finished signing transaction %s", txid.c_str()); } else { - uint64_t diff = (_service.now_msec() - timing_it->second); - _timing_map.erase(timing_it); - LOG_INFO("Finished signing %lu blocks for transaction %s (tenant %s) in %" PRIu64 "ms", sig.size(), txid.c_str(), _service.get_current_tenantid().c_str(), diff); + LOG_INFO("Finished signing %lu blocks for transaction %s (tenant %s) in %" PRIu64 "ms", sig.size(), txid.c_str(), _service.get_current_tenantid().c_str(), *diff); } return my_id; diff --git a/src/common/cosigner/timing_map.cpp b/src/common/cosigner/timing_map.cpp new file mode 100644 index 0000000..7fcc1a5 --- /dev/null +++ b/src/common/cosigner/timing_map.cpp @@ -0,0 +1,58 @@ +#include "cosigner/timing_map.h" + +namespace fireblocks +{ +namespace common +{ +namespace cosigner +{ + +TimingMap::TimingMap(platform_service& platform_service): + _time_service(platform_service) +{ + +} +void TimingMap::insert(const std::string& key) +{ + std::unique_lock guard(_lock); +#ifdef DEBUG + // Unit tests may call some phase handlers more then once to test replays + if (_data.find(key) == _data.end()) +#endif + _data[key] = _time_service.now_msec(); +} + +void TimingMap::erase(const std::string& key) +{ + std::unique_lock guard(_lock); + _data.erase(key); +} + +const std::optional TimingMap::extract_impl(const std::string& key) +{ + std::unique_lock guard(_lock); + auto iterator = _data.find(key); + if (iterator == _data.end()) + { + return std::nullopt; + } + const uint64_t value = iterator->second; + + _data.erase(iterator); + return value; +} + +const std::optional TimingMap::extract(const std::string& key) +{ + const std::optional extracted = extract_impl(key); + if (!extracted) + { + return std::nullopt; + } + const uint64_t diff = (_time_service.now_msec() - *extracted); + return diff; +} + +} +} +} \ No newline at end of file