aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/db.cpp15
-rw-r--r--src/main.cpp103
-rw-r--r--src/main.h161
3 files changed, 155 insertions, 124 deletions
diff --git a/src/db.cpp b/src/db.cpp
index 9ad67892f1..cef395c444 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -637,12 +637,12 @@ bool CTxDB::LoadBlockIndex()
nCheckDepth = nBestHeight;
printf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
CBlockIndex* pindexFork = NULL;
- map<pair<unsigned int, unsigned int>, CBlockIndex*> mapBlockPos;
for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev)
{
if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth)
break;
CBlock block;
+ CDiskBlockPos blockPos = pindex->GetBlockPos();
if (!block.ReadFromDisk(pindex))
return error("LoadBlockIndex() : block.ReadFromDisk failed");
// check level 1: verify block validity
@@ -654,8 +654,6 @@ bool CTxDB::LoadBlockIndex()
// check level 2: verify transaction index validity
if (nCheckLevel>1)
{
- pair<unsigned int, unsigned int> pos = make_pair(pindex->nFile, pindex->nBlockPos);
- mapBlockPos[pos] = pindex;
BOOST_FOREACH(const CTransaction &tx, block.vtx)
{
uint256 hashTx = tx.GetHash();
@@ -663,7 +661,7 @@ bool CTxDB::LoadBlockIndex()
if (ReadTxIndex(hashTx, txindex))
{
// check level 3: checker transaction hashes
- if (nCheckLevel>2 || pindex->nFile != txindex.pos.nFile || pindex->nBlockPos != txindex.pos.nBlockPos)
+ if (nCheckLevel>2 || blockPos != txindex.pos.blockPos)
{
// either an error or a duplicate transaction
CTransaction txFound;
@@ -687,12 +685,6 @@ bool CTxDB::LoadBlockIndex()
{
if (!txpos.IsNull())
{
- pair<unsigned int, unsigned int> posFind = make_pair(txpos.nFile, txpos.nBlockPos);
- if (!mapBlockPos.count(posFind))
- {
- printf("LoadBlockIndex(): *** found bad spend at %d, hashBlock=%s, hashTx=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str(), hashTx.ToString().c_str());
- pindexFork = pindex->pprev;
- }
// check level 6: check whether spent txouts were spent by a valid transaction that consume them
if (nCheckLevel>5)
{
@@ -795,9 +787,8 @@ bool CTxDB::LoadBlockIndexGuts()
CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash());
pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev);
pindexNew->pnext = InsertBlockIndex(diskindex.hashNext);
- pindexNew->nFile = diskindex.nFile;
- pindexNew->nBlockPos = diskindex.nBlockPos;
pindexNew->nHeight = diskindex.nHeight;
+ pindexNew->nAlternative = diskindex.nAlternative;
pindexNew->nVersion = diskindex.nVersion;
pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
pindexNew->nTime = diskindex.nTime;
diff --git a/src/main.cpp b/src/main.cpp
index ed677f31c8..fa818bd053 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -389,7 +389,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
CTxIndex txindex;
if (!CTxDB("r").ReadTxIndex(GetHash(), txindex))
return 0;
- if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos))
+ if (!blockTmp.ReadFromDisk(txindex.pos.blockPos))
return 0;
pblock = &blockTmp;
}
@@ -646,7 +646,7 @@ bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs,
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
- if (!tx.ConnectInputs(mapInputs, mapUnused, CDiskTxPos(1,1,1), pindexBest, false, false))
+ if (!tx.ConnectInputs(mapInputs, mapUnused, CDiskTxPos(true), pindexBest, false, false))
{
return error("CTxMemPool::accept() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str());
}
@@ -817,7 +817,7 @@ int CTxIndex::GetDepthInMainChain() const
{
// Read block header
CBlock block;
- if (!block.ReadFromDisk(pos.nFile, pos.nBlockPos, false))
+ if (!block.ReadFromDisk(pos.blockPos, false))
return 0;
// Find the block in the index
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(block.GetHash());
@@ -847,7 +847,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock)
if (tx.ReadFromDisk(txdb, COutPoint(hash, 0), txindex))
{
CBlock block;
- if (block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
+ if (block.ReadFromDisk(txindex.pos.blockPos, false))
hashBlock = block.GetHash();
return true;
}
@@ -892,7 +892,7 @@ bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions)
*this = pindex->GetBlockHeader();
return true;
}
- if (!ReadFromDisk(pindex->nFile, pindex->nBlockPos, fReadTransactions))
+ if (!ReadFromDisk(pindex->GetBlockPos(), fReadTransactions))
return false;
if (GetHash() != pindex->GetBlockHash())
return error("CBlock::ReadFromDisk() : GetHash() doesn't match index");
@@ -1156,7 +1156,7 @@ bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTes
// Read txPrev
CTransaction& txPrev = inputsRet[prevout.hash].second;
- if (!fFound || txindex.pos == CDiskTxPos(1,1,1))
+ if (!fFound || txindex.pos.IsMemPool())
{
// Get prev tx from single transactions in memory
{
@@ -1262,7 +1262,7 @@ bool CTransaction::ConnectInputs(MapPrevTx inputs,
// If prev is coinbase, check that it's matured
if (txPrev.IsCoinBase())
for (const CBlockIndex* pindex = pindexBlock; pindex && pindexBlock->nHeight - pindex->nHeight < COINBASE_MATURITY; pindex = pindex->pprev)
- if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile)
+ if (pindex->GetBlockPos() == txindex.pos.blockPos)
return error("ConnectInputs() : tried to spend coinbase at depth %d", pindexBlock->nHeight - pindex->nHeight);
// Check for negative or overflow input values
@@ -1427,11 +1427,10 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
//// issue here: it doesn't know the version
unsigned int nTxPos;
if (fJustCheck)
- // FetchInputs treats CDiskTxPos(1,1,1) as a special "refer to memorypool" indicator
// Since we're just checking the block and not actually connecting it, it might not (and probably shouldn't) be on the disk to get the transaction from
nTxPos = 1;
else
- nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK, CLIENT_VERSION) - 1 + GetSizeOfCompactSize(vtx.size());
+ nTxPos = ::GetSerializeSize(CBlock(), SER_DISK, CLIENT_VERSION) - 1 + GetSizeOfCompactSize(vtx.size());
map<uint256, CTxIndex> mapQueuedChanges;
int64 nFees = 0;
@@ -1453,9 +1452,11 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck)
if (nSigOps > MAX_BLOCK_SIGOPS)
return DoS(100, error("ConnectBlock() : too many sigops"));
- CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos);
+ CDiskTxPos posThisTx(pindex->GetBlockPos(), nTxPos);
if (!fJustCheck)
nTxPos += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
+ else
+ posThisTx = CDiskTxPos(true);
MapPrevTx mapInputs;
if (!tx.IsCoinBase())
@@ -1750,7 +1751,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
}
-bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
+bool CBlock::AddToBlockIndex(const CDiskBlockPos &pos)
{
// Check for duplicate
uint256 hash = GetHash();
@@ -1758,7 +1759,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,20).c_str());
// Construct new block index object
- CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
+ CBlockIndex* pindexNew = new CBlockIndex(*this);
if (!pindexNew)
return error("AddToBlockIndex() : new CBlockIndex failed");
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
@@ -1770,6 +1771,8 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
}
pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork();
+ assert(pos.nHeight == pindexNew->nHeight);
+ pindexNew->nAlternative = pos.nAlternative;
CTxDB txdb;
if (!txdb.TxnBegin())
@@ -1908,13 +1911,12 @@ bool CBlock::AcceptBlock()
}
// Write block to history file
+ CDiskBlockPos blockPos = CDiskBlockPos(nHeight);
if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION)))
return error("AcceptBlock() : out of disk space");
- unsigned int nFile = -1;
- unsigned int nBlockPos = 0;
- if (!WriteToDisk(nFile, nBlockPos))
+ if (!WriteToDisk(blockPos))
return error("AcceptBlock() : WriteToDisk failed");
- if (!AddToBlockIndex(nFile, nBlockPos))
+ if (!AddToBlockIndex(blockPos))
return error("AcceptBlock() : AddToBlockIndex failed");
// Relay inventory, but don't relay old inventory during initial block download
@@ -2048,53 +2050,18 @@ bool CheckDiskSpace(uint64 nAdditionalBytes)
return true;
}
-static filesystem::path BlockFilePath(unsigned int nFile)
+FILE* OpenBlockFile(const CDiskBlockPos &pos, const char* pszMode)
{
- string strBlockFn = strprintf("blk%04u.dat", nFile);
- return GetDataDir() / strBlockFn;
-}
-
-FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode)
-{
- if ((nFile < 1) || (nFile == (unsigned int) -1))
+ boost::filesystem::path path = pos.GetFileName(GetDataDir());
+ boost::filesystem::create_directories(path.parent_path());
+ if (pos.IsNull() || pos.IsMemPool())
return NULL;
- FILE* file = fopen(BlockFilePath(nFile).string().c_str(), pszMode);
+ FILE* file = fopen(path.string().c_str(), pszMode);
if (!file)
return NULL;
- if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w'))
- {
- if (fseek(file, nBlockPos, SEEK_SET) != 0)
- {
- fclose(file);
- return NULL;
- }
- }
return file;
}
-static unsigned int nCurrentBlockFile = 1;
-
-FILE* AppendBlockFile(unsigned int& nFileRet)
-{
- nFileRet = 0;
- loop
- {
- FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab");
- if (!file)
- return NULL;
- if (fseek(file, 0, SEEK_END) != 0)
- return NULL;
- // FAT32 file size max 4GB, fseek and ftell max 2GB, so we must stay under 2GB
- if (ftell(file) < (long)(0x7F000000 - MAX_SIZE))
- {
- nFileRet = nCurrentBlockFile;
- return file;
- }
- fclose(file);
- nCurrentBlockFile++;
- }
-}
-
bool LoadBlockIndex(bool fAllowNew)
{
if (fTestNet)
@@ -2153,19 +2120,19 @@ bool LoadBlockIndex(bool fAllowNew)
}
//// debug print
- printf("%s\n", block.GetHash().ToString().c_str());
+ uint256 hash = block.GetHash();
+ printf("%s\n", hash.ToString().c_str());
printf("%s\n", hashGenesisBlock.ToString().c_str());
printf("%s\n", block.hashMerkleRoot.ToString().c_str());
assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
block.print();
- assert(block.GetHash() == hashGenesisBlock);
+ assert(hash == hashGenesisBlock);
// Start new block file
- unsigned int nFile;
- unsigned int nBlockPos;
- if (!block.WriteToDisk(nFile, nBlockPos))
+ CDiskBlockPos blockPos(0);
+ if (!block.WriteToDisk(blockPos))
return error("LoadBlockIndex() : writing genesis block to disk failed");
- if (!block.AddToBlockIndex(nFile, nBlockPos))
+ if (!block.AddToBlockIndex(blockPos))
return error("LoadBlockIndex() : genesis block not accepted");
}
@@ -2219,11 +2186,9 @@ void PrintBlockTree()
// print item
CBlock block;
block.ReadFromDisk(pindex);
- printf("%d (%u,%u) %s %s tx %"PRIszu"",
+ printf("%d (%s) %s tx %"PRIszu"",
pindex->nHeight,
- pindex->nFile,
- pindex->nBlockPos,
- block.GetHash().ToString().substr(0,20).c_str(),
+ pindex->GetBlockPos().GetFileName("").string().c_str(),
DateTimeStrFormat("%x %H:%M:%S", block.GetBlockTime()).c_str(),
block.vtx.size());
@@ -3693,9 +3658,9 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
continue;
- if (!tx.ConnectInputs(mapInputs, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, false, true))
+ if (!tx.ConnectInputs(mapInputs, mapTestPoolTmp, CDiskTxPos(true), pindexPrev, false, true))
continue;
- mapTestPoolTmp[tx.GetHash()] = CTxIndex(CDiskTxPos(1,1,1), tx.vout.size());
+ mapTestPoolTmp[tx.GetHash()] = CTxIndex(CDiskTxPos(true), tx.vout.size());
swap(mapTestPool, mapTestPoolTmp);
// Added
@@ -3743,7 +3708,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
pblock->nNonce = 0;
pblock->vtx[0].vin[0].scriptSig = scriptDummy;
- CBlockIndex indexDummy(1, 1, *pblock);
+ CBlockIndex indexDummy(*pblock);
indexDummy.pprev = pindexPrev;
indexDummy.nHeight = pindexPrev->nHeight + 1;
if (!pblock->ConnectBlock(txdb, &indexDummy, true))
diff --git a/src/main.h b/src/main.h
index 0c85286391..a1d6334746 100644
--- a/src/main.h
+++ b/src/main.h
@@ -80,14 +80,14 @@ static const uint64 nMinDiskSpace = 52428800;
class CReserveKey;
class CTxDB;
class CTxIndex;
+class CDiskBlockPos;
void RegisterWallet(CWallet* pwalletIn);
void UnregisterWallet(CWallet* pwalletIn);
void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false);
bool ProcessBlock(CNode* pfrom, CBlock* pblock);
bool CheckDiskSpace(uint64 nAdditionalBytes=0);
-FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
-FILE* AppendBlockFile(unsigned int& nFileRet);
+FILE* OpenBlockFile(const CDiskBlockPos &pos, const char* pszMode="rb");
bool LoadBlockIndex(bool fAllowNew=true);
void PrintBlockTree();
CBlockIndex* FindBlockByHeight(int nHeight);
@@ -118,34 +118,115 @@ bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock);
bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
+class CDiskBlockPos
+{
+public:
+ int nHeight;
+ int nAlternative;
+
+ CDiskBlockPos() {
+ SetNull();
+ }
+
+ CDiskBlockPos(int nHeightIn, int nAlternativeIn = 0) {
+ nHeight = nHeightIn;
+ nAlternative = nAlternativeIn;
+ }
+
+ std::string GetAlternative() const {
+ char c[9]={0,0,0,0,0,0,0,0,0};
+ char *cp = &c[8];
+ unsigned int n = nAlternative;
+ while (n > 0 && cp>c) {
+ n--;
+ *(--cp) = 'a' + (n % 26);
+ n /= 26;
+ }
+ return std::string(cp);
+ }
+
+ boost::filesystem::path GetDirectory(const boost::filesystem::path &base) const {
+ assert(nHeight != -1);
+ return base / strprintf("era%02u", nHeight / 210000) /
+ strprintf("cycle%04u", nHeight / 2016);
+ }
+
+ boost::filesystem::path GetFileName(const boost::filesystem::path &base) const {
+ return GetDirectory(base) / strprintf("%08u%s.blk", nHeight, GetAlternative().c_str());
+ }
+
+ // TODO: make thread-safe (lockfile, atomic file creation, ...?)
+ void MakeUnique(const boost::filesystem::path &base) {
+ while (boost::filesystem::exists(GetFileName(base)))
+ nAlternative++;
+ }
+
+ IMPLEMENT_SERIALIZE(({
+ CDiskBlockPos *me = const_cast<CDiskBlockPos*>(this);
+ if (!fRead) {
+ unsigned int nCode = (nHeight + 1) * 2 + (nAlternative > 0);
+ READWRITE(VARINT(nCode));
+ if (nAlternative > 0) {
+ unsigned int nAlt = nAlternative - 1;
+ READWRITE(VARINT(nAlt));
+ }
+ } else {
+ unsigned int nCode = 0;
+ READWRITE(VARINT(nCode));
+ me->nHeight = (nCode / 2) - 1;
+ if (nCode & 1) {
+ unsigned int nAlt = 0;
+ READWRITE(VARINT(nAlt));
+ me->nAlternative = 1 + nAlt;
+ } else {
+ me->nAlternative = 0;
+ }
+ }
+ });)
+
+ friend bool operator==(const CDiskBlockPos &a, const CDiskBlockPos &b) {
+ return ((a.nHeight == b.nHeight) && (a.nAlternative == b.nAlternative));
+ }
+
+ friend bool operator!=(const CDiskBlockPos &a, const CDiskBlockPos &b) {
+ return !(a == b);
+ }
+
+ void SetNull() { nHeight = -1; nAlternative = 0; }
+ bool IsNull() const { return ((nHeight == -1) && (nAlternative == 0)); }
+
+ void SetMemPool() { nHeight = -1; nAlternative = -1; }
+ bool IsMemPool() const { return ((nHeight == -1) && (nAlternative == -1)); }
+};
+
/** Position on disk for a particular transaction. */
class CDiskTxPos
{
public:
- unsigned int nFile;
- unsigned int nBlockPos;
+ CDiskBlockPos blockPos;
unsigned int nTxPos;
- CDiskTxPos()
+ CDiskTxPos(bool fInMemPool = false)
{
SetNull();
+ if (fInMemPool)
+ blockPos.SetMemPool();
}
- CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn)
- {
- nFile = nFileIn;
- nBlockPos = nBlockPosIn;
- nTxPos = nTxPosIn;
- }
+ CDiskTxPos(const CDiskBlockPos &block, unsigned int nTxPosIn) : blockPos(block), nTxPos(nTxPosIn) { }
- IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
- void SetNull() { nFile = (unsigned int) -1; nBlockPos = 0; nTxPos = 0; }
- bool IsNull() const { return (nFile == (unsigned int) -1); }
+ IMPLEMENT_SERIALIZE(
+ READWRITE(blockPos);
+ READWRITE(VARINT(nTxPos));
+ )
+
+ void SetNull() { blockPos.SetNull(); nTxPos = 0; }
+ bool IsNull() const { return blockPos.IsNull(); }
+ bool IsMemPool() const { return blockPos.IsMemPool(); }
friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
{
- return (a.nFile == b.nFile &&
- a.nBlockPos == b.nBlockPos &&
+ return (a.blockPos == b.blockPos &&
a.nTxPos == b.nTxPos);
}
@@ -158,8 +239,10 @@ public:
{
if (IsNull())
return "null";
+ else if (blockPos.IsMemPool())
+ return "mempool";
else
- return strprintf("(nFile=%u, nBlockPos=%u, nTxPos=%u)", nFile, nBlockPos, nTxPos);
+ return strprintf("(%s, nTxPos=%u)", blockPos.GetFileName("").string().c_str(), nTxPos);
}
void print() const
@@ -545,7 +628,7 @@ public:
bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
{
- CAutoFile filein = CAutoFile(OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb"), SER_DISK, CLIENT_VERSION);
+ CAutoFile filein = CAutoFile(OpenBlockFile(pos.blockPos, pfileRet ? "rb+" : "rb"), SER_DISK, CLIENT_VERSION);
if (!filein)
return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
@@ -1215,22 +1298,15 @@ public:
}
- bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
+ bool WriteToDisk(CDiskBlockPos &pos)
{
// Open history file to append
- CAutoFile fileout = CAutoFile(AppendBlockFile(nFileRet), SER_DISK, CLIENT_VERSION);
+ pos.MakeUnique(GetDataDir());
+ CAutoFile fileout = CAutoFile(OpenBlockFile(pos, "ab"), SER_DISK, CLIENT_VERSION);
if (!fileout)
return error("CBlock::WriteToDisk() : AppendBlockFile failed");
- // Write index header
- unsigned int nSize = fileout.GetSerializeSize(*this);
- fileout << FLATDATA(pchMessageStart) << nSize;
-
// Write block
- long fileOutPos = ftell(fileout);
- if (fileOutPos < 0)
- return error("CBlock::WriteToDisk() : ftell failed");
- nBlockPosRet = fileOutPos;
fileout << *this;
// Flush stdio buffers and commit to disk before returning
@@ -1241,12 +1317,12 @@ public:
return true;
}
- bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
+ bool ReadFromDisk(const CDiskBlockPos &pos, bool fReadTransactions = true)
{
SetNull();
// Open history file to read
- CAutoFile filein = CAutoFile(OpenBlockFile(nFile, nBlockPos, "rb"), SER_DISK, CLIENT_VERSION);
+ CAutoFile filein = CAutoFile(OpenBlockFile(pos, "rb"), SER_DISK, CLIENT_VERSION);
if (!filein)
return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
if (!fReadTransactions)
@@ -1294,7 +1370,7 @@ public:
bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck=false);
bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
- bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
+ bool AddToBlockIndex(const CDiskBlockPos &pos);
bool CheckBlock(bool fCheckPOW=true, bool fCheckMerkleRoot=true) const;
bool AcceptBlock();
@@ -1320,9 +1396,8 @@ public:
const uint256* phashBlock;
CBlockIndex* pprev;
CBlockIndex* pnext;
- unsigned int nFile;
- unsigned int nBlockPos;
int nHeight;
+ unsigned int nAlternative;
CBigNum bnChainWork;
// block header
@@ -1338,10 +1413,9 @@ public:
phashBlock = NULL;
pprev = NULL;
pnext = NULL;
- nFile = 0;
- nBlockPos = 0;
nHeight = 0;
bnChainWork = 0;
+ nAlternative = 0;
nVersion = 0;
hashMerkleRoot = 0;
@@ -1350,15 +1424,14 @@ public:
nNonce = 0;
}
- CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
+ CBlockIndex(CBlock& block)
{
phashBlock = NULL;
pprev = NULL;
pnext = NULL;
- nFile = nFileIn;
- nBlockPos = nBlockPosIn;
nHeight = 0;
bnChainWork = 0;
+ nAlternative = 0;
nVersion = block.nVersion;
hashMerkleRoot = block.hashMerkleRoot;
@@ -1367,6 +1440,10 @@ public:
nNonce = block.nNonce;
}
+ CDiskBlockPos GetBlockPos() const {
+ return CDiskBlockPos(nHeight, nAlternative);
+ }
+
CBlock GetBlockHeader() const
{
CBlock block;
@@ -1444,11 +1521,10 @@ public:
static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart,
unsigned int nRequired, unsigned int nToCheck);
-
std::string ToString() const
{
- return strprintf("CBlockIndex(pprev=%p, pnext=%p, nFile=%u, nBlockPos=%-6u nHeight=%d, merkle=%s, hashBlock=%s)",
- pprev, pnext, nFile, nBlockPos, nHeight,
+ return strprintf("CBlockIndex(pprev=%p, pnext=%p, nHeight=%d, merkle=%s, hashBlock=%s)",
+ pprev, pnext, nHeight,
hashMerkleRoot.ToString().substr(0,10).c_str(),
GetBlockHash().ToString().substr(0,20).c_str());
}
@@ -1486,9 +1562,8 @@ public:
READWRITE(nVersion);
READWRITE(hashNext);
- READWRITE(nFile);
- READWRITE(nBlockPos);
READWRITE(nHeight);
+ READWRITE(nAlternative);
// block header
READWRITE(this->nVersion);