Skip to content

Commit 7fe0dae

Browse files
authored
New diff algo (#147)
* Added new difficulty algorithm based on exponential difficulty retargeting * Added hardfork conditions. Fixed issue with signmessage and tposcontract cleanup * Reverted difficulty changes. Implementing PoSV3 stake modifiers * Fixes to hardfork transition * Reverted testing changes. Changed where pos block is checked * Changed upgrage height. Reverted some old changes * Updated hf details * Updated version * Changed hf payments * Changed hardfork date
1 parent 43ed8dd commit 7fe0dae

File tree

15 files changed

+227
-91
lines changed

15 files changed

+227
-91
lines changed

configure.ac

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
22
AC_PREREQ([2.60])
33
define(_CLIENT_VERSION_MAJOR, 1)
44
define(_CLIENT_VERSION_MINOR, 0)
5-
define(_CLIENT_VERSION_REVISION, 20)
5+
define(_CLIENT_VERSION_REVISION, 21)
66
define(_CLIENT_VERSION_BUILD, 0)
77
define(_CLIENT_VERSION_IS_RELEASE, true)
8-
define(_COPYRIGHT_YEAR, 2018)
8+
define(_COPYRIGHT_YEAR, 2019)
99
define(_COPYRIGHT_HOLDERS,[The %s developers])
1010
define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[XSN Core]])
1111
AC_INIT([XSN Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/xsn/xsn/issues],[xsn],[https://xsncore.org/])

src/chain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ arith_uint256 CBlockIndex::GetBlockTrust() const
193193
if (bnTarget <= 0)
194194
return 0;
195195

196-
if (IsProofOfStake()) {
196+
if (IsProofOfStake(false)) {
197197
// Return trust score as usual
198198
return (arith_uint256(1) << 256) / (bnTarget + 1);
199199
} else {

src/chain.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,12 @@ class CBlockIndex
215215
BLOCK_PROOF_OF_STAKE = (1 << 0), // is proof-of-stake block
216216
BLOCK_STAKE_ENTROPY = (1 << 1), // entropy bit for stake modifier
217217
BLOCK_STAKE_MODIFIER = (1 << 2), // regenerated stake modifier
218+
BLOCK_PROOF_OF_STAKE_V3 = (1 << 3),
218219
};
219220

220221
// proof-of-stake specific fields
221222
arith_uint256 GetBlockTrust() const;
223+
uint256 hashStakeModifierV3; // hash modifier for PoS v3.
222224
uint64_t nStakeModifier; // hash modifier for proof-of-stake
223225
unsigned int nStakeModifierChecksum; // checksum of index; in-memeory only
224226
COutPoint prevoutStake;
@@ -259,6 +261,7 @@ class CBlockIndex
259261
nMint = 0;
260262
nMoneySupply = 0;
261263
nFlags = 0;
264+
hashStakeModifierV3.SetNull();
262265
nStakeModifier = 0;
263266
nStakeModifierChecksum = 0;
264267
prevoutStake.SetNull();
@@ -296,7 +299,7 @@ class CBlockIndex
296299
hashProofOfStake = uint256();
297300

298301
if (block.IsProofOfStake()) {
299-
SetProofOfStake();
302+
SetProofOfStake(false);
300303
prevoutStake = block.vtx[1]->vin[0].prevout;
301304
nStakeTime = block.nTime;
302305
} else {
@@ -372,14 +375,22 @@ class CBlockIndex
372375
return !(nFlags & BLOCK_PROOF_OF_STAKE);
373376
}
374377

375-
bool IsProofOfStake() const
378+
bool IsProofOfStake(bool isProofOfStakeV3) const
376379
{
380+
if(isProofOfStakeV3) {
381+
return (nFlags & BLOCK_PROOF_OF_STAKE_V3);
382+
}
383+
377384
return (nFlags & BLOCK_PROOF_OF_STAKE);
378385
}
379386

380-
void SetProofOfStake()
387+
void SetProofOfStake(bool isProofOfStakeV3)
381388
{
382389
nFlags |= BLOCK_PROOF_OF_STAKE;
390+
if(isProofOfStakeV3)
391+
{
392+
nFlags |= BLOCK_PROOF_OF_STAKE_V3;
393+
}
383394
}
384395

385396
unsigned int GetStakeEntropyBit() const;
@@ -484,10 +495,15 @@ class CDiskBlockIndex : public CBlockIndex
484495
READWRITE(nMoneySupply);
485496
READWRITE(nFlags);
486497
READWRITE(nStakeModifier);
487-
if (IsProofOfStake()) {
498+
if (IsProofOfStake(false)) {
488499
READWRITE(prevoutStake);
489500
READWRITE(nStakeTime);
490501
READWRITE(hashProofOfStake);
502+
503+
if(IsProofOfStake(true)) {
504+
READWRITE(hashStakeModifierV3);
505+
}
506+
491507
} else {
492508
const_cast<CDiskBlockIndex*>(this)->prevoutStake.SetNull();
493509
const_cast<CDiskBlockIndex*>(this)->nStakeTime = 0;

src/chainparams.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class CMainParams : public CChainParams {
9898
consensus.nPowTargetSpacing = 1 * 60; // XSN: 1 minutes
9999
consensus.nPosTargetSpacing = 1 * 60; // XSN: 1 minutes
100100
consensus.nPosTargetTimespan = 60 * 40;
101+
consensus.nPoSUpdgradeHFHeight = 898488; // 1st of January 2019
101102
consensus.nMerchantnodeMinimumConfirmations = 1;
102103
consensus.nMasternodeMinimumConfirmations = 15;
103104
consensus.nStakeMinAge = 60 * 60;

src/consensus/params.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ struct Params {
100100
int nCoinbaseMaturity;
101101
int nTPoSContractSignatureDeploymentTime;
102102
int nMaxBlockSpacingFixDeploymentHeight;
103+
int nPoSUpdgradeHFHeight;
103104
};
104105
} // namespace Consensus
105106

src/kernel.cpp

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,14 @@ static bool SelectBlockFromCandidates(
101101
continue;
102102
// compute the selection hash by hashing its proof-hash and the
103103
// previous proof-of-stake modifier
104-
uint256 hashProof = pindex->IsProofOfStake()? pindex->hashProofOfStake : pindex->GetBlockHash();
104+
uint256 hashProof = pindex->IsProofOfStake(false) ? pindex->hashProofOfStake : pindex->GetBlockHash();
105105
CDataStream ss(SER_GETHASH, 0);
106106
ss << hashProof << nStakeModifierPrev;
107107
arith_uint256 hashSelection = UintToArith256(Hash(ss.begin(), ss.end()));
108108
// the selection hash is divided by 2**32 so that proof-of-stake block
109109
// is always favored over proof-of-work block. this is to preserve
110110
// the energy efficiency property
111-
if (pindex->IsProofOfStake())
111+
if (pindex->IsProofOfStake(false))
112112
hashSelection >>= 32;
113113
if (fSelected && hashSelection < hashBest)
114114
{
@@ -127,6 +127,22 @@ static bool SelectBlockFromCandidates(
127127
return fSelected;
128128
}
129129

130+
// Stake Modifier (hash modifier of proof-of-stake):
131+
// The purpose of stake modifier is to prevent a txout (coin) owner from
132+
// computing future proof-of-stake generated by this txout at the time
133+
// of transaction confirmation. To meet kernel protocol, the txout
134+
// must hash with a future stake modifier to generate the proof.
135+
uint256 ComputeStakeModifierV3(const CBlockIndex* pindexPrev, const uint256& kernel)
136+
{
137+
if (!pindexPrev)
138+
return uint256(); // genesis block's modifier is 0
139+
140+
CDataStream ss(SER_GETHASH, 0);
141+
ss << kernel << pindexPrev->hashStakeModifierV3;
142+
return Hash(ss.begin(), ss.end());
143+
}
144+
145+
130146
// Stake Modifier (hash modifier of proof-of-stake):
131147
// The purpose of stake modifier is to prevent a txout (coin) owner from
132148
// computing future proof-of-stake generated by this txout at the time
@@ -217,15 +233,15 @@ bool ComputeNextStakeModifier(const CBlockIndex* pindexCurrent, uint64_t& nStake
217233
while (pindex && pindex->nHeight >= nHeightFirstCandidate)
218234
{
219235
// '=' indicates proof-of-stake blocks not selected
220-
if (pindex->IsProofOfStake())
236+
if (pindex->IsProofOfStake(false))
221237
strSelectionMap.replace(pindex->nHeight - nHeightFirstCandidate, 1, "=");
222238
pindex = pindex->pprev;
223239
}
224240
for(const auto& item : mapSelectedBlocks)
225241
{
226242
// 'S' indicates selected proof-of-stake blocks
227243
// 'W' indicates selected proof-of-work blocks
228-
strSelectionMap.replace(item.second->nHeight - nHeightFirstCandidate, 1, item.second->IsProofOfStake()? "S" : "W");
244+
strSelectionMap.replace(item.second->nHeight - nHeightFirstCandidate, 1, item.second->IsProofOfStake(false) ? "S" : "W");
229245
}
230246
LogPrint(BCLog::KERNEL, "%s : selection height [%d, %d] map %s\n", __func__, nHeightFirstCandidate, pindexPrev->nHeight, strSelectionMap.c_str());
231247
}
@@ -368,16 +384,18 @@ uint256 stakeHash(unsigned int nTimeTx, CDataStream ss, unsigned int prevoutInde
368384
// quantities so as to generate blocks faster, degrading the system back into
369385
// a proof-of-work situation.
370386
//
371-
bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransactionRef& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, bool fPrintProofOfStake)
387+
bool CheckStakeKernelHash(const CBlockIndex* pindexPrev, unsigned int nBits, uint256 hashBlockFrom, int64_t blockFromTime,
388+
const CTransactionRef& txPrev, const COutPoint& prevout, unsigned int nTimeTx,
389+
uint256& hashProofOfStake, bool fPoSV3, bool fPrintProofOfStake)
372390
{
373-
nTxPrevOffset = 336;
374-
auto txPrevTime = blockFrom.GetBlockTime();
391+
auto nTxPrevOffset = 336;
392+
auto txPrevTime = blockFromTime;
393+
unsigned int nTimeBlockFrom = blockFromTime;
375394
if (nTimeTx < txPrevTime) // Transaction timestamp violation
376395
return error("CheckStakeKernelHash() : nTime violation");
377396

378397
auto nStakeMinAge = Params().GetConsensus().nStakeMinAge;
379398
auto nStakeMaxAge = Params().GetConsensus().nStakeMaxAge;
380-
unsigned int nTimeBlockFrom = blockFrom.GetBlockTime();
381399
if (nTimeBlockFrom + nStakeMinAge > nTimeTx) // Min age requirement
382400
return error("CheckStakeKernelHash() : min age violation");
383401

@@ -396,10 +414,16 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned
396414
int nStakeModifierHeight = 0;
397415
int64_t nStakeModifierTime = 0;
398416

399-
if (!GetKernelStakeModifier(blockFrom.GetHash(), nTimeTx, nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake))
400-
return error("Failed to get kernel stake modifier");
417+
if(fPoSV3) {
418+
ss << pindexPrev->hashStakeModifierV3;
419+
}
420+
else {
421+
422+
if (!GetKernelStakeModifier(hashBlockFrom, nTimeTx, nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake))
423+
return error("Failed to get kernel stake modifier");
401424

402-
ss << nStakeModifier;
425+
ss << nStakeModifier;
426+
}
403427

404428
ss << nTimeBlockFrom << nTxPrevOffset << txPrevTime << prevout.n << nTimeTx;
405429
hashProofOfStake = Hash(ss.begin(), ss.end());
@@ -409,14 +433,14 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned
409433
__func__,
410434
nStakeModifier, nStakeModifierHeight,
411435
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nStakeModifierTime).c_str(),
412-
mapBlockIndex[blockFrom.GetHash()]->nHeight,
413-
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", blockFrom.GetBlockTime()).c_str());
436+
mapBlockIndex[hashBlockFrom]->nHeight,
437+
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", blockFromTime).c_str());
414438

415439
LogPrint(BCLog::KERNEL, "%s : check protocol=%s modifier=0x%016" PRI64x" nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n",
416440
__func__,
417441
"0.5",
418442
nStakeModifier,
419-
nTimeBlockFrom, nTxPrevOffset,
443+
blockFromTime, nTxPrevOffset,
420444
txPrevTime, prevout.n, nTimeTx,
421445
hashProofOfStake.ToString().c_str());
422446
}
@@ -431,13 +455,14 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned
431455
__func__,
432456
nStakeModifier, nStakeModifierHeight,
433457
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nStakeModifierTime).c_str(),
434-
mapBlockIndex[blockFrom.GetHash()]->nHeight,
435-
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", blockFrom.GetBlockTime()).c_str());
458+
mapBlockIndex[hashBlockFrom]->nHeight,
459+
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", blockFromTime).c_str());
460+
436461
LogPrint(BCLog::KERNEL, "%s : Generated pass protocol=%s modifier=0x%016" PRI64x" nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n",
437462
__func__,
438463
"0.5",
439464
nStakeModifier,
440-
nTimeBlockFrom, nTxPrevOffset, txPrevTime, prevout.n, nTimeTx,
465+
blockFromTime, nTxPrevOffset, txPrevTime, prevout.n, nTimeTx,
441466
hashProofOfStake.ToString().c_str());
442467
}
443468
return true;
@@ -470,7 +495,7 @@ bool CheckKernelScript(CScript scriptVin, CScript scriptVout)
470495
}
471496

472497
// Check kernel hash target and coinstake signature
473-
bool CheckProofOfStake(const CBlock &block, uint256& hashProofOfStake)
498+
bool CheckProofOfStake(const CBlockIndex *pindexPrev, const CBlock &block, uint256& hashProofOfStake, const Consensus::Params &params)
474499
{
475500
const CTransactionRef &tx = block.vtx[1];
476501
if (!tx->IsCoinStake())
@@ -483,9 +508,7 @@ bool CheckProofOfStake(const CBlock &block, uint256& hashProofOfStake)
483508
uint256 hashBlock;
484509
CTransactionRef txPrev;
485510

486-
const auto &cons = Params().GetConsensus();
487-
488-
if (!GetTransaction(txin.prevout.hash, txPrev, cons, hashBlock, true))
511+
if (!GetTransaction(txin.prevout.hash, txPrev, params, hashBlock, true))
489512
return error("CheckProofOfStake() : INFO: read txPrev failed");
490513

491514
CTxOut prevTxOut = txPrev->vout[txin.prevout.n];
@@ -498,7 +521,7 @@ bool CheckProofOfStake(const CBlock &block, uint256& hashProofOfStake)
498521
return error("CheckProofOfStake() : VerifySignature failed on coinstake %s", tx->GetHash().ToString().c_str());
499522
}
500523

501-
CBlockIndex* pindex = NULL;
524+
CBlockIndex* pindex = nullptr;
502525
BlockMap::iterator it = mapBlockIndex.find(hashBlock);
503526
if (it != mapBlockIndex.end())
504527
pindex = it->second;
@@ -507,14 +530,16 @@ bool CheckProofOfStake(const CBlock &block, uint256& hashProofOfStake)
507530

508531
// Read block header
509532
CBlock blockprev;
510-
if (!ReadBlockFromDisk(blockprev, pindex->GetBlockPos(), cons))
533+
if (!ReadBlockFromDisk(blockprev, pindex->GetBlockPos(), params))
511534
return error("CheckProofOfStake(): INFO: failed to find block");
512535

513536
if(!CheckKernelScript(prevTxOut.scriptPubKey, tx->vout[1].scriptPubKey))
514537
return error("CheckProofOfStake() : INFO: check kernel script failed on coinstake %s, hashProof=%s \n", tx->GetHash().ToString().c_str(), hashProofOfStake.ToString().c_str());
515538

539+
bool isProofOfStakeV3 = params.nPoSUpdgradeHFHeight < pindexPrev->nHeight;
540+
516541
unsigned int nTime = block.nTime;
517-
if (!CheckStakeKernelHash(block.nBits, blockprev, /*postx->nTxOffset + */sizeof(CBlock), txPrev, txin.prevout, nTime, hashProofOfStake, true))
542+
if (!CheckStakeKernelHash(pindexPrev, block.nBits, blockprev.GetHash(), blockprev.GetBlockTime(), txPrev, txin.prevout, nTime, hashProofOfStake, isProofOfStakeV3, true))
518543
return error("CheckProofOfStake() : INFO: check kernel failed on coinstake %s, hashProof=%s \n", tx->GetHash().ToString().c_str(), hashProofOfStake.ToString().c_str()); // may occur during initial download or if behind on block chain sync
519544

520545
return true;
@@ -547,3 +572,4 @@ bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierCheck
547572
return nStakeModifierChecksum == mapStakeModifierCheckpoints[nHeight];
548573
return true;
549574
}
575+

src/kernel.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
#include <arith_uint256.h>
1010
#include <primitives/transaction.h>
1111

12+
namespace Consensus {
13+
struct Params;
14+
}
15+
1216
class CBlock;
1317
class CWallet;
1418
class COutPoint;
@@ -24,18 +28,18 @@ extern unsigned int getIntervalVersion(bool fTestNet);
2428
// ratio of group interval length between the last group and the first group
2529
static const int MODIFIER_INTERVAL_RATIO = 3;
2630

27-
// Compute the hash modifier for proof-of-stake
28-
bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeModifier, bool& fGeneratedStakeModifier);
31+
uint256 ComputeStakeModifierV3(const CBlockIndex* pindexPrev, const uint256& kernel);
32+
bool ComputeNextStakeModifier(const CBlockIndex* pindexCurrent, uint64_t& nStakeModifier, bool& fGeneratedStakeModifier);
2933

3034
// Check whether stake kernel meets hash target
3135
// Sets hashProofOfStake on success return
32-
bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset,
33-
const CTransactionRef& txPrev, const COutPoint& prevout, unsigned int nTimeTx,
34-
uint256& hashProofOfStake, bool fPrintProofOfStake = false);
36+
bool CheckStakeKernelHash(const CBlockIndex *pindexPrev, unsigned int nBits, uint256 hashBlockFrom, int64_t blockFromTime, const CTransactionRef& txPrev,
37+
const COutPoint& prevout, unsigned int nTimeTx,
38+
uint256& hashProofOfStake, bool fPoSV3, bool fPrintProofOfStake);
3539

3640
// Check kernel hash target and coinstake signature
3741
// Sets hashProofOfStake on success return
38-
bool CheckProofOfStake(const CBlock &block, uint256& hashProofOfStake);
42+
bool CheckProofOfStake(const CBlockIndex *pindexPrev, const CBlock &block, uint256& hashProofOfStake, const Consensus::Params &params);
3943

4044
// Check whether the coinstake timestamp meets protocol
4145
bool CheckCoinStakeTimestamp(int64_t nTimeBlock, int64_t nTimeTx);

0 commit comments

Comments
 (0)