BlockChain: use Network in constructors

Constructors that take NetworkParameters are marked as @VisibleForTesting.
This is because of the special UNITTEST NetworkParameters that is required for
certain tests.
This commit is contained in:
Sean Gilligan 2023-07-15 08:38:24 -07:00 committed by Andreas Schildbach
parent 3284b6e309
commit 39c34186cc
18 changed files with 64 additions and 40 deletions

View file

@ -17,6 +17,8 @@
package org.bitcoinj.core;
import com.google.common.annotations.VisibleForTesting;
import org.bitcoinj.base.Network;
import org.bitcoinj.base.Sha256Hash;
import org.bitcoinj.core.listeners.NewBestBlockListener;
import org.bitcoinj.core.listeners.ReorganizeListener;
@ -160,6 +162,18 @@ public abstract class AbstractBlockChain {
private final VersionTally versionTally;
/**
* Constructs a BlockChain connected to the given list of listeners (wallets) and a store.
* @param network network for this chain
* @param wallets list of listeners (wallets)
* @param blockStore where to store blocks
* @throws BlockStoreException if a failure occurs while storing a block
*/
public AbstractBlockChain(Network network, List<? extends Wallet> wallets,
BlockStore blockStore) throws BlockStoreException {
this( NetworkParameters.of(network), wallets, blockStore);
}
/**
* Constructs a BlockChain connected to the given list of listeners (wallets) and a store.
* @param params network parameters for this chain
@ -167,6 +181,7 @@ public abstract class AbstractBlockChain {
* @param blockStore where to store blocks
* @throws BlockStoreException if a failure occurs while storing a block
*/
@VisibleForTesting
public AbstractBlockChain(NetworkParameters params, List<? extends Wallet> wallets,
BlockStore blockStore) throws BlockStoreException {
this.blockStore = blockStore;

View file

@ -17,6 +17,8 @@
package org.bitcoinj.core;
import com.google.common.annotations.VisibleForTesting;
import org.bitcoinj.base.Network;
import org.bitcoinj.base.Sha256Hash;
import org.bitcoinj.store.BlockStore;
import org.bitcoinj.store.BlockStoreException;
@ -27,6 +29,7 @@ import org.bitcoinj.wallet.WalletExtension;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.bitcoinj.base.internal.Preconditions.checkArgument;
@ -51,24 +54,29 @@ public class BlockChain extends AbstractBlockChain {
* {@link 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<Wallet>(), blockStore);
addWallet(wallet);
public BlockChain(Network network, Wallet wallet, BlockStore blockStore) throws BlockStoreException {
this(network, Collections.singletonList(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(NetworkParameters params, BlockStore blockStore) throws BlockStoreException {
this(params, new ArrayList<Wallet>(), blockStore);
public BlockChain(Network network, BlockStore blockStore) throws BlockStoreException {
this(network, Collections.emptyList(), blockStore);
}
/**
* Constructs a BlockChain connected to the given list of listeners and a store.
*/
public BlockChain(NetworkParameters params, List<? extends Wallet> wallets, BlockStore blockStore) throws BlockStoreException {
super(params, wallets, blockStore);
public BlockChain(Network network, List<? extends Wallet> wallets, BlockStore blockStore) throws BlockStoreException {
super(network, wallets, blockStore);
this.blockStore = blockStore;
}
@VisibleForTesting
public BlockChain(NetworkParameters params, Wallet wallet, BlockStore blockStore) throws BlockStoreException {
super(params, Collections.singletonList(wallet), blockStore);
this.blockStore = blockStore;
}

View file

@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
@ -72,15 +73,14 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
* {@link Wallet#loadFromFile(File, WalletExtension...)}
*/
public FullPrunedBlockChain(NetworkParameters params, Wallet wallet, FullPrunedBlockStore blockStore) throws BlockStoreException {
this(params, new ArrayList<Wallet>(), blockStore);
addWallet(wallet);
this(params, Collections.singletonList(wallet), blockStore);
}
/**
* Constructs a block chain connected to the given store.
*/
public FullPrunedBlockChain(NetworkParameters params, FullPrunedBlockStore blockStore) throws BlockStoreException {
this(params, new ArrayList<Wallet>(), blockStore);
this(params, Collections.emptyList(), blockStore);
}
/**

View file

@ -433,7 +433,7 @@ public class WalletAppKit extends AbstractIdleService implements Closeable {
vStore.clear();
}
}
vChain = new BlockChain(params, vStore);
vChain = new BlockChain(network, vStore);
vPeerGroup = createPeerGroup();
if (this.userAgent != null)
vPeerGroup.setUserAgent(userAgent, version);

View file

@ -93,7 +93,7 @@ public class BitcoindComparisonTool {
ver.appendToSubVer("BlockAcceptanceComparisonTool", "1.1", null);
ver.localServices = Services.of(Services.NODE_NETWORK);
final Peer bitcoind = new Peer(PARAMS, ver, PeerAddress.localhost(PARAMS),
new BlockChain(PARAMS, new MemoryBlockStore(PARAMS.getGenesisBlock())));
new BlockChain(PARAMS.network(), new MemoryBlockStore(PARAMS.getGenesisBlock())));
checkState(bitcoind.getVersionMessage().services().has(Services.NODE_NETWORK));
final BlockWrapper currentBlock = new BlockWrapper();

View file

@ -79,7 +79,7 @@ public class BlockChainTest {
Context.propagate(new Context(100, Coin.ZERO, false, false));
testNetWallet = Wallet.createDeterministic(BitcoinNetwork.TESTNET, ScriptType.P2PKH);
testNetStore = new MemoryBlockStore(TESTNET.getGenesisBlock());
testNetChain = new BlockChain(TESTNET, testNetWallet, testNetStore);
testNetChain = new BlockChain(BitcoinNetwork.TESTNET, testNetWallet, testNetStore);
coinbaseTo = testNetWallet.currentReceiveKey().toAddress(ScriptType.P2PKH, BitcoinNetwork.TESTNET);
}
@ -165,7 +165,7 @@ public class BlockChainTest {
@Test
public void difficultyTransitions_perfectSpacing() throws Exception {
Context.propagate(new Context(100, Coin.ZERO, false, true));
BlockChain chain = new BlockChain(MAINNET, new MemoryBlockStore(MAINNET.getGenesisBlock()));
BlockChain chain = new BlockChain(BitcoinNetwork.MAINNET, new MemoryBlockStore(MAINNET.getGenesisBlock()));
// genesis block is already there
addIntermediteBlocks(chain, 0, Duration.ofMinutes(10));
addTransitionBlock(chain, 1, Duration.ofMinutes(10));
@ -174,7 +174,7 @@ public class BlockChainTest {
@Test(expected = VerificationException.class)
public void difficultyTransitions_tooQuick() throws Exception {
Context.propagate(new Context(100, Coin.ZERO, false, true));
BlockChain chain = new BlockChain(MAINNET, new MemoryBlockStore(MAINNET.getGenesisBlock()));
BlockChain chain = new BlockChain(BitcoinNetwork.MAINNET, new MemoryBlockStore(MAINNET.getGenesisBlock()));
// genesis block is already there
addIntermediteBlocks(chain, 0, Duration.ofMinutes(10).minusSeconds(1));
addTransitionBlock(chain, 1, Duration.ofMinutes(10).minusSeconds(1));
@ -184,7 +184,7 @@ public class BlockChainTest {
public void difficultyTransitions_tooSlow() throws Exception {
// we're using signet because it's not at max target from the start
Context.propagate(new Context(100, Coin.ZERO, false, true));
BlockChain chain = new BlockChain(SIGNET, new MemoryBlockStore(SIGNET.getGenesisBlock()));
BlockChain chain = new BlockChain(BitcoinNetwork.SIGNET, new MemoryBlockStore(SIGNET.getGenesisBlock()));
// genesis block is already there
addIntermediteBlocks(chain, 0, Duration.ofMinutes(10).plusSeconds(1));
addTransitionBlock(chain, 1, Duration.ofMinutes(10).plusSeconds(1));
@ -193,7 +193,7 @@ public class BlockChainTest {
@Test
public void difficultyTransitions_tooSlow_butIsAtMax() throws Exception {
Context.propagate(new Context(100, Coin.ZERO, false, true));
BlockChain chain = new BlockChain(MAINNET, new MemoryBlockStore(MAINNET.getGenesisBlock()));
BlockChain chain = new BlockChain(BitcoinNetwork.MAINNET, new MemoryBlockStore(MAINNET.getGenesisBlock()));
// genesis block is already there
addIntermediteBlocks(chain, 0, Duration.ofMinutes(20));
// we can add the transition block with the old target, becuase it is already at the maximum (genesis block)
@ -203,7 +203,7 @@ public class BlockChainTest {
@Test(expected = VerificationException.class)
public void difficultyTransitions_unexpectedChange() throws Exception {
Context.propagate(new Context(100, Coin.ZERO, false, true));
BlockChain chain = new BlockChain(MAINNET, new MemoryBlockStore(MAINNET.getGenesisBlock()));
BlockChain chain = new BlockChain(BitcoinNetwork.MAINNET, new MemoryBlockStore(MAINNET.getGenesisBlock()));
// genesis block is already there
Block prev = chain.getChainHead().getHeader();
Instant newTime = prev.time().plus(Duration.ofMinutes(10));
@ -439,7 +439,7 @@ public class BlockChainTest {
@Test
public void estimatedBlockTime() throws Exception {
BlockChain prod = new BlockChain(MAINNET, new MemoryBlockStore(MAINNET.getGenesisBlock()));
BlockChain prod = new BlockChain(BitcoinNetwork.MAINNET, new MemoryBlockStore(MAINNET.getGenesisBlock()));
Instant t = prod.estimateBlockTimeInstant(200000);
// The actual date of block 200,000 was 2012-09-22 10:47:00
Instant expected = Instant.from(DateTimeFormatter.ISO_INSTANT.parse("2012-10-23T15:35:05Z"));

View file

@ -75,7 +75,7 @@ public class ChainSplitTest {
wallet = Wallet.createDeterministic(BitcoinNetwork.TESTNET, ScriptType.P2PKH);
ECKey key1 = wallet.freshReceiveKey();
ECKey key2 = wallet.freshReceiveKey();
chain = new BlockChain(TESTNET, wallet, blockStore);
chain = new BlockChain(BitcoinNetwork.TESTNET, wallet, blockStore);
coinsTo = key1.toAddress(ScriptType.P2PKH, BitcoinNetwork.TESTNET);
coinsTo2 = key2.toAddress(ScriptType.P2PKH, BitcoinNetwork.TESTNET);
someOtherGuy = new ECKey().toAddress(ScriptType.P2PKH, BitcoinNetwork.TESTNET);

View file

@ -262,7 +262,7 @@ public class WalletProtobufSerializerTest {
public void testAppearedAtChainHeightDepthAndWorkDone() throws Exception {
// Test the TransactionConfidence appearedAtChainHeight, depth and workDone field are stored.
Context.propagate(new Context(100, Transaction.DEFAULT_TX_FEE, false, true));
BlockChain chain = new BlockChain(TESTNET, myWallet, new MemoryBlockStore(TESTNET.getGenesisBlock()));
BlockChain chain = new BlockChain(BitcoinNetwork.TESTNET, myWallet, new MemoryBlockStore(TESTNET.getGenesisBlock()));
final ArrayList<Transaction> txns = new ArrayList<>(2);
myWallet.addCoinsReceivedEventListener((wallet, tx, prevBalance, newBalance) -> txns.add(tx));
@ -380,7 +380,7 @@ public class WalletProtobufSerializerTest {
Block b = TESTNET.getGenesisBlock().createNextBlockWithCoinbase(Block.BLOCK_VERSION_GENESIS, myKey.getPubKey(), FIFTY_COINS, Block.BLOCK_HEIGHT_GENESIS);
Transaction coinbase = b.getTransactions().get(0);
assertTrue(coinbase.isCoinBase());
BlockChain chain = new BlockChain(TESTNET, myWallet, new MemoryBlockStore(TESTNET.getGenesisBlock()));
BlockChain chain = new BlockChain(BitcoinNetwork.TESTNET, myWallet, new MemoryBlockStore(TESTNET.getGenesisBlock()));
assertTrue(chain.add(b));
// Wallet now has a coinbase tx in it.
assertEquals(1, myWallet.getTransactions(true).size());

View file

@ -73,7 +73,7 @@ public class TestWithWallet {
myKey = wallet.freshReceiveKey();
myAddress = wallet.freshReceiveAddress(ScriptType.P2PKH);
blockStore = new MemoryBlockStore(TESTNET.getGenesisBlock());
chain = new BlockChain(TESTNET, wallet, blockStore);
chain = new BlockChain(BitcoinNetwork.TESTNET, wallet, blockStore);
}
public void tearDown() throws Exception {

View file

@ -16,6 +16,7 @@
package org.bitcoinj.utils;
import org.bitcoinj.base.BitcoinNetwork;
import org.bitcoinj.base.internal.TimeUtils;
import org.bitcoinj.core.BlockChain;
import org.bitcoinj.core.Context;
@ -108,7 +109,7 @@ public class VersionTallyTest {
public void testInitialize() throws BlockStoreException {
Context.propagate(new Context(100, Transaction.DEFAULT_TX_FEE, false, true));
final BlockStore blockStore = new MemoryBlockStore(TESTNET.getGenesisBlock());
final BlockChain chain = new BlockChain(TESTNET, blockStore);
final BlockChain chain = new BlockChain(BitcoinNetwork.TESTNET, blockStore);
// Build a historical chain of version 2 blocks
Instant time = Instant.ofEpochSecond(1231006505);

View file

@ -59,7 +59,7 @@ public class FetchBlock implements Callable<Integer> {
final Network network = BitcoinNetwork.TESTNET;
final NetworkParameters params = NetworkParameters.of(network);
BlockStore blockStore = new MemoryBlockStore(params.getGenesisBlock());
BlockChain chain = new BlockChain(params, blockStore);
BlockChain chain = new BlockChain(network, blockStore);
PeerGroup peerGroup = new PeerGroup(network, chain);
if (localhost) {
peerGroup.addPeerDiscovery(new DnsDiscovery(params));

View file

@ -40,7 +40,7 @@ public class FetchTransactions {
final NetworkParameters params = NetworkParameters.of(network);
BlockStore blockStore = new MemoryBlockStore(params.getGenesisBlock());
BlockChain chain = new BlockChain(params, blockStore);
BlockChain chain = new BlockChain(network, blockStore);
PeerGroup peerGroup = new PeerGroup(network, chain);
peerGroup.start();
peerGroup.addAddress(PeerAddress.localhost(params));

View file

@ -71,7 +71,7 @@ public class PrivateKeys {
// Find the transactions that involve those coins.
final MemoryBlockStore blockStore = new MemoryBlockStore(params.getGenesisBlock());
BlockChain chain = new BlockChain(params, wallet, blockStore);
BlockChain chain = new BlockChain(network, wallet, blockStore);
final PeerGroup peerGroup = new PeerGroup(network, chain);
peerGroup.addAddress(PeerAddress.localhost(params));

View file

@ -40,9 +40,8 @@ public class RefreshWallet {
// Set up the components and link them together.
final Network network = BitcoinNetwork.TESTNET;
final NetworkParameters params = NetworkParameters.of(network);
BlockStore blockStore = new MemoryBlockStore(params.getGenesisBlock());
BlockChain chain = new BlockChain(params, wallet, blockStore);
BlockStore blockStore = new MemoryBlockStore(NetworkParameters.of(network).getGenesisBlock());
BlockChain chain = new BlockChain(network, wallet, blockStore);
final PeerGroup peerGroup = new PeerGroup(network, chain);
peerGroup.startAsync();

View file

@ -65,7 +65,7 @@ public class RestoreFromSeed {
// Setting up the BlochChain, the BlocksStore and connecting to the network.
SPVBlockStore chainStore = new SPVBlockStore(params, chainFile);
BlockChain chain = new BlockChain(params, chainStore);
BlockChain chain = new BlockChain(network, chainStore);
PeerGroup peerGroup = new PeerGroup(network, chain);
peerGroup.addPeerDiscovery(new DnsDiscovery(params));

View file

@ -16,9 +16,9 @@
package org.bitcoinj.tools;
import org.bitcoinj.base.BitcoinNetwork;
import org.bitcoinj.base.Network;
import org.bitcoinj.core.*;
import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.params.TestNet3Params;
import org.bitcoinj.store.*;
import org.bitcoinj.utils.BlockFileLoader;
@ -34,11 +34,12 @@ public class BlockImporter {
System.out.println(" Does full verification if the store supports it");
checkArgument(args.length == 2 || args.length == 3);
NetworkParameters params;
Network network;
if (args[0].equals("test"))
params = TestNet3Params.get();
network = BitcoinNetwork.TESTNET;
else
params = MainNetParams.get();
network = BitcoinNetwork.MAINNET;
NetworkParameters params = NetworkParameters.of(network);
BlockStore store;
switch (args[1]) {
@ -63,9 +64,9 @@ public class BlockImporter {
if (store instanceof FullPrunedBlockStore)
chain = new FullPrunedBlockChain(params, (FullPrunedBlockStore) store);
else
chain = new BlockChain(params, store);
chain = new BlockChain(network, store);
BlockFileLoader loader = new BlockFileLoader(params.network(), BlockFileLoader.getReferenceClientBlockFileList());
BlockFileLoader loader = new BlockFileLoader(network, BlockFileLoader.getReferenceClientBlockFileList());
for (Block block : loader)
chain.add(block);

View file

@ -101,7 +101,7 @@ public class BuildCheckpoints implements Callable<Integer> {
// Configure bitcoinj to fetch only headers, not save them to disk, connect to a local fully synced/validated
// node and to save block headers that are on interval boundaries, as long as they are <1 month old.
final BlockStore store = new MemoryBlockStore(params.getGenesisBlock());
final BlockChain chain = new BlockChain(params, store);
final BlockChain chain = new BlockChain(net, store);
final PeerGroup peerGroup = new PeerGroup(net, chain);
final InetAddress ipAddress;

View file

@ -999,7 +999,7 @@ public class WalletTool implements Callable<Integer> {
System.out.println("Could not load checkpoints: " + x.getMessage());
}
}
chain = new BlockChain(params, wallet, store);
chain = new BlockChain(net, wallet, store);
} else if (mode == ValidationMode.FULL) {
store = new MemoryFullPrunedBlockStore(params, 5000);
chain = new FullPrunedBlockChain(params, wallet, (FullPrunedBlockStore) store);