mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-01-18 21:32:35 +01:00
BlockChainTest: replace difficultyTransitions()
by five individual tests
These tests use `MainNetParams` and `SigNetParams`, but not `UnitTestParams`.
This commit is contained in:
parent
c1e83e53c4
commit
ce10061510
@ -25,8 +25,8 @@ import org.bitcoinj.base.Sha256Hash;
|
|||||||
import org.bitcoinj.base.internal.TimeUtils;
|
import org.bitcoinj.base.internal.TimeUtils;
|
||||||
import org.bitcoinj.crypto.ECKey;
|
import org.bitcoinj.crypto.ECKey;
|
||||||
import org.bitcoinj.params.MainNetParams;
|
import org.bitcoinj.params.MainNetParams;
|
||||||
|
import org.bitcoinj.params.SigNetParams;
|
||||||
import org.bitcoinj.params.TestNet3Params;
|
import org.bitcoinj.params.TestNet3Params;
|
||||||
import org.bitcoinj.params.UnitTestParams;
|
|
||||||
import org.bitcoinj.store.BlockStore;
|
import org.bitcoinj.store.BlockStore;
|
||||||
import org.bitcoinj.store.MemoryBlockStore;
|
import org.bitcoinj.store.MemoryBlockStore;
|
||||||
import org.bitcoinj.testing.FakeTxBuilder;
|
import org.bitcoinj.testing.FakeTxBuilder;
|
||||||
@ -69,7 +69,9 @@ public class BlockChainTest {
|
|||||||
private BlockChain testNetChain;
|
private BlockChain testNetChain;
|
||||||
private Address coinbaseTo;
|
private Address coinbaseTo;
|
||||||
|
|
||||||
private static final TestNet3Params TESTNET = TestNet3Params.get();
|
private static final NetworkParameters TESTNET = TestNet3Params.get();
|
||||||
|
private static final NetworkParameters SIGNET = SigNetParams.get();
|
||||||
|
private static final NetworkParameters MAINNET = MainNetParams.get();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
@ -138,37 +140,77 @@ public class BlockChainTest {
|
|||||||
assertEquals(testNetChain.getChainHead().getHeader(), b3.cloneAsHeader());
|
assertEquals(testNetChain.getChainHead().getHeader(), b3.cloneAsHeader());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
// adds 2015 (interval-1) intermediate blocks between the transition points
|
||||||
public void difficultyTransitions() throws Exception {
|
private static void addIntermediteBlocks(BlockChain chain, int epoch, Duration spacing) throws PrunedException {
|
||||||
NetworkParameters UNITTEST = UnitTestParams.get();
|
int interval = chain.params.interval;
|
||||||
BlockChain unitTestChain = new BlockChain(UNITTEST,
|
Block prev = chain.getChainHead().getHeader();
|
||||||
Wallet.createDeterministic(UNITTEST, ScriptType.P2PKH),
|
// there is an additional spacing here, to account for the fact that for the difficulty adjustment only
|
||||||
new MemoryBlockStore(UNITTEST.getGenesisBlock()));
|
// interval minus 1 blocks are taken into account
|
||||||
|
Instant newTime = prev.time().plus(spacing);
|
||||||
// Add a bunch of blocks in a loop until we reach a difficulty transition point. The unit test params have an
|
for (int i = 1; i < interval; i++) {
|
||||||
// artificially shortened period.
|
newTime = newTime.plus(spacing);
|
||||||
Block prev = UNITTEST.getGenesisBlock();
|
Block newBlock = prev.createNextBlock(null, 1, newTime, epoch * interval + i);
|
||||||
TimeUtils.setMockClock();
|
assertTrue(chain.add(newBlock));
|
||||||
for (int height = 0; height < UNITTEST.getInterval() - 1; height++) {
|
|
||||||
Block newBlock = prev.createNextBlock(coinbaseTo, 1, TimeUtils.currentTime(), height);
|
|
||||||
assertTrue(unitTestChain.add(newBlock));
|
|
||||||
prev = newBlock;
|
prev = newBlock;
|
||||||
// The fake chain should seem to be "fast" for the purposes of difficulty calculations.
|
|
||||||
TimeUtils.rollMockClock(Duration.ofSeconds(2));
|
|
||||||
}
|
}
|
||||||
// Now add another block that has no difficulty adjustment, it should be rejected.
|
}
|
||||||
try {
|
|
||||||
unitTestChain.add(prev.createNextBlock(coinbaseTo, 1, TimeUtils.currentTime(), UNITTEST.getInterval()));
|
private static void addTransitionBlock(BlockChain chain, int epoch, Duration spacing) throws PrunedException {
|
||||||
fail();
|
int interval = chain.params.interval;
|
||||||
} catch (VerificationException e) {
|
Block prev = chain.getChainHead().getHeader();
|
||||||
}
|
Instant newTime = prev.time().plus(spacing);
|
||||||
// Create a new block with the right difficulty target given our blistering speed relative to the huge amount
|
Block newBlock = prev.createNextBlock(null, 1, newTime, epoch * interval);
|
||||||
// of time it's supposed to take (set in the unit test network parameters).
|
assertTrue(chain.add(newBlock));
|
||||||
Block b = prev.createNextBlock(coinbaseTo, 1, TimeUtils.currentTime(), UNITTEST.getInterval() + 1);
|
}
|
||||||
b.setDifficultyTarget(0x201fFFFFL);
|
|
||||||
b.solve();
|
@Test
|
||||||
assertTrue(unitTestChain.add(b));
|
public void difficultyTransitions_perfectSpacing() throws Exception {
|
||||||
// Successfully traversed a difficulty transition period.
|
Context.propagate(new Context(100, Coin.ZERO, false, true));
|
||||||
|
BlockChain chain = new BlockChain(MAINNET, new MemoryBlockStore(MAINNET.getGenesisBlock()));
|
||||||
|
// genesis block is already there
|
||||||
|
addIntermediteBlocks(chain, 0, Duration.ofMinutes(10));
|
||||||
|
addTransitionBlock(chain, 1, Duration.ofMinutes(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@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()));
|
||||||
|
// genesis block is already there
|
||||||
|
addIntermediteBlocks(chain, 0, Duration.ofMinutes(10).minusSeconds(1));
|
||||||
|
addTransitionBlock(chain, 1, Duration.ofMinutes(10).minusSeconds(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = VerificationException.class)
|
||||||
|
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()));
|
||||||
|
// genesis block is already there
|
||||||
|
addIntermediteBlocks(chain, 0, Duration.ofMinutes(10).plusSeconds(1));
|
||||||
|
addTransitionBlock(chain, 1, Duration.ofMinutes(10).plusSeconds(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@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()));
|
||||||
|
// 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)
|
||||||
|
addTransitionBlock(chain, 1, Duration.ofMinutes(20));
|
||||||
|
}
|
||||||
|
|
||||||
|
@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()));
|
||||||
|
// genesis block is already there
|
||||||
|
Block prev = chain.getChainHead().getHeader();
|
||||||
|
Instant newTime = prev.time().plus(Duration.ofMinutes(10));
|
||||||
|
Block newBlock = prev.createNextBlock(null, 1, newTime, 1);
|
||||||
|
newBlock.setDifficultyTarget(newBlock.getDifficultyTarget() + 10);
|
||||||
|
assertTrue(chain.add(newBlock));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TweakableTestNet3Params extends TestNet3Params {
|
private static class TweakableTestNet3Params extends TestNet3Params {
|
||||||
@ -420,7 +462,6 @@ public class BlockChainTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void estimatedBlockTime() throws Exception {
|
public void estimatedBlockTime() throws Exception {
|
||||||
NetworkParameters MAINNET = MainNetParams.get();
|
|
||||||
BlockChain prod = new BlockChain(MAINNET, new MemoryBlockStore(MAINNET.getGenesisBlock()));
|
BlockChain prod = new BlockChain(MAINNET, new MemoryBlockStore(MAINNET.getGenesisBlock()));
|
||||||
Instant t = prod.estimateBlockTimeInstant(200000);
|
Instant t = prod.estimateBlockTimeInstant(200000);
|
||||||
// The actual date of block 200,000 was 2012-09-22 10:47:00
|
// The actual date of block 200,000 was 2012-09-22 10:47:00
|
||||||
|
Loading…
Reference in New Issue
Block a user