mirror of
https://github.com/jwinterm/myriadcoin.git
synced 2026-10-17 05:41:34 +02:00
@@ -28,6 +28,7 @@ BITCOIN_CORE_H = \
|
||||
addrman.h \
|
||||
alert.h \
|
||||
allocators.h \
|
||||
auxpow.h \
|
||||
base58.h bignum.h \
|
||||
bloom.h \
|
||||
chainparams.h \
|
||||
@@ -108,6 +109,7 @@ version.o: obj/build.h
|
||||
libbitcoin_server_a_SOURCES = \
|
||||
addrman.cpp \
|
||||
alert.cpp \
|
||||
auxpow.cpp \
|
||||
bloom.cpp \
|
||||
checkpoints.cpp \
|
||||
coins.cpp \
|
||||
|
||||
+10
-11
@@ -85,6 +85,16 @@ inline std::string GetAlgoName(int Algo)
|
||||
}
|
||||
|
||||
class CTransaction;
|
||||
class CAuxPow;
|
||||
|
||||
template <typename Stream>
|
||||
int ReadWriteAuxPow(Stream& s, const boost::shared_ptr<CAuxPow>& auxpow, int nType, int nVersion, CSerActionSerialize ser_action);
|
||||
|
||||
template <typename Stream>
|
||||
int ReadWriteAuxPow(Stream& s, boost::shared_ptr<CAuxPow>& auxpow, int nType, int nVersion, CSerActionUnserialize ser_action);
|
||||
|
||||
template <typename Stream>
|
||||
int ReadWriteAuxPow(Stream& s, const boost::shared_ptr<CAuxPow>& auxpow, int nType, int nVersion, CSerActionGetSerializeSize ser_action);
|
||||
|
||||
/** No amount larger than this (in satoshi) is valid */
|
||||
static const int64_t MAX_MONEY = 2000000000 * COIN;
|
||||
@@ -413,17 +423,6 @@ public:
|
||||
)
|
||||
};
|
||||
|
||||
class CAuxPow;
|
||||
|
||||
template <typename Stream>
|
||||
int ReadWriteAuxPow(Stream& s, const boost::shared_ptr<CAuxPow>& auxpow, int nType, int nVersion, CSerActionSerialize ser_action);
|
||||
|
||||
template <typename Stream>
|
||||
int ReadWriteAuxPow(Stream& s, boost::shared_ptr<CAuxPow>& auxpow, int nType, int nVersion, CSerActionUnserialize ser_action);
|
||||
|
||||
template <typename Stream>
|
||||
int ReadWriteAuxPow(Stream& s, const boost::shared_ptr<CAuxPow>& auxpow, int nType, int nVersion, CSerActionGetSerializeSize ser_action);
|
||||
|
||||
/** Nodes collect new transactions into a block, hash them into a hash tree,
|
||||
* and scan through nonce values to make the block's hash satisfy proof-of-work
|
||||
* requirements. When they solve the proof-of-work, they broadcast the block
|
||||
|
||||
+101
-48
@@ -1135,17 +1135,6 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
|
||||
// CBlock and CBlockIndex
|
||||
//
|
||||
|
||||
std::string CDiskBlockIndex::ToString() const
|
||||
{
|
||||
std::string str = "CDiskBlockIndex(";
|
||||
str += CBlockIndex::ToString();
|
||||
str += strprintf("\n hashBlock=%s, hashPrev=%s, hashParentBlock=%s)",
|
||||
GetBlockHash().ToString().c_str(),
|
||||
hashPrev.ToString().c_str(),
|
||||
(auxpow.get() != NULL) ? auxpow->GetParentBlockHash(GetAlgo()).ToString().substr(0,20).c_str() : "-");
|
||||
return str;
|
||||
}
|
||||
|
||||
bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos)
|
||||
{
|
||||
// Open history file to append
|
||||
@@ -1190,7 +1179,8 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos)
|
||||
}
|
||||
|
||||
// Check the header
|
||||
if (!CheckProofOfWork(block.GetPoWHash(block.GetAlgo()), block.nBits, block.GetAlgo()))
|
||||
//if (!CheckProofOfWork(block.GetPoWHash(block.GetAlgo()), block.nBits, block.GetAlgo()))
|
||||
if (!block.CheckProofOfWork(mapBlockIndex[block.GetHash()]->nHeight))
|
||||
return error("ReadBlockFromDisk : Errors in block header");
|
||||
|
||||
return true;
|
||||
@@ -1533,7 +1523,7 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits, int algo)
|
||||
bool CBlockHeader::CheckProofOfWork(int nHeight) const
|
||||
{
|
||||
int algo = GetAlgo();
|
||||
if ((nHeight >= GetAuxPowStartBlock()) && (algo == ALGO_SHA256D && algo == ALGO_SCRYPT))
|
||||
if ((nHeight >= GetAuxPowStartBlock()) && (algo == ALGO_SHA256D || algo == ALGO_SCRYPT))
|
||||
{
|
||||
// Prevent same work from being submitted twice:
|
||||
// - this block must have our chain ID
|
||||
@@ -1999,7 +1989,8 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
// Check it again in case a previous version let a bad block in
|
||||
if (!CheckBlock(block, state, !fJustCheck, !fJustCheck))
|
||||
//if (!CheckBlock(block, state, !fJustCheck, !fJustCheck))
|
||||
if (!CheckBlock(block, state, pindex->nHeight, !fJustCheck, !fJustCheck))
|
||||
return false;
|
||||
|
||||
// verify that the view's current state corresponds to the previous block
|
||||
@@ -2409,27 +2400,6 @@ bool ActivateBestChain(CValidationState &state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
CBlockHeader CBlockIndex::GetBlockHeader() const
|
||||
{
|
||||
CBlockHeader block;
|
||||
|
||||
if (nVersion & BLOCK_VERSION_AUXPOW) {
|
||||
CDiskBlockIndex diskblockindex;
|
||||
// auxpow is not in memory, load CDiskBlockHeader
|
||||
// from database to get it
|
||||
pblocktree->ReadDiskBlockIndex(*phashBlock, diskblockindex);
|
||||
block.auxpow = diskblockindex.auxpow;
|
||||
}
|
||||
block.nVersion = nVersion;
|
||||
if (pprev)
|
||||
block.hashPrevBlock = pprev->GetBlockHash();
|
||||
block.hashMerkleRoot = hashMerkleRoot;
|
||||
block.nTime = nTime;
|
||||
block.nBits = nBits;
|
||||
block.nNonce = nNonce;
|
||||
return block;
|
||||
}
|
||||
|
||||
bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos& pos)
|
||||
{
|
||||
// Check for duplicate
|
||||
@@ -2466,10 +2436,8 @@ bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos
|
||||
pindexNew->nStatus = BLOCK_VALID_TRANSACTIONS | BLOCK_HAVE_DATA;
|
||||
setBlockIndexValid.insert(pindexNew);
|
||||
|
||||
//if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew, block.auxpow)) || !pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew)))
|
||||
if (!pblocktree->WriteDiskBlockIndex(CDiskBlockIndex(pindexNew, block.auxpow)) || !pblocktree->WriteBlockIndex(*pindexNew))
|
||||
/* write both the immutible data (CDiskBlockIndex) and the mutable data (BlockIndex) */
|
||||
//if (!pblocktree->WriteDiskBlockIndex(CDiskBlockIndex(pindexNew, block.auxpow)) || !pblocktree->WriteBlockIndex(*pindexNew))
|
||||
if (!pblocktree->WriteDiskBlockIndex(CDiskBlockIndex(pindexNew, block.auxpow)) || !pblocktree->WriteBlockIndex(*pindexNew))
|
||||
return state.Abort(_("Failed to write block index"));
|
||||
|
||||
// New best?
|
||||
@@ -2590,26 +2558,66 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, int nHeight, bool fCheckPOW)
|
||||
{
|
||||
// Check proof of work matches claimed amount
|
||||
if (fCheckPOW && !block.CheckProofOfWork(nHeight))
|
||||
//if (fCheckPOW && !CheckProofOfWork(block.GetPoWHash(block.GetAlgo()), block.nBits, block.GetAlgo()))
|
||||
return state.DoS(50, error("CheckBlockHeader() : proof of work failed"),
|
||||
REJECT_INVALID, "high-hash");
|
||||
|
||||
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot)
|
||||
// Check timestamp
|
||||
if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
|
||||
return state.Invalid(error("CheckBlockHeader() : block timestamp too far in the future"),
|
||||
REJECT_INVALID, "time-too-new");
|
||||
|
||||
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
|
||||
if (pcheckpoint && block.hashPrevBlock != (chainActive.Tip() ? chainActive.Tip()->GetBlockHash() : uint256(0)))
|
||||
{
|
||||
// Extra checks to prevent "fill up memory by spamming with bogus blocks"
|
||||
int64_t deltaTime = block.GetBlockTime() - pcheckpoint->nTime;
|
||||
if (deltaTime < 0)
|
||||
{
|
||||
LogPrintf("CheckBlockHeader(): Height=%d, hash=%s, BlockTime=%d, Checkpoint=%d\n", nHeight, block.GetHash().GetHex().c_str(), block.GetBlockTime(), pcheckpoint->nTime);
|
||||
return state.DoS(100, error("CheckBlockHeader() : block with timestamp before last checkpoint"),
|
||||
REJECT_CHECKPOINT, "time-too-old");
|
||||
}
|
||||
CBigNum bnNewBlock;
|
||||
bnNewBlock.SetCompact(block.nBits);
|
||||
CBigNum bnRequired;
|
||||
bnRequired.SetCompact(ComputeMinWork(pcheckpoint->nBits, deltaTime));
|
||||
if (bnNewBlock > bnRequired)
|
||||
{
|
||||
return state.DoS(100, error("CheckBlockHeader() : block with too little proof-of-work"),
|
||||
REJECT_INVALID, "bad-diffbits");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckBlock(const CBlock& block, CValidationState& state, int nHeight, bool fCheckPOW, bool fCheckMerkleRoot)
|
||||
{
|
||||
// These are checks that are independent of context
|
||||
// that can be verified before saving an orphan block.
|
||||
|
||||
if (!CheckBlockHeader(block, state, nHeight, fCheckPOW))
|
||||
return false;
|
||||
|
||||
// Size limits
|
||||
if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
|
||||
return state.DoS(100, error("CheckBlock() : size limits failed"),
|
||||
REJECT_INVALID, "bad-blk-length");
|
||||
|
||||
// Check proof of work matches claimed amount
|
||||
if (fCheckPOW && !CheckProofOfWork(block.GetPoWHash(block.GetAlgo()), block.nBits, block.GetAlgo()))
|
||||
return state.DoS(50, error("CheckBlock() : proof of work failed"),
|
||||
REJECT_INVALID, "high-hash");
|
||||
// if (fCheckPOW && !CheckProofOfWork(block.GetPoWHash(block.GetAlgo()), block.nBits, block.GetAlgo()))
|
||||
// return state.DoS(50, error("CheckBlock() : proof of work failed"),
|
||||
// REJECT_INVALID, "high-hash");
|
||||
|
||||
// Check timestamp
|
||||
if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
|
||||
return state.Invalid(error("CheckBlock() : block timestamp too far in the future"),
|
||||
REJECT_INVALID, "time-too-new");
|
||||
// if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
|
||||
// return state.Invalid(error("CheckBlock() : block timestamp too far in the future"),
|
||||
// REJECT_INVALID, "time-too-new");
|
||||
|
||||
// First transaction must be coinbase, the rest must not be
|
||||
if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
|
||||
@@ -2812,6 +2820,48 @@ int64_t CBlockIndex::GetMedianTime() const
|
||||
return pindex->GetMedianTimePast();
|
||||
}
|
||||
|
||||
std::string CBlockIndex::ToString() const
|
||||
{
|
||||
return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)",
|
||||
pprev, nHeight,
|
||||
hashMerkleRoot.ToString().substr(0,10).c_str(),
|
||||
GetBlockHash().ToString().c_str());
|
||||
}
|
||||
|
||||
std::string CDiskBlockIndex::ToString() const
|
||||
{
|
||||
std::string str = "CDiskBlockIndex(";
|
||||
str += CBlockIndex::ToString();
|
||||
str += strprintf("\n hashBlock=%s, hashPrev=%s, hashParentBlock=%s)",
|
||||
GetBlockHash().ToString().c_str(),
|
||||
hashPrev.ToString().c_str(),
|
||||
(auxpow.get() != NULL) ? auxpow->GetParentBlockHash(GetAlgo()).ToString().substr(0,20).c_str() : "-");
|
||||
return str;
|
||||
}
|
||||
|
||||
CBlockHeader CBlockIndex::GetBlockHeader() const
|
||||
{
|
||||
CBlockHeader block;
|
||||
|
||||
if (nVersion & BLOCK_VERSION_AUXPOW) {
|
||||
CDiskBlockIndex diskblockindex;
|
||||
// auxpow is not in memory, load CDiskBlockHeader
|
||||
// from database to get it
|
||||
|
||||
pblocktree->ReadDiskBlockIndex(*phashBlock, diskblockindex);
|
||||
block.auxpow = diskblockindex.auxpow;
|
||||
}
|
||||
|
||||
block.nVersion = nVersion;
|
||||
if (pprev)
|
||||
block.hashPrevBlock = pprev->GetBlockHash();
|
||||
block.hashMerkleRoot = hashMerkleRoot;
|
||||
block.nTime = nTime;
|
||||
block.nBits = nBits;
|
||||
block.nNonce = nNonce;
|
||||
return block;
|
||||
}
|
||||
|
||||
void PushGetBlocks(CNode* pnode, CBlockIndex* pindexBegin, uint256 hashEnd)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
@@ -2835,9 +2885,12 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
|
||||
if (mapOrphanBlocks.count(hash))
|
||||
return state.Invalid(error("ProcessBlock() : already have block (orphan) %s", hash.ToString()), 0, "duplicate");
|
||||
|
||||
// Preliminary checks
|
||||
if (!CheckBlock(*pblock, state))
|
||||
if (!CheckBlock(*pblock, state, INT_MAX))
|
||||
{
|
||||
if (state.CorruptionPossible())
|
||||
mapAlreadyAskedFor.erase(CInv(MSG_BLOCK, hash));
|
||||
return error("ProcessBlock() : CheckBlock FAILED");
|
||||
}
|
||||
|
||||
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
|
||||
if (pcheckpoint && pblock->hashPrevBlock != (chainActive.Tip() ? chainActive.Tip()->GetBlockHash() : uint256(0)))
|
||||
@@ -3235,7 +3288,7 @@ bool VerifyDB(int nCheckLevel, int nCheckDepth)
|
||||
if (!ReadBlockFromDisk(block, pindex))
|
||||
return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
|
||||
// check level 1: verify block validity
|
||||
if (nCheckLevel >= 1 && !CheckBlock(block, state))
|
||||
if (nCheckLevel >= 1 && !CheckBlock(block, state, pindex->nHeight))
|
||||
return error("VerifyDB() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
|
||||
// check level 2: verify undo validity
|
||||
if (nCheckLevel >= 2 && pindex) {
|
||||
|
||||
+8
-11
@@ -622,7 +622,8 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
|
||||
bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos& pos);
|
||||
|
||||
// Context-independent validity checks
|
||||
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
|
||||
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, int nHeight, bool fCheckPOW = true);
|
||||
bool CheckBlock(const CBlock& block, CValidationState& state, int nHeight, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
|
||||
|
||||
// Store block on disk
|
||||
// if dbp is provided, the file is known to already reside on disk
|
||||
@@ -994,10 +995,12 @@ public:
|
||||
|
||||
bool CheckIndex() const
|
||||
{
|
||||
int algo = GetAlgo();
|
||||
/* This check was considered unneccessary given the other safeguards like the genesis and checkpoints, and it breaks LoadBlockIndexGuts() after AuxPow is enabled. */
|
||||
|
||||
/* int algo = GetAlgo();
|
||||
if (algo == ALGO_SHA256D)
|
||||
return CheckProofOfWork(GetBlockHash(), nBits, algo);
|
||||
else
|
||||
else*/
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1026,13 +1029,7 @@ public:
|
||||
static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart,
|
||||
unsigned int nRequired, unsigned int nToCheck);
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)",
|
||||
pprev, nHeight,
|
||||
hashMerkleRoot.ToString().c_str(),
|
||||
GetBlockHash().ToString().c_str());
|
||||
}
|
||||
std::string ToString() const; //moved code to main.cpp because new method required access to auxpow
|
||||
|
||||
void print() const
|
||||
{
|
||||
@@ -1096,7 +1093,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
std::string ToString() const;
|
||||
std::string ToString() const; // moved code to main.cpp
|
||||
|
||||
void print() const
|
||||
{
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
using namespace json_spirit;
|
||||
using namespace std;
|
||||
|
||||
// from rpcraw.cpp
|
||||
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry);
|
||||
|
||||
void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex);
|
||||
|
||||
double GetDifficulty(const CBlockIndex* blockindex, int algo)
|
||||
@@ -76,6 +79,38 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex)
|
||||
result.push_back(Pair("pow_algo", GetAlgoName(algo)));
|
||||
result.push_back(Pair("pow_hash", block.GetPoWHash(algo).GetHex()));
|
||||
result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
|
||||
if (block.nVersion & BLOCK_VERSION_AUXPOW) {
|
||||
// this block includes auxpow
|
||||
Object auxpow;
|
||||
auxpow.push_back(Pair("size", (int)::GetSerializeSize(*block.auxpow, SER_NETWORK, PROTOCOL_VERSION)));
|
||||
|
||||
Object coinbasetx;
|
||||
TxToJSON(*block.auxpow, 0, coinbasetx);
|
||||
auxpow.push_back(Pair("coinbasetx", Value(coinbasetx)));
|
||||
|
||||
Array coinbaseMerkle;
|
||||
BOOST_FOREACH(const uint256 &hash, block.auxpow->vMerkleBranch)
|
||||
coinbaseMerkle.push_back(hash.GetHex());
|
||||
auxpow.push_back(Pair("coinbaseMerkleBranch", coinbaseMerkle));
|
||||
auxpow.push_back(Pair("coinbaseIndex", block.auxpow->nIndex));
|
||||
|
||||
Array chainMerkle;
|
||||
BOOST_FOREACH(const uint256 &hash, block.auxpow->vChainMerkleBranch)
|
||||
chainMerkle.push_back(hash.GetHex());
|
||||
auxpow.push_back(Pair("chainMerkleBranch", chainMerkle));
|
||||
auxpow.push_back(Pair("chainIndex", (boost::uint64_t)block.auxpow->nChainIndex));
|
||||
|
||||
Object parent_block;
|
||||
parent_block.push_back(Pair("hash", block.auxpow->parentBlockHeader.GetHash().GetHex()));
|
||||
parent_block.push_back(Pair("version", (boost::uint64_t)block.auxpow->parentBlockHeader.nVersion));
|
||||
parent_block.push_back(Pair("previousblockhash", block.auxpow->parentBlockHeader.hashPrevBlock.GetHex()));
|
||||
parent_block.push_back(Pair("merkleroot", block.auxpow->parentBlockHeader.hashMerkleRoot.GetHex()));
|
||||
parent_block.push_back(Pair("time", (boost::int64_t)block.auxpow->parentBlockHeader.nTime));
|
||||
parent_block.push_back(Pair("bits", HexBits(block.auxpow->parentBlockHeader.nBits)));
|
||||
parent_block.push_back(Pair("nonce", (boost::uint64_t)block.auxpow->parentBlockHeader.nNonce));
|
||||
auxpow.push_back(Pair("parent_block", Value(parent_block)));
|
||||
result.push_back(Pair("auxpow", Value(auxpow)));
|
||||
}
|
||||
Array txs;
|
||||
BOOST_FOREACH(const CTransaction&tx, block.vtx)
|
||||
txs.push_back(tx.GetHash().GetHex());
|
||||
|
||||
+1
-1
@@ -315,7 +315,7 @@ static const CRPCCommand vRPCCommands[] =
|
||||
{ "gethashespersec", &gethashespersec, true, false, false },
|
||||
{ "getwork", &getwork, true, false, true },
|
||||
{ "setgenerate", &setgenerate, true, true, false },
|
||||
|
||||
|
||||
/* Stealth */
|
||||
{ "getnewstealthaddress", &getnewstealthaddress, false, false, true},
|
||||
{ "liststealthaddresses", &liststealthaddresses, false, false, true},
|
||||
|
||||
+9
-9
@@ -215,35 +215,35 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
|
||||
char chType;
|
||||
ssKey >> chType;
|
||||
if (chType == 'b') {
|
||||
// Detect pre-auxpow keys in the database and abort if found
|
||||
if (slKey.size() < ssKeySet.size()) {
|
||||
return error("Database key size is %d expected %d, require reindex to upgrade.", slKey.size(), ssKeySet.size());
|
||||
}
|
||||
|
||||
ssKey >> hash;
|
||||
|
||||
leveldb::Slice slValue = pcursor->value();
|
||||
// CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
|
||||
CDataStream ssValue_immutable(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
|
||||
CDiskBlockIndex diskindex;
|
||||
// ssValue >> diskindex;
|
||||
ssValue_immutable >> diskindex; // read all immutable data
|
||||
|
||||
// Construct immutable parts of block index objecty
|
||||
CBlockIndex* pindexNew = InsertBlockIndex(hash);
|
||||
assert(diskindex.GetBlockHash() == *pindexNew->phashBlock); // paranoia check
|
||||
|
||||
// // Construct block index object
|
||||
// CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash());
|
||||
pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev);
|
||||
pindexNew->nHeight = diskindex.nHeight;
|
||||
// pindexNew->nFile = diskindex.nFile;
|
||||
// pindexNew->nDataPos = diskindex.nDataPos;
|
||||
// pindexNew->nUndoPos = diskindex.nUndoPos;
|
||||
pindexNew->nFile = diskindex.nFile;
|
||||
pindexNew->nDataPos = diskindex.nDataPos;
|
||||
pindexNew->nUndoPos = diskindex.nUndoPos;
|
||||
pindexNew->nVersion = diskindex.nVersion;
|
||||
pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
|
||||
pindexNew->nTime = diskindex.nTime;
|
||||
pindexNew->nBits = diskindex.nBits;
|
||||
pindexNew->nNonce = diskindex.nNonce;
|
||||
// pindexNew->nStatus = diskindex.nStatus;
|
||||
pindexNew->nStatus = diskindex.nStatus;
|
||||
pindexNew->nTx = diskindex.nTx;
|
||||
|
||||
// if (!pindexNew->CheckIndex())
|
||||
// CheckIndex need phashBlock to be set
|
||||
diskindex.phashBlock = pindexNew->phashBlock;
|
||||
if (!diskindex.CheckIndex())
|
||||
|
||||
Reference in New Issue
Block a user