3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-13 10:45:51 +00:00

Context: add c'tors that take a context to [Abstract/FullPruned/]BlockChain and PeerGroup. The existing c'tors now do a consistency check against the existing context or create a new one on the fly.

This commit is contained in:
Mike Hearn 2015-04-05 19:52:58 +02:00
parent 960e58343e
commit 4c12127501
7 changed files with 98 additions and 48 deletions

View File

@ -137,16 +137,21 @@ public abstract class AbstractBlockChain {
private double falsePositiveTrend;
private double previousFalsePositiveRate;
/** See {@link #AbstractBlockChain(Context, List, BlockStore)} */
public AbstractBlockChain(NetworkParameters params, List<BlockChainListener> listeners,
BlockStore blockStore) throws BlockStoreException {
this(Context.getOrCreate(params), listeners, blockStore);
}
/**
* Constructs a BlockChain connected to the given list of listeners (eg, wallets) and a store.
*/
public AbstractBlockChain(NetworkParameters params, List<BlockChainListener> listeners,
public AbstractBlockChain(Context context, List<BlockChainListener> listeners,
BlockStore blockStore) throws BlockStoreException {
this.blockStore = blockStore;
chainHead = blockStore.getChainHead();
log.info("chain head is at height {}:\n{}", chainHead.getHeight(), chainHead.getHeader());
this.params = params;
this.params = context.getParams();
this.listeners = new CopyOnWriteArrayList<ListenerRegistration<BlockChainListener>>();
for (BlockChainListener l : listeners) addListener(l, Threading.SAME_THREAD);
}

View File

@ -25,11 +25,12 @@ import org.bitcoinj.store.BlockStoreException;
import java.util.ArrayList;
import java.util.List;
// TODO: Rename this class to SPVBlockChain at some point.
/**
* <p>A BlockChain implements the <i>simplified payment verification</i> mode of the Bitcoin protocol. It is the right
* A BlockChain implements the <i>simplified payment verification</i> mode of the Bitcoin protocol. It is the right
* choice to use for programs that have limited resources as it won't verify transactions signatures or attempt to store
* all of the block chain. Really, this class should be called SPVBlockChain but for backwards compatibility it is not.
* </p>
*/
public class BlockChain extends AbstractBlockChain {
/** Keeps a map of block hashes to StoredBlocks. */
@ -44,17 +45,25 @@ public class BlockChain extends AbstractBlockChain {
* {@link org.bitcoinj.store.MemoryBlockStore} if you want to hold all headers in RAM and don't care about
* disk serialization (this is rare).</p>
*/
public BlockChain(NetworkParameters params, Wallet wallet, BlockStore blockStore) throws BlockStoreException {
this(params, new ArrayList<BlockChainListener>(), blockStore);
Context.getOrCreate(params);
if (wallet != null)
public BlockChain(Context context, Wallet wallet, BlockStore blockStore) throws BlockStoreException {
this(context, new ArrayList<BlockChainListener>(), blockStore);
addWallet(wallet);
}
/** See {@link #BlockChain(Context, Wallet, BlockStore)}} */
public BlockChain(NetworkParameters params, Wallet wallet, BlockStore blockStore) throws BlockStoreException {
this(Context.getOrCreate(params), wallet, blockStore);
}
/**
* Constructs a BlockChain that has no wallet at all. This is helpful when you don't actually care about sending
* and receiving coins but rather, just want to explore the network data structures.
*/
public BlockChain(Context context, BlockStore blockStore) throws BlockStoreException {
this(context, new ArrayList<BlockChainListener>(), blockStore);
}
/** See {@link #BlockChain(Context, BlockStore)} */
public BlockChain(NetworkParameters params, BlockStore blockStore) throws BlockStoreException {
this(params, new ArrayList<BlockChainListener>(), blockStore);
}
@ -62,12 +71,16 @@ public class BlockChain extends AbstractBlockChain {
/**
* Constructs a BlockChain connected to the given list of listeners and a store.
*/
public BlockChain(NetworkParameters params, List<BlockChainListener> wallets,
BlockStore blockStore) throws BlockStoreException {
public BlockChain(Context params, List<BlockChainListener> wallets, BlockStore blockStore) throws BlockStoreException {
super(params, wallets, blockStore);
this.blockStore = blockStore;
}
/** See {@link #BlockChain(Context, List, BlockStore)} */
public BlockChain(NetworkParameters params, List<BlockChainListener> wallets, BlockStore blockStore) throws BlockStoreException {
this(Context.getOrCreate(params), wallets, blockStore);
}
@Override
protected StoredBlock addToBlockStore(StoredBlock storedPrev, Block blockHeader, TransactionOutputChanges txOutChanges)
throws BlockStoreException, VerificationException {

View File

@ -54,34 +54,48 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
private boolean runScripts = true;
/**
* Constructs a BlockChain connected to the given wallet and store. To obtain a {@link Wallet} you can construct
* Constructs a block chain connected to the given wallet and store. To obtain a {@link Wallet} you can construct
* one from scratch, or you can deserialize a saved wallet from disk using {@link Wallet#loadFromFile(java.io.File)}
*/
public FullPrunedBlockChain(NetworkParameters params, Wallet wallet, FullPrunedBlockStore blockStore) throws BlockStoreException {
this(params, new ArrayList<BlockChainListener>(), blockStore);
if (wallet != null)
public FullPrunedBlockChain(Context context, Wallet wallet, FullPrunedBlockStore blockStore) throws BlockStoreException {
this(context, new ArrayList<BlockChainListener>(), blockStore);
addWallet(wallet);
}
/**
* Constructs a BlockChain that has no wallet at all. This is helpful when you don't actually care about sending
* and receiving coins but rather, just want to explore the network data structures.
* Constructs a block chain connected to the given wallet and store. To obtain a {@link Wallet} you can construct
* one from scratch, or you can deserialize a saved wallet from disk using {@link Wallet#loadFromFile(java.io.File)}
*/
public FullPrunedBlockChain(NetworkParameters params, Wallet wallet, FullPrunedBlockStore blockStore) throws BlockStoreException {
this(Context.getOrCreate(params), wallet, blockStore);
}
/** Constructs a block chain connected to the given store. */
public FullPrunedBlockChain(Context context, FullPrunedBlockStore blockStore) throws BlockStoreException {
this(context, new ArrayList<BlockChainListener>(), blockStore);
}
/** See {@link #FullPrunedBlockChain(Context, Wallet, FullPrunedBlockStore)} */
public FullPrunedBlockChain(NetworkParameters params, FullPrunedBlockStore blockStore) throws BlockStoreException {
this(params, new ArrayList<BlockChainListener>(), blockStore);
this(Context.getOrCreate(params), blockStore);
}
/**
* Constructs a BlockChain connected to the given list of wallets and a store.
* Constructs a block chain connected to the given list of wallets and a store.
*/
public FullPrunedBlockChain(NetworkParameters params, List<BlockChainListener> listeners,
FullPrunedBlockStore blockStore) throws BlockStoreException {
super(params, listeners, blockStore);
public FullPrunedBlockChain(Context context, List<BlockChainListener> listeners, FullPrunedBlockStore blockStore) throws BlockStoreException {
super(context, listeners, blockStore);
this.blockStore = blockStore;
// Ignore upgrading for now
this.chainHead = blockStore.getVerifiedChainHead();
}
/** See {@link #FullPrunedBlockChain(Context, List, FullPrunedBlockStore)} */
public FullPrunedBlockChain(NetworkParameters params, List<BlockChainListener> listeners,
FullPrunedBlockStore blockStore) throws BlockStoreException {
this(Context.getOrCreate(params), listeners, blockStore);
}
@Override
protected StoredBlock addToBlockStore(StoredBlock storedPrev, Block header, TransactionOutputChanges txOutChanges)
throws BlockStoreException, VerificationException {

View File

@ -249,24 +249,36 @@ public class PeerGroup implements TransactionBroadcaster {
/** Whether bloom filter support is enabled when using a non FullPrunedBlockchain*/
private volatile boolean vBloomFilteringEnabled = true;
/**
* Creates a PeerGroup with the given parameters. No chain is provided so this node will report its chain height
* as zero to other peers. This constructor is useful if you just want to explore the network but aren't interested
* in downloading block data.
*
* @param params Network parameters
*/
/** See {@link #PeerGroup(Context)} */
public PeerGroup(NetworkParameters params) {
this(params, null);
}
/**
* Creates a PeerGroup for the given network and chain. Blocks will be passed to the chain as they are broadcast
* Creates a PeerGroup with the given context. No chain is provided so this node will report its chain height
* as zero to other peers. This constructor is useful if you just want to explore the network but aren't interested
* in downloading block data.
*/
public PeerGroup(Context context) {
this(context, null);
}
/** See {@link #PeerGroup(Context, AbstractBlockChain)} */
public PeerGroup(NetworkParameters params, @Nullable AbstractBlockChain chain) {
this(Context.getOrCreate(params), chain, new NioClientManager());
}
/**
* Creates a PeerGroup for the given context and chain. Blocks will be passed to the chain as they are broadcast
* and downloaded. This is probably the constructor you want to use.
*/
public PeerGroup(NetworkParameters params, @Nullable AbstractBlockChain chain) {
this(params, chain, new NioClientManager());
public PeerGroup(Context context, @Nullable AbstractBlockChain chain) {
this(context, chain, new NioClientManager());
}
/** See {@link #newWithTor(Context, AbstractBlockChain, TorClient)} */
public static PeerGroup newWithTor(NetworkParameters params, @Nullable AbstractBlockChain chain, TorClient torClient) throws TimeoutException {
return newWithTor(Context.getOrCreate(params), chain, torClient);
}
/**
@ -283,33 +295,38 @@ public class PeerGroup implements TransactionBroadcaster {
*
* @throws java.util.concurrent.TimeoutException if Tor fails to start within 20 seconds.
*/
public static PeerGroup newWithTor(NetworkParameters params, @Nullable AbstractBlockChain chain, TorClient torClient) throws TimeoutException {
public static PeerGroup newWithTor(Context context, @Nullable AbstractBlockChain chain, TorClient torClient) throws TimeoutException {
checkNotNull(torClient);
DRMWorkaround.maybeDisableExportControls();
BlockingClientManager manager = new BlockingClientManager(torClient.getSocketFactory());
final int CONNECT_TIMEOUT_MSEC = TOR_TIMEOUT_SECONDS * 1000;
manager.setConnectTimeoutMillis(CONNECT_TIMEOUT_MSEC);
PeerGroup result = new PeerGroup(params, chain, manager, torClient);
PeerGroup result = new PeerGroup(context, chain, manager, torClient);
result.setConnectTimeoutMillis(CONNECT_TIMEOUT_MSEC);
result.addPeerDiscovery(new TorDiscovery(params, torClient));
result.addPeerDiscovery(new TorDiscovery(context.getParams(), torClient));
return result;
}
/**
* Creates a new PeerGroup allowing you to specify the {@link ClientConnectionManager} which is used to create new
* connections and keep track of existing ones.
*/
/** See {@link #PeerGroup(Context, AbstractBlockChain, ClientConnectionManager)} */
public PeerGroup(NetworkParameters params, @Nullable AbstractBlockChain chain, ClientConnectionManager connectionManager) {
this(params, chain, connectionManager, null);
this(Context.getOrCreate(params), chain, connectionManager, null);
}
/**
* Creates a new PeerGroup allowing you to specify the {@link ClientConnectionManager} which is used to create new
* connections and keep track of existing ones.
*/
private PeerGroup(NetworkParameters params, @Nullable AbstractBlockChain chain, ClientConnectionManager connectionManager, @Nullable TorClient torClient) {
this.params = checkNotNull(params);
this.context = Context.getOrCreate(params);
public PeerGroup(Context context, @Nullable AbstractBlockChain chain, ClientConnectionManager connectionManager) {
this(context, chain, connectionManager, null);
}
/**
* Creates a new PeerGroup allowing you to specify the {@link ClientConnectionManager} which is used to create new
* connections and keep track of existing ones.
*/
private PeerGroup(Context context, @Nullable AbstractBlockChain chain, ClientConnectionManager connectionManager, @Nullable TorClient torClient) {
this.context = checkNotNull(context);
this.params = context.getParams();
this.chain = chain;
fastCatchupTimeSecs = params.getGenesisBlock().getTimeSeconds();
wallets = new CopyOnWriteArrayList<Wallet>();

View File

@ -209,7 +209,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
* {@link #loadFromFile}.
*/
public Wallet(NetworkParameters params) {
this(params, new KeyChainGroup(params));
this(Context.getOrCreate(params));
}
/**

View File

@ -214,12 +214,13 @@ public abstract class AbstractFullPrunedBlockChainTest {
@Test
public void testFirst100KBlocks() throws Exception {
NetworkParameters params = MainNetParams.get();
Context context = new Context(params);
File blockFile = new File(getClass().getResource("first-100k-blocks.dat").getFile());
BlockFileLoader loader = new BlockFileLoader(params, Arrays.asList(blockFile));
store = createStore(params, 10);
resetStore(store);
chain = new FullPrunedBlockChain(params, store);
chain = new FullPrunedBlockChain(context, store);
for (Block block : loader)
chain.add(block);
try {

View File

@ -396,7 +396,7 @@ public class BlockChainTest {
@Test
public void estimatedBlockTime() throws Exception {
NetworkParameters params = MainNetParams.get();
BlockChain prod = new BlockChain(params, new MemoryBlockStore(params));
BlockChain prod = new BlockChain(new Context(params), new MemoryBlockStore(params));
Date d = prod.estimateBlockTime(200000);
// The actual date of block 200,000 was 2012-09-22 10:47:00
assertEquals(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US).parse("2012-10-23T08:35:05.000-0700"), d);