Skip to content

Commit

Permalink
Port consensus
Browse files Browse the repository at this point in the history
  • Loading branch information
timemarkovqtum committed Feb 9, 2024
1 parent 238706b commit c2f85fc
Show file tree
Hide file tree
Showing 22 changed files with 332 additions and 33 deletions.
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@ libbitcoin_consensus_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libbitcoin_consensus_a_SOURCES = \
arith_uint256.cpp \
arith_uint256.h \
consensus/consensus.cpp \
consensus/amount.h \
consensus/merkle.cpp \
consensus/merkle.h \
Expand Down
8 changes: 4 additions & 4 deletions src/bitcoin-tx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,14 @@ static int AppInitRawTx(int argc, char* argv[])

if (argc < 2 || HelpRequested(gArgs) || gArgs.IsArgSet("-version")) {
// First part of help message is specific to this utility
std::string strUsage = PACKAGE_NAME " bitcoin-tx utility version " + FormatFullVersion() + "\n";
std::string strUsage = PACKAGE_NAME " qtum-tx utility version " + FormatFullVersion() + "\n";

if (gArgs.IsArgSet("-version")) {
strUsage += FormatParagraph(LicenseInfo());
} else {
strUsage += "\n"
"Usage: bitcoin-tx [options] <hex-tx> [commands] Update hex-encoded bitcoin transaction\n"
"or: bitcoin-tx [options] -create [commands] Create hex-encoded bitcoin transaction\n"
"Usage: qtum-tx [options] <hex-tx> [commands] Update hex-encoded qtum transaction\n"
"or: qtum-tx [options] -create [commands] Create hex-encoded qtum transaction\n"
"\n";
strUsage += gArgs.GetHelpMessage();
}
Expand Down Expand Up @@ -265,7 +265,7 @@ static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInpu
}

static const unsigned int minTxOutSz = 9;
static const unsigned int maxVout = MAX_BLOCK_WEIGHT / (WITNESS_SCALE_FACTOR * minTxOutSz);
static const unsigned int maxVout = dgpMaxBlockWeight / (WITNESS_SCALE_FACTOR * minTxOutSz);

// extract and validate vout
const std::string& strVout = vStrInputParts[1];
Expand Down
29 changes: 28 additions & 1 deletion src/chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <chain.h>
#include <tinyformat.h>
#include <util/time.h>
#include <pubkey.h>

std::string CBlockFileInfo::ToString() const
{
Expand Down Expand Up @@ -153,7 +154,7 @@ int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& fr
r = from.nChainWork - to.nChainWork;
sign = -1;
}
r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip);
r = r * arith_uint256(params.TargetSpacing(tip.nHeight)) / GetBlockProof(tip);
if (r.bits() > 63) {
return sign * std::numeric_limits<int64_t>::max();
}
Expand All @@ -178,3 +179,29 @@ const CBlockIndex* LastCommonAncestor(const CBlockIndex* pa, const CBlockIndex*
assert(pa == pb);
return pa;
}

std::vector<unsigned char> CBlockIndex::GetBlockSignature() const
{
if(vchBlockSigDlgt.size() < 2 * CPubKey::COMPACT_SIGNATURE_SIZE)
{
return vchBlockSigDlgt;
}

return std::vector<unsigned char>(vchBlockSigDlgt.begin(), vchBlockSigDlgt.end() - CPubKey::COMPACT_SIGNATURE_SIZE );
}

std::vector<unsigned char> CBlockIndex::GetProofOfDelegation() const
{
if(vchBlockSigDlgt.size() < 2 * CPubKey::COMPACT_SIGNATURE_SIZE)
{
return std::vector<unsigned char>();
}

return std::vector<unsigned char>(vchBlockSigDlgt.begin() + vchBlockSigDlgt.size() - CPubKey::COMPACT_SIGNATURE_SIZE, vchBlockSigDlgt.end());

}

bool CBlockIndex::HasProofOfDelegation() const
{
return vchBlockSigDlgt.size() >= 2 * CPubKey::COMPACT_SIGNATURE_SIZE;
}
55 changes: 54 additions & 1 deletion src/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ class CBlockIndex
//! pointer to the index of the predecessor of this block
CBlockIndex* pprev{nullptr};

//! pointer to the index of the successor of this block
CBlockIndex* pnext{nullptr};

//! pointer to the index of some further predecessor of this block
CBlockIndex* pskip{nullptr};

Expand Down Expand Up @@ -199,6 +202,15 @@ class CBlockIndex
uint32_t nTime{0};
uint32_t nBits{0};
uint32_t nNonce{0};
uint256 hashStateRoot{}; // qtum
uint256 hashUTXORoot{}; // qtum
// block signature - proof-of-stake protect the block by signing the block using a stake holder private key
std::vector<unsigned char> vchBlockSigDlgt{};
uint256 nStakeModifier{};
// proof-of-stake specific fields
COutPoint prevoutStake{};
uint256 hashProof{}; // qtum
uint64_t nMoneySupply{0};

//! (memory only) Sequential id assigned to distinguish order in which blocks are received.
int32_t nSequenceId{0};
Expand All @@ -211,7 +223,11 @@ class CBlockIndex
hashMerkleRoot{block.hashMerkleRoot},
nTime{block.nTime},
nBits{block.nBits},
nNonce{block.nNonce}
nNonce{block.nNonce},
hashStateRoot{block.hashStateRoot},
hashUTXORoot{block.hashUTXORoot},
vchBlockSigDlgt{block.vchBlockSigDlgt},
prevoutStake{block.prevoutStake}
{
}

Expand Down Expand Up @@ -247,6 +263,10 @@ class CBlockIndex
block.nTime = nTime;
block.nBits = nBits;
block.nNonce = nNonce;
block.hashStateRoot = hashStateRoot; // qtum
block.hashUTXORoot = hashUTXORoot; // qtum
block.vchBlockSigDlgt = vchBlockSigDlgt;
block.prevoutStake = prevoutStake;
return block;
}

Expand Down Expand Up @@ -300,6 +320,22 @@ class CBlockIndex
return pbegin[(pend - pbegin) / 2];
}

bool IsProofOfWork() const // qtum
{
return !IsProofOfStake();
}

bool IsProofOfStake() const
{
return !prevoutStake.IsNull();
}

std::vector<unsigned char> GetBlockSignature() const;

std::vector<unsigned char> GetProofOfDelegation() const;

bool HasProofOfDelegation() const;

std::string ToString() const;

//! Check whether this block index entry is valid up to the passed validity level.
Expand Down Expand Up @@ -411,6 +447,7 @@ class CDiskBlockIndex : public CBlockIndex
if (obj.nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO)) READWRITE(VARINT_MODE(obj.nFile, VarIntMode::NONNEGATIVE_SIGNED));
if (obj.nStatus & BLOCK_HAVE_DATA) READWRITE(VARINT(obj.nDataPos));
if (obj.nStatus & BLOCK_HAVE_UNDO) READWRITE(VARINT(obj.nUndoPos));
READWRITE(VARINT(obj.nMoneySupply));

// block header
READWRITE(obj.nVersion);
Expand All @@ -419,6 +456,12 @@ class CDiskBlockIndex : public CBlockIndex
READWRITE(obj.nTime);
READWRITE(obj.nBits);
READWRITE(obj.nNonce);
READWRITE(obj.hashStateRoot); // qtum
READWRITE(obj.hashUTXORoot); // qtum
READWRITE(obj.nStakeModifier);
READWRITE(obj.prevoutStake);
READWRITE(obj.hashProof);
READWRITE(obj.vchBlockSigDlgt); // qtum
}

uint256 ConstructBlockHash() const
Expand All @@ -430,6 +473,10 @@ class CDiskBlockIndex : public CBlockIndex
block.nTime = nTime;
block.nBits = nBits;
block.nNonce = nNonce;
block.hashStateRoot = hashStateRoot; // qtum
block.hashUTXORoot = hashUTXORoot; // qtum
block.vchBlockSigDlgt = vchBlockSigDlgt;
block.prevoutStake = prevoutStake;
return block.GetHash();
}

Expand Down Expand Up @@ -468,6 +515,12 @@ class CChain
return vChain[nHeight];
}

/** Compare two chains efficiently. */
friend bool operator==(const CChain &a, const CChain &b) {
return a.vChain.size() == b.vChain.size() &&
a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1];
}

/** Efficiently check whether a block is present in this chain. */
bool Contains(const CBlockIndex* pindex) const
{
Expand Down
1 change: 1 addition & 0 deletions src/coins.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class Coin

//! whether containing transaction was a coinbase
unsigned int fCoinBase : 1;
unsigned int fCoinStake : 1;

//! at which height this containing transaction was included in the active block chain
uint32_t nHeight : 31;
Expand Down
10 changes: 2 additions & 8 deletions src/consensus/amount.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,11 @@ typedef int64_t CAmount;

/** The amount of satoshis in one BTC. */
static constexpr CAmount COIN = 100000000;
static constexpr CAmount CENT = 1000000;

/** No amount larger than this (in satoshi) is valid.
*
* Note that this constant is *not* the total money supply, which in Bitcoin
* currently happens to be less than 21,000,000 BTC for various reasons, but
* rather a sanity check. As this sanity check is used by consensus-critical
* validation code, the exact value of the MAX_MONEY constant is consensus
* critical; in unusual circumstances like a(nother) overflow bug that allowed
* for the creation of coins out of thin air modification could lead to a fork.
* */
static constexpr CAmount MAX_MONEY = 21000000 * COIN;
static constexpr CAmount MAX_MONEY = 107822406 * COIN + 25 * (COIN / 100);
inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }

#endif // BITCOIN_CONSENSUS_AMOUNT_H
13 changes: 13 additions & 0 deletions src/consensus/consensus.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,25 @@
#include <stdint.h>

/** The maximum allowed size for a serialized block, in bytes (only for buffer size limits) */
extern unsigned int dgpMaxBlockSerSize;
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE = 4000000;
/** The maximum allowed weight for a block, see BIP 141 (network rule) */
extern unsigned int dgpMaxBlockWeight;

extern unsigned int dgpMaxBlockSize; // qtum

static const unsigned int MAX_BLOCK_WEIGHT = 4000000;
/** The maximum allowed number of signature check operations in a block (network rule) */
static const int64_t MAX_BLOCK_SIGOPS_COST = 80000;
/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */
static const int COINBASE_MATURITY = 100;
extern int64_t dgpMaxBlockSigOps;

extern unsigned int dgpMaxProtoMsgLength;

extern unsigned int dgpMaxTxSigOps;

static const int MAX_TRANSACTION_BASE_SIZE = 1000000;
static const int WITNESS_SCALE_FACTOR = 4;

static const size_t MIN_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR * 60; // 60 is the lower bound for the size of a valid serialized CTransaction
Expand All @@ -27,4 +38,6 @@ static const size_t MIN_SERIALIZABLE_TRANSACTION_WEIGHT = WITNESS_SCALE_FACTOR *
/** Interpret sequence numbers as relative lock-time constraints. */
static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE = (1 << 0);

void updateBlockSizeParams(unsigned int newBlockSize);

#endif // BITCOIN_CONSENSUS_CONSENSUS_H
9 changes: 7 additions & 2 deletions src/consensus/merkle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,17 @@ uint256 BlockMerkleRoot(const CBlock& block, bool* mutated)
return ComputeMerkleRoot(std::move(leaves), mutated);
}

uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated)
uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated, bool* pfProofOfStake)
{
bool fProofOfStake = pfProofOfStake ? *pfProofOfStake : block.IsProofOfStake();
std::vector<uint256> leaves;
leaves.resize(block.vtx.size());
leaves[0].SetNull(); // The witness hash of the coinbase is 0.
for (size_t s = 1; s < block.vtx.size(); s++) {
if(fProofOfStake)
{
leaves[1].SetNull(); // The witness hash of the coinstake is 0.
}
for (size_t s = 1 + (fProofOfStake ? 1 : 0); s < block.vtx.size(); s++) {
leaves[s] = block.vtx[s]->GetWitnessHash();
}
return ComputeMerkleRoot(std::move(leaves), mutated);
Expand Down
2 changes: 1 addition & 1 deletion src/consensus/merkle.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ uint256 BlockMerkleRoot(const CBlock& block, bool* mutated = nullptr);
* Compute the Merkle root of the witness transactions in a block.
* *mutated is set to true if a duplicated subtree was found.
*/
uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated = nullptr);
uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated = nullptr, bool* pfProofOfStake = nullptr);

#endif // BITCOIN_CONSENSUS_MERKLE_H
Loading

0 comments on commit c2f85fc

Please sign in to comment.