Skip to content
This repository has been archived by the owner on Apr 15, 2021. It is now read-only.

Commit

Permalink
Merge pull request #63 from spectrecoin/develop
Browse files Browse the repository at this point in the history
Merge develop with fork code into master
  • Loading branch information
teknex committed Jul 25, 2018
2 parents 7d45481 + 6f91fd0 commit ba3d207
Show file tree
Hide file tree
Showing 17 changed files with 166 additions and 74 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
AC_INIT([spectrecoind], [1.3.8])
AC_INIT([spectrecoind], [1.4.1])
AC_CONFIG_SRCDIR([src/main.cpp])
AC_CONFIG_AUX_DIR([.])
AM_INIT_AUTOMAKE([foreign 1.13 subdir-objects -Wall -Werror -Wno-portability])
Expand Down
18 changes: 12 additions & 6 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ class CMainParams : public CBaseChainParams {

//nLastPOWBlock = 2016; // Running for 1 Week after ICO
nLastPOWBlock = 17000;

nFirstPosv2Block = 17001;
nFirstPosv3Block = 17010;

Expand All @@ -162,6 +161,10 @@ class CMainParams : public CBaseChainParams {
base58Prefixes[EXT_SECRET_KEY_BTC] = list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container<std::vector<unsigned char> >(); // xpub

convertSeeds(vFixedSeeds, pnSeed, ARRAYLEN(pnSeed), nDefaultPort);

nForkV2Time = 1534888800; // MAINNET V2 chain fork (GMT: Tuesday, 21. August 2018 22.00)

devContributionAddress = "SdrdWNtjD7V6BSt3EyQZKCnZDkeE28cZhr";
}

virtual Network NetworkID() const { return CChainParams::MAIN; }
Expand Down Expand Up @@ -193,19 +196,18 @@ class CTestNetParams : public CBaseChainParams {
nBIP44ID = 0x80000001;

nLastPOWBlock = 110;

nFirstPosv2Block = 110;
nFirstPosv3Block = 500;

bnProofOfWorkLimit = CBigNum(~uint256(0) >> 16);
bnProofOfWorkLimit = CBigNum(~uint256(0) >> 1);
bnProofOfStakeLimit = CBigNum(~uint256(0) >> 20);
bnProofOfStakeLimitV2 = CBigNum(~uint256(0) >> 16);

genesis.nBits = bnProofOfWorkLimit.GetCompact();
genesis.nNonce = 52419;
genesis.nNonce = 1001;

hashGenesisBlock = genesis.GetHash();
assert(hashGenesisBlock == uint256("0x00004351133a2c6c1f7277b0d684192b605bc62c03727bba81e4d20863944049"));
hashGenesisBlock = genesis.GetHash();
assert(hashGenesisBlock == uint256("0x0eaef840827189830c177c345f53a26ad87e0770b200a83d7ff6a928d725d882"));

base58Prefixes[PUBKEY_ADDRESS] = list_of(127).convert_to_container<std::vector<unsigned char> >();
base58Prefixes[SCRIPT_ADDRESS] = list_of(196).convert_to_container<std::vector<unsigned char> >();
Expand All @@ -219,6 +221,10 @@ class CTestNetParams : public CBaseChainParams {
base58Prefixes[EXT_SECRET_KEY_BTC] = list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >(); // tpub

convertSeeds(vFixedSeeds, pnTestnetSeed, ARRAYLEN(pnTestnetSeed), nDefaultPort);

nForkV2Time = 1532466000; // TESTNET V2 chain fork (GMT: Tuesday, 24. July 2018 21.00)

devContributionAddress = "tQuY2feSvtYogfWPbXLgqgDT2JfdZYUf7h";
}
virtual Network NetworkID() const { return CChainParams::TESTNET; }
};
Expand Down
11 changes: 10 additions & 1 deletion src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ class CChainParams
int64_t GetProofOfWorkReward(int nHeight, int64_t nFees) const;
int64_t GetProofOfStakeReward(const CBlockIndex* pindexPrev, int64_t nCoinAge, int64_t nFees) const;

const std::string GetDevContributionAddress() const { return devContributionAddress; }

const bool IsForkV2(unsigned int nTime) const { return nTime > nForkV2Time; }
int GetForkId(unsigned int nTime) const { return (nTime > nForkV2Time) ? 2 : 0; }

protected:
CChainParams() {};

Expand All @@ -114,6 +119,10 @@ class CChainParams
std::vector<CDNSSeedData> vSeeds;
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
int nLastPOWBlock;

std::string devContributionAddress;

unsigned int nForkV2Time;
};

/**
Expand Down Expand Up @@ -141,7 +150,7 @@ void SelectParams(CChainParams::Network network);
*/
bool SelectParamsFromCommandLine();

inline bool TestNet() {
const inline bool TestNet() {
// Note: it's deliberate that this returns "false" for regression test mode.
return Params().NetworkID() == CChainParams::TESTNET;
}
Expand Down
6 changes: 3 additions & 3 deletions src/clientversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
//

// 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 4
#define CLIENT_VERSION_REVISION 0
#define CLIENT_VERSION_MAJOR 2
#define CLIENT_VERSION_MINOR 0
#define CLIENT_VERSION_REVISION 4
#define CLIENT_VERSION_BUILD 0

// Converts the parameter X to a string after macro replacement on X has been performed.
Expand Down
4 changes: 2 additions & 2 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ bool AppInit2(boost::thread_group& threadGroup)
nNodeLifespan = GetArg("-addrlifespan", 7);

nMinStakeInterval = GetArg("-minstakeinterval", 0);
nStakingDonation = GetArg("-stakingdonation", 15);
nStakingDonation = GetArg("-stakingdonation", 0);
nMinerSleep = GetArg("-minersleep", 500);

fUseFastIndex = GetBoolArg("-fastindex", true);
Expand Down Expand Up @@ -476,7 +476,7 @@ bool AppInit2(boost::thread_group& threadGroup)

if (fTestNet)
{
nStakeMinAge = 1 * 60 * 60; // test net min age is 1 hour
nStakeMinAge = 15 * 60; // test net min age is 15 minutes
nCoinbaseMaturity = 10; // test maturity is 10 blocks
nStakeMinConfirmations = 10; // test maturity is 10 blocks
};
Expand Down
5 changes: 2 additions & 3 deletions src/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -794,14 +794,13 @@ bool CheckKernel(CBlockIndex* pindexPrev, unsigned int nBits, int64_t nTime, con
if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
return false;

if (Params().IsProtocolV3(nTime))
if (Params().IsProtocolV3(pindexPrev->nHeight+1))
{
int nDepth;
if (IsConfirmedInNPrevBlocks(txindex, pindexPrev, nStakeMinConfirmations - 1, nDepth))
return false;
}
else
if (block.GetBlockTime() + nStakeMinAge > nTime)
else if (block.GetBlockTime() + nStakeMinAge > nTime)
return false; // only count coins meeting min age requirement

if (pBlockTime)
Expand Down
103 changes: 73 additions & 30 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2443,21 +2443,21 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, MapPrevTx inputs, map<uint256, CTx

if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
return DoS(100, error("ConnectInputs() : %s prevout.n out of range %d %u %u prev tx %s\n%s", GetHash().ToString(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString(), txPrev.ToString()));

// If prev is coinbase or coinstake, check that it's matured
if (txPrev.IsCoinBase() || txPrev.IsCoinStake())
{
int nSpendDepth;
if (IsConfirmedInNPrevBlocks(txindex, pindexBlock, nCoinbaseMaturity, nSpendDepth))
return error("ConnectInputs() : tried to spend %s at depth %d", txPrev.IsCoinBase() ? "coinbase" : "coinstake", nSpendDepth);
}


// ppcoin: check transaction timestamp
if (txPrev.nTime > nTime)
return DoS(100, error("ConnectInputs() : transaction timestamp earlier than input transaction"));

if (Params().IsProtocolV3(pindexBlock->nHeight))
{
// If prev is coinbase or coinstake, check that it's matured
if (txPrev.IsCoinBase() || txPrev.IsCoinStake())
{
int nSpendDepth;
if (IsConfirmedInNPrevBlocks(txindex, pindexBlock, nCoinbaseMaturity, nSpendDepth))
return error("ConnectInputs() : tried to spend %s at depth %d", txPrev.IsCoinBase() ? "coinbase" : "coinstake", nSpendDepth);
}

if (txPrev.vout[prevout.n].IsEmpty())
return DoS(1, error("ConnectInputs() : special marker is not spendable"));
}
Expand Down Expand Up @@ -2728,6 +2728,30 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)

if (nStakeReward > nCalculatedStakeReward)
return DoS(100, error("ConnectBlock() : coinstake pays too much(actual=%d vs calculated=%d)", nStakeReward, nCalculatedStakeReward));


if (Params().IsForkV2(nTime) && pindex->nHeight % 6 == 0) {
CBitcoinAddress address(Params().GetDevContributionAddress());
CScript scriptPubKey;
scriptPubKey.SetDestination(address.Get());

bool containsDonation = false;

//the donation can be at i = 2 or above. so we start looking for it there
for (int i = 2; i < vtx[1].vout.size(); i++) {
if (vtx[1].vout[i].scriptPubKey == scriptPubKey) {
if (vtx[1].vout[i].nValue >= nCalculatedStakeReward) {
//we found a donation. Stop searching
containsDonation = true;
break;
}
}
}
if (!containsDonation) {
LogPrintf("ConnectBlock() : stake does not pay to the donation address\n");
return DoS(100, error("ConnectBlock() : stake does not pay to the donation address in trx\n%s\n", vtx[1].ToString()));
}
}
}

// ppcoin: track money supply and mint amount info
Expand Down Expand Up @@ -3009,48 +3033,48 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
return true;
}

int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const
std::pair<int, int> CMerkleTx::GetDepthAndHeightInMainChainINTERNAL(CBlockIndex* &pindexRet) const
{
if (hashBlock == 0 || nIndex == -1)
return 0;
return std::make_pair(0, -1);

AssertLockHeld(cs_main);

// Find the block it claims to be in
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
if (mi == mapBlockIndex.end())
return 0;
return std::make_pair(0, -1);
CBlockIndex* pindex = (*mi).second;
if (!pindex || !pindex->IsInMainChain())
return 0;
return std::make_pair(0, -1);

// Make sure the merkle branch connects to this block
if (!fMerkleVerified)
{
if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
return 0;
return std::make_pair(0, -1);
fMerkleVerified = true;
}

pindexRet = pindex;
return pindexBest->nHeight - pindex->nHeight + 1;
return std::make_pair(pindexBest->nHeight - pindex->nHeight + 1, pindex->nHeight);
}

int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const
std::pair<int, int> CMerkleTx::GetDepthAndHeightInMainChain(CBlockIndex* &pindexRet) const
{
AssertLockHeld(cs_main);
int nResult = GetDepthInMainChainINTERNAL(pindexRet);
if (nResult == 0 && !mempool.exists(GetHash()))
return -1; // Not in chain, not in mempool
pair<int, int> nResult = GetDepthAndHeightInMainChainINTERNAL(pindexRet);
if (nResult.first == 0 && !mempool.exists(GetHash()))
return std::make_pair(-1, -1); // Not in chain, not in mempool

return nResult;
}

int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockThinIndex* &pindexRet) const
std::pair<int, int> CMerkleTx::GetDepthAndHeightInMainChainINTERNAL(CBlockThinIndex* &pindexRet) const
{
//if (hashBlock == 0 || nIndex == -1)
if (hashBlock == 0)
return 0;
return std::make_pair(0, -1);

AssertLockHeld(cs_main);

Expand All @@ -3068,15 +3092,15 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockThinIndex* &pindexRet) const
CDiskBlockThinIndex diskindex;
if (txdb.ReadBlockThinIndex(hashBlock, diskindex)
&& diskindex.hashNext != 0)
return pindexBestHeader->nHeight - diskindex.nHeight + 1;
return std::make_pair(pindexBestHeader->nHeight - diskindex.nHeight + 1, diskindex.nHeight);
};

return 0;
return std::make_pair(0, -1);
};

CBlockThinIndex* pindex = (*mi).second;
if (!pindex || !pindex->IsInMainChain())
return 0;
return std::make_pair(0, -1);

/*
// Make sure the merkle branch connects to this block
Expand All @@ -3088,15 +3112,15 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockThinIndex* &pindexRet) const
};
*/
pindexRet = pindex;
return pindexBestHeader->nHeight - pindex->nHeight + 1;
return std::make_pair(pindexBestHeader->nHeight - pindex->nHeight + 1, pindex->nHeight);
}

int CMerkleTx::GetDepthInMainChain(CBlockThinIndex* &pindexRet) const
std::pair<int, int> CMerkleTx::GetDepthAndHeightInMainChain(CBlockThinIndex* &pindexRet) const
{
AssertLockHeld(cs_main);
int nResult = GetDepthInMainChainINTERNAL(pindexRet);
if (nResult == 0 && !mempool.exists(GetHash()))
return -1; // Not in chain, not in mempool
std::pair<int, int> nResult = GetDepthAndHeightInMainChainINTERNAL(pindexRet);
if (nResult.first == 0 && !mempool.exists(GetHash()))
return std::make_pair(-1, -1); // Not in chain, not in mempool

return nResult;
}
Expand All @@ -3106,7 +3130,13 @@ int CMerkleTx::GetBlocksToMaturity() const
if (!(IsCoinBase() || IsCoinStake()))
return 0;

return max(0, (nCoinbaseMaturity + 5) - GetDepthInMainChain());
std::pair<int, int> pDepthAndHeight = GetDepthAndHeightInMainChain();

// Block to maturity is only relevant for PoSv3 according to the consensus rule in CheckProofOfStake
if (pDepthAndHeight.second != -1 && !Params().IsProtocolV3(pDepthAndHeight.second))
return 0;

return max(0, (nCoinbaseMaturity + 5) - pDepthAndHeight.first);
}


Expand Down Expand Up @@ -4968,6 +4998,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CAddress addrFrom;
uint64_t nNonce = 1;
vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;

// Future fork condition. Enforce minimum protcol version based on nTime.
if (Params().IsForkV2(nTime)) {
if (pfrom->nVersion < LEGACY_CUTOFF_MIN_PROTOCOL_VERSION)
{
// disconnect from peers older than this proto version
LogPrintf("Peer %s using pre-fork version %i; disconnecting\n", pfrom->addr.ToString(), pfrom->nVersion);
pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE, strprintf("node < %d", MIN_PEER_PROTO_VERSION));
pfrom->fDisconnect = true;
return false;
}
}

if (pfrom->nVersion < MIN_PEER_PROTO_VERSION)
{
// disconnect from peers older than this proto version
Expand Down
28 changes: 21 additions & 7 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -507,8 +507,11 @@ bool AcceptToMemoryPool(CTxMemPool &pool, CTransaction &tx, CTxDB& txdb, bool *p
class CMerkleTx : public CTransaction
{
private:
int GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const;
int GetDepthInMainChainINTERNAL(CBlockThinIndex* &pindexRet) const;
int GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const { return GetDepthAndHeightInMainChainINTERNAL(pindexRet).first; };
int GetDepthInMainChainINTERNAL(CBlockThinIndex* &pindexRet) const { return GetDepthAndHeightInMainChainINTERNAL(pindexRet).first; };

std::pair<int, int> GetDepthAndHeightInMainChainINTERNAL(CBlockIndex* &pindexRet) const;
std::pair<int, int> GetDepthAndHeightInMainChainINTERNAL(CBlockThinIndex* &pindexRet) const;
public:
uint256 hashBlock;
std::vector<uint256> vMerkleBranch;
Expand Down Expand Up @@ -552,19 +555,30 @@ class CMerkleTx : public CTransaction
// -1 : not in blockchain, and not in memory pool (conflicted transaction)
// 0 : in memory pool, waiting to be included in a block
// >=1 : this many blocks deep in the main chain
int GetDepthInMainChain(CBlockIndex* &pindexRet) const;
int GetDepthInMainChain(CBlockThinIndex* &pindexRet) const;
int GetDepthInMainChain() const
int GetDepthInMainChain(CBlockIndex* &pindexRet) const { return GetDepthAndHeightInMainChain(pindexRet).first; };
int GetDepthInMainChain(CBlockThinIndex* &pindexRet) const { return GetDepthAndHeightInMainChain(pindexRet).first; };
int GetDepthInMainChain() const { return GetDepthAndHeightInMainChain().first; };

// Return depth and height of transaction in blockchain as pair.
// first contains the depth:
// -1 : not in blockchain, and not in memory pool (conflicted transaction)
// 0 : in memory pool, waiting to be included in a block
// >=1 : this many blocks deep in the main chain
// seconds contains the height of the block or -1 if the block is not in the blockchain
std::pair<int, int> GetDepthAndHeightInMainChain(CBlockIndex* &pindexRet) const;
std::pair<int, int> GetDepthAndHeightInMainChain(CBlockThinIndex* &pindexRet) const;
std::pair<int, int> GetDepthAndHeightInMainChain() const
{
if (nNodeMode == NT_FULL)
{
CBlockIndex *pindexRet;
return GetDepthInMainChain(pindexRet);
return GetDepthAndHeightInMainChain(pindexRet);
};

CBlockThinIndex *pindexRet;
return GetDepthInMainChain(pindexRet);
return GetDepthAndHeightInMainChain(pindexRet);
}

bool IsInMainChain() const
{
if (nNodeMode == NT_THIN)
Expand Down
Loading

0 comments on commit ba3d207

Please sign in to comment.