mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-01-19 05:33:44 +01:00
Add the start of unit tests covering chain splits/reorgs, along with supporting code. The tests don't pass yet so they are marked @Ignore.
This commit is contained in:
parent
d58ad311fe
commit
5e2e48eb5a
@ -417,11 +417,20 @@ public class Block extends Message {
|
||||
this.hash = null;
|
||||
}
|
||||
|
||||
/** Adds a fake coinbase transaction for unit tests. */
|
||||
void addFakeTransaction() {
|
||||
static private int coinbaseCounter;
|
||||
/** Adds a coinbase transaction to the block. This exists for unit tests. */
|
||||
void addCoinbaseTransaction(Address to) {
|
||||
transactions = new ArrayList<Transaction>();
|
||||
Transaction coinbase = new Transaction(params);
|
||||
coinbase.setFakeHashForTesting(Utils.doubleDigest("test tx".getBytes()));
|
||||
// A real coinbase transaction has some stuff in the scriptSig like the extraNonce and difficulty. The
|
||||
// transactions are distinguished by every TX output going to a different key.
|
||||
//
|
||||
// Here we will do things a bit differently so a new address isn't needed every time. We'll put a simple
|
||||
// counter in the scriptSig so every transaction has a different hash. The output is also different.
|
||||
// Real coinbase transactions use <pubkey> OP_CHECKSIG rather than a send to an address though there's
|
||||
// nothing in the system that enforces that and both are just as valid.
|
||||
coinbase.inputs.add(new TransactionInput(params, new byte[] { (byte) coinbaseCounter++ } ));
|
||||
coinbase.outputs.add(new TransactionOutput(params, Utils.toNanoCoins(50, 0), to));
|
||||
transactions.add(coinbase);
|
||||
}
|
||||
}
|
||||
|
@ -69,9 +69,8 @@ public class NetworkParameters implements Serializable {
|
||||
return genesisBlock;
|
||||
}
|
||||
|
||||
/** The test chain created by Gavin. */
|
||||
public static NetworkParameters testNet() {
|
||||
NetworkParameters n = new NetworkParameters();
|
||||
/** Sets up the given NetworkParameters with testnet values. */
|
||||
private static NetworkParameters createTestNet(NetworkParameters n) {
|
||||
// Genesis hash is 0000000224b1593e3ff16a0e3b61285bbc393a39f78c8aa48c456142671f7110
|
||||
n.proofOfWorkLimit = new BigInteger("0000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16);
|
||||
n.packetMagic = 0xfabfb5daL;
|
||||
@ -86,6 +85,12 @@ public class NetworkParameters implements Serializable {
|
||||
return n;
|
||||
}
|
||||
|
||||
/** The test chain created by Gavin. */
|
||||
public static NetworkParameters testNet() {
|
||||
NetworkParameters n = new NetworkParameters();
|
||||
return createTestNet(n);
|
||||
}
|
||||
|
||||
/** The primary BitCoin chain created by Satoshi. */
|
||||
public static NetworkParameters prodNet() {
|
||||
NetworkParameters n = new NetworkParameters();
|
||||
@ -104,7 +109,8 @@ public class NetworkParameters implements Serializable {
|
||||
|
||||
/** Returns a testnet params modified to allow any difficulty target. */
|
||||
static NetworkParameters unitTests() {
|
||||
NetworkParameters n = NetworkParameters.testNet();
|
||||
NetworkParameters n = new NetworkParameters();
|
||||
n = createTestNet(n);
|
||||
n.proofOfWorkLimit = new BigInteger("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16);
|
||||
n.genesisBlock.setDifficultyTarget(Block.EASIEST_DIFFICULTY_TARGET);
|
||||
return n;
|
||||
|
@ -18,6 +18,7 @@ package com.google.bitcoin.core;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.util.encoders.Hex;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.math.BigInteger;
|
||||
@ -62,6 +63,64 @@ public class BlockChainTest {
|
||||
assertTrue(chain.add(b2));
|
||||
}
|
||||
|
||||
private Block createNextBlock(Address to, Block prev) throws VerificationException {
|
||||
Block b = new Block(prev.params);
|
||||
b.setDifficultyTarget(Block.EASIEST_DIFFICULTY_TARGET);
|
||||
b.addCoinbaseTransaction(to);
|
||||
b.setPrevBlockHash(prev.getHash());
|
||||
b.solve();
|
||||
b.verify();
|
||||
return b;
|
||||
}
|
||||
|
||||
@Test @Ignore
|
||||
public void testForking() throws Exception {
|
||||
// Check that if the block chain forks, we end up using the right one.
|
||||
NetworkParameters unitTestParams = NetworkParameters.unitTests();
|
||||
Wallet wallet = new Wallet(unitTestParams);
|
||||
wallet.addKey(new ECKey());
|
||||
Address coinbaseTo = wallet.keychain.get(0).toAddress(unitTestParams);
|
||||
// Start by building a couple of blocks on top of the genesis block.
|
||||
Block b1 = createNextBlock(coinbaseTo, unitTestParams.genesisBlock);
|
||||
Block b2 = createNextBlock(coinbaseTo, b1);
|
||||
chain = new BlockChain(unitTestParams, wallet);
|
||||
chain.add(b1);
|
||||
chain.add(b2);
|
||||
// We got two blocks which generated 50 coins each, to us.
|
||||
assertEquals("100.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
|
||||
// We now have the following chain:
|
||||
// genesis -> b1 -> b2
|
||||
//
|
||||
// so fork like this:
|
||||
//
|
||||
// genesis -> b1 -> b2
|
||||
// \-> b3
|
||||
//
|
||||
// Nothing should happen at this point. We saw b2 first so it takes priority.
|
||||
Address someOtherGuy = new ECKey().toAddress(unitTestParams);
|
||||
Block b3 = createNextBlock(someOtherGuy, b1);
|
||||
chain.add(b3);
|
||||
assertEquals("100.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
|
||||
// Now we add another block to make the alternative chain longer.
|
||||
chain.add(createNextBlock(someOtherGuy, b3));
|
||||
//
|
||||
// genesis -> b1 -> b2
|
||||
// \-> b3 -> b4
|
||||
//
|
||||
// We lost some coins! b2 is no longer a part of the best chain so our balance should drop to 50 again.
|
||||
assertEquals("50.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
|
||||
// ... and back to the first chain
|
||||
Block b5 = createNextBlock(coinbaseTo, b2);
|
||||
Block b6 = createNextBlock(coinbaseTo, b5);
|
||||
chain.add(b5);
|
||||
chain.add(b6);
|
||||
//
|
||||
// genesis -> b1 -> b2 -> b5 -> b6
|
||||
// \-> b3 -> b4
|
||||
//
|
||||
assertEquals("200.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadDifficulty() throws Exception {
|
||||
assertTrue(chain.add(getBlock1()));
|
||||
|
Loading…
Reference in New Issue
Block a user