diff options
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 103 |
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)) |