From 02b68885a0fbecb1d5a8d2a52fe566b1c6fa127b Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 15 Feb 2019 14:11:47 +0100 Subject: [PATCH] Implement CBLSLazySignature for lazy serialization/deserialization In some cases it takes too much time to perform full deserialization of BLS signatures in the message handler thread. Better to just read the buffer and do the actual deserialization when the signature is needed for the first time (which is can be in another thread). --- src/bls/bls.cpp | 28 ++++++++++++++++++++++++++++ src/bls/bls.h | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/src/bls/bls.cpp b/src/bls/bls.cpp index bb44f5029..534fd8ad0 100644 --- a/src/bls/bls.cpp +++ b/src/bls/bls.cpp @@ -423,6 +423,34 @@ bool CBLSSignature::Recover(const std::vector& sigs, const std::v return true; } +CBLSLazySignature::CBLSLazySignature(CBLSSignature& _sig) : + bufValid(false), + sigInitialized(true), + sig(_sig) +{ + +} + +void CBLSLazySignature::SetSig(const CBLSSignature& _sig) +{ + bufValid = false; + sigInitialized = true; + sig = _sig; +} + +const CBLSSignature& CBLSLazySignature::GetSig() const +{ + if (!bufValid && !sigInitialized) { + static CBLSSignature invalidSig; + return invalidSig; + } + if (!sigInitialized) { + sig.SetBuf(buf, sizeof(buf)); + sigInitialized = true; + } + return sig; +} + #ifndef BUILD_BITCOIN_INTERNAL static std::once_flag init_flag; diff --git a/src/bls/bls.h b/src/bls/bls.h index 3c953050c..01f730244 100644 --- a/src/bls/bls.h +++ b/src/bls/bls.h @@ -308,6 +308,45 @@ protected: bool InternalGetBuf(void* buf) const; }; +class CBLSLazySignature +{ +private: + mutable char buf[BLS_CURVE_SIG_SIZE]; + mutable bool bufValid{false}; + + mutable CBLSSignature sig; + mutable bool sigInitialized{false}; + +public: + template + inline void Serialize(Stream& s) const + { + if (!sigInitialized && !bufValid) { + throw std::ios_base::failure("sig and buf not initialized"); + } + if (!bufValid) { + sig.GetBuf(buf, sizeof(buf)); + bufValid = true; + } + s.write(buf, sizeof(buf)); + } + + template + inline void Unserialize(Stream& s) + { + s.read(buf, sizeof(buf)); + bufValid = true; + sigInitialized = false; + } + +public: + CBLSLazySignature() = default; + CBLSLazySignature(CBLSSignature& _sig); + + void SetSig(const CBLSSignature& _sig); + const CBLSSignature& GetSig() const; +}; + typedef std::vector BLSIdVector; typedef std::vector BLSVerificationVector; typedef std::vector BLSPublicKeyVector;