mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 20:12:57 +01:00
refactor: Misc LLMQ refactoring (#4590)
* use unique_ptr instead of shared Signed-off-by: pasta <pasta@dashboost.org> * unique_ptr over shared_ptr Signed-off-by: pasta <pasta@dashboost.org> * remove unneeded ptr Signed-off-by: pasta <pasta@dashboost.org> * Adjust IsTxSafeForMining checks Signed-off-by: pasta <pasta@dashboost.org> * use const ref Signed-off-by: pasta <pasta@dashboost.org> * add a todo Signed-off-by: pasta <pasta@dashboost.org> * use optional instead of magic max value fixes a hypothetical bug where myIdx is not "initialized" (ie max), and we sleep forever Signed-off-by: pasta <pasta@dashboost.org> * simplify relay check Signed-off-by: pasta <pasta@dashboost.org> * use count_if instead of a loop Signed-off-by: pasta <pasta@dashboost.org> * add a few vector reserves Signed-off-by: pasta <pasta@dashboost.org>
This commit is contained in:
parent
850806e6e7
commit
5cf97c1b07
@ -67,7 +67,7 @@ void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, con
|
|||||||
#endif // ENABLE_WALLET
|
#endif // ENABLE_WALLET
|
||||||
|
|
||||||
llmq::quorumInstantSendManager->UpdatedBlockTip(pindexNew);
|
llmq::quorumInstantSendManager->UpdatedBlockTip(pindexNew);
|
||||||
llmq::chainLocksHandler->UpdatedBlockTip(pindexNew);
|
llmq::chainLocksHandler->UpdatedBlockTip();
|
||||||
|
|
||||||
llmq::quorumManager->UpdatedBlockTip(pindexNew, fInitialDownload);
|
llmq::quorumManager->UpdatedBlockTip(pindexNew, fInitialDownload);
|
||||||
llmq::quorumDKGSessionManager->UpdatedBlockTip(pindexNew, fInitialDownload);
|
llmq::quorumDKGSessionManager->UpdatedBlockTip(pindexNew, fInitialDownload);
|
||||||
|
@ -431,7 +431,7 @@ CFinalCommitmentPtr CQuorumBlockProcessor::GetMinedCommitment(Consensus::LLMQTyp
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
retMinedBlockHash = p.second;
|
retMinedBlockHash = p.second;
|
||||||
return std::make_shared<CFinalCommitment>(p.first);
|
return std::make_unique<CFinalCommitment>(p.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The returned quorums are in reversed order, so the most recent one is at index 0
|
// The returned quorums are in reversed order, so the most recent one is at index 0
|
||||||
|
@ -27,7 +27,7 @@ namespace llmq
|
|||||||
{
|
{
|
||||||
|
|
||||||
class CFinalCommitment;
|
class CFinalCommitment;
|
||||||
using CFinalCommitmentPtr = std::shared_ptr<CFinalCommitment>;
|
using CFinalCommitmentPtr = std::unique_ptr<CFinalCommitment>;
|
||||||
|
|
||||||
class CQuorumBlockProcessor
|
class CQuorumBlockProcessor
|
||||||
{
|
{
|
||||||
|
@ -202,7 +202,7 @@ void CChainLocksHandler::AcceptedBlockHeader(const CBlockIndex* pindexNew)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CChainLocksHandler::UpdatedBlockTip(const CBlockIndex* pindexNew)
|
void CChainLocksHandler::UpdatedBlockTip()
|
||||||
{
|
{
|
||||||
// don't call TrySignChainTip directly but instead let the scheduler call it. This way we ensure that cs_main is
|
// don't call TrySignChainTip directly but instead let the scheduler call it. This way we ensure that cs_main is
|
||||||
// never locked and TrySignChainTip is not called twice in parallel. Also avoids recursive calls due to
|
// never locked and TrySignChainTip is not called twice in parallel. Also avoids recursive calls due to
|
||||||
@ -460,10 +460,14 @@ bool CChainLocksHandler::IsTxSafeForMining(const uint256& txid) const
|
|||||||
if (!RejectConflictingBlocks()) {
|
if (!RejectConflictingBlocks()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (!isEnabled || !isEnforced) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!IsInstantSendEnabled()) {
|
if (!IsInstantSendEnabled()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!isEnabled || !isEnforced) {
|
if (quorumInstantSendManager->IsLocked(txid)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,10 +480,7 @@ bool CChainLocksHandler::IsTxSafeForMining(const uint256& txid) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (txAge < WAIT_FOR_ISLOCK_TIMEOUT && !quorumInstantSendManager->IsLocked(txid)) {
|
return txAge >= WAIT_FOR_ISLOCK_TIMEOUT;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WARNING: cs_main and cs should not be held!
|
// WARNING: cs_main and cs should not be held!
|
||||||
|
@ -97,7 +97,7 @@ public:
|
|||||||
void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv);
|
void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv);
|
||||||
void ProcessNewChainLock(NodeId from, const CChainLockSig& clsig, const uint256& hash);
|
void ProcessNewChainLock(NodeId from, const CChainLockSig& clsig, const uint256& hash);
|
||||||
void AcceptedBlockHeader(const CBlockIndex* pindexNew);
|
void AcceptedBlockHeader(const CBlockIndex* pindexNew);
|
||||||
void UpdatedBlockTip(const CBlockIndex* pindexNew);
|
void UpdatedBlockTip();
|
||||||
void TransactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime);
|
void TransactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime);
|
||||||
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex, const std::vector<CTransactionRef>& vtxConflicted);
|
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex, const std::vector<CTransactionRef>& vtxConflicted);
|
||||||
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected);
|
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected);
|
||||||
|
@ -101,7 +101,7 @@ public:
|
|||||||
obj.pushKV("membersSig", membersSig.ToString());
|
obj.pushKV("membersSig", membersSig.ToString());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
using CFinalCommitmentPtr = std::shared_ptr<CFinalCommitment>;
|
using CFinalCommitmentPtr = std::unique_ptr<CFinalCommitment>;
|
||||||
|
|
||||||
class CFinalCommitmentTxPayload
|
class CFinalCommitmentTxPayload
|
||||||
{
|
{
|
||||||
|
@ -82,7 +82,7 @@ CDKGPrematureCommitment::CDKGPrematureCommitment(const Consensus::LLMQParams& pa
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CDKGMember::CDKGMember(CDeterministicMNCPtr _dmn, size_t _idx) :
|
CDKGMember::CDKGMember(const CDeterministicMNCPtr& _dmn, size_t _idx) :
|
||||||
dmn(_dmn),
|
dmn(_dmn),
|
||||||
idx(_idx),
|
idx(_idx),
|
||||||
id(_dmn->proTxHash)
|
id(_dmn->proTxHash)
|
||||||
@ -321,7 +321,7 @@ void CDKGSession::ReceiveMessage(const CDKGContribution& qc, bool& retBan)
|
|||||||
|
|
||||||
bool complain = false;
|
bool complain = false;
|
||||||
CBLSSecretKey skContribution;
|
CBLSSecretKey skContribution;
|
||||||
if (!qc.contributions->Decrypt(myIdx, WITH_LOCK(activeMasternodeInfoCs, return *activeMasternodeInfo.blsKeyOperator), skContribution, PROTOCOL_VERSION)) {
|
if (!qc.contributions->Decrypt(*myIdx, WITH_LOCK(activeMasternodeInfoCs, return *activeMasternodeInfo.blsKeyOperator), skContribution, PROTOCOL_VERSION)) {
|
||||||
logger.Batch("contribution from %s could not be decrypted", member->dmn->proTxHash.ToString());
|
logger.Batch("contribution from %s could not be decrypted", member->dmn->proTxHash.ToString());
|
||||||
complain = true;
|
complain = true;
|
||||||
} else if (member->idx != myIdx && ShouldSimulateError("complain-lie")) {
|
} else if (member->idx != myIdx && ShouldSimulateError("complain-lie")) {
|
||||||
@ -670,7 +670,7 @@ void CDKGSession::VerifyAndJustify(CDKGPendingMessages& pendingMessages)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto& qc = WITH_LOCK(invCs, return std::move(complaints.at(*m->complaints.begin())));
|
const auto& qc = WITH_LOCK(invCs, return std::move(complaints.at(*m->complaints.begin())));
|
||||||
if (qc.complainForMembers[myIdx]) {
|
if (qc.complainForMembers[*myIdx]) {
|
||||||
justifyFor.emplace(qc.proTxHash);
|
justifyFor.emplace(qc.proTxHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -874,18 +874,12 @@ void CDKGSession::ReceiveMessage(const CDKGJustification& qj, bool& retBan)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int receivedCount = 0;
|
auto receivedCount = std::count_if(members.cbegin(), members.cend(), [](const auto& m){
|
||||||
int expectedCount = 0;
|
return !m->justifications.empty();
|
||||||
|
});
|
||||||
for (const auto& m : members) {
|
auto expectedCount = std::count_if(members.cbegin(), members.cend(), [](const auto& m){
|
||||||
if (!m->justifications.empty()) {
|
return m->someoneComplain;
|
||||||
receivedCount++;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (m->someoneComplain) {
|
|
||||||
expectedCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Batch("verified justification: received=%d/%d time=%d", receivedCount, expectedCount, t1.count());
|
logger.Batch("verified justification: received=%d/%d time=%d", receivedCount, expectedCount, t1.count());
|
||||||
}
|
}
|
||||||
@ -899,7 +893,9 @@ void CDKGSession::VerifyAndCommit(CDKGPendingMessages& pendingMessages)
|
|||||||
CDKGLogger logger(*this, __func__);
|
CDKGLogger logger(*this, __func__);
|
||||||
|
|
||||||
std::vector<size_t> badMembers;
|
std::vector<size_t> badMembers;
|
||||||
|
badMembers.reserve(members.size());
|
||||||
std::vector<size_t> openComplaintMembers;
|
std::vector<size_t> openComplaintMembers;
|
||||||
|
openComplaintMembers.reserve(members.size());
|
||||||
|
|
||||||
for (const auto& m : members) {
|
for (const auto& m : members) {
|
||||||
if (m->bad) {
|
if (m->bad) {
|
||||||
@ -1319,14 +1315,8 @@ void CDKGSession::MarkBadMember(size_t idx)
|
|||||||
void CDKGSession::RelayInvToParticipants(const CInv& inv) const
|
void CDKGSession::RelayInvToParticipants(const CInv& inv) const
|
||||||
{
|
{
|
||||||
g_connman->ForEachNode([&](CNode* pnode) {
|
g_connman->ForEachNode([&](CNode* pnode) {
|
||||||
bool relay = false;
|
if (pnode->qwatch ||
|
||||||
auto verifiedProRegTxHash = pnode->GetVerifiedProRegTxHash();
|
(!pnode->GetVerifiedProRegTxHash().IsNull() && relayMembers.count(pnode->GetVerifiedProRegTxHash()))) {
|
||||||
if (pnode->qwatch) {
|
|
||||||
relay = true;
|
|
||||||
} else if (!verifiedProRegTxHash.IsNull() && relayMembers.count(verifiedProRegTxHash)) {
|
|
||||||
relay = true;
|
|
||||||
}
|
|
||||||
if (relay) {
|
|
||||||
pnode->PushInventory(inv);
|
pnode->PushInventory(inv);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -122,6 +122,7 @@ public:
|
|||||||
Consensus::LLMQType llmqType;
|
Consensus::LLMQType llmqType;
|
||||||
uint256 quorumHash;
|
uint256 quorumHash;
|
||||||
uint256 proTxHash;
|
uint256 proTxHash;
|
||||||
|
// TODO make this pair a struct with named fields
|
||||||
std::vector<std::pair<uint32_t, CBLSSecretKey>> contributions;
|
std::vector<std::pair<uint32_t, CBLSSecretKey>> contributions;
|
||||||
CBLSSignature sig;
|
CBLSSignature sig;
|
||||||
|
|
||||||
@ -190,7 +191,7 @@ public:
|
|||||||
class CDKGMember
|
class CDKGMember
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CDKGMember(CDeterministicMNCPtr _dmn, size_t _idx);
|
CDKGMember(const CDeterministicMNCPtr& _dmn, size_t _idx);
|
||||||
|
|
||||||
CDeterministicMNCPtr dmn;
|
CDeterministicMNCPtr dmn;
|
||||||
size_t idx;
|
size_t idx;
|
||||||
@ -255,7 +256,7 @@ private:
|
|||||||
|
|
||||||
uint256 myProTxHash;
|
uint256 myProTxHash;
|
||||||
CBLSId myId;
|
CBLSId myId;
|
||||||
size_t myIdx{(size_t)-1};
|
std::optional<size_t> myIdx;
|
||||||
|
|
||||||
// all indexed by msg hash
|
// all indexed by msg hash
|
||||||
// we expect to only receive a single vvec and contribution per member, but we must also be able to relay
|
// we expect to only receive a single vvec and contribution per member, but we must also be able to relay
|
||||||
@ -279,7 +280,7 @@ public:
|
|||||||
|
|
||||||
bool Init(const CBlockIndex* pQuorumBaseBlockIndex, const std::vector<CDeterministicMNCPtr>& mns, const uint256& _myProTxHash);
|
bool Init(const CBlockIndex* pQuorumBaseBlockIndex, const std::vector<CDeterministicMNCPtr>& mns, const uint256& _myProTxHash);
|
||||||
|
|
||||||
size_t GetMyMemberIndex() const { return myIdx; }
|
std::optional<size_t> GetMyMemberIndex() const { return myIdx; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The following sets of methods are for the first 4 phases handled in the session. The flow of message calls
|
* The following sets of methods are for the first 4 phases handled in the session. The flow of message calls
|
||||||
|
@ -90,7 +90,7 @@ CDKGSessionHandler::CDKGSessionHandler(const Consensus::LLMQParams& _params, CBL
|
|||||||
params(_params),
|
params(_params),
|
||||||
blsWorker(_blsWorker),
|
blsWorker(_blsWorker),
|
||||||
dkgManager(_dkgManager),
|
dkgManager(_dkgManager),
|
||||||
curSession(std::make_shared<CDKGSession>(_params, _blsWorker, _dkgManager)),
|
curSession(std::make_unique<CDKGSession>(_params, _blsWorker, _dkgManager)),
|
||||||
pendingContributions((size_t)_params.size * 2, MSG_QUORUM_CONTRIB), // we allow size*2 messages as we need to make sure we see bad behavior (double messages)
|
pendingContributions((size_t)_params.size * 2, MSG_QUORUM_CONTRIB), // we allow size*2 messages as we need to make sure we see bad behavior (double messages)
|
||||||
pendingComplaints((size_t)_params.size * 2, MSG_QUORUM_COMPLAINT),
|
pendingComplaints((size_t)_params.size * 2, MSG_QUORUM_COMPLAINT),
|
||||||
pendingJustifications((size_t)_params.size * 2, MSG_QUORUM_JUSTIFICATION),
|
pendingJustifications((size_t)_params.size * 2, MSG_QUORUM_JUSTIFICATION),
|
||||||
@ -158,7 +158,7 @@ void CDKGSessionHandler::StopThread()
|
|||||||
|
|
||||||
bool CDKGSessionHandler::InitNewQuorum(const CBlockIndex* pQuorumBaseBlockIndex)
|
bool CDKGSessionHandler::InitNewQuorum(const CBlockIndex* pQuorumBaseBlockIndex)
|
||||||
{
|
{
|
||||||
curSession = std::make_shared<CDKGSession>(params, blsWorker, dkgManager);
|
curSession = std::make_unique<CDKGSession>(params, blsWorker, dkgManager);
|
||||||
|
|
||||||
if (!deterministicMNManager->IsDIP3Enforced(pQuorumBaseBlockIndex->nHeight)) {
|
if (!deterministicMNManager->IsDIP3Enforced(pQuorumBaseBlockIndex->nHeight)) {
|
||||||
return false;
|
return false;
|
||||||
@ -271,7 +271,7 @@ void CDKGSessionHandler::SleepBeforePhase(QuorumPhase curPhase,
|
|||||||
// Don't expect perfect block times and thus reduce the phase time to be on the secure side (caller chooses factor)
|
// Don't expect perfect block times and thus reduce the phase time to be on the secure side (caller chooses factor)
|
||||||
double adjustedPhaseSleepTimePerMember = phaseSleepTimePerMember * randomSleepFactor;
|
double adjustedPhaseSleepTimePerMember = phaseSleepTimePerMember * randomSleepFactor;
|
||||||
|
|
||||||
int64_t sleepTime = (int64_t)(adjustedPhaseSleepTimePerMember * curSession->GetMyMemberIndex());
|
int64_t sleepTime = (int64_t)(adjustedPhaseSleepTimePerMember * curSession->GetMyMemberIndex().value_or(0));
|
||||||
int64_t endTime = GetTimeMillis() + sleepTime;
|
int64_t endTime = GetTimeMillis() + sleepTime;
|
||||||
int heightTmp{-1};
|
int heightTmp{-1};
|
||||||
int heightStart{-1};
|
int heightStart{-1};
|
||||||
|
@ -114,7 +114,7 @@ private:
|
|||||||
int currentHeight GUARDED_BY(cs) {-1};
|
int currentHeight GUARDED_BY(cs) {-1};
|
||||||
uint256 quorumHash GUARDED_BY(cs);
|
uint256 quorumHash GUARDED_BY(cs);
|
||||||
|
|
||||||
std::shared_ptr<CDKGSession> curSession;
|
std::unique_ptr<CDKGSession> curSession;
|
||||||
std::thread phaseHandlerThread;
|
std::thread phaseHandlerThread;
|
||||||
|
|
||||||
// Do not guard these, they protect their internals themselves
|
// Do not guard these, they protect their internals themselves
|
||||||
|
@ -51,9 +51,9 @@ CQuorum::CQuorum(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker) :
|
|||||||
|
|
||||||
CQuorum::~CQuorum() = default;
|
CQuorum::~CQuorum() = default;
|
||||||
|
|
||||||
void CQuorum::Init(const CFinalCommitmentPtr& _qc, const CBlockIndex* _pQuorumBaseBlockIndex, const uint256& _minedBlockHash, const std::vector<CDeterministicMNCPtr>& _members)
|
void CQuorum::Init(CFinalCommitmentPtr _qc, const CBlockIndex* _pQuorumBaseBlockIndex, const uint256& _minedBlockHash, const std::vector<CDeterministicMNCPtr>& _members)
|
||||||
{
|
{
|
||||||
qc = _qc;
|
qc = std::move(_qc);
|
||||||
m_quorum_base_block_index = _pQuorumBaseBlockIndex;
|
m_quorum_base_block_index = _pQuorumBaseBlockIndex;
|
||||||
members = _members;
|
members = _members;
|
||||||
minedBlockHash = _minedBlockHash;
|
minedBlockHash = _minedBlockHash;
|
||||||
@ -315,17 +315,17 @@ CQuorumPtr CQuorumManager::BuildQuorumFromCommitment(const Consensus::LLMQType l
|
|||||||
auto quorum = std::make_shared<CQuorum>(llmqParams, blsWorker);
|
auto quorum = std::make_shared<CQuorum>(llmqParams, blsWorker);
|
||||||
auto members = CLLMQUtils::GetAllQuorumMembers(llmqParams, pQuorumBaseBlockIndex);
|
auto members = CLLMQUtils::GetAllQuorumMembers(llmqParams, pQuorumBaseBlockIndex);
|
||||||
|
|
||||||
quorum->Init(qc, pQuorumBaseBlockIndex, minedBlockHash, members);
|
quorum->Init(std::move(qc), pQuorumBaseBlockIndex, minedBlockHash, members);
|
||||||
|
|
||||||
bool hasValidVvec = false;
|
bool hasValidVvec = false;
|
||||||
if (quorum->ReadContributions(evoDb)) {
|
if (quorum->ReadContributions(evoDb)) {
|
||||||
hasValidVvec = true;
|
hasValidVvec = true;
|
||||||
} else {
|
} else {
|
||||||
if (BuildQuorumContributions(qc, quorum)) {
|
if (BuildQuorumContributions(quorum->qc, quorum)) {
|
||||||
quorum->WriteContributions(evoDb);
|
quorum->WriteContributions(evoDb);
|
||||||
hasValidVvec = true;
|
hasValidVvec = true;
|
||||||
} else {
|
} else {
|
||||||
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- quorum.ReadContributions and BuildQuorumContributions for block %s failed\n", __func__, qc->quorumHash.ToString());
|
LogPrint(BCLog::LLMQ, "CQuorumManager::%s -- quorum.ReadContributions and BuildQuorumContributions for block %s failed\n", __func__, quorum->qc->quorumHash.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ using CQuorumPtr = std::shared_ptr<CQuorum>;
|
|||||||
using CQuorumCPtr = std::shared_ptr<const CQuorum>;
|
using CQuorumCPtr = std::shared_ptr<const CQuorum>;
|
||||||
|
|
||||||
class CFinalCommitment;
|
class CFinalCommitment;
|
||||||
using CFinalCommitmentPtr = std::shared_ptr<CFinalCommitment>;
|
using CFinalCommitmentPtr = std::unique_ptr<CFinalCommitment>;
|
||||||
|
|
||||||
|
|
||||||
class CQuorum
|
class CQuorum
|
||||||
@ -171,7 +171,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
CQuorum(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker);
|
CQuorum(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker);
|
||||||
~CQuorum();
|
~CQuorum();
|
||||||
void Init(const CFinalCommitmentPtr& _qc, const CBlockIndex* _pQuorumBaseBlockIndex, const uint256& _minedBlockHash, const std::vector<CDeterministicMNCPtr>& _members);
|
void Init(CFinalCommitmentPtr _qc, const CBlockIndex* _pQuorumBaseBlockIndex, const uint256& _minedBlockHash, const std::vector<CDeterministicMNCPtr>& _members);
|
||||||
|
|
||||||
bool SetVerificationVector(const BLSVerificationVector& quorumVecIn);
|
bool SetVerificationVector(const BLSVerificationVector& quorumVecIn);
|
||||||
bool SetSecretKeyShare(const CBLSSecretKey& secretKeyShare);
|
bool SetSecretKeyShare(const CBLSSecretKey& secretKeyShare);
|
||||||
|
Loading…
Reference in New Issue
Block a user