Commit 76bd8ed6 authored by Tom Bradshaw's avatar Tom Bradshaw
Browse files

Merge branch 'proof_check' into 'mn_pos'

proof hash checking added to connect block

See merge request presstab/crown-core!1
parents 80c1443c 133741dc
Showing with 67 additions and 5 deletions
+67 -5
......@@ -1408,7 +1408,7 @@ bool AcceptableInputs(CTxMemPool& pool, CValidationState &state, const CTransact
}
/** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256& hashBlock, bool fAllowSlow)
{
CBlockIndex *pindexSlow = NULL;
{
......@@ -2073,7 +2073,7 @@ void ThreadScriptCheck() {
scriptcheckqueue.Thread();
}
bool CheckBlockProofPointer(const CBlock& block, CPubKey& pubkeyMasternode)
bool CheckBlockProofPointer(const CBlock& block, CPubKey& pubkeyMasternode, COutPoint& outpoint)
{
StakePointer stakePointer = block.stakePointer;
if (!mapBlockIndex.count(stakePointer.hashBlock))
......@@ -2097,8 +2097,10 @@ bool CheckBlockProofPointer(const CBlock& block, CPubKey& pubkeyMasternode)
if (!ExtractDestination(tx.vout[stakePointer.nPos].scriptPubKey, dest))
return error("%s: failed to get destination from scriptPubKey", __func__);
if (CBitcoinAddress(stakePointer.hashPubKey).ToString() != CBitcoinAddress(dest).ToString())
return error("%s: Pubkeyhash from proof does not match stakepointer", __func__);
// if (CBitcoinAddress(stakePointer.hashPubKey).ToString() != CBitcoinAddress(dest).ToString())
// return error("%s: Pubkeyhash from proof does not match stakepointer", __func__);
outpoint = COutPoint(stakePointer.txid, stakePointer.nPos);
found = true;
break;
......@@ -2128,7 +2130,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
"pow-end");
CPubKey pubkeyMasternode;
if (!CheckBlockProofPointer(block, pubkeyMasternode))
COutPoint outpoint;
if (!CheckBlockProofPointer(block, pubkeyMasternode, outpoint))
return state.DoS(100, error("%s: Invalid block proof pointer", __func__), REJECT_INVALID,
"signature-invalid");
......@@ -2136,6 +2139,18 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
return state.DoS(100, error("%s: Invalid signature", __func__), REJECT_INVALID,
"signature-invalid");
CTransaction txPayment;
uint256 hashPrevBlock;
if (!GetTransaction(outpoint.hash, txPayment, hashPrevBlock, true)) {
return state.DoS(100, error("%s: Cannot find MN or SN payment", __func__), REJECT_INVALID, "tx-invalid");
}
CBlockIndex* pindexFrom = mapBlockIndex.at(block.stakePointer.hashBlock);
if (!CheckProofOfStake(block, pindexFrom, outpoint, txPayment)) {
return state.DoS(100, error("%s: Proof of Stake check failed", __func__), REJECT_INVALID, "PoS invalid");
}
} else if (block.IsProofOfStake()) {
return state.DoS(100, error("%s: Proof of Stake block submitted before PoW end", __func__), REJECT_INVALID,
"pos-early");
......
......@@ -2,6 +2,7 @@
#define CROWNCOIN_PROOFPOINTER_H
#include "uint256.h"
#include "serialize.h"
/*
* Crown's masternode staking consensus layer use a "staking node proof pointer" that will point to the most recent
......@@ -29,6 +30,16 @@ struct StakePointer
hashPubKey = uint160();
nPos = 0;
}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(hashBlock);
READWRITE(txid);
READWRITE(nPos);
READWRITE(hashPubKey);
}
};
#endif //CROWNCOIN_PROOFPOINTER_H
#include "stakevalidation.h"
#include "kernel.h"
#include <primitives/block.h>
#include <chain.h>
#include <pubkey.h>
#include <util.h>
#include <arith_uint256.h>
bool CheckBlockSignature(const CBlock& block, const CPubKey& pubkeyMasternode)
{
......@@ -9,3 +13,29 @@ bool CheckBlockSignature(const CBlock& block, const CPubKey& pubkeyMasternode)
return pubkeyMasternode.Verify(hashBlock, block.vchBlockSig);
}
// Check kernel hash target and coinstake signature
bool CheckProofOfStake(const CBlock& block, const CBlockIndex* prevBlock, const COutPoint& outpoint, const CTransaction& txPayment)
{
const CTransaction tx = block.vtx[1];
if (!tx.IsCoinStake())
return error("CheckProofOfStake() : called on non-coinstake %s", tx.GetHash().ToString().c_str());
CAmount nMNPayment = txPayment.vout[1].nValue;
CAmount nSNPayment = txPayment.vout[2].nValue;
auto pairOut = std::make_pair(outpoint.hash, outpoint.n);
Kernel kernel(pairOut, (outpoint.n == 1 ? nMNPayment : nSNPayment), uint256(), prevBlock->GetBlockTime(), block.nTime);
bool fNegative;
bool fOverflow;
arith_uint256 bnTarget;
bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
// Check range
if (fNegative || bnTarget == 0 || fOverflow)
return error("CheckProofOfStake() : nBits below minimum stake");
return kernel.IsValidProof(ArithToUint256(bnTarget));
}
\ No newline at end of file
......@@ -3,7 +3,13 @@
class CBlock;
class CPubKey;
class CBlockIndex;
class COutPoint;
class CTransaction;
bool CheckBlockSignature(const CBlock& block, const CPubKey& pubkeyMasternode);
// Check kernel hash target and coinstake signature
bool CheckProofOfStake(const CBlock& block, const CBlockIndex* prevBlock, const COutPoint& outpoint, const CTransaction& txPayment);
#endif //CROWNCOIN_STAKEVALIDATION_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment