Split the BlockChain.add method out into some smaller functions.

This commit is contained in:
Mike Hearn
2011-04-21 09:19:05 +00:00
parent 90c7ec80ff
commit 1e2f3ae3e2

View File

@@ -113,22 +113,9 @@ public class BlockChain {
LOG(block.toString()); LOG(block.toString());
throw e; throw e;
} }
// If this block is a full block, scan, otherwise it's just headers (eg from getheaders or a unit test). // Inform the wallet about transactions relevant to our keys, then throw away the transaction data.
if (block.transactions != null) { extractRelevantTransactions(block);
// Scan the transactions to find out if any sent money to us. We don't care about the rest. assert block.transactions == null;
// TODO: We should also scan to see if any of our own keys sent money to somebody else and became spent.
for (Transaction tx : block.transactions) {
try {
scanTransaction(tx);
} catch (ScriptException e) {
// We don't want scripts we don't understand to break the block chain,
// so just note that this tx was not scanned here and continue.
LOG("Failed to parse a script: " + e.toString());
}
}
}
// We don't need the transaction data anymore. Free up some memory.
block.transactions = null;
if (blockStore.get(block.getHash()) != null) { if (blockStore.get(block.getHash()) != null) {
LOG("Already have block"); LOG("Already have block");
@@ -143,10 +130,19 @@ public class BlockChain {
unconnectedBlocks.add(block); unconnectedBlocks.add(block);
return false; return false;
} else { } else {
// The block connects to somewhere on the chain. Not necessarily the top of the best known chain. // It connects to somewhere on the chain. Not necessarily the top of the best known chain.
checkDifficultyTransitions(storedPrev, block); checkDifficultyTransitions(storedPrev, block);
connectAndStoreBlock(block, storedPrev);
}
if (tryConnecting)
tryConnectingUnconnected();
return true;
}
private void connectAndStoreBlock(Block block, StoredBlock storedPrev) throws BlockStoreException, VerificationException {
StoredBlock newStoredBlock = storedPrev.build(block); StoredBlock newStoredBlock = storedPrev.build(block);
// Store it.
blockStore.put(newStoredBlock); blockStore.put(newStoredBlock);
if (storedPrev.equals(chainHead)) { if (storedPrev.equals(chainHead)) {
// This block connects to the best known block, it is a normal continuation of the system. // This block connects to the best known block, it is a normal continuation of the system.
@@ -166,10 +162,25 @@ public class BlockChain {
} }
} }
if (tryConnecting) private void extractRelevantTransactions(Block block) throws VerificationException {
tryConnectingUnconnected(); // If this block is a full block, scan, otherwise it's just headers (eg from getheaders or a unit test).
if (block.transactions != null) {
return true; // Scan the transactions to find out if any sent money to us. We don't care about the rest.
// TODO: We should also scan to see if any of our own keys sent money to somebody else and became spent.
for (Transaction tx : block.transactions) {
try {
scanTransaction(tx);
} catch (ScriptException e) {
// We don't want scripts we don't understand to break the block chain,
// so just note that this tx was not scanned here and continue.
LOG("Failed to parse a script: " + e.toString());
}
}
}
// Throw away the transactions. We have to do this because we can't hold all the transaction data for the
// production chain in memory at once. Because BitCoinJ implements client mode/simplified payment
// verification we don't store the transactions to disk or use them later anyway.
block.transactions = null;
} }
private void setChainHead(StoredBlock chainHead) { private void setChainHead(StoredBlock chainHead) {