Skip to content

Commit

Permalink
v1.2.0.1 (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
MotoAcidic committed Jan 27, 2019
1 parent 1b8853c commit ba1d51e
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 59 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Expand Up @@ -3,7 +3,7 @@ AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 1)
define(_CLIENT_VERSION_MINOR, 2)
define(_CLIENT_VERSION_REVISION, 0)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_BUILD, 1)

define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2018)
Expand Down
2 changes: 1 addition & 1 deletion src/clientversion.h
Expand Up @@ -20,7 +20,7 @@
#define CLIENT_VERSION_MAJOR 1
#define CLIENT_VERSION_MINOR 2
#define CLIENT_VERSION_REVISION 0
#define CLIENT_VERSION_BUILD 0
#define CLIENT_VERSION_BUILD 1

//! Set to true for release, false for prerelease or test build
#define CLIENT_VERSION_IS_RELEASE true
Expand Down
122 changes: 65 additions & 57 deletions src/main.cpp
Expand Up @@ -2959,6 +2959,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
coins->vout.resize(out.n + 1);
coins->vout[out.n] = undo.txout;

if (ActiveProtocol() >= FAKE_STAKE_VERSION)
// erase the spent input
mapStakeSpent.erase(out);
}
Expand Down Expand Up @@ -3437,22 +3438,27 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
return state.Abort("Failed to write transaction index");


// add new entries
for (const CTransaction tx : block.vtx) {
if (tx.IsCoinBase() || tx.IsZerocoinSpend())
continue;
for (const CTxIn in : tx.vin) {
mapStakeSpent.insert(std::make_pair(in.prevout, pindex->nHeight));
}
}

// delete old entries
for (auto it = mapStakeSpent.begin(); it != mapStakeSpent.end(); ++it) {
if (it->second < pindex->nHeight - Params().MaxReorganizationDepth()) {
mapStakeSpent.erase(it->first);
}
}
if (ActiveProtocol() >= FAKE_STAKE_VERSION) {
// add new entries
for (const CTransaction tx : block.vtx) {
if (tx.IsCoinBase())
continue;
for (const CTxIn in : tx.vin) {
LogPrint("map", "mapStakeSpent: Insert %s | %u\n", in.prevout.ToString(), pindex->nHeight);
mapStakeSpent.insert(std::make_pair(in.prevout, pindex->nHeight));
}
}

// delete old entries
for (auto it = mapStakeSpent.begin(); it != mapStakeSpent.end();) {
if (it->second < pindex->nHeight - Params().MaxReorganizationDepth()) {
LogPrint("map", "mapStakeSpent: Erase %s | %u\n", it->first.ToString(), it->second);
it = mapStakeSpent.erase(it);
} else {
it++;
}
}
}

// add this block to the view's block chain
view.SetBestBlock(pindex->GetBlockHash());
Expand Down Expand Up @@ -4618,53 +4624,55 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,

int nHeight = pindex->nHeight;

if (block.IsProofOfStake()) {
LOCK(cs_main);
if (ActiveProtocol() >= FAKE_STAKE_VERSION) {
if (block.IsProofOfStake()) {
LOCK(cs_main);

CCoinsViewCache coins(pcoinsTip);
CCoinsViewCache coins(pcoinsTip);

if (!coins.HaveInputs(block.vtx[1])) {
// the inputs are spent at the chain tip so we should look at the recently spent outputs
if (!coins.HaveInputs(block.vtx[1])) {
// the inputs are spent at the chain tip so we should look at the recently spent outputs

for (CTxIn in : block.vtx[1].vin) {
auto it = mapStakeSpent.find(in.prevout);
if (it == mapStakeSpent.end()) {
return false;
}
if (it->second <= pindexPrev->nHeight) {
return false;
}
}
}
for (CTxIn in : block.vtx[1].vin) {
auto it = mapStakeSpent.find(in.prevout);
if (it == mapStakeSpent.end()) {
return false;
}
if (it->second <= pindexPrev->nHeight) {
return false;
}
}
}

// if this is on a fork
if (!chainActive.Contains(pindexPrev)) {
// start at the block we're adding on to
CBlockIndex *last = pindexPrev;

// while that block is not on the main chain
while (!chainActive.Contains(last)) {
CBlock bl;
ReadBlockFromDisk(bl, last);
// loop through every spent input from said block
for (CTransaction t : bl.vtx) {
for (CTxIn in : t.vin) {
// loop through every spent input in the staking transaction of the new block
for (CTxIn stakeIn : block.vtx[1].vin) {
// if they spend the same input
if (stakeIn.prevout == in.prevout) {
// reject the block
return false;
}
}
}
}
// if this is on a fork
if (!chainActive.Contains(pindexPrev) && pindexPrev != NULL) {
// start at the block we're adding on to
CBlockIndex* last = pindexPrev;

//while that block is not on the main chain
while (!chainActive.Contains(last) && pindexPrev != NULL) {
CBlock bl;
ReadBlockFromDisk(bl, last);
// loop through every spent input from said block
for (CTransaction t : bl.vtx) {
for (CTxIn in : t.vin) {
// loop through every spent input in the staking transaction of the new block
for (CTxIn stakeIn : block.vtx[1].vin) {
// if they spend the same input
if (stakeIn.prevout == in.prevout) {
//reject the block
return false;
}
}
}
}

// go to the parent block
last = pindexPrev->pprev;
}
}
}
// go to the parent block
last = pindexPrev->pprev;
}
}
}
}

// Write block to history file
try {
Expand Down
3 changes: 3 additions & 0 deletions src/version.h
Expand Up @@ -51,5 +51,8 @@ static const int MEMPOOL_GD_VERSION = 60002;
//! "filter*" commands are disabled without NODE_BLOOM after and including this version
static const int NO_BLOOM_VERSION = 70000;

//! In this version, "Fake Stake" vulnerability mitigations were introduced.
static const int FAKE_STAKE_VERSION = 70008;


#endif // BITCOIN_VERSION_H

0 comments on commit ba1d51e

Please sign in to comment.