mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-02-25 07:07:39 +01:00
Enforce v4 block switchover
This enforces the switch over to block v4 once a supermajority is met, as per BIP65.
This commit is contained in:
parent
1c8a60d2ef
commit
344c4c3baa
3 changed files with 25 additions and 7 deletions
|
@ -544,12 +544,13 @@ public abstract class AbstractBlockChain {
|
||||||
if (expensiveChecks && block.getTimeSeconds() <= getMedianTimestampOfRecentBlocks(head, blockStore))
|
if (expensiveChecks && block.getTimeSeconds() <= getMedianTimestampOfRecentBlocks(head, blockStore))
|
||||||
throw new VerificationException("Block's timestamp is too early");
|
throw new VerificationException("Block's timestamp is too early");
|
||||||
|
|
||||||
// BIP 66: Enforce block version 3 once it's a supermajority of blocks
|
// BIP 66 & 65: Enforce block version 3/4 once they are a supermajority of blocks
|
||||||
// NOTE: This requires 1,000 blocks since the last checkpoint (on main
|
// NOTE: This requires 1,000 blocks since the last checkpoint (on main
|
||||||
// net, less on test) in order to be applied. It is also limited to
|
// net, less on test) in order to be applied. It is also limited to
|
||||||
// stopping addition of new v2 blocks to the tip of the chain.
|
// stopping addition of new v2/3 blocks to the tip of the chain.
|
||||||
if (block.getVersion() == Block.BLOCK_VERSION_BIP34) {
|
if (block.getVersion() == Block.BLOCK_VERSION_BIP34
|
||||||
final Integer count = versionTally.getCountAtOrAbove(Block.BLOCK_VERSION_BIP66);
|
|| block.getVersion() == Block.BLOCK_VERSION_BIP66) {
|
||||||
|
final Integer count = versionTally.getCountAtOrAbove(block.getVersion() + 1);
|
||||||
if (count != null
|
if (count != null
|
||||||
&& count >= params.getMajorityRejectBlockOutdated()) {
|
&& count >= params.getMajorityRejectBlockOutdated()) {
|
||||||
throw new VerificationException.BlockVersionOutOfDate(block.getVersion());
|
throw new VerificationException.BlockVersionOutOfDate(block.getVersion());
|
||||||
|
|
|
@ -84,6 +84,8 @@ public class Block extends Message {
|
||||||
public static final long BLOCK_VERSION_BIP34 = 2;
|
public static final long BLOCK_VERSION_BIP34 = 2;
|
||||||
/** Block version introduced in BIP 66: Strict DER signatures */
|
/** Block version introduced in BIP 66: Strict DER signatures */
|
||||||
public static final long BLOCK_VERSION_BIP66 = 3;
|
public static final long BLOCK_VERSION_BIP66 = 3;
|
||||||
|
/** Block version introduced in BIP 65: OP_CHECKLOCKTIMEVERIFY */
|
||||||
|
public static final long BLOCK_VERSION_BIP65 = 4;
|
||||||
|
|
||||||
// Fields defined as part of the protocol format.
|
// Fields defined as part of the protocol format.
|
||||||
private long version;
|
private long version;
|
||||||
|
|
|
@ -38,6 +38,7 @@ import java.util.Date;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import static org.bitcoinj.core.Coin.*;
|
import static org.bitcoinj.core.Coin.*;
|
||||||
|
import org.bitcoinj.store.BlockStoreException;
|
||||||
import static org.bitcoinj.testing.FakeTxBuilder.createFakeBlock;
|
import static org.bitcoinj.testing.FakeTxBuilder.createFakeBlock;
|
||||||
import static org.bitcoinj.testing.FakeTxBuilder.createFakeTx;
|
import static org.bitcoinj.testing.FakeTxBuilder.createFakeTx;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
@ -230,6 +231,20 @@ public class BlockChainTest {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void badBip66Version() throws Exception {
|
public void badBip66Version() throws Exception {
|
||||||
|
testDeprecatedBlockVersion(Block.BLOCK_VERSION_BIP34, Block.BLOCK_VERSION_BIP66);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that version 3 blocks are rejected once version 4 blocks are a super
|
||||||
|
* majority.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void badBip65Version() throws Exception {
|
||||||
|
testDeprecatedBlockVersion(Block.BLOCK_VERSION_BIP66, Block.BLOCK_VERSION_BIP65);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testDeprecatedBlockVersion(final long deprecatedVersion, final long newVersion)
|
||||||
|
throws Exception {
|
||||||
final BlockStore versionBlockStore = new MemoryBlockStore(unitTestParams);
|
final BlockStore versionBlockStore = new MemoryBlockStore(unitTestParams);
|
||||||
final BlockChain versionChain = new BlockChain(unitTestParams, versionBlockStore);
|
final BlockChain versionChain = new BlockChain(unitTestParams, versionBlockStore);
|
||||||
|
|
||||||
|
@ -240,18 +255,18 @@ public class BlockChainTest {
|
||||||
|
|
||||||
// Put in just enough v2 blocks to be a minority
|
// Put in just enough v2 blocks to be a minority
|
||||||
for (height = 0; height < (unitTestParams.getMajorityWindow() - unitTestParams.getMajorityRejectBlockOutdated()); height++) {
|
for (height = 0; height < (unitTestParams.getMajorityWindow() - unitTestParams.getMajorityRejectBlockOutdated()); height++) {
|
||||||
chainHead = FakeTxBuilder.createFakeBlock(versionBlockStore, Block.BLOCK_VERSION_BIP34, timeSeconds, height);
|
chainHead = FakeTxBuilder.createFakeBlock(versionBlockStore, deprecatedVersion, timeSeconds, height);
|
||||||
versionChain.add(chainHead.block);
|
versionChain.add(chainHead.block);
|
||||||
timeSeconds += 60;
|
timeSeconds += 60;
|
||||||
}
|
}
|
||||||
// Fill the rest of the window with v3 blocks
|
// Fill the rest of the window with v3 blocks
|
||||||
for (; height < unitTestParams.getMajorityWindow(); height++) {
|
for (; height < unitTestParams.getMajorityWindow(); height++) {
|
||||||
chainHead = FakeTxBuilder.createFakeBlock(versionBlockStore, Block.BLOCK_VERSION_BIP66, timeSeconds, height);
|
chainHead = FakeTxBuilder.createFakeBlock(versionBlockStore, newVersion, timeSeconds, height);
|
||||||
versionChain.add(chainHead.block);
|
versionChain.add(chainHead.block);
|
||||||
timeSeconds += 60;
|
timeSeconds += 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
chainHead = FakeTxBuilder.createFakeBlock(versionBlockStore, Block.BLOCK_VERSION_BIP34, timeSeconds, height);
|
chainHead = FakeTxBuilder.createFakeBlock(versionBlockStore, deprecatedVersion, timeSeconds, height);
|
||||||
// Trying to add a new v2 block should result in rejection
|
// Trying to add a new v2 block should result in rejection
|
||||||
thrown.expect(VerificationException.BlockVersionOutOfDate.class);
|
thrown.expect(VerificationException.BlockVersionOutOfDate.class);
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Add table
Reference in a new issue