mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-13 07:28:59 +01:00
Prepare database format for multi-stage block processing
This commit adds a status field and a transaction counter to the block indexes.
This commit is contained in:
111
src/main.h
111
src/main.h
@@ -23,6 +23,8 @@ class CInv;
|
||||
class CRequestTracker;
|
||||
class CNode;
|
||||
|
||||
class CBlockIndexWorkComparator;
|
||||
|
||||
static const unsigned int MAX_BLOCK_SIZE = 1000000;
|
||||
static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
|
||||
static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
|
||||
@@ -55,6 +57,7 @@ extern CScript COINBASE_FLAGS;
|
||||
|
||||
extern CCriticalSection cs_main;
|
||||
extern std::map<uint256, CBlockIndex*> mapBlockIndex;
|
||||
extern std::set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexValid;
|
||||
extern uint256 hashGenesisBlock;
|
||||
extern CBlockIndex* pindexGenesisBlock;
|
||||
extern int nBestHeight;
|
||||
@@ -114,6 +117,9 @@ int GetNumBlocksOfPeers();
|
||||
bool IsInitialBlockDownload();
|
||||
std::string GetWarnings(std::string strFor);
|
||||
bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false);
|
||||
bool SetBestChain(CBlockIndex* pindexNew);
|
||||
bool ConnectBestBlock();
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1234,9 +1240,6 @@ public:
|
||||
// Read a block from disk
|
||||
bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
|
||||
|
||||
// Make this block (with given index) the new tip of the active block chain
|
||||
bool SetBestChain(CBlockIndex* pindexNew);
|
||||
|
||||
// Add this block to the block index, and if necessary, switch the active block chain to this
|
||||
bool AddToBlockIndex(const CDiskBlockPos &pos);
|
||||
|
||||
@@ -1308,6 +1311,24 @@ extern CCriticalSection cs_LastBlockFile;
|
||||
extern CBlockFileInfo infoLastBlockFile;
|
||||
extern int nLastBlockFile;
|
||||
|
||||
enum BlockStatus {
|
||||
BLOCK_VALID_UNKNOWN = 0,
|
||||
BLOCK_VALID_HEADER = 1, // parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future
|
||||
BLOCK_VALID_TREE = 2, // parent found, difficulty matches, timestamp >= median previous, checkpoint
|
||||
BLOCK_VALID_TRANSACTIONS = 3, // only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid, no duplicate txids, sigops, size, merkle root
|
||||
BLOCK_VALID_CHAIN = 4, // outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends, BIP30
|
||||
BLOCK_VALID_SCRIPTS = 5, // scripts/signatures ok
|
||||
BLOCK_VALID_MASK = 7,
|
||||
|
||||
BLOCK_HAVE_DATA = 8, // full block available in blk*.dat
|
||||
BLOCK_HAVE_UNDO = 16, // undo data available in rev*.dat
|
||||
BLOCK_HAVE_MASK = 24,
|
||||
|
||||
BLOCK_FAILED_VALID = 32, // stage after last reached validness failed
|
||||
BLOCK_FAILED_CHILD = 64, // descends from failed block
|
||||
BLOCK_FAILED_MASK = 96
|
||||
};
|
||||
|
||||
/** The block chain is a tree shaped structure starting with the
|
||||
* genesis block at the root, with each block potentially having multiple
|
||||
* candidates to be the next block. pprev and pnext link a path through the
|
||||
@@ -1318,14 +1339,40 @@ extern int nLastBlockFile;
|
||||
class CBlockIndex
|
||||
{
|
||||
public:
|
||||
// pointer to the hash of the block, if any. memory is owned by this CBlockIndex
|
||||
const uint256* phashBlock;
|
||||
|
||||
// pointer to the index of the predecessor of this block
|
||||
CBlockIndex* pprev;
|
||||
|
||||
// (memory only) pointer to the index of the *active* successor of this block
|
||||
CBlockIndex* pnext;
|
||||
|
||||
// height of the entry in the chain. The genesis block has height 0
|
||||
int nHeight;
|
||||
CDiskBlockPos pos;
|
||||
|
||||
// Which # file this block is stored in (blk?????.dat)
|
||||
int nFile;
|
||||
|
||||
// Byte offset within blk?????.dat where this block's data is stored
|
||||
unsigned int nDataPos;
|
||||
|
||||
// Byte offset within rev?????.dat where this block's undo data is stored
|
||||
unsigned int nUndoPos;
|
||||
|
||||
// (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block
|
||||
CBigNum bnChainWork;
|
||||
|
||||
// Number of transactions in this block.
|
||||
// Note: in a potential headers-first mode, this number cannot be relied upon
|
||||
unsigned int nTx;
|
||||
|
||||
// (memory only) Number of transactions in the chain up to and including this block
|
||||
unsigned int nChainTx; // change to 64-bit type when necessary; won't happen before 2030
|
||||
|
||||
// Verification status of this block. See enum BlockStatus
|
||||
unsigned int nStatus;
|
||||
|
||||
// block header
|
||||
int nVersion;
|
||||
uint256 hashMerkleRoot;
|
||||
@@ -1340,9 +1387,13 @@ public:
|
||||
pprev = NULL;
|
||||
pnext = NULL;
|
||||
nHeight = 0;
|
||||
pos.SetNull();
|
||||
nFile = 0;
|
||||
nDataPos = 0;
|
||||
nUndoPos = 0;
|
||||
bnChainWork = 0;
|
||||
nTx = 0;
|
||||
nChainTx = 0;
|
||||
nStatus = 0;
|
||||
|
||||
nVersion = 0;
|
||||
hashMerkleRoot = 0;
|
||||
@@ -1357,9 +1408,13 @@ public:
|
||||
pprev = NULL;
|
||||
pnext = NULL;
|
||||
nHeight = 0;
|
||||
pos.SetNull();
|
||||
nFile = 0;
|
||||
nDataPos = 0;
|
||||
nUndoPos = 0;
|
||||
bnChainWork = 0;
|
||||
nTx = 0;
|
||||
nChainTx = 0;
|
||||
nStatus = 0;
|
||||
|
||||
nVersion = block.nVersion;
|
||||
hashMerkleRoot = block.hashMerkleRoot;
|
||||
@@ -1369,15 +1424,22 @@ public:
|
||||
}
|
||||
|
||||
CDiskBlockPos GetBlockPos() const {
|
||||
return pos;
|
||||
CDiskBlockPos ret;
|
||||
if (nStatus & BLOCK_HAVE_DATA) {
|
||||
ret.nFile = nFile;
|
||||
ret.nPos = nDataPos;
|
||||
} else
|
||||
ret.SetNull();
|
||||
return ret;
|
||||
}
|
||||
|
||||
CDiskBlockPos GetUndoPos() const {
|
||||
CDiskBlockPos ret = pos;
|
||||
if (nUndoPos == 0)
|
||||
CDiskBlockPos ret;
|
||||
if (nStatus & BLOCK_HAVE_UNDO) {
|
||||
ret.nFile = nFile;
|
||||
ret.nPos = nUndoPos;
|
||||
} else
|
||||
ret.SetNull();
|
||||
else
|
||||
ret.nPos = nUndoPos - 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1472,6 +1534,19 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct CBlockIndexWorkComparator
|
||||
{
|
||||
bool operator()(CBlockIndex *pa, CBlockIndex *pb) {
|
||||
if (pa->bnChainWork > pb->bnChainWork) return false;
|
||||
if (pa->bnChainWork < pb->bnChainWork) return true;
|
||||
|
||||
if (pa->GetBlockHash() < pb->GetBlockHash()) return false;
|
||||
if (pa->GetBlockHash() > pb->GetBlockHash()) return true;
|
||||
|
||||
return false; // identical blocks
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** Used to marshal pointers into hashes for db storage. */
|
||||
@@ -1491,11 +1566,17 @@ public:
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
if (!(nType & SER_GETHASH))
|
||||
READWRITE(nVersion);
|
||||
READWRITE(VARINT(nVersion));
|
||||
|
||||
READWRITE(nHeight);
|
||||
READWRITE(pos);
|
||||
READWRITE(nUndoPos);
|
||||
READWRITE(VARINT(nHeight));
|
||||
READWRITE(VARINT(nStatus));
|
||||
READWRITE(VARINT(nTx));
|
||||
if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO))
|
||||
READWRITE(VARINT(nFile));
|
||||
if (nStatus & BLOCK_HAVE_DATA)
|
||||
READWRITE(VARINT(nDataPos));
|
||||
if (nStatus & BLOCK_HAVE_UNDO)
|
||||
READWRITE(VARINT(nUndoPos));
|
||||
|
||||
// block header
|
||||
READWRITE(this->nVersion);
|
||||
|
||||
Reference in New Issue
Block a user