Skip to content

Commit

Permalink
posTime
Browse files Browse the repository at this point in the history
  • Loading branch information
VizzoTopCore committed Mar 24, 2018
1 parent 3ed777f commit 464b64a
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/clientversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it
#define CLIENT_VERSION_MAJOR 1
#define CLIENT_VERSION_MINOR 0
#define CLIENT_VERSION_REVISION 3
#define CLIENT_VERSION_REVISION 4
#define CLIENT_VERSION_BUILD 0

// Set to true for release, false for prerelease or test build
Expand Down
27 changes: 15 additions & 12 deletions src/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,20 @@

#include "kernel.h"
#include "txdb.h"
#include "main.h"

using namespace std;

// Get time weight
int64_t GetWeight(int64_t nIntervalBeginning, int64_t nIntervalEnd)
int64_t GetWeight(int64_t nIntervalBeginning, int64_t nIntervalEnd, int nHeight)
{
// Kernel hash weight starts from 0 at the min age
// this change increases active coins participating the hash and helps
// to secure the network when proof-of-stake difficulty is low

return nIntervalEnd - nIntervalBeginning - nStakeMinAge;

//return nIntervalEnd - nIntervalBeginning - nStakeMinAge;
return nIntervalEnd - nIntervalBeginning - GetStakeMinAge(nHeight);

}

// Get the last stake modifier and its generation time from a given block
Expand Down Expand Up @@ -204,7 +207,7 @@ static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64_t& nStakeModifi
{
if (!pindex->pnext)
{ // reached best block; may happen if node is behind on block chain
if (fPrintProofOfStake || (pindex->GetBlockTime() + nStakeMinAge - nStakeModifierSelectionInterval > GetAdjustedTime()))
if (fPrintProofOfStake || (pindex->GetBlockTime() + GetStakeMinAge(nStakeModifierHeight) - nStakeModifierSelectionInterval > GetAdjustedTime()))
return error("GetKernelStakeModifier() : reached best block %s at height %d from block %s",
pindex->GetBlockHash().ToString(), pindex->nHeight, hashBlockFrom.ToString());
else
Expand Down Expand Up @@ -242,13 +245,13 @@ static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64_t& nStakeModifi
// quantities so as to generate blocks faster, degrading the system back into
// a proof-of-work situation.
//
static bool CheckStakeKernelHashV1(unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool fPrintProofOfStake)
static bool CheckStakeKernelHashV1(unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool fPrintProofOfStake, int nHeight)
{
if (nTimeTx < txPrev.nTime) // Transaction timestamp violation
return error("CheckStakeKernelHash() : nTime violation");

unsigned int nTimeBlockFrom = blockFrom.GetBlockTime();
if (nTimeBlockFrom + nStakeMinAge > nTimeTx) // Min age requirement
if (nTimeBlockFrom + GetStakeMinAge(nHeight) > nTimeTx) // Min age requirement
return error("CheckStakeKernelHash() : min age violation");

CBigNum bnTargetPerCoinDay;
Expand All @@ -257,7 +260,7 @@ static bool CheckStakeKernelHashV1(unsigned int nBits, const CBlock& blockFrom,

uint256 hashBlockFrom = blockFrom.GetHash();

CBigNum bnCoinDayWeight = CBigNum(nValueIn) * GetWeight((int64_t)txPrev.nTime, (int64_t)nTimeTx) / COIN / (24 * 60 * 60);
CBigNum bnCoinDayWeight = CBigNum(nValueIn) * GetWeight((int64_t)txPrev.nTime, (int64_t)nTimeTx, nHeight) / COIN / (24 * 60 * 60);
targetProofOfStake = (bnCoinDayWeight * bnTargetPerCoinDay).getuint256();

// Calculate hash
Expand Down Expand Up @@ -324,12 +327,12 @@ static bool CheckStakeKernelHashV1(unsigned int nBits, const CBlock& blockFrom,
// quantities so as to generate blocks faster, degrading the system back into
// a proof-of-work situation.
//
static bool CheckStakeKernelHashV2(CBlockIndex* pindexPrev, unsigned int nBits, unsigned int nTimeBlockFrom, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool fPrintProofOfStake)
static bool CheckStakeKernelHashV2(CBlockIndex* pindexPrev, unsigned int nBits, unsigned int nTimeBlockFrom, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool fPrintProofOfStake, int nHeight)
{
if (nTimeTx < txPrev.nTime) // Transaction timestamp violation
return error("CheckStakeKernelHash() : nTime violation");

if (nTimeBlockFrom + nStakeMinAge > nTimeTx) // Min age requirement
if (nTimeBlockFrom + GetStakeMinAge(nHeight) > nTimeTx) // Min age requirement
return error("CheckStakeKernelHash() : min age violation");

// Base target
Expand Down Expand Up @@ -386,9 +389,9 @@ static bool CheckStakeKernelHashV2(CBlockIndex* pindexPrev, unsigned int nBits,
bool CheckStakeKernelHash(CBlockIndex* pindexPrev, unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool fPrintProofOfStake)
{
if (IsProtocolV2(pindexPrev->nHeight+1))
return CheckStakeKernelHashV2(pindexPrev, nBits, blockFrom.GetBlockTime(), txPrev, prevout, nTimeTx, hashProofOfStake, targetProofOfStake, fPrintProofOfStake);
return CheckStakeKernelHashV2(pindexPrev, nBits, blockFrom.GetBlockTime(), txPrev, prevout, nTimeTx, hashProofOfStake, targetProofOfStake, fPrintProofOfStake, pindexPrev->nHeight+1);
else
return CheckStakeKernelHashV1(nBits, blockFrom, nTxPrevOffset, txPrev, prevout, nTimeTx, hashProofOfStake, targetProofOfStake, fPrintProofOfStake);
return CheckStakeKernelHashV1(nBits, blockFrom, nTxPrevOffset, txPrev, prevout, nTimeTx, hashProofOfStake, targetProofOfStake, fPrintProofOfStake, pindexPrev->nHeight+1);
}

// Check kernel hash target and coinstake signature
Expand Down Expand Up @@ -446,7 +449,7 @@ bool CheckKernel(CBlockIndex* pindexPrev, unsigned int nBits, int64_t nTime, con
if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
return false;

if (block.GetBlockTime() + nStakeMinAge > nTime)
if (block.GetBlockTime() + GetStakeMinAge(pindexPrev->nHeight+1) > nTime)
return false; // only count coins meeting min age requirement

if (pBlockTime)
Expand Down
2 changes: 1 addition & 1 deletion src/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ bool CheckProofOfStake(CBlockIndex* pindexPrev, const CTransaction& tx, unsigned
bool CheckCoinStakeTimestamp(int nHeight, int64_t nTimeBlock, int64_t nTimeTx);

// Get time weight using supplied timestamps
int64_t GetWeight(int64_t nIntervalBeginning, int64_t nIntervalEnd);
int64_t GetWeight(int64_t nIntervalBeginning, int64_t nIntervalEnd, int nHeight);

// Wrapper around CheckStakeKernelHash()
// Also checks existence of kernel input and min age
Expand Down
91 changes: 87 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,31 @@ set<pair<COutPoint, unsigned int> > setStakeSeen;
CBigNum bnProofOfStakeLimit(~uint256(0) >> 20);
CBigNum bnProofOfStakeLimitV2(~uint256(0) >> 34);

unsigned int nStakeMinAge = 60 * 60; // 1 hours

static unsigned int nStakeMinAgeV1 = 60 * 60; // 1 hours
static unsigned int nStakeMinAgeV2 = 8 * 60 * 60; // 8 hours after block 11,000

unsigned int nModifierInterval = 10 * 60; // time to elapse before new modifier is computed
const int targetReadjustment_forkBlockHeight = 11000; //retargeting since 11,000 block

bool IsProtocolMaturityV2(int nHeight)
{
return(nHeight >= targetReadjustment_forkBlockHeight);
}

unsigned int GetStakeMinAge(int nHeight)
{
if(IsProtocolMaturityV2(nHeight))
return nStakeMinAgeV2;
else
return nStakeMinAgeV1;
}

int GetMinPeerProtoVersion(int nHeight)
{
return(IsProtocolMaturityV2(nHeight)? NEW_PROTOCOL_VERSION : MIN_PEER_PROTO_VERSION);
}


int nCoinbaseMaturity = 15; //15
CBlockIndex* pindexGenesisBlock = NULL;
Expand Down Expand Up @@ -1226,10 +1249,63 @@ const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfSta
return pindex;
}



int nTargetSpacing = 60; //60s

unsigned int GetNextTargetRequiredV2(const CBlockIndex* pindexLast, bool fProofOfStake)
{
CBigNum bnTargetLimit = fProofOfStake ? GetProofOfStakeLimit(pindexLast->nHeight) : Params().ProofOfWorkLimit();

if (pindexLast == NULL)
return bnTargetLimit.GetCompact(); // genesis block

const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake);
if (pindexPrev->pprev == NULL)
return bnTargetLimit.GetCompact(); // first block
const CBlockIndex* pindexPrevPrev = GetLastBlockIndex(pindexPrev->pprev, fProofOfStake);
if (pindexPrevPrev->pprev == NULL)
return bnTargetLimit.GetCompact(); // second block

int64_t nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime();

if (nActualSpacing < 0) {
LogPrintf("Warning: spacing between blocks is negative. Resetting to target spacing.\n");
nActualSpacing = nTargetSpacing;
} else if (nActualSpacing < 1 && pindexLast->nHeight >= targetReadjustment_forkBlockHeight) {
// For a smooth transition to the new readjustment algorithm set actual spacing close to TARGET_SPACING for 100 blocks.
nActualSpacing = nTargetSpacing - 10;
} else if (nActualSpacing < 1 && pindexLast->nHeight >= (targetReadjustment_forkBlockHeight + 100)) {
nActualSpacing = 1;
}

// ppcoin: target change every block
// ppcoin: retarget with exponential moving toward target spacing
CBigNum bnNew;
bnNew.SetCompact(pindexPrev->nBits);
int64_t nInterval = 5; // Average over 5 blocks

if (pindexLast->nHeight < targetReadjustment_forkBlockHeight) {
// Allow different difficulty in old blocks before the fork.
nInterval = 1;
}

bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing);
bnNew /= ((nInterval + 1) * nTargetSpacing);

if (bnNew <= 0 || bnNew > bnTargetLimit) {
LogPrintf("Warning: new difficulty target out of range. Resetting to minimum difficulty.\n");
bnNew = bnTargetLimit;
}

return bnNew.GetCompact();
}

unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake)
{
if(IsProtocolMaturityV2(pindexLast->nHeight+1))
return GetNextTargetRequiredV2(pindexLast,fProofOfStake);

CBigNum bnTargetLimit = fProofOfStake ? GetProofOfStakeLimit(pindexLast->nHeight) : Params().ProofOfWorkLimit();

if (pindexLast == NULL)
Expand Down Expand Up @@ -1260,6 +1336,7 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS
return bnNew.GetCompact();
}


bool CheckProofOfWork(uint256 hash, unsigned int nBits)
{
CBigNum bnTarget;
Expand Down Expand Up @@ -2200,7 +2277,13 @@ bool CTransaction::GetCoinAge(CTxDB& txdb, uint64_t& nCoinAge) const
CBlock block;
if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
return false; // unable to read block of previous transaction
if (block.GetBlockTime() + nStakeMinAge > nTime)

CBlockLocator locator(block.GetHash());
int nHeight = locator.GetHeight();

assert(nHeight);

if (block.GetBlockTime() + GetStakeMinAge(nHeight) > nTime)
continue; // only count coins meeting min age requirement

int64_t nValueIn = txPrev.vout[txin.prevout.n].nValue;
Expand Down Expand Up @@ -2873,7 +2956,7 @@ bool LoadBlockIndex(bool fAllowNew)

if (TestNet())
{
nStakeMinAge = 1 * 60 * 60; // test net min age is 1 hour
nStakeMinAgeV1 = 1 * 60 * 60; // test net min age is 1 hour
nCoinbaseMaturity = 10; // test maturity is 10 blocks
}

Expand Down Expand Up @@ -3332,7 +3415,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CAddress addrFrom;
uint64_t nNonce = 1;
vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
if (pfrom->nVersion < MIN_PEER_PROTO_VERSION)
if (pfrom->nVersion < GetMinPeerProtoVersion(nBestHeight))
{
// disconnect from peers older than this proto version
LogPrintf("partner %s using obsolete version %i; disconnecting\n", pfrom->addr.ToString(), pfrom->nVersion);
Expand Down
3 changes: 3 additions & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20
inline bool IsProtocolV1RetargetingFixed(int nHeight) { return TestNet() || nHeight > 0; }
inline bool IsProtocolV2(int nHeight) { return TestNet() || nHeight > 0; }

bool IsProtocolMaturityV2(int nHeight);
unsigned int GetStakeMinAge(int nHeight);

inline int64_t FutureDriftV1(int64_t nTime) { return nTime + 10 * 60; }
inline int64_t FutureDriftV2(int64_t nTime) { return nTime + 10 * 60; }
inline int64_t FutureDrift(int64_t nTime, int nHeight) { return IsProtocolV2(nHeight) ? FutureDriftV2(nTime) : FutureDriftV1(nTime); }
Expand Down
5 changes: 3 additions & 2 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ using namespace std;
using namespace boost;

static const int MAX_OUTBOUND_CONNECTIONS = 76;
int GetMinPeerProtoVersion(int nHeight);

bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);

Expand Down Expand Up @@ -445,8 +446,8 @@ void CNode::PushVersion()
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
CAddress addrMe = GetLocalAddress(&addr);
RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), addr.ToString());
PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", GetMinPeerProtoVersion(nBestHeight), nBestHeight, addrMe.ToString(), addrYou.ToString(), addr.ToString());
PushMessage("version", GetMinPeerProtoVersion(nBestHeight), nLocalServices, nTime, addrYou, addrMe,
nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
}

Expand Down
5 changes: 3 additions & 2 deletions src/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ static const int DATABASE_VERSION = 71500;
// network protocol versioning
//

static const int PROTOCOL_VERSION = 69110;
static const int NEW_PROTOCOL_VERSION = 69120; //new version with modified maturity time and retargeting
static const int PROTOCOL_VERSION = 69110; //new version with modified maturity time and retargeting

// intial proto version, to be increased after version/verack negotiation
static const int INIT_PROTO_VERSION = 209;

// disconnect from peers older than this proto version
static const int MIN_PEER_PROTO_VERSION = 69100;
static const int MIN_PEER_PROTO_VERSION = 69110;

static const int MIN_INSTANTX_PROTO_VERSION = 69100;

Expand Down
8 changes: 4 additions & 4 deletions src/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1541,7 +1541,7 @@ void CWallet::AvailableCoinsForStaking(vector<COutput>& vCoins, unsigned int nSp
const CWalletTx* pcoin = &(*it).second;

// Filtering by tx timestamp instead of block timestamp may give false positives but never false negatives
if (pcoin->nTime + nStakeMinAge > nSpendTime)
if (pcoin->nTime + GetStakeMinAge(nBestHeight) > nSpendTime)
continue;

if (pcoin->GetBlocksToMaturity() > 0)
Expand Down Expand Up @@ -3346,7 +3346,7 @@ uint64_t CWallet::GetStakeWeight() const
if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex))
continue;

if (nCurrentTime - pcoin.first->nTime > nStakeMinAge)
if (nCurrentTime - pcoin.first->nTime > GetStakeMinAge(nBestHeight))
nWeight += pcoin.first->vout[pcoin.second].nValue;
}

Expand Down Expand Up @@ -3474,7 +3474,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
if (txNew.vout.size() == 2 && ((pcoin.first->vout[pcoin.second].scriptPubKey == scriptPubKeyKernel || pcoin.first->vout[pcoin.second].scriptPubKey == txNew.vout[1].scriptPubKey))
&& pcoin.first->GetHash() != txNew.vin[0].prevout.hash)
{
int64_t nTimeWeight = GetWeight((int64_t)pcoin.first->nTime, (int64_t)txNew.nTime);
int64_t nTimeWeight = GetWeight((int64_t)pcoin.first->nTime, (int64_t)txNew.nTime, nBestHeight);

// Stop adding more inputs if already too many inputs
if (txNew.vin.size() >= 100)
Expand All @@ -3489,7 +3489,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
if (pcoin.first->vout[pcoin.second].nValue >= GetStakeCombineThreshold())
continue;
// Do not add input that is still too young
if (nTimeWeight < nStakeMinAge)
if (nTimeWeight < GetStakeMinAge(nBestHeight))
continue;

txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second));
Expand Down

0 comments on commit 464b64a

Please sign in to comment.