Skip to content

Commit

Permalink
Port init
Browse files Browse the repository at this point in the history
  • Loading branch information
timemarkovqtum committed Jun 13, 2024
1 parent 42d533c commit b2bad08
Show file tree
Hide file tree
Showing 16 changed files with 578 additions and 57 deletions.
11 changes: 10 additions & 1 deletion src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,16 @@ struct Params {
{
return std::chrono::seconds{nPowTargetSpacing};
}
int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; }
std::chrono::seconds TargetSpacingChrono(int height) const
{
return std::chrono::seconds{TargetSpacing(height)};
}
int64_t DifficultyAdjustmentInterval(int height=0) const
{
int64_t targetTimespan = TargetTimespan(height);
int64_t targetSpacing = TargetSpacing(height);
return targetTimespan / targetSpacing;
}
/** The best chain should have at least this much work */
uint256 nMinimumChainWork;
/** By default assume that the signatures in ancestors of this block are valid */
Expand Down
317 changes: 314 additions & 3 deletions src/init.cpp

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/init.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,7 @@ void SetupServerArgs(ArgsManager& argsman);
/** Validates requirements to run the indexes and spawns each index initial sync thread */
bool StartIndexBackgroundSync(node::NodeContext& node);

/** Unlock the data directory */
void UnlockDataDirectory();

#endif // BITCOIN_INIT_H
2 changes: 2 additions & 0 deletions src/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ static const bool DEFAULT_LOGTIMESTAMPS = true;
static const bool DEFAULT_LOGTHREADNAMES = false;
static const bool DEFAULT_LOGSOURCELOCATIONS = false;
static constexpr bool DEFAULT_LOGLEVELALWAYS = false;
static const bool DEFAULT_SHOWEVMLOGS = false;
extern const char * const DEFAULT_DEBUGLOGFILE;
extern const char * const DEFAULT_DEBUGVMLOGFILE;

extern bool fLogIPs;

Expand Down
16 changes: 16 additions & 0 deletions src/net_processing.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ static const int DISCOURAGEMENT_THRESHOLD{100};
/** Maximum number of outstanding CMPCTBLOCK requests for the same block. */
static const unsigned int MAX_CMPCTBLOCKS_INFLIGHT_PER_BLOCK = 3;

/** Default maximum orphan blocks */
static const unsigned int DEFAULT_MAX_ORPHAN_BLOCKS = 40;
/** Default for -headerspamfilter, use header spam filter */
static const bool DEFAULT_HEADER_SPAM_FILTER = true;
/** Default for -headerspamfiltermaxsize, maximum size of the list of indexes in the header spam filter */
static const unsigned int DEFAULT_HEADER_SPAM_FILTER_MAX_SIZE = 2000;
/** Default for -headerspamfiltermaxavg, maximum average size of an index occurrence in the header spam filter */
static const unsigned int DEFAULT_HEADER_SPAM_FILTER_MAX_AVG = 10;
/** Default for -headerspamfilterignoreport, ignore the port in the ip address when looking for header spam,
multiple nodes on the same ip will be treated as the one when computing the filter*/
static const unsigned int DEFAULT_HEADER_SPAM_FILTER_IGNORE_PORT = true;
/** Default for -cleanblockindex. */
static const bool DEFAULT_CLEANBLOCKINDEX = true;
/** Default for -cleanblockindextimeout. */
static const unsigned int DEFAULT_CLEANBLOCKINDEXTIMEOUT = 600;

struct CNodeStateStats {
int nSyncHeight = -1;
int nCommonHeight = -1;
Expand Down
4 changes: 4 additions & 0 deletions src/node/chainstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ struct ChainstateLoadOptions {
int64_t check_blocks{DEFAULT_CHECKBLOCKS};
int64_t check_level{DEFAULT_CHECKLEVEL};
std::function<void()> coins_error_cb;
bool getting_values_dgp{false};
bool record_log_opcodes{false};
bool addrindex{false};
bool logevents{false};
};

//! Chainstate load status. Simple applications can just check for the success
Expand Down
42 changes: 42 additions & 0 deletions src/node/miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,54 @@ class CChainParams;
class CScript;
class Chainstate;
class ChainstateManager;
#ifdef ENABLE_WALLET
namespace wallet { class CWallet; };
#endif

namespace Consensus { struct Params; };

namespace node {
static const bool DEFAULT_PRINTPRIORITY = false;

static const bool DEFAULT_STAKE = true;

static const bool DEFAULT_STAKE_CACHE = true;

static const bool DEFAULT_SUPER_STAKE = false;

static const bool ENABLE_HARDWARE_STAKE = false;

//How many seconds to look ahead and prepare a block for staking
//Look ahead up to 3 "timeslots" in the future, 48 seconds
//Reduce this to reduce computational waste for stakers, increase this to increase the amount of time available to construct full blocks
static const int32_t MAX_STAKE_LOOKAHEAD = 16 * 3;

//Will not add any more contracts when GetAdjustedTime() >= nTimeLimit-BYTECODE_TIME_BUFFER
//This does not affect non-contract transactions
static const int32_t BYTECODE_TIME_BUFFER = 6;

//Will not attempt to add more transactions when GetAdjustedTime() >= nTimeLimit
//And nTimeLimit = StakeExpirationTime - STAKE_TIME_BUFFER
static const int32_t STAKE_TIME_BUFFER = 2;

//How often to try to stake blocks in milliseconds
static const int32_t STAKER_POLLING_PERIOD = 5000;

//How often to try to stake blocks in milliseconds for minimum difficulty
static const int32_t STAKER_POLLING_PERIOD_MIN_DIFFICULTY = 20000;

//How often to try to check for future walid block
static const int32_t STAKER_WAIT_FOR_WALID_BLOCK = 3000;

//How much time to wait for best block header to be downloaded to the blockchain
static const int32_t STAKER_WAIT_FOR_BEST_BLOCK_HEADER = 250;

//How much max time to wait for best block header to be downloaded to the blockchain
static const int32_t DEFAULT_MAX_STAKER_WAIT_FOR_BEST_BLOCK_HEADER = 4000;

//How much time to spend trying to process transactions when using the generate RPC call
static const int32_t POW_MINER_MAX_TIME = 60;

struct CBlockTemplate
{
CBlock block;
Expand Down
5 changes: 4 additions & 1 deletion src/outputtype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const std::string& FormatOutputType(OutputType type)
case OutputType::P2SH_SEGWIT: return OUTPUT_TYPE_STRING_P2SH_SEGWIT;
case OutputType::BECH32: return OUTPUT_TYPE_STRING_BECH32;
case OutputType::BECH32M: return OUTPUT_TYPE_STRING_BECH32M;
case OutputType::P2PK: return OUTPUT_TYPE_STRING_LEGACY;
case OutputType::UNKNOWN: return OUTPUT_TYPE_STRING_UNKNOWN;
} // no default case, so the compiler can warn about missing cases
assert(false);
Expand All @@ -50,7 +51,8 @@ const std::string& FormatOutputType(OutputType type)
CTxDestination GetDestinationForKey(const CPubKey& key, OutputType type)
{
switch (type) {
case OutputType::LEGACY: return PKHash(key);
case OutputType::LEGACY:
case OutputType::P2PK: return PKHash(key);
case OutputType::P2SH_SEGWIT:
case OutputType::BECH32: {
if (!key.IsCompressed()) return PKHash(key);
Expand Down Expand Up @@ -88,6 +90,7 @@ CTxDestination AddAndGetDestinationForScript(FillableSigningProvider& keystore,
// Note that scripts over 520 bytes are not yet supported.
switch (type) {
case OutputType::LEGACY:
case OutputType::P2PK:
return ScriptHash(script);
case OutputType::P2SH_SEGWIT:
case OutputType::BECH32: {
Expand Down
2 changes: 2 additions & 0 deletions src/outputtype.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ enum class OutputType {
P2SH_SEGWIT,
BECH32,
BECH32M,
P2PK,
UNKNOWN,
};

Expand All @@ -27,6 +28,7 @@ static constexpr auto OUTPUT_TYPES = std::array{
OutputType::P2SH_SEGWIT,
OutputType::BECH32,
OutputType::BECH32M,
OutputType::P2PK,
};

std::optional<OutputType> ParseOutputType(const std::string& str);
Expand Down
163 changes: 120 additions & 43 deletions src/pow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,74 +10,150 @@
#include <primitives/block.h>
#include <uint256.h>

unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
{
assert(pindexLast != nullptr);
unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();

// Only change once per difficulty adjustment interval
if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)
namespace {
// returns a * exp(p/q) where |p/q| is small
arith_uint256 mul_exp(arith_uint256 a, int64_t p, int64_t q)
{
if (params.fPowAllowMinDifficultyBlocks)
{
// Special difficulty rule for testnet:
// If the new block's timestamp is more than 2* 10 minutes
// then allow mining of a min-difficulty block.
if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
return nProofOfWorkLimit;
else
{
// Return the last non-special-min-difficulty-rules-block
const CBlockIndex* pindex = pindexLast;
while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
pindex = pindex->pprev;
return pindex->nBits;
bool isNegative = p < 0;
uint64_t abs_p = p >= 0 ? p : -p;
arith_uint256 result = a;
uint64_t n = 0;
while (a > 0) {
++n;
a = a * abs_p / q / n;
if (isNegative && (n % 2 == 1)) {
result -= a;
} else {
result += a;
}
}
return pindexLast->nBits;
return result;
}
}

// Go back by what we want to be 14 days worth of blocks
int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1);
assert(nHeightFirst >= 0);
const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
assert(pindexFirst);
// ppcoin: find last block index up to pindex
const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfStake)
{
//CBlockIndex will be updated with information about the proof type later
while (pindex && pindex->pprev && (pindex->IsProofOfStake() != fProofOfStake))
pindex = pindex->pprev;
return pindex;
}

return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
inline arith_uint256 GetLimit(int nHeight, const Consensus::Params& params, bool fProofOfStake)
{
if(fProofOfStake) {
if(nHeight < params.QIP9Height) {
return UintToArith256(params.posLimit);
} else if(nHeight < params.nReduceBlocktimeHeight) {
return UintToArith256(params.QIP9PosLimit);
} else {
return UintToArith256(params.RBTPosLimit);
}
} else {
return UintToArith256(params.powLimit);
}
}

unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params, bool fProofOfStake)
{
if (params.fPowNoRetargeting)

unsigned int nTargetLimit = GetLimit(pindexLast ? pindexLast->nHeight+1 : 0, params, fProofOfStake).GetCompact();

// genesis block
if (pindexLast == NULL)
return nTargetLimit;

// first block
const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake);
if (pindexPrev->pprev == NULL)
return nTargetLimit;

// second block
const CBlockIndex* pindexPrevPrev = GetLastBlockIndex(pindexPrev->pprev, fProofOfStake);
if (pindexPrevPrev->pprev == NULL)
return nTargetLimit;

// min difficulty
if (params.fPowAllowMinDifficultyBlocks)
{
// Special difficulty rule for testnet:
// If the new block's timestamp is more than 2* 10 minutes
// then allow mining of a min-difficulty block.
int nHeight = pindexLast->nHeight + 1;
if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.TargetSpacing(nHeight)*2)
return nTargetLimit;
else
{
// Return the last non-special-min-difficulty-rules-block
const CBlockIndex* pindex = pindexLast;
while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval(pindex->nHeight) != 0 && pindex->nBits == nTargetLimit)
pindex = pindex->pprev;
return pindex->nBits;
}
return pindexLast->nBits;
}

// Limit adjustment step
int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
if (nActualTimespan < params.nPowTargetTimespan/4)
nActualTimespan = params.nPowTargetTimespan/4;
if (nActualTimespan > params.nPowTargetTimespan*4)
nActualTimespan = params.nPowTargetTimespan*4;
return CalculateNextWorkRequired(pindexPrev, pindexPrevPrev->GetBlockTime(), params, fProofOfStake);
}

unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params, bool fProofOfStake)
{
if(fProofOfStake){
if (params.fPoSNoRetargeting)
return pindexLast->nBits;
}else{
if (params.fPowNoRetargeting)
return pindexLast->nBits;
}
// Limit adjustment step
int nHeight = pindexLast->nHeight + 1;
int64_t nTargetSpacing = params.TargetSpacing(nHeight);
int64_t nActualSpacing = pindexLast->GetBlockTime() - nFirstBlockTime;
// Retarget
const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
const arith_uint256 bnTargetLimit = GetLimit(nHeight, params, fProofOfStake);
// ppcoin: target change every block
// ppcoin: retarget with exponential moving toward target spacing
arith_uint256 bnNew;
bnNew.SetCompact(pindexLast->nBits);
bnNew *= nActualTimespan;
bnNew /= params.nPowTargetTimespan;

if (bnNew > bnPowLimit)
bnNew = bnPowLimit;
int64_t nInterval = params.DifficultyAdjustmentInterval(nHeight);

if (nHeight < params.QIP9Height) {
if (nActualSpacing < 0)
nActualSpacing = nTargetSpacing;
if (nActualSpacing > nTargetSpacing * 10)
nActualSpacing = nTargetSpacing * 10;
bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing);
bnNew /= ((nInterval + 1) * nTargetSpacing);
} else {
if (nActualSpacing < 0)
nActualSpacing = nTargetSpacing;
if (nActualSpacing > nTargetSpacing * 20)
nActualSpacing = nTargetSpacing * 20;
uint32_t stakeTimestampMask=params.StakeTimestampMask(nHeight);
bnNew = mul_exp(bnNew, 2 * (nActualSpacing - nTargetSpacing) / (stakeTimestampMask + 1), (nInterval + 1) * nTargetSpacing / (stakeTimestampMask + 1));
}

if (bnNew <= 0 || bnNew > bnTargetLimit)
bnNew = bnTargetLimit;
return bnNew.GetCompact();
}

// Check that on difficulty adjustments, the new difficulty does not increase
// or decrease beyond the permitted limits.
#ifdef QTUM_BUILD
bool PermittedDifficultyTransition(const Consensus::Params&, int64_t, uint32_t, uint32_t)
{
// Qtum has different difficulty adjustment algorithm than Bitcoin, so checking the borders for the new difficulty value might not be the same.
// The method is used for unit testing and to reject headers (headerssync.cpp) during synching for Bitcoin depending on the difficulty transition.
return true;
}
#else
bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t height, uint32_t old_nbits, uint32_t new_nbits)
{
if (params.fPowAllowMinDifficultyBlocks) return true;

if (height % params.DifficultyAdjustmentInterval() == 0) {
if (height % params.DifficultyAdjustmentInterval(height) == 0) {
int64_t smallest_timespan = params.nPowTargetTimespan/4;
int64_t largest_timespan = params.nPowTargetTimespan*4;

Expand Down Expand Up @@ -121,6 +197,7 @@ bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t heig
}
return true;
}
#endif

bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
{
Expand Down
5 changes: 3 additions & 2 deletions src/pow.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ class CBlockHeader;
class CBlockIndex;
class uint256;

unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&);
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&);
const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfStake);
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&, bool fProofOfStake = false);
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&, bool fProofOfStake = false);

/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);
Expand Down
2 changes: 1 addition & 1 deletion src/serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
* The maximum size of a serialized object in bytes or number of elements
* (for eg vectors) when the size is encoded as CompactSize.
*/
static constexpr uint64_t MAX_SIZE = 0x02000000;
static constexpr uint64_t MAX_SIZE = 0x10000000; // Qtum: Increase max serialized size to 256mb

/** Maximum amount of memory (in bytes) to allocate at once when deserializing vectors. */
static const unsigned int MAX_VECTOR_ALLOCATE = 5000000;
Expand Down
Loading

0 comments on commit b2bad08

Please sign in to comment.