mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
add ehf special tx (#4577)
This commit is contained in:
parent
06ebacbb9a
commit
459bc3ee7e
@ -169,6 +169,7 @@ BITCOIN_CORE_H = \
|
|||||||
evo/deterministicmns.h \
|
evo/deterministicmns.h \
|
||||||
evo/evodb.h \
|
evo/evodb.h \
|
||||||
evo/mnauth.h \
|
evo/mnauth.h \
|
||||||
|
evo/mnhftx.h \
|
||||||
evo/providertx.h \
|
evo/providertx.h \
|
||||||
evo/simplifiedmns.h \
|
evo/simplifiedmns.h \
|
||||||
evo/specialtx.h \
|
evo/specialtx.h \
|
||||||
@ -356,6 +357,7 @@ libdash_server_a_SOURCES = \
|
|||||||
evo/deterministicmns.cpp \
|
evo/deterministicmns.cpp \
|
||||||
evo/evodb.cpp \
|
evo/evodb.cpp \
|
||||||
evo/mnauth.cpp \
|
evo/mnauth.cpp \
|
||||||
|
evo/mnhftx.cpp \
|
||||||
evo/providertx.cpp \
|
evo/providertx.cpp \
|
||||||
evo/simplifiedmns.cpp \
|
evo/simplifiedmns.cpp \
|
||||||
evo/specialtx.cpp \
|
evo/specialtx.cpp \
|
||||||
|
@ -181,6 +181,7 @@ BITCOIN_TESTS =\
|
|||||||
test/sighash_tests.cpp \
|
test/sighash_tests.cpp \
|
||||||
test/sigopcount_tests.cpp \
|
test/sigopcount_tests.cpp \
|
||||||
test/skiplist_tests.cpp \
|
test/skiplist_tests.cpp \
|
||||||
|
test/specialtx_tests.cpp \
|
||||||
test/streams_tests.cpp \
|
test/streams_tests.cpp \
|
||||||
test/subsidy_tests.cpp \
|
test/subsidy_tests.cpp \
|
||||||
test/sync_tests.cpp \
|
test/sync_tests.cpp \
|
||||||
|
@ -212,6 +212,7 @@ bool CBloomFilter::CheckSpecialTransactionMatchesAndUpdate(const CTransaction &t
|
|||||||
}
|
}
|
||||||
case(TRANSACTION_COINBASE):
|
case(TRANSACTION_COINBASE):
|
||||||
case(TRANSACTION_QUORUM_COMMITMENT):
|
case(TRANSACTION_QUORUM_COMMITMENT):
|
||||||
|
case(TRANSACTION_MNHF_SIGNAL):
|
||||||
// No additional checks for this transaction types
|
// No additional checks for this transaction types
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -281,6 +281,7 @@ public:
|
|||||||
consensus.llmqTypeChainLocks = Consensus::LLMQType::LLMQ_400_60;
|
consensus.llmqTypeChainLocks = Consensus::LLMQType::LLMQ_400_60;
|
||||||
consensus.llmqTypeInstantSend = Consensus::LLMQType::LLMQ_50_60;
|
consensus.llmqTypeInstantSend = Consensus::LLMQType::LLMQ_50_60;
|
||||||
consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_100_67;
|
consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_100_67;
|
||||||
|
consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_400_85;
|
||||||
|
|
||||||
fDefaultConsistencyChecks = false;
|
fDefaultConsistencyChecks = false;
|
||||||
fRequireStandard = true;
|
fRequireStandard = true;
|
||||||
@ -492,6 +493,7 @@ public:
|
|||||||
consensus.llmqTypeChainLocks = Consensus::LLMQType::LLMQ_50_60;
|
consensus.llmqTypeChainLocks = Consensus::LLMQType::LLMQ_50_60;
|
||||||
consensus.llmqTypeInstantSend = Consensus::LLMQType::LLMQ_50_60;
|
consensus.llmqTypeInstantSend = Consensus::LLMQType::LLMQ_50_60;
|
||||||
consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_100_67;
|
consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_100_67;
|
||||||
|
consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_50_60;
|
||||||
|
|
||||||
fDefaultConsistencyChecks = false;
|
fDefaultConsistencyChecks = false;
|
||||||
fRequireStandard = false;
|
fRequireStandard = false;
|
||||||
@ -685,6 +687,7 @@ public:
|
|||||||
consensus.llmqTypeChainLocks = Consensus::LLMQType::LLMQ_50_60;
|
consensus.llmqTypeChainLocks = Consensus::LLMQType::LLMQ_50_60;
|
||||||
consensus.llmqTypeInstantSend = Consensus::LLMQType::LLMQ_50_60;
|
consensus.llmqTypeInstantSend = Consensus::LLMQType::LLMQ_50_60;
|
||||||
consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_100_67;
|
consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_100_67;
|
||||||
|
consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_50_60;
|
||||||
|
|
||||||
UpdateDevnetLLMQChainLocksFromArgs(args);
|
UpdateDevnetLLMQChainLocksFromArgs(args);
|
||||||
UpdateDevnetLLMQInstantSendFromArgs(args);
|
UpdateDevnetLLMQInstantSendFromArgs(args);
|
||||||
@ -922,6 +925,7 @@ public:
|
|||||||
consensus.llmqTypeChainLocks = Consensus::LLMQType::LLMQ_TEST;
|
consensus.llmqTypeChainLocks = Consensus::LLMQType::LLMQ_TEST;
|
||||||
consensus.llmqTypeInstantSend = Consensus::LLMQType::LLMQ_TEST;
|
consensus.llmqTypeInstantSend = Consensus::LLMQType::LLMQ_TEST;
|
||||||
consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_TEST;
|
consensus.llmqTypePlatform = Consensus::LLMQType::LLMQ_TEST;
|
||||||
|
consensus.llmqTypeMnhf = Consensus::LLMQType::LLMQ_TEST;
|
||||||
|
|
||||||
UpdateLLMQTestParametersFromArgs(args);
|
UpdateLLMQTestParametersFromArgs(args);
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,7 @@ struct Params {
|
|||||||
LLMQType llmqTypeChainLocks;
|
LLMQType llmqTypeChainLocks;
|
||||||
LLMQType llmqTypeInstantSend{LLMQType::LLMQ_NONE};
|
LLMQType llmqTypeInstantSend{LLMQType::LLMQ_NONE};
|
||||||
LLMQType llmqTypePlatform{LLMQType::LLMQ_NONE};
|
LLMQType llmqTypePlatform{LLMQType::LLMQ_NONE};
|
||||||
|
LLMQType llmqTypeMnhf{LLMQType::LLMQ_NONE};
|
||||||
};
|
};
|
||||||
} // namespace Consensus
|
} // namespace Consensus
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <spentindex.h>
|
#include <spentindex.h>
|
||||||
|
|
||||||
#include <evo/cbtx.h>
|
#include <evo/cbtx.h>
|
||||||
|
#include <evo/mnhftx.h>
|
||||||
#include <evo/providertx.h>
|
#include <evo/providertx.h>
|
||||||
#include <evo/specialtx.h>
|
#include <evo/specialtx.h>
|
||||||
#include <llmq/commitment.h>
|
#include <llmq/commitment.h>
|
||||||
@ -305,6 +306,13 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
|
|||||||
qcTx.ToJson(obj);
|
qcTx.ToJson(obj);
|
||||||
entry.pushKV("qcTx", obj);
|
entry.pushKV("qcTx", obj);
|
||||||
}
|
}
|
||||||
|
} else if (tx.nType == TRANSACTION_MNHF_SIGNAL) {
|
||||||
|
MNHFTxPayload mnhfTx;
|
||||||
|
if (GetTxPayload(tx, mnhfTx)) {
|
||||||
|
UniValue obj;
|
||||||
|
mnhfTx.ToJson(obj);
|
||||||
|
entry.pushKV("mnhfTx", obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hashBlock.IsNull())
|
if (!hashBlock.IsNull())
|
||||||
|
70
src/evo/mnhftx.cpp
Normal file
70
src/evo/mnhftx.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// Copyright (c) 2021-2022 The Dash Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <consensus/validation.h>
|
||||||
|
#include <evo/mnhftx.h>
|
||||||
|
#include <evo/specialtx.h>
|
||||||
|
#include <llmq/commitment.h>
|
||||||
|
#include <llmq/signing.h>
|
||||||
|
|
||||||
|
#include <chain.h>
|
||||||
|
#include <chainparams.h>
|
||||||
|
#include <validation.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
extern const std::string CBLSIG_REQUESTID_PREFIX = "clsig";
|
||||||
|
|
||||||
|
bool MNHFTx::Verify(const CBlockIndex* pQuorumIndex) const
|
||||||
|
{
|
||||||
|
if (nVersion == 0 || nVersion > CURRENT_VERSION) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Consensus::LLMQType llmqType = Params().GetConsensus().llmqTypeMnhf;
|
||||||
|
int signOffset{llmq::GetLLMQParams(llmqType).dkgInterval};
|
||||||
|
|
||||||
|
const uint256 requestId = ::SerializeHash(std::make_pair(CBLSIG_REQUESTID_PREFIX, pQuorumIndex->nHeight));
|
||||||
|
return llmq::CSigningManager::VerifyRecoveredSig(llmqType, pQuorumIndex->nHeight, requestId, pQuorumIndex->GetBlockHash(), sig, 0) ||
|
||||||
|
llmq::CSigningManager::VerifyRecoveredSig(llmqType, pQuorumIndex->nHeight, requestId, pQuorumIndex->GetBlockHash(), sig, signOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckMNHFTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||||
|
{
|
||||||
|
MNHFTxPayload mnhfTx;
|
||||||
|
if (!GetTxPayload(tx, mnhfTx)) {
|
||||||
|
return state.DoS(100, false, REJECT_INVALID, "bad-mnhf-payload");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mnhfTx.nVersion == 0 || mnhfTx.nVersion > MNHFTxPayload::CURRENT_VERSION) {
|
||||||
|
return state.DoS(100, false, REJECT_INVALID, "bad-mnhf-version");
|
||||||
|
}
|
||||||
|
|
||||||
|
const CBlockIndex* pindexQuorum = LookupBlockIndex(mnhfTx.signal.quorumHash);
|
||||||
|
if (!pindexQuorum) {
|
||||||
|
return state.DoS(100, false, REJECT_INVALID, "bad-mnhf-quorum-hash");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pindexQuorum != pindexPrev->GetAncestor(pindexQuorum->nHeight)) {
|
||||||
|
// not part of active chain
|
||||||
|
return state.DoS(100, false, REJECT_INVALID, "bad-mnhf-quorum-hash");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Params().GetConsensus().llmqs.count(Params().GetConsensus().llmqTypeMnhf)) {
|
||||||
|
return state.DoS(100, false, REJECT_INVALID, "bad-mnhf-type");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mnhfTx.signal.Verify(pindexQuorum)) {
|
||||||
|
return state.DoS(100, false, REJECT_INVALID, "bad-mnhf-invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MNHFTx::ToString() const
|
||||||
|
{
|
||||||
|
return strprintf("MNHFTx(nVersion=%d, quorumHash=%s, sig=%s)",
|
||||||
|
nVersion, quorumHash.ToString(), sig.ToString());
|
||||||
|
}
|
||||||
|
|
74
src/evo/mnhftx.h
Normal file
74
src/evo/mnhftx.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// Copyright (c) 2021-2022 The Dash Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef BITCOIN_EVO_MNHFTX_H
|
||||||
|
#define BITCOIN_EVO_MNHFTX_H
|
||||||
|
|
||||||
|
#include <bls/bls.h>
|
||||||
|
#include <primitives/transaction.h>
|
||||||
|
#include <sync.h>
|
||||||
|
#include <threadsafety.h>
|
||||||
|
#include <univalue.h>
|
||||||
|
|
||||||
|
class CBlockIndex;
|
||||||
|
class CValidationState;
|
||||||
|
extern CCriticalSection cs_main;
|
||||||
|
|
||||||
|
// mnhf signal special transaction
|
||||||
|
class MNHFTx
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr uint16_t CURRENT_VERSION = 1;
|
||||||
|
|
||||||
|
uint16_t nVersion{CURRENT_VERSION};
|
||||||
|
uint256 quorumHash;
|
||||||
|
CBLSSignature sig;
|
||||||
|
|
||||||
|
MNHFTx() = default;
|
||||||
|
bool Verify(const CBlockIndex* pQuorumIndex) const;
|
||||||
|
|
||||||
|
SERIALIZE_METHODS(MNHFTx, obj)
|
||||||
|
{
|
||||||
|
READWRITE(obj.nVersion, obj.quorumHash, obj.sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToString() const;
|
||||||
|
|
||||||
|
void ToJson(UniValue& obj) const
|
||||||
|
{
|
||||||
|
obj.clear();
|
||||||
|
obj.setObject();
|
||||||
|
obj.pushKV("version", (int)nVersion);
|
||||||
|
obj.pushKV("quorumHash", quorumHash.ToString());
|
||||||
|
obj.pushKV("sig", sig.ToString());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MNHFTxPayload
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr uint16_t CURRENT_VERSION = 1;
|
||||||
|
|
||||||
|
uint16_t nVersion{CURRENT_VERSION};
|
||||||
|
MNHFTx signal;
|
||||||
|
|
||||||
|
SERIALIZE_METHODS(MNHFTxPayload, obj)
|
||||||
|
{
|
||||||
|
READWRITE(obj.nVersion, obj.signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToJson(UniValue& obj) const
|
||||||
|
{
|
||||||
|
obj.setObject();
|
||||||
|
obj.pushKV("version", (int)nVersion);
|
||||||
|
|
||||||
|
UniValue mnhfObj;
|
||||||
|
signal.ToJson(mnhfObj);
|
||||||
|
obj.pushKV("signal", mnhfObj);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool CheckMNHFTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
|
|
||||||
|
#endif // BITCOIN_EVO_MNHFTX_H
|
@ -6,16 +6,19 @@
|
|||||||
|
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
#include <consensus/validation.h>
|
#include <consensus/validation.h>
|
||||||
#include <hash.h>
|
|
||||||
#include <primitives/block.h>
|
|
||||||
#include <validation.h>
|
|
||||||
#include <evo/cbtx.h>
|
#include <evo/cbtx.h>
|
||||||
#include <evo/deterministicmns.h>
|
#include <evo/deterministicmns.h>
|
||||||
#include <llmq/commitment.h>
|
#include <evo/mnhftx.h>
|
||||||
|
#include <hash.h>
|
||||||
#include <llmq/blockprocessor.h>
|
#include <llmq/blockprocessor.h>
|
||||||
|
#include <llmq/commitment.h>
|
||||||
|
#include <primitives/block.h>
|
||||||
|
#include <validation.h>
|
||||||
|
|
||||||
bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state, const CCoinsViewCache& view)
|
bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state, const CCoinsViewCache& view)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_main);
|
||||||
|
|
||||||
if (tx.nVersion != 3 || tx.nType == TRANSACTION_NORMAL)
|
if (tx.nVersion != 3 || tx.nType == TRANSACTION_NORMAL)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -37,6 +40,8 @@ bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CVali
|
|||||||
return CheckCbTx(tx, pindexPrev, state);
|
return CheckCbTx(tx, pindexPrev, state);
|
||||||
case TRANSACTION_QUORUM_COMMITMENT:
|
case TRANSACTION_QUORUM_COMMITMENT:
|
||||||
return llmq::CheckLLMQCommitment(tx, pindexPrev, state);
|
return llmq::CheckLLMQCommitment(tx, pindexPrev, state);
|
||||||
|
case TRANSACTION_MNHF_SIGNAL:
|
||||||
|
return VersionBitsTipState(Params().GetConsensus(), Consensus::DEPLOYMENT_GOV_FEE) == ThresholdState::ACTIVE && CheckMNHFTx(tx, pindexPrev, state);
|
||||||
}
|
}
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
LogPrintf("%s -- failed: %s\n", __func__, e.what());
|
LogPrintf("%s -- failed: %s\n", __func__, e.what());
|
||||||
@ -62,6 +67,8 @@ bool ProcessSpecialTx(const CTransaction& tx, const CBlockIndex* pindex, CValida
|
|||||||
return true; // nothing to do
|
return true; // nothing to do
|
||||||
case TRANSACTION_QUORUM_COMMITMENT:
|
case TRANSACTION_QUORUM_COMMITMENT:
|
||||||
return true; // handled per block
|
return true; // handled per block
|
||||||
|
case TRANSACTION_MNHF_SIGNAL:
|
||||||
|
return true; // handled per block
|
||||||
}
|
}
|
||||||
|
|
||||||
return state.DoS(100, false, REJECT_INVALID, "bad-tx-type-proc");
|
return state.DoS(100, false, REJECT_INVALID, "bad-tx-type-proc");
|
||||||
@ -83,6 +90,8 @@ bool UndoSpecialTx(const CTransaction& tx, const CBlockIndex* pindex)
|
|||||||
return true; // nothing to do
|
return true; // nothing to do
|
||||||
case TRANSACTION_QUORUM_COMMITMENT:
|
case TRANSACTION_QUORUM_COMMITMENT:
|
||||||
return true; // handled per block
|
return true; // handled per block
|
||||||
|
case TRANSACTION_MNHF_SIGNAL:
|
||||||
|
return true; // handled per block
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -18,7 +18,7 @@ class CValidationState;
|
|||||||
|
|
||||||
extern CCriticalSection cs_main;
|
extern CCriticalSection cs_main;
|
||||||
|
|
||||||
bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state, const CCoinsViewCache& view);
|
bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state, const CCoinsViewCache& view) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CValidationState& state, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, CValidationState& state, const CCoinsViewCache& view, bool fJustCheck, bool fCheckCbTxMerleRoots) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ enum {
|
|||||||
TRANSACTION_PROVIDER_UPDATE_REVOKE = 4,
|
TRANSACTION_PROVIDER_UPDATE_REVOKE = 4,
|
||||||
TRANSACTION_COINBASE = 5,
|
TRANSACTION_COINBASE = 5,
|
||||||
TRANSACTION_QUORUM_COMMITMENT = 6,
|
TRANSACTION_QUORUM_COMMITMENT = 6,
|
||||||
|
TRANSACTION_MNHF_SIGNAL = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An outpoint - a combination of a transaction hash and an index n into its vout */
|
/** An outpoint - a combination of a transaction hash and an index n into its vout */
|
||||||
|
84
src/test/specialtx_tests.cpp
Normal file
84
src/test/specialtx_tests.cpp
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// Copyright (c) 2021 The Dash Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <bls/bls.h>
|
||||||
|
#include <consensus/validation.h>
|
||||||
|
#include <evo/mnhftx.h>
|
||||||
|
#include <evo/specialtx.h>
|
||||||
|
#include <primitives/transaction.h>
|
||||||
|
#include <uint256.h>
|
||||||
|
#include <util/strencodings.h>
|
||||||
|
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#include <test/setup_common.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
bool VerifyMNHFTx(const CTransaction& tx, CValidationState& state)
|
||||||
|
{
|
||||||
|
MNHFTxPayload mnhfTx;
|
||||||
|
if (!GetTxPayload(tx, mnhfTx)) {
|
||||||
|
return state.DoS(100, false, REJECT_INVALID, "bad-mnhf-payload");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mnhfTx.nVersion == 0 || mnhfTx.nVersion > MNHFTxPayload::CURRENT_VERSION) {
|
||||||
|
return state.DoS(100, false, REJECT_INVALID, "bad-mnhf-version");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CMutableTransaction CreateMNHFTx(const uint256& mnhfTxHash, const CBLSSignature& cblSig, const uint16_t& versionBit)
|
||||||
|
{
|
||||||
|
MNHFTxPayload extraPayload;
|
||||||
|
extraPayload.nVersion = 1;
|
||||||
|
extraPayload.signal.nVersion = versionBit;
|
||||||
|
extraPayload.signal.quorumHash = mnhfTxHash;
|
||||||
|
extraPayload.signal.sig = cblSig;
|
||||||
|
|
||||||
|
CMutableTransaction tx;
|
||||||
|
tx.nVersion = 3;
|
||||||
|
tx.nType = TRANSACTION_MNHF_SIGNAL;
|
||||||
|
SetTxPayload(tx, extraPayload);
|
||||||
|
|
||||||
|
return tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FIXTURE_TEST_SUITE(specialtx_tests, BasicTestingSetup)
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(verify_mnhf_specialtx_tests)
|
||||||
|
{
|
||||||
|
int count = 10;
|
||||||
|
uint16_t ver = 2;
|
||||||
|
|
||||||
|
std::vector<CBLSSignature> vec_sigs;
|
||||||
|
std::vector<CBLSPublicKey> vec_pks;
|
||||||
|
std::vector<CBLSSecretKey> vec_sks;
|
||||||
|
|
||||||
|
CBLSSecretKey sk;
|
||||||
|
uint256 hash = GetRandHash();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
sk.MakeNewKey();
|
||||||
|
vec_pks.push_back(sk.GetPublicKey());
|
||||||
|
vec_sks.push_back(sk);
|
||||||
|
}
|
||||||
|
|
||||||
|
CBLSSecretKey ag_sk = CBLSSecretKey::AggregateInsecure(vec_sks);
|
||||||
|
CBLSPublicKey ag_pk = CBLSPublicKey::AggregateInsecure(vec_pks);
|
||||||
|
|
||||||
|
BOOST_CHECK(ag_sk.IsValid());
|
||||||
|
BOOST_CHECK(ag_pk.IsValid());
|
||||||
|
|
||||||
|
uint256 verHash = uint256S(itostr(ver));
|
||||||
|
auto sig = ag_sk.Sign(verHash);
|
||||||
|
BOOST_CHECK(sig.VerifyInsecure(ag_pk, verHash));
|
||||||
|
|
||||||
|
const CMutableTransaction tx = CreateMNHFTx(hash, sig, ver);
|
||||||
|
CValidationState state;
|
||||||
|
BOOST_CHECK(VerifyMNHFTx(CTransaction(tx), state));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
@ -378,7 +378,8 @@ bool ContextualCheckTransaction(const CTransaction& tx, CValidationState &state,
|
|||||||
tx.nType != TRANSACTION_PROVIDER_UPDATE_REGISTRAR &&
|
tx.nType != TRANSACTION_PROVIDER_UPDATE_REGISTRAR &&
|
||||||
tx.nType != TRANSACTION_PROVIDER_UPDATE_REVOKE &&
|
tx.nType != TRANSACTION_PROVIDER_UPDATE_REVOKE &&
|
||||||
tx.nType != TRANSACTION_COINBASE &&
|
tx.nType != TRANSACTION_COINBASE &&
|
||||||
tx.nType != TRANSACTION_QUORUM_COMMITMENT) {
|
tx.nType != TRANSACTION_QUORUM_COMMITMENT &&
|
||||||
|
tx.nType != TRANSACTION_MNHF_SIGNAL) {
|
||||||
return state.DoS(100, false, REJECT_INVALID, "bad-txns-type");
|
return state.DoS(100, false, REJECT_INVALID, "bad-txns-type");
|
||||||
}
|
}
|
||||||
if (tx.IsCoinBase() && tx.nType != TRANSACTION_COINBASE)
|
if (tx.IsCoinBase() && tx.nType != TRANSACTION_COINBASE)
|
||||||
|
@ -105,6 +105,7 @@ EXPECTED_CIRCULAR_DEPENDENCIES=(
|
|||||||
"coinjoin/coinjoin -> llmq/chainlocks -> net -> coinjoin/coinjoin"
|
"coinjoin/coinjoin -> llmq/chainlocks -> net -> coinjoin/coinjoin"
|
||||||
"evo/deterministicmns -> llmq/utils -> net -> evo/deterministicmns"
|
"evo/deterministicmns -> llmq/utils -> net -> evo/deterministicmns"
|
||||||
"evo/deterministicmns -> llmq/utils -> net -> masternode/sync -> evo/deterministicmns"
|
"evo/deterministicmns -> llmq/utils -> net -> masternode/sync -> evo/deterministicmns"
|
||||||
|
"evo/mnhftx -> evo/specialtx -> evo/mnhftx"
|
||||||
)
|
)
|
||||||
|
|
||||||
EXIT_CODE=0
|
EXIT_CODE=0
|
||||||
|
Loading…
Reference in New Issue
Block a user