27 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-ipaddr");
30 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-ipaddr");
36 if (addr.
GetPort() != mainnetDefaultPort) {
37 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-ipaddr-port");
39 }
else if (addr.
GetPort() == mainnetDefaultPort) {
40 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-ipaddr-port");
45 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-ipaddr");
51 template <
typename Payload>
56 return state.
DoS(100,
false, REJECT_INVALID,
"bad-protx-sig",
false, strError);
61 template <
typename Payload>
65 return state.
DoS(100,
false, REJECT_INVALID,
"bad-protx-sig",
false);
70 template <
typename Payload>
75 return state.
DoS(100,
false, REJECT_INVALID,
"bad-protx-sig",
false, strError);
80 template <
typename Payload>
84 return state.
DoS(100,
false, REJECT_INVALID,
"bad-protx-inputs-hash");
93 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-collateral-dest");
99 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-collateral-reuse");
102 if (out.
nValue !=
Params().GetConsensus().nMNCollateralAmt) {
103 return state.
DoS(100,
false, REJECT_INVALID,
"bad-protx-collateral-amount");
128 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-collateral-index");
137 return state.
DoS(100,
false, REJECT_INVALID,
"bad-protx-sig");
139 }
else if (pindexPrev !=
nullptr) {
140 assert(view !=
nullptr);
148 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-collateral");
151 if (!CheckCollateralOut(coin.
out, pl, state, collateralTxDest)) {
157 const CKeyID* keyForPayloadSig = boost::get<CKeyID>(&collateralTxDest);
158 if (!keyForPayloadSig) {
159 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-collateral-pkh");
162 if (!CheckStringSig(pl, *keyForPayloadSig, state)) {
168 if (!CheckInputsHash(tx, pl, state)) {
176 return state.
DoS(10,
false, REJECT_DUPLICATE,
"bad-protx-dup-IP-address");
179 if (mnList.HasUniqueProperty(pl.
keyIDOwner)) {
180 return state.
DoS(10,
false, REJECT_DUPLICATE,
"bad-protx-dup-owner-key");
183 return state.
DoS(10,
false, REJECT_DUPLICATE,
"bad-protx-dup-operator-key");
200 if (!CheckService(pl.
addr, state)) {
205 if (!CheckInputsHash(tx, pl, state)) {
214 return state.
DoS(100,
false, REJECT_INVALID,
"bad-protx-hash");
218 if (mnList.HasUniqueProperty(pl.
addr) && mnList.GetUniquePropertyMN(pl.
addr)->proTxHash != pl.
proTxHash) {
219 return state.
DoS(10,
false, REJECT_DUPLICATE,
"bad-protx-dup-addr");
223 if (mn->nOperatorReward == 0) {
225 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-operator-payee");
229 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-operator-payee");
234 if (!CheckHashSig(pl, mn->pdmnState->pubKeyOperator.Get(), state)) {
256 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-payee-dest");
261 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-payee-reuse");
264 if (!CheckInputsHash(tx, pl, state)) {
269 assert(view !=
nullptr);
274 return state.
DoS(10,
false, REJECT_INVALID,
"spork-21-inactive");
280 return state.
DoS(100,
false, REJECT_INVALID,
"bad-protx-hash");
285 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-payee-reuse");
289 if (!view->
GetUTXOCoin(dmn->collateralOutpoint, coin)) {
291 return state.
DoS(100,
false, REJECT_INVALID,
"bad-protx-collateral");
297 return state.
DoS(100,
false, REJECT_INVALID,
"bad-protx-collateral-dest");
299 if (collateralTxDest ==
CTxDestination(dmn->pdmnState->keyIDOwner) ||
301 return state.
DoS(10,
false, REJECT_INVALID,
"bad-protx-collateral-reuse");
306 if (pl.
proTxHash != otherDmn->proTxHash) {
307 return state.
DoS(10,
false, REJECT_DUPLICATE,
"bad-protx-dup-key");
311 if (!CheckHashSig(pl, dmn->pdmnState->keyIDOwner, state)) {
331 if (!CheckInputsHash(tx, pl, state)) {
340 return state.
DoS(100,
false, REJECT_INVALID,
"bad-protx-hash");
342 if (!CheckHashSig(pl, dmn->pdmnState->pubKeyOperator.Get(), state)) {
360 return state.
DoS(50,
false, REJECT_INVALID,
"bad-qc-not-null-spork22");
366 return state.
DoS(100,
false, REJECT_INVALID,
"bad-qc-quorum-version");
371 if (params == nullopt) {
372 return state.
DoS(100,
false, REJECT_INVALID,
"bad-qc-quorum-type");
377 return state.
DoS(100,
false, REJECT_INVALID,
"bad-qc-quorum-sizes");
384 return state.
DoS(100,
false, REJECT_INVALID,
"bad-qc-quorum-hash-not-found");
388 if (pindexQuorum->
nHeight % params->dkgInterval != 0) {
390 return state.
DoS(100,
false, REJECT_INVALID,
"bad-qc-quorum-height");
394 if (pindexPrev->
nHeight - pindexQuorum->
nHeight > params->cacheDkgInterval) {
395 return state.
DoS(100,
false, REJECT_INVALID,
"bad-qc-quorum-height-old");
400 return state.
DoS(100,
false, REJECT_INVALID,
"bad-qc-quorum-hash-not-active-chain");
405 std::vector<CBLSPublicKey> allkeys;
407 allkeys.emplace_back(m->pdmnState->pubKeyOperator.Get());
409 if (!qfc.
Verify(allkeys, *params)) {
410 return state.
DoS(100,
false, REJECT_INVALID,
"bad-qc-invalid");
424 return state.
DoS(100,
false, REJECT_INVALID,
"bad-qc-payload");
428 return state.
DoS(100,
false, REJECT_INVALID,
"bad-qc-version");
431 if (pindexPrev && pl.
nHeight != (uint32_t)pindexPrev->
nHeight + 1) {
432 return state.
DoS(100,
false, REJECT_INVALID,
"bad-qc-height");
445 if (hasExtraPayload) {
446 return state.
DoS(100,
error(
"%s: Type 0 doesn't support extra payload", __func__),
447 REJECT_INVALID,
"bad-txns-type-payload");
455 return state.
DoS(100,
error(
"%s: Type %d not supported with version %d", __func__, tx.
nType, tx.
nVersion),
456 REJECT_INVALID,
"bad-txns-type-version");
461 return state.
DoS(10,
error(
"%s: Special tx is coinbase or coinstake", __func__),
462 REJECT_INVALID,
"bad-txns-special-coinbase");
466 if (!hasExtraPayload) {
467 return state.
DoS(100,
error(
"%s: Special tx (type=%d) without extra payload", __func__, tx.
nType),
468 REJECT_INVALID,
"bad-txns-payload-empty");
472 if (tx.
extraPayload->size() > MAX_SPECIALTX_EXTRAPAYLOAD) {
473 return state.
DoS(100,
error(
"%s: Special tx payload oversize (%d)", __func__, tx.
extraPayload->size()),
474 REJECT_INVALID,
"bad-txns-payload-oversize");
488 if (!CheckSpecialTxBasic(tx, state)) {
495 return state.
DoS(100,
error(
"%s: Special tx when v6 upgrade not enforced yet", __func__),
496 REJECT_INVALID,
"bad-txns-v6-not-active");
501 case CTransaction::TxType::NORMAL: {
505 case CTransaction::TxType::PROREG: {
507 return CheckProRegTx(tx, pindexPrev, view, state);
509 case CTransaction::TxType::PROUPSERV: {
511 return CheckProUpServTx(tx, pindexPrev, state);
513 case CTransaction::TxType::PROUPREG: {
515 return CheckProUpRegTx(tx, pindexPrev, view, state);
517 case CTransaction::TxType::PROUPREV: {
519 return CheckProUpRevTx(tx, pindexPrev, state);
521 case CTransaction::TxType::LLMQCOMM: {
523 return CheckLLMQCommitmentTx(tx, pindexPrev, state);
528 REJECT_INVALID,
"bad-tx-type");
589 template <
typename T>
592 if (tx.
nType != T::SPECIALTX_TYPE) {
593 return state.
DoS(100,
false, REJECT_INVALID,
"bad-protx-type");
596 return state.
DoS(100,
false, REJECT_INVALID,
"bad-protx-payload");
598 return obj.IsTriviallyValid(state);
const CChainParams & Params()
Return the currently selected parameters.
std::unique_ptr< CChainParams > CreateChainParams(const std::string &chain)
Creates and returns a std::unique_ptr<CChainParams> of the chosen chain.
static const std::string MAIN
Chain name strings.
std::vector< CTransactionRef > vtx
The block chain is a tree shaped structure starting with the genesis block at the root,...
CBlockIndex * pprev
pointer to the index of the predecessor of this block
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
int nHeight
height of the entry in the chain. The genesis block has height 0
const Consensus::Params & GetConsensus() const
CCoinsView that adds a memory cache for transactions to another CCoinsView.
bool GetUTXOCoin(const COutPoint &outpoint, Coin &coin) const
Get the coin and check if it's spent.
static bool VerifyHash(const uint256 &hash, const CPubKey &pubkey, const std::vector< unsigned char > &vchSig, std::string &strErrorRet)
Verify the hash signature, returns true if successful.
A writer stream (for serialization) that computes a 256-bit hash.
A reference to a CKey: the Hash160 of its serialized public key.
static bool VerifyMessage(const CPubKey &pubkey, const std::vector< unsigned char > &vchSig, const std::string &strMessage, std::string &strErrorRet)
Verify the message signature, returns true if successful.
bool IsPayToPublicKeyHash() const
A combination of a network address (CNetAddr) and a (TCP) port.
bool IsSporkActive(SporkId nSporkID)
The basic transaction that is broadcasted on the network and contained in blocks.
bool IsNormalType() const
bool hasExtraPayload() const
const uint256 & GetHash() const
Optional< std::vector< uint8_t > > extraPayload
Optional< SaplingTxData > sapData
bool isSaplingVersion() const
std::vector< CTxOut > vout
bool hasSaplingData() const
An input of a transaction.
An output of a transaction.
Capture information about block/transaction validation.
bool DoS(int level, bool ret=false, unsigned int chRejectCodeIn=0, std::string strRejectReasonIn="", bool corruptionIn=false, const std::string &strDebugMessageIn="")
CTxOut out
unspent transaction output
COutPoint collateralOutpoint
CBLSPublicKey pubKeyOperator
std::vector< unsigned char > vchSig
CBLSPublicKey pubKeyOperator
CScript scriptOperatorPayout
A shielded input to a transaction.
uint256 nullifier
The nullifier of the input note.
std::string ToString() const
static const uint16_t CURRENT_VERSION
bool Verify(const std::vector< CBLSPublicKey > &allkeys, const Consensus::LLMQParams ¶ms) const
bool VerifySizes(const Consensus::LLMQParams ¶ms) const
static const uint16_t CURRENT_VERSION
CFinalCommitment commitment
std::unique_ptr< CDeterministicMNManager > deterministicMNManager
uint256 SerializeHash(const T &obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
Compute the 256-bit hash of an object's serialization.
#define T(expected, seed, data)
std::unique_ptr< CQuorumBlockProcessor > quorumBlockProcessor
RecursiveMutex cs_main
Global state.
boost::optional< T > Optional
Substitute for C++17 std::optional.
bool VerifyLLMQCommitment(const llmq::CFinalCommitment &qfc, const CBlockIndex *pindexPrev, CValidationState &state)
bool UndoSpecialTxsInBlock(const CBlock &block, const CBlockIndex *pindex)
bool CheckSpecialTx(const CTransaction &tx, const CBlockIndex *pindexPrev, const CCoinsViewCache *view, CValidationState &state)
Payload validity checks (including duplicate unique properties against list at pindexPrev)
uint256 CalcTxInputsHash(const CTransaction &tx)
bool GetValidatedTxPayload(const CTransaction &tx, T &obj, CValidationState &state)
bool CheckSpecialTxNoContext(const CTransaction &tx, CValidationState &state)
bool ProcessSpecialTxsInBlock(const CBlock &block, const CBlockIndex *pindex, const CCoinsViewCache *view, CValidationState &state, bool fJustCheck)
CSporkManager sporkManager
@ SPORK_22_LLMQ_DKG_MAINTENANCE
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet, bool fColdStake)
Parse a standard scriptPubKey for the destination address.
boost::variant< CNoDestination, CKeyID, CScriptID, CExchangeKeyID > CTxDestination
A txout script template with a specific destination.
Optional< LLMQParams > GetLLMQParams(uint8_t llmqtype) const
#define AssertLockHeld(cs)
bool error(const char *fmt, const Args &... args)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
bool GetTxPayload(const std::vector< unsigned char > &payload, T &obj)
std::shared_ptr< const CTransaction > CTransactionRef
bool NetworkUpgradeActive(int nHeight, const Consensus::Params ¶ms, Consensus::UpgradeIndex idx)
Returns true if the given network upgrade is active as of the given block height.
bool IsInitialBlockDownload()
Check whether we are doing an initial block download (synchronizing from disk or network)
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)