aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp103
1 files changed, 34 insertions, 69 deletions
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))