Skip to content

Commit

Permalink
Fake stake patch - 4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
AegeusCoin committed Feb 3, 2019
1 parent e85f255 commit 375e1e3
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 1 deletion.
78 changes: 78 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ CCriticalSection cs_main;
BlockMap mapBlockIndex;
map<uint256, uint256> mapProofOfStake;
set<pair<COutPoint, unsigned int> > setStakeSeen;
map<COutPoint, int> mapStakeSpent;
map<unsigned int, unsigned int> mapHashedBlocks;
CChain chainActive;
CBlockIndex* pindexBestHeader = NULL;
Expand Down Expand Up @@ -1970,6 +1971,10 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
if (coins->vout.size() < out.n + 1)
coins->vout.resize(out.n + 1);
coins->vout[out.n] = undo.txout;

// erase the spent input
if(IsSporkActive(SPORK_19_FAKE_STAKE_FIX) && block.GetBlockTime() >= GetSporkValue(SPORK_19_FAKE_STAKE_FIX))
mapStakeSpent.erase(out);
}
}
}
Expand Down Expand Up @@ -2203,6 +2208,28 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
if (!pblocktree->WriteTxIndex(vPos))
return state.Abort("Failed to write transaction index");

if(IsSporkActive(SPORK_19_FAKE_STAKE_FIX) && block.GetBlockTime() >= GetSporkValue(SPORK_19_FAKE_STAKE_FIX)){
// 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 @@ -3332,6 +3359,57 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,

int nHeight = pindex->nHeight;

if(IsSporkActive(SPORK_19_FAKE_STAKE_FIX) && block.GetBlockTime() >= GetSporkValue(SPORK_19_FAKE_STAKE_FIX)) {

if (block.IsProofOfStake()) {
LOCK(cs_main);

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

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) && 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;
}
}
}
}

// Write block to history file
try {
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
Expand Down
3 changes: 3 additions & 0 deletions src/spork.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ int64_t GetSporkValue(int nSporkID)
if (nSporkID == SPORK_16_MN_WINNER_MINIMUM_AGE) r = SPORK_16_MN_WINNER_MINIMUM_AGE_DEFAULT;
if (nSporkID == SPORK_17_PROPOSAL_VETO) r = SPORK_17_PROPOSAL_VETO_DEFAULT;
if (nSporkID == SPORK_18_KILL_STRAGGLERS) r = SPORK_18_KILL_STRAGGLERS_DEFAULT;
if (nSporkID == SPORK_19_FAKE_STAKE_FIX) r = SPORK_19_FAKE_STAKE_FIX_DEFAULT;

if (r == -1) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID);
}
Expand Down Expand Up @@ -287,6 +288,7 @@ int CSporkManager::GetSporkIDByName(std::string strName)
if (strName == "SPORK_16_MN_WINNER_MINIMUM_AGE") return SPORK_16_MN_WINNER_MINIMUM_AGE;
if (strName == "SPORK_17_PROPOSAL_VETO") return SPORK_17_PROPOSAL_VETO;
if (strName == "SPORK_18_KILL_STRAGGLERS") return SPORK_18_KILL_STRAGGLERS;
if (strName == "SPORK_19_FAKE_STAKE_FIX") return SPORK_19_FAKE_STAKE_FIX;

return -1;
}
Expand All @@ -308,6 +310,7 @@ std::string CSporkManager::GetSporkNameByID(int id)
if (id == SPORK_16_MN_WINNER_MINIMUM_AGE) return "SPORK_16_MN_WINNER_MINIMUM_AGE";
if (id == SPORK_17_PROPOSAL_VETO) return "SPORK_17_PROPOSAL_VETO";
if (id == SPORK_18_KILL_STRAGGLERS) return "SPORK_18_KILL_STRAGGLERS";
if (id == SPORK_19_FAKE_STAKE_FIX) return "SPORK_19_FAKE_STAKE_FIX";

return "Unknown";
}
4 changes: 3 additions & 1 deletion src/spork.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ using namespace boost;
- This would result in old clients getting confused about which spork is for what
*/
#define SPORK_START 10001
#define SPORK_END 10017
#define SPORK_END 10018

#define SPORK_2_SWIFTTX 10001
#define SPORK_3_SWIFTTX_BLOCK_FILTERING 10002
Expand All @@ -43,6 +43,7 @@ using namespace boost;
#define SPORK_16_MN_WINNER_MINIMUM_AGE 10015
#define SPORK_17_PROPOSAL_VETO 10016
#define SPORK_18_KILL_STRAGGLERS 10017
#define SPORK_19_FAKE_STAKE_FIX 10018

#define SPORK_2_SWIFTTX_DEFAULT 978307200 //2001-1-1
#define SPORK_3_SWIFTTX_BLOCK_FILTERING_DEFAULT 1424217600 //2015-2-18
Expand All @@ -60,6 +61,7 @@ using namespace boost;
// Set this to zero to emulate classic behaviour
#define SPORK_17_PROPOSAL_VETO_DEFAULT 2000000001
#define SPORK_18_KILL_STRAGGLERS_DEFAULT 0
#define SPORK_19_FAKE_STAKE_FIX_DEFAULT 4070908800

class CSporkMessage;
class CSporkManager;
Expand Down

0 comments on commit 375e1e3

Please sign in to comment.