com.google.bitcoin.core
Class AbstractBlockChain

java.lang.Object
  extended by com.google.bitcoin.core.AbstractBlockChain
Direct Known Subclasses:
BlockChain, FullPrunedBlockChain

public abstract class AbstractBlockChain
extends Object

An AbstractBlockChain holds a series of Block objects, links them together, and knows how to verify that the chain follows the rules of the NetworkParameters for this chain.

It can be connected to a Wallet, and also BlockChainListeners that can receive transactions and notifications of re-organizations.

An AbstractBlockChain implementation must be connected to a BlockStore implementation. The chain object by itself doesn't store any data, that's delegated to the store. Which store you use is a decision best made by reading the getting started guide, but briefly, fully validating block chains need fully validating stores. In the lightweight SPV mode, a SPVBlockStore is the right choice.

This class implements an abstract class which makes it simple to create a BlockChain that does/doesn't do full verification. It verifies headers and is implements most of what is required to implement SPV mode, but also provides callback hooks which can be used to do full verification.

There are two subclasses of AbstractBlockChain that are useful: BlockChain, which is the simplest class and implements simplified payment verification. This is a lightweight and efficient mode that does not verify the contents of blocks, just their headers. A FullPrunedBlockChain paired with a H2FullPrunedBlockStore implements full verification, which is equivalent to the original Satoshi client. To learn more about the alternative security models, please consult the articles on the website.

Theory

The 'chain' is actually a tree although in normal operation it operates mostly as a list of Blocks. When multiple new head blocks are found simultaneously, there are multiple stories of the economy competing to become the one true consensus. This can happen naturally when two miners solve a block within a few seconds of each other, or it can happen when the chain is under attack.

A reference to the head block of the best known chain is stored. If you can reach the genesis block by repeatedly walking through the prevBlock pointers, then we say this is a full chain. If you cannot reach the genesis block we say it is an orphan chain. Orphan chains can occur when blocks are solved and received during the initial block chain download, or if we connect to a peer that doesn't send us blocks in order.

A reorganize occurs when the blocks that make up the best known chain changes. Note that simply adding a new block to the top of the best chain isn't as reorganize, but that a reorganize is always triggered by adding a new block that connects to some other (non best head) block. By "best" we mean the chain representing the largest amount of work done.

Every so often the block chain passes a difficulty transition point. At that time, all the blocks in the last 2016 blocks are examined and a new difficulty target is calculated from them.


Nested Class Summary
static class AbstractBlockChain.NewBlockType
           
 
Field Summary
protected  StoredBlock chainHead
          Tracks the top of the best known chain.
static double FP_ESTIMATOR_ALPHA
          False positive estimation uses a double exponential moving average.
static double FP_ESTIMATOR_BETA
          False positive estimation uses a double exponential moving average.
protected  ReentrantLock lock
           
protected  NetworkParameters params
           
 
Constructor Summary
AbstractBlockChain(NetworkParameters params, List<BlockChainListener> listeners, BlockStore blockStore)
          Constructs a BlockChain connected to the given list of listeners (eg, wallets) and a store.
 
Method Summary
 boolean add(Block block)
          Processes a received block and tries to add it to the chain.
 boolean add(FilteredBlock block)
          Processes a received block and tries to add it to the chain.
 void addListener(BlockChainListener listener)
          Adds a generic BlockChainListener listener to the chain.
 void addListener(BlockChainListener listener, Executor executor)
          Adds a generic BlockChainListener listener to the chain.
protected abstract  StoredBlock addToBlockStore(StoredBlock storedPrev, Block block)
          Adds/updates the given Block with the block store.
protected abstract  StoredBlock addToBlockStore(StoredBlock storedPrev, Block header, TransactionOutputChanges txOutputChanges)
          Adds/updates the given StoredBlock with the block store.
 void addWallet(Wallet wallet)
          Add a wallet to the BlockChain.
protected abstract  TransactionOutputChanges connectTransactions(int height, Block block)
          Connect each transaction in block.transactions, verifying them as we go and removing spent outputs If an error is encountered in a transaction, no changes should be made to the underlying BlockStore.
protected abstract  TransactionOutputChanges connectTransactions(StoredBlock newBlock)
          Load newBlock from BlockStore and connect its transactions, returning changes to the set of unspent transactions.
protected abstract  void disconnectTransactions(StoredBlock block)
          Disconnect each transaction in the block (after reading it from the block store) Only called if(shouldVerifyTransactions())
protected abstract  void doSetChainHead(StoredBlock chainHead)
          Called before setting chain head in memory.
 Date estimateBlockTime(int height)
          Returns an estimate of when the given block will be reached, assuming a perfect 10 minute average for each block.
 int getBestChainHeight()
           
 BlockStore getBlockStore()
          Returns the BlockStore the chain was constructed with.
 StoredBlock getChainHead()
          Returns the block at the head of the current best chain.
 double getFalsePositiveRate()
          The false positive rate is the average over all blockchain transactions of: - 1.0 if the transaction was false-positive (was irrelevant to all listeners) - 0.0 if the transaction was relevant or filtered out
 com.google.common.util.concurrent.ListenableFuture<StoredBlock> getHeightFuture(int height)
          Returns a future that completes when the block chain has reached the given height.
 Block getOrphanRoot(Sha256Hash from)
          An orphan block is one that does not connect to the chain anywhere (ie we can't find its parent, therefore it's an orphan).
protected abstract  StoredBlock getStoredBlockInCurrentScope(Sha256Hash hash)
          For a standard BlockChain, this should return blockStore.get(hash), for a FullPrunedBlockChain blockStore.getOnceUndoableStoredBlock(hash)
 boolean isOrphan(Sha256Hash block)
          Returns true if the given block is currently in the orphan blocks list.
protected abstract  void notSettingChainHead()
          Called if we (possibly) previously called disconnectTransaction/connectTransactions, but will not be calling preSetChainHead as a block failed verification.
 void removeListener(BlockChainListener listener)
          Removes the given BlockChainListener from the chain.
 void removeWallet(Wallet wallet)
          Removes a wallet from the chain.
 void resetFalsePositiveEstimate()
          Resets estimates of false positives.
protected  void setChainHead(StoredBlock chainHead)
           
protected abstract  boolean shouldVerifyTransactions()
          Whether or not we are maintaining a set of unspent outputs and are verifying all transactions.
protected  void trackFilteredTransactions(int count)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

lock

protected final ReentrantLock lock

chainHead

protected StoredBlock chainHead
Tracks the top of the best known chain.

Following this one down to the genesis block produces the story of the economy from the creation of Bitcoin until the present day. The chain head can change if a new set of blocks is received that results in a chain of greater work than the one obtained by following this one down. In that case a reorganize is triggered, potentially invalidating transactions in our wallet.


params

protected final NetworkParameters params

FP_ESTIMATOR_ALPHA

public static final double FP_ESTIMATOR_ALPHA
False positive estimation uses a double exponential moving average.

See Also:
Constant Field Values

FP_ESTIMATOR_BETA

public static final double FP_ESTIMATOR_BETA
False positive estimation uses a double exponential moving average.

See Also:
Constant Field Values
Constructor Detail

AbstractBlockChain

public AbstractBlockChain(NetworkParameters params,
                          List<BlockChainListener> listeners,
                          BlockStore blockStore)
                   throws BlockStoreException
Constructs a BlockChain connected to the given list of listeners (eg, wallets) and a store.

Throws:
BlockStoreException
Method Detail

addWallet

public void addWallet(Wallet wallet)
Add a wallet to the BlockChain. Note that the wallet will be unaffected by any blocks received while it was not part of this BlockChain. This method is useful if the wallet has just been created, and its keys have never been in use, or if the wallet has been loaded along with the BlockChain. Note that adding multiple wallets is not well tested!


removeWallet

public void removeWallet(Wallet wallet)
Removes a wallet from the chain.


addListener

public void addListener(BlockChainListener listener)
Adds a generic BlockChainListener listener to the chain.


addListener

public void addListener(BlockChainListener listener,
                        Executor executor)
Adds a generic BlockChainListener listener to the chain.


removeListener

public void removeListener(BlockChainListener listener)
Removes the given BlockChainListener from the chain.


getBlockStore

public BlockStore getBlockStore()
Returns the BlockStore the chain was constructed with. You can use this to iterate over the chain.


addToBlockStore

protected abstract StoredBlock addToBlockStore(StoredBlock storedPrev,
                                               Block block)
                                        throws BlockStoreException,
                                               VerificationException
Adds/updates the given Block with the block store. This version is used when the transactions have not been verified.

Parameters:
storedPrev - The StoredBlock which immediately precedes block.
block - The Block to add/update.
Returns:
the newly created StoredBlock
Throws:
BlockStoreException
VerificationException

addToBlockStore

protected abstract StoredBlock addToBlockStore(StoredBlock storedPrev,
                                               Block header,
                                               @Nullable
                                               TransactionOutputChanges txOutputChanges)
                                        throws BlockStoreException,
                                               VerificationException
Adds/updates the given StoredBlock with the block store. This version is used when the transactions have already been verified to properly spend txOutputChanges.

Parameters:
storedPrev - The StoredBlock which immediately precedes block.
header - The StoredBlock to add/update.
txOutputChanges - The total sum of all changes made by this block to the set of open transaction outputs (from a call to connectTransactions), if in fully verifying mode (null otherwise).
Returns:
the newly created StoredBlock
Throws:
BlockStoreException
VerificationException

doSetChainHead

protected abstract void doSetChainHead(StoredBlock chainHead)
                                throws BlockStoreException
Called before setting chain head in memory. Should write the new head to block store and then commit any database transactions that were started by disconnectTransactions/connectTransactions.

Throws:
BlockStoreException

notSettingChainHead

protected abstract void notSettingChainHead()
                                     throws BlockStoreException
Called if we (possibly) previously called disconnectTransaction/connectTransactions, but will not be calling preSetChainHead as a block failed verification. Can be used to abort database transactions that were started by disconnectTransactions/connectTransactions.

Throws:
BlockStoreException

getStoredBlockInCurrentScope

protected abstract StoredBlock getStoredBlockInCurrentScope(Sha256Hash hash)
                                                     throws BlockStoreException
For a standard BlockChain, this should return blockStore.get(hash), for a FullPrunedBlockChain blockStore.getOnceUndoableStoredBlock(hash)

Throws:
BlockStoreException

add

public boolean add(Block block)
            throws VerificationException,
                   PrunedException
Processes a received block and tries to add it to the chain. If there's something wrong with the block an exception is thrown. If the block is OK but cannot be connected to the chain at this time, returns false. If the block can be connected to the chain, returns true. Accessing block's transactions in another thread while this method runs may result in undefined behavior.

Throws:
VerificationException
PrunedException

add

public boolean add(FilteredBlock block)
            throws VerificationException,
                   PrunedException
Processes a received block and tries to add it to the chain. If there's something wrong with the block an exception is thrown. If the block is OK but cannot be connected to the chain at this time, returns false. If the block can be connected to the chain, returns true.

Throws:
VerificationException
PrunedException

shouldVerifyTransactions

protected abstract boolean shouldVerifyTransactions()
Whether or not we are maintaining a set of unspent outputs and are verifying all transactions. Also indicates that all calls to add() should provide a block containing transactions


connectTransactions

protected abstract TransactionOutputChanges connectTransactions(int height,
                                                                Block block)
                                                         throws VerificationException,
                                                                BlockStoreException
Connect each transaction in block.transactions, verifying them as we go and removing spent outputs If an error is encountered in a transaction, no changes should be made to the underlying BlockStore. and a VerificationException should be thrown. Only called if(shouldVerifyTransactions())

Returns:
The full set of all changes made to the set of open transaction outputs.
Throws:
VerificationException - if an attempt was made to spend an already-spent output, or if a transaction incorrectly solved an output script.
BlockStoreException - if the block store had an underlying error.

connectTransactions

protected abstract TransactionOutputChanges connectTransactions(StoredBlock newBlock)
                                                         throws VerificationException,
                                                                BlockStoreException,
                                                                PrunedException
Load newBlock from BlockStore and connect its transactions, returning changes to the set of unspent transactions. If an error is encountered in a transaction, no changes should be made to the underlying BlockStore. Only called if(shouldVerifyTransactions())

Returns:
The full set of all changes made to the set of open transaction outputs.
Throws:
PrunedException - if newBlock does not exist as a StoredUndoableBlock in the block store.
VerificationException - if an attempt was made to spend an already-spent output, or if a transaction incorrectly solved an output script.
BlockStoreException - if the block store had an underlying error or newBlock does not exist in the block store at all.

disconnectTransactions

protected abstract void disconnectTransactions(StoredBlock block)
                                        throws PrunedException,
                                               BlockStoreException
Disconnect each transaction in the block (after reading it from the block store) Only called if(shouldVerifyTransactions())

Throws:
PrunedException - if block does not exist as a StoredUndoableBlock in the block store.
BlockStoreException - if the block store had an underlying error or block does not exist in the block store at all.

getBestChainHeight

public int getBestChainHeight()
Returns:
the height of the best known chain, convenience for getChainHead().getHeight().

setChainHead

protected void setChainHead(StoredBlock chainHead)
                     throws BlockStoreException
Throws:
BlockStoreException

getChainHead

public StoredBlock getChainHead()
Returns the block at the head of the current best chain. This is the block which represents the greatest amount of cumulative work done.


getOrphanRoot

@Nullable
public Block getOrphanRoot(Sha256Hash from)
An orphan block is one that does not connect to the chain anywhere (ie we can't find its parent, therefore it's an orphan). Typically this occurs when we are downloading the chain and didn't reach the head yet, and/or if a block is solved whilst we are downloading. It's possible that we see a small amount of orphan blocks which chain together, this method tries walking backwards through the known orphan blocks to find the bottom-most.

Returns:
from or one of froms parents, or null if "from" does not identify an orphan block

isOrphan

public boolean isOrphan(Sha256Hash block)
Returns true if the given block is currently in the orphan blocks list.


estimateBlockTime

public Date estimateBlockTime(int height)
Returns an estimate of when the given block will be reached, assuming a perfect 10 minute average for each block. This is useful for turning transaction lock times into human readable times. Note that a height in the past will still be estimated, even though the time of solving is actually known (we won't scan backwards through the chain to obtain the right answer).


getHeightFuture

public com.google.common.util.concurrent.ListenableFuture<StoredBlock> getHeightFuture(int height)
Returns a future that completes when the block chain has reached the given height. Yields the StoredBlock of the block that reaches that height first. The future completes on a peer thread.


getFalsePositiveRate

public double getFalsePositiveRate()
The false positive rate is the average over all blockchain transactions of: - 1.0 if the transaction was false-positive (was irrelevant to all listeners) - 0.0 if the transaction was relevant or filtered out


trackFilteredTransactions

protected void trackFilteredTransactions(int count)

resetFalsePositiveEstimate

public void resetFalsePositiveEstimate()
Resets estimates of false positives. Used when the filter is sent to the peer.



Copyright © 2014. All rights reserved.