PIVX Core  5.6.99
P2P Digital Currency
specialtx_validation.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017 The Dash Core developers
2 // Copyright (c) 2020-2022 The PIVX Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
7 
8 #include "chain.h"
9 #include "coins.h"
10 #include "chainparams.h"
11 #include "clientversion.h"
12 #include "consensus/validation.h"
13 #include "evo/deterministicmns.h"
14 #include "evo/providertx.h"
16 #include "messagesigner.h"
17 #include "primitives/transaction.h"
18 #include "primitives/block.h"
19 #include "script/standard.h"
20 #include "spork.h"
21 
22 /* -- Helper static functions -- */
23 
24 static bool CheckService(const CService& addr, CValidationState& state)
25 {
26  if (!addr.IsValid()) {
27  return state.DoS(10, false, REJECT_INVALID, "bad-protx-ipaddr");
28  }
29  if (!Params().IsRegTestNet() && !addr.IsRoutable()) {
30  return state.DoS(10, false, REJECT_INVALID, "bad-protx-ipaddr");
31  }
32 
33  // IP port must be the default one on main-net, which cannot be used on other nets.
34  static int mainnetDefaultPort = CreateChainParams(CBaseChainParams::MAIN)->GetDefaultPort();
35  if (Params().NetworkIDString() == CBaseChainParams::MAIN) {
36  if (addr.GetPort() != mainnetDefaultPort) {
37  return state.DoS(10, false, REJECT_INVALID, "bad-protx-ipaddr-port");
38  }
39  } else if (addr.GetPort() == mainnetDefaultPort) {
40  return state.DoS(10, false, REJECT_INVALID, "bad-protx-ipaddr-port");
41  }
42 
43  // !TODO: add support for IPv6 and Tor
44  if (!addr.IsIPv4()) {
45  return state.DoS(10, false, REJECT_INVALID, "bad-protx-ipaddr");
46  }
47 
48  return true;
49 }
50 
51 template <typename Payload>
52 static bool CheckHashSig(const Payload& pl, const CKeyID& keyID, CValidationState& state)
53 {
54  std::string strError;
55  if (!CHashSigner::VerifyHash(::SerializeHash(pl), keyID, pl.vchSig, strError)) {
56  return state.DoS(100, false, REJECT_INVALID, "bad-protx-sig", false, strError);
57  }
58  return true;
59 }
60 
61 template <typename Payload>
62 static bool CheckHashSig(const Payload& pl, const CBLSPublicKey& pubKey, CValidationState& state)
63 {
64  if (!pl.sig.VerifyInsecure(pubKey, ::SerializeHash(pl))) {
65  return state.DoS(100, false, REJECT_INVALID, "bad-protx-sig", false);
66  }
67  return true;
68 }
69 
70 template <typename Payload>
71 static bool CheckStringSig(const Payload& pl, const CKeyID& keyID, CValidationState& state)
72 {
73  std::string strError;
74  if (!CMessageSigner::VerifyMessage(keyID, pl.vchSig, pl.MakeSignString(), strError)) {
75  return state.DoS(100, false, REJECT_INVALID, "bad-protx-sig", false, strError);
76  }
77  return true;
78 }
79 
80 template <typename Payload>
81 static bool CheckInputsHash(const CTransaction& tx, const Payload& pl, CValidationState& state)
82 {
83  if (CalcTxInputsHash(tx) != pl.inputsHash) {
84  return state.DoS(100, false, REJECT_INVALID, "bad-protx-inputs-hash");
85  }
86 
87  return true;
88 }
89 
90 static bool CheckCollateralOut(const CTxOut& out, const ProRegPL& pl, CValidationState& state, CTxDestination& collateralDestRet)
91 {
92  if (!ExtractDestination(out.scriptPubKey, collateralDestRet)) {
93  return state.DoS(10, false, REJECT_INVALID, "bad-protx-collateral-dest");
94  }
95  // don't allow reuse of collateral key for other keys (don't allow people to put the collateral key onto an online server)
96  // this check applies to internal and external collateral, but internal collaterals are not necessarely a P2PKH
97  if (collateralDestRet == CTxDestination(pl.keyIDOwner) ||
98  collateralDestRet == CTxDestination(pl.keyIDVoting)) {
99  return state.DoS(10, false, REJECT_INVALID, "bad-protx-collateral-reuse");
100  }
101  // check collateral amount
102  if (out.nValue != Params().GetConsensus().nMNCollateralAmt) {
103  return state.DoS(100, false, REJECT_INVALID, "bad-protx-collateral-amount");
104  }
105  return true;
106 }
107 
108 // Provider Register Payload
109 static bool CheckProRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, const CCoinsViewCache* view, CValidationState& state)
110 {
111 
112  ProRegPL pl;
113  if (!GetValidatedTxPayload(tx, pl, state)) {
114  // pass the state returned by the function above
115  return false;
116  }
117 
118  // It's allowed to set addr to 0, which will put the MN into PoSe-banned state and require a ProUpServTx to be issues later
119  // If any of both is set, it must be valid however
120  if (pl.addr != CService() && !CheckService(pl.addr, state)) {
121  // pass the state returned by the function above
122  return false;
123  }
124 
125  if (pl.collateralOutpoint.hash.IsNull()) {
126  // collateral included in the proReg tx
127  if (pl.collateralOutpoint.n >= tx.vout.size()) {
128  return state.DoS(10, false, REJECT_INVALID, "bad-protx-collateral-index");
129  }
130  CTxDestination collateralTxDest;
131  if (!CheckCollateralOut(tx.vout[pl.collateralOutpoint.n], pl, state, collateralTxDest)) {
132  // pass the state returned by the function above
133  return false;
134  }
135  // collateral is part of this ProRegTx, so we know the collateral is owned by the issuer
136  if (!pl.vchSig.empty()) {
137  return state.DoS(100, false, REJECT_INVALID, "bad-protx-sig");
138  }
139  } else if (pindexPrev != nullptr) {
140  assert(view != nullptr);
141 
142  // Referenced external collateral.
143  // This is checked only when pindexPrev is not null (thus during ConnectBlock-->CheckSpecialTx),
144  // because this is a contextual check: we need the updated utxo set, to verify that
145  // the coin exists and it is unspent.
146  Coin coin;
147  if (!view->GetUTXOCoin(pl.collateralOutpoint, coin)) {
148  return state.DoS(10, false, REJECT_INVALID, "bad-protx-collateral");
149  }
150  CTxDestination collateralTxDest;
151  if (!CheckCollateralOut(coin.out, pl, state, collateralTxDest)) {
152  // pass the state returned by the function above
153  return false;
154  }
155  // Extract key from collateral. This only works for P2PK and P2PKH collaterals and will fail for P2SH.
156  // Issuer of this ProRegTx must prove ownership with this key by signing the ProRegTx
157  const CKeyID* keyForPayloadSig = boost::get<CKeyID>(&collateralTxDest);
158  if (!keyForPayloadSig) {
159  return state.DoS(10, false, REJECT_INVALID, "bad-protx-collateral-pkh");
160  }
161  // collateral is not part of this ProRegTx, so we must verify ownership of the collateral
162  if (!CheckStringSig(pl, *keyForPayloadSig, state)) {
163  // pass the state returned by the function above
164  return false;
165  }
166  }
167 
168  if (!CheckInputsHash(tx, pl, state)) {
169  return false;
170  }
171 
172  if (pindexPrev) {
173  auto mnList = deterministicMNManager->GetListForBlock(pindexPrev);
174  // only allow reusing of addresses when it's for the same collateral (which replaces the old MN)
175  if (mnList.HasUniqueProperty(pl.addr) && mnList.GetUniquePropertyMN(pl.addr)->collateralOutpoint != pl.collateralOutpoint) {
176  return state.DoS(10, false, REJECT_DUPLICATE, "bad-protx-dup-IP-address");
177  }
178  // never allow duplicate keys, even if this ProTx would replace an existing MN
179  if (mnList.HasUniqueProperty(pl.keyIDOwner)) {
180  return state.DoS(10, false, REJECT_DUPLICATE, "bad-protx-dup-owner-key");
181  }
182  if (mnList.HasUniqueProperty(pl.pubKeyOperator)) {
183  return state.DoS(10, false, REJECT_DUPLICATE, "bad-protx-dup-operator-key");
184  }
185  }
186 
187  return true;
188 }
189 
190 // Provider Update Service Payload
191 static bool CheckProUpServTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state)
192 {
193 
194  ProUpServPL pl;
195  if (!GetValidatedTxPayload(tx, pl, state)) {
196  // pass the state returned by the function above
197  return false;
198  }
199 
200  if (!CheckService(pl.addr, state)) {
201  // pass the state returned by the function above
202  return false;
203  }
204 
205  if (!CheckInputsHash(tx, pl, state)) {
206  // pass the state returned by the function above
207  return false;
208  }
209 
210  if (pindexPrev) {
211  auto mnList = deterministicMNManager->GetListForBlock(pindexPrev);
212  auto mn = mnList.GetMN(pl.proTxHash);
213  if (!mn) {
214  return state.DoS(100, false, REJECT_INVALID, "bad-protx-hash");
215  }
216 
217  // don't allow updating to addresses already used by other MNs
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");
220  }
221 
222  if (!pl.scriptOperatorPayout.empty()) {
223  if (mn->nOperatorReward == 0) {
224  // don't allow to set operator reward payee in case no operatorReward was set
225  return state.DoS(10, false, REJECT_INVALID, "bad-protx-operator-payee");
226  }
227  // we may support other kinds of scripts later, but restrict it for now
229  return state.DoS(10, false, REJECT_INVALID, "bad-protx-operator-payee");
230  }
231  }
232 
233  // we can only check the signature if pindexPrev != nullptr and the MN is known
234  if (!CheckHashSig(pl, mn->pdmnState->pubKeyOperator.Get(), state)) {
235  // pass the state returned by the function above
236  return false;
237  }
238  }
239 
240  return true;
241 }
242 
243 // Provider Update Registrar Payload
244 static bool CheckProUpRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, const CCoinsViewCache* view, CValidationState& state)
245 {
246 
247  ProUpRegPL pl;
248  if (!GetValidatedTxPayload(tx, pl, state)) {
249  // pass the state returned by the function above
250  return false;
251  }
252 
253  CTxDestination payoutDest;
254  if (!ExtractDestination(pl.scriptPayout, payoutDest)) {
255  // should not happen as we checked script types before
256  return state.DoS(10, false, REJECT_INVALID, "bad-protx-payee-dest");
257  }
258 
259  // don't allow reuse of payee key for other keys
260  if (payoutDest == CTxDestination(pl.keyIDVoting)) {
261  return state.DoS(10, false, REJECT_INVALID, "bad-protx-payee-reuse");
262  }
263 
264  if (!CheckInputsHash(tx, pl, state)) {
265  return false;
266  }
267 
268  if (pindexPrev) {
269  assert(view != nullptr);
270 
271  // ProUpReg txes are disabled when the legacy system is still active
272  // !TODO: remove after complete transition to DMN
273  if (!deterministicMNManager->LegacyMNObsolete(pindexPrev->nHeight + 1)) {
274  return state.DoS(10, false, REJECT_INVALID, "spork-21-inactive");
275  }
276 
277  auto mnList = deterministicMNManager->GetListForBlock(pindexPrev);
278  auto dmn = mnList.GetMN(pl.proTxHash);
279  if (!dmn) {
280  return state.DoS(100, false, REJECT_INVALID, "bad-protx-hash");
281  }
282 
283  // don't allow reuse of payee key for owner key
284  if (payoutDest == CTxDestination(dmn->pdmnState->keyIDOwner)) {
285  return state.DoS(10, false, REJECT_INVALID, "bad-protx-payee-reuse");
286  }
287 
288  Coin coin;
289  if (!view->GetUTXOCoin(dmn->collateralOutpoint, coin)) {
290  // this should never happen (there would be no dmn otherwise)
291  return state.DoS(100, false, REJECT_INVALID, "bad-protx-collateral");
292  }
293 
294  // don't allow reuse of collateral key for other keys (don't allow people to put the payee key onto an online server)
295  CTxDestination collateralTxDest;
296  if (!ExtractDestination(coin.out.scriptPubKey, collateralTxDest)) {
297  return state.DoS(100, false, REJECT_INVALID, "bad-protx-collateral-dest");
298  }
299  if (collateralTxDest == CTxDestination(dmn->pdmnState->keyIDOwner) ||
300  collateralTxDest == CTxDestination(pl.keyIDVoting)) {
301  return state.DoS(10, false, REJECT_INVALID, "bad-protx-collateral-reuse");
302  }
303 
304  if (mnList.HasUniqueProperty(pl.pubKeyOperator)) {
305  auto otherDmn = mnList.GetUniquePropertyMN(pl.pubKeyOperator);
306  if (pl.proTxHash != otherDmn->proTxHash) {
307  return state.DoS(10, false, REJECT_DUPLICATE, "bad-protx-dup-key");
308  }
309  }
310 
311  if (!CheckHashSig(pl, dmn->pdmnState->keyIDOwner, state)) {
312  // pass the state returned by the function above
313  return false;
314  }
315 
316  }
317 
318  return true;
319 }
320 
321 // Provider Update Revoke Payload
322 static bool CheckProUpRevTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state)
323 {
324 
325  ProUpRevPL pl;
326  if (!GetValidatedTxPayload(tx, pl, state)) {
327  // pass the state returned by the function above
328  return false;
329  }
330 
331  if (!CheckInputsHash(tx, pl, state)) {
332  // pass the state returned by the function above
333  return false;
334  }
335 
336  if (pindexPrev) {
337  auto mnList = deterministicMNManager->GetListForBlock(pindexPrev);
338  auto dmn = mnList.GetMN(pl.proTxHash);
339  if (!dmn)
340  return state.DoS(100, false, REJECT_INVALID, "bad-protx-hash");
341 
342  if (!CheckHashSig(pl, dmn->pdmnState->pubKeyOperator.Get(), state)) {
343  // pass the state returned by the function above
344  return false;
345  }
346  }
347 
348  return true;
349 }
350 
351 // LLMQ final commitment Payload
352 bool VerifyLLMQCommitment(const llmq::CFinalCommitment& qfc, const CBlockIndex* pindexPrev, CValidationState& state)
353 {
355 
356  // Check DKG maintenance mode
358  // only null commitments are accepted
359  if (!qfc.IsNull()) {
360  return state.DoS(50, false, REJECT_INVALID, "bad-qc-not-null-spork22");
361  }
362  }
363 
364  // Check version
366  return state.DoS(100, false, REJECT_INVALID, "bad-qc-quorum-version");
367  }
368 
369  // Check type
371  if (params == nullopt) {
372  return state.DoS(100, false, REJECT_INVALID, "bad-qc-quorum-type");
373  }
374 
375  // Check sizes
376  if (!qfc.VerifySizes(*params)) {
377  return state.DoS(100, false, REJECT_INVALID, "bad-qc-quorum-sizes");
378  }
379 
380  if (pindexPrev) {
381  // Get quorum index
382  CBlockIndex* pindexQuorum = LookupBlockIndex(qfc.quorumHash);
383  if (!pindexQuorum) {
384  return state.DoS(100, false, REJECT_INVALID, "bad-qc-quorum-hash-not-found");
385  }
386 
387  // Check height
388  if (pindexQuorum->nHeight % params->dkgInterval != 0) {
389  // not first block of DKG interval
390  return state.DoS(100, false, REJECT_INVALID, "bad-qc-quorum-height");
391  }
392 
393  // Check height limit
394  if (pindexPrev->nHeight - pindexQuorum->nHeight > params->cacheDkgInterval) {
395  return state.DoS(100, false, REJECT_INVALID, "bad-qc-quorum-height-old");
396  }
397 
398  if (pindexQuorum != pindexPrev->GetAncestor(pindexQuorum->nHeight)) {
399  // not part of active chain
400  return state.DoS(100, false, REJECT_INVALID, "bad-qc-quorum-hash-not-active-chain");
401  }
402 
403  // Get members and check signatures (for not-null commitments)
404  if (!qfc.IsNull()) {
405  std::vector<CBLSPublicKey> allkeys;
406  for (const auto& m : deterministicMNManager->GetAllQuorumMembers((Consensus::LLMQType)qfc.llmqType, pindexQuorum)) {
407  allkeys.emplace_back(m->pdmnState->pubKeyOperator.Get());
408  }
409  if (!qfc.Verify(allkeys, *params)) {
410  return state.DoS(100, false, REJECT_INVALID, "bad-qc-invalid");
411  }
412  }
413  }
414 
415  return true;
416 }
417 
418 static bool CheckLLMQCommitmentTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
419 {
421 
422  llmq::LLMQCommPL pl;
423  if (!GetTxPayload(tx, pl)) {
424  return state.DoS(100, false, REJECT_INVALID, "bad-qc-payload");
425  }
426 
428  return state.DoS(100, false, REJECT_INVALID, "bad-qc-version");
429  }
430 
431  if (pindexPrev && pl.nHeight != (uint32_t)pindexPrev->nHeight + 1) {
432  return state.DoS(100, false, REJECT_INVALID, "bad-qc-height");
433  }
434 
435  return VerifyLLMQCommitment(pl.commitment, pindexPrev, state);
436 }
437 
438 // Basic non-contextual checks for all tx types
439 static bool CheckSpecialTxBasic(const CTransaction& tx, CValidationState& state)
440 {
441  bool hasExtraPayload = tx.hasExtraPayload();
442 
443  if (tx.IsNormalType()) {
444  // Type-0 txes don't have extra payload
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");
448  }
449  // Normal transaction. Nothing to check
450  return true;
451  }
452 
453  // Special txes need at least version 2
454  if (!tx.isSaplingVersion()) {
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");
457  }
458 
459  // Cannot be coinbase/coinstake tx
460  if (tx.IsCoinBase() || tx.IsCoinStake()) {
461  return state.DoS(10, error("%s: Special tx is coinbase or coinstake", __func__),
462  REJECT_INVALID, "bad-txns-special-coinbase");
463  }
464 
465  // Special txes must have a non-empty payload
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");
469  }
470 
471  // Size limits
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");
475  }
476 
477  return true;
478 }
479 
480 // contextual and non-contextual per-type checks
481 // - pindexPrev=null: CheckBlock-->CheckSpecialTxNoContext
482 // - pindexPrev=chainActive.Tip: AcceptToMemoryPoolWorker-->CheckSpecialTx
483 // - pindexPrev=pindex->pprev: ConnectBlock-->ProcessSpecialTxsInBlock-->CheckSpecialTx
484 bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, const CCoinsViewCache* view, CValidationState& state)
485 {
487 
488  if (!CheckSpecialTxBasic(tx, state)) {
489  // pass the state returned by the function above
490  return false;
491  }
492  if (pindexPrev) {
493  // reject special transactions before enforcement
494  if (!tx.IsNormalType() && !Params().GetConsensus().NetworkUpgradeActive(pindexPrev->nHeight + 1, Consensus::UPGRADE_V6_0)) {
495  return state.DoS(100, error("%s: Special tx when v6 upgrade not enforced yet", __func__),
496  REJECT_INVALID, "bad-txns-v6-not-active");
497  }
498  }
499  // per-type checks
500  switch (tx.nType) {
501  case CTransaction::TxType::NORMAL: {
502  // nothing to check
503  return true;
504  }
505  case CTransaction::TxType::PROREG: {
506  // provider-register
507  return CheckProRegTx(tx, pindexPrev, view, state);
508  }
509  case CTransaction::TxType::PROUPSERV: {
510  // provider-update-service
511  return CheckProUpServTx(tx, pindexPrev, state);
512  }
513  case CTransaction::TxType::PROUPREG: {
514  // provider-update-registrar
515  return CheckProUpRegTx(tx, pindexPrev, view, state);
516  }
517  case CTransaction::TxType::PROUPREV: {
518  // provider-update-revoke
519  return CheckProUpRevTx(tx, pindexPrev, state);
520  }
521  case CTransaction::TxType::LLMQCOMM: {
522  // quorum commitment
523  return CheckLLMQCommitmentTx(tx, pindexPrev, state);
524  }
525  }
526 
527  return state.DoS(10, error("%s: special tx %s with invalid type %d", __func__, tx.GetHash().ToString(), tx.nType),
528  REJECT_INVALID, "bad-tx-type");
529 }
530 
532 {
533  return CheckSpecialTx(tx, nullptr, nullptr, state);
534 }
535 
536 
537 bool ProcessSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex, const CCoinsViewCache* view, CValidationState& state, bool fJustCheck)
538 {
540 
541  // check special txes
542  for (const CTransactionRef& tx: block.vtx) {
543  if (!CheckSpecialTx(*tx, pindex->pprev, view, state)) {
544  // pass the state returned by the function above
545  return false;
546  }
547  }
548 
549  if (!llmq::quorumBlockProcessor->ProcessBlock(block, pindex, state, fJustCheck)) {
550  // pass the state returned by the function above
551  return false;
552  }
553 
554  if (!deterministicMNManager->ProcessBlock(block, pindex, state, fJustCheck)) {
555  // pass the state returned by the function above
556  return false;
557  }
558 
559  return true;
560 }
561 
562 bool UndoSpecialTxsInBlock(const CBlock& block, const CBlockIndex* pindex)
563 {
564  if (!deterministicMNManager->UndoBlock(block, pindex)) {
565  return false;
566  }
567  if (!llmq::quorumBlockProcessor->UndoBlock(block, pindex)) {
568  return false;
569  }
570  return true;
571 }
572 
574 {
575  CHashWriter hw(CLIENT_VERSION, SER_GETHASH);
576  // transparent inputs
577  for (const CTxIn& in: tx.vin) {
578  hw << in.prevout;
579  }
580  // shield inputs
581  if (tx.hasSaplingData()) {
582  for (const SpendDescription& sd: tx.sapData->vShieldedSpend) {
583  hw << sd.nullifier;
584  }
585  }
586  return hw.GetHash();
587 }
588 
589 template <typename T>
591 {
592  if (tx.nType != T::SPECIALTX_TYPE) {
593  return state.DoS(100, false, REJECT_INVALID, "bad-protx-type");
594  }
595  if (!GetTxPayload(tx, obj)) {
596  return state.DoS(100, false, REJECT_INVALID, "bad-protx-payload");
597  }
598  return obj.IsTriviallyValid(state);
599 }
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.
uint256 hash
Definition: transaction.h:35
uint32_t n
Definition: transaction.h:36
static const std::string MAIN
Chain name strings.
Definition: block.h:80
std::vector< CTransactionRef > vtx
Definition: block.h:83
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:139
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:145
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: chain.cpp:113
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:151
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:72
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:283
bool GetUTXOCoin(const COutPoint &outpoint, Coin &coin) const
Get the coin and check if it's spent.
Definition: coins.cpp:584
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.
Definition: hash.h:216
uint256 GetHash()
Definition: hash.h:236
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:21
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 IsRoutable() const
Definition: netaddress.cpp:454
bool IsValid() const
Definition: netaddress.cpp:418
bool IsIPv4() const
Definition: netaddress.cpp:295
bool IsPayToPublicKeyHash() const
Definition: script.cpp:212
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:484
uint16_t GetPort() const
Definition: netaddress.cpp:882
bool IsSporkActive(SporkId nSporkID)
Definition: spork.cpp:220
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:244
bool IsNormalType() const
Definition: transaction.h:334
const int16_t nType
Definition: transaction.h:273
std::vector< CTxIn > vin
Definition: transaction.h:270
const int16_t nVersion
Definition: transaction.h:272
bool hasExtraPayload() const
Definition: transaction.h:324
const uint256 & GetHash() const
Definition: transaction.h:301
Optional< std::vector< uint8_t > > extraPayload
Definition: transaction.h:276
bool IsCoinBase() const
Definition: transaction.h:376
Optional< SaplingTxData > sapData
Definition: transaction.h:275
bool isSaplingVersion() const
Definition: transaction.h:314
bool IsCoinStake() const
std::vector< CTxOut > vout
Definition: transaction.h:271
bool hasSaplingData() const
Definition: transaction.h:305
An input of a transaction.
Definition: transaction.h:94
COutPoint prevout
Definition: transaction.h:96
An output of a transaction.
Definition: transaction.h:137
CScript scriptPubKey
Definition: transaction.h:140
CAmount nValue
Definition: transaction.h:139
Capture information about block/transaction validation.
Definition: validation.h:24
bool DoS(int level, bool ret=false, unsigned int chRejectCodeIn=0, std::string strRejectReasonIn="", bool corruptionIn=false, const std::string &strDebugMessageIn="")
Definition: validation.h:39
A UTXO entry.
Definition: coins.h:32
CTxOut out
unspent transaction output
Definition: coins.h:41
CKeyID keyIDVoting
Definition: providertx.h:33
COutPoint collateralOutpoint
Definition: providertx.h:29
CBLSPublicKey pubKeyOperator
Definition: providertx.h:32
std::vector< unsigned char > vchSig
Definition: providertx.h:38
CKeyID keyIDOwner
Definition: providertx.h:31
CService addr
Definition: providertx.h:30
CKeyID keyIDVoting
Definition: providertx.h:113
CScript scriptPayout
Definition: providertx.h:114
uint256 proTxHash
Definition: providertx.h:110
CBLSPublicKey pubKeyOperator
Definition: providertx.h:112
uint256 proTxHash
Definition: providertx.h:151
CService addr
Definition: providertx.h:81
uint256 proTxHash
Definition: providertx.h:80
CScript scriptOperatorPayout
Definition: providertx.h:82
A shielded input to a transaction.
uint256 nullifier
The nullifier of the input note.
std::string ToString() const
Definition: uint256.cpp:65
bool IsNull() const
Definition: uint256.h:36
static const uint16_t CURRENT_VERSION
bool Verify(const std::vector< CBLSPublicKey > &allkeys, const Consensus::LLMQParams &params) const
bool VerifySizes(const Consensus::LLMQParams &params) const
static const uint16_t CURRENT_VERSION
CFinalCommitment commitment
bool empty() const
Definition: prevector.h:281
256-bit opaque blob.
Definition: uint256.h:138
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.
Definition: hash.h:289
#define T(expected, seed, data)
@ UPGRADE_V6_0
Definition: params.h:41
LLMQType
Definition: params.h:90
std::unique_ptr< CQuorumBlockProcessor > quorumBlockProcessor
RecursiveMutex cs_main
Global state.
Definition: validation.cpp:80
boost::optional< T > Optional
Substitute for C++17 std::optional.
Definition: optional.h:12
@ SER_GETHASH
Definition: serialize.h:176
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
Definition: spork.cpp:29
@ SPORK_22_LLMQ_DKG_MAINTENANCE
Definition: sporkid.h:29
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet, bool fColdStake)
Parse a standard scriptPubKey for the destination address.
Definition: standard.cpp:162
boost::variant< CNoDestination, CKeyID, CScriptID, CExchangeKeyID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:72
Optional< LLMQParams > GetLLMQParams(uint8_t llmqtype) const
Definition: params.cpp:25
#define AssertLockHeld(cs)
Definition: sync.h:75
bool error(const char *fmt, const Args &... args)
Definition: system.h:77
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:50
bool GetTxPayload(const std::vector< unsigned char > &payload, T &obj)
Definition: transaction.h:464
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:456
bool NetworkUpgradeActive(int nHeight, const Consensus::Params &params, Consensus::UpgradeIndex idx)
Returns true if the given network upgrade is active as of the given block height.
Definition: upgrades.cpp:107
bool IsInitialBlockDownload()
Check whether we are doing an initial block download (synchronizing from disk or network)
Definition: validation.cpp:862
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: validation.h:345