Block: Add convenience methods for BIP conformance (BIP34, BIP66, BIP65). Also list BIPs in Block.toString().

This commit is contained in:
Andreas Schildbach
2015-12-13 20:02:23 +01:00
parent c6873443b5
commit 9d82642a93
6 changed files with 79 additions and 2 deletions

View File

@@ -20,6 +20,7 @@ package org.bitcoinj.core;
import org.bitcoinj.script.Script;
import org.bitcoinj.script.ScriptBuilder;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import org.slf4j.Logger;
@@ -74,6 +75,13 @@ public class Block extends Message {
/** A value for difficultyTarget (nBits) that allows half of all possible hash solutions. Used in unit testing. */
public static final long EASIEST_DIFFICULTY_TARGET = 0x207fFFFFL;
/** Block version introduced in BIP 34: Height in coinbase */
public static final long BLOCK_VERSION_BIP34 = 2;
/** Block version introduced in BIP 66: Strict DER signatures */
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.
private long version;
private Sha256Hash prevBlockHash;
@@ -582,9 +590,14 @@ public class Block extends Message {
*/
@Override
public String toString() {
StringBuilder s = new StringBuilder("v");
s.append(version);
StringBuilder s = new StringBuilder();
s.append(" block: \n");
s.append(" version: ").append(version);
String bips = Joiner.on(", ").skipNulls().join(isBIP34() ? "BIP34" : null, isBIP66() ? "BIP66" : null,
isBIP65() ? "BIP65" : null);
if (!bips.isEmpty())
s.append(" (").append(bips).append(')');
s.append('\n');
s.append(" previous block: ").append(getPrevBlockHash()).append("\n");
s.append(" merkle root: ").append(getMerkleRoot()).append("\n");
s.append(" time: [").append(time).append("] ").append(Utils.dateTimeFormat(time * 1000)).append("\n");
@@ -1081,4 +1094,28 @@ public class Block extends Message {
boolean isTransactionBytesValid() {
return transactionBytesValid;
}
/**
* Returns whether this block conforms to
* <a href="https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki">BIP34: Height in Coinbase</a>.
*/
public boolean isBIP34() {
return version >= BLOCK_VERSION_BIP34;
}
/**
* Returns whether this block conforms to
* <a href="https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki">BIP66: Strict DER signatures</a>.
*/
public boolean isBIP66() {
return version >= BLOCK_VERSION_BIP66;
}
/**
* Returns whether this block conforms to
* <a href="https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki">BIP65: OP_CHECKLOCKTIMEVERIFY</a>.
*/
public boolean isBIP65() {
return version >= BLOCK_VERSION_BIP65;
}
}

View File

@@ -17,12 +17,15 @@
package org.bitcoinj.core;
import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.params.TestNet2Params;
import org.bitcoinj.params.UnitTestParams;
import org.bitcoinj.script.ScriptOpCodes;
import org.junit.Before;
import org.junit.Test;
import com.google.common.io.ByteStreams;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
@@ -192,4 +195,41 @@ public class BlockTest {
assertEquals(block.length, origBlockLen + tx.length);
assertEquals(tx.length, origTxLength + 41); // - 1 + 40 + 1 + 1
}
@Test
public void isBIPs() throws Exception {
final MainNetParams mainnet = MainNetParams.get();
final Block genesis = mainnet.getGenesisBlock();
assertFalse(genesis.isBIP34());
assertFalse(genesis.isBIP66());
assertFalse(genesis.isBIP65());
// 227835/00000000000001aa077d7aa84c532a4d69bdbff519609d1da0835261b7a74eb6: last version 1 block
final Block block227835 = new Block(mainnet,
ByteStreams.toByteArray(getClass().getResourceAsStream("block227835.dat")));
assertFalse(block227835.isBIP34());
assertFalse(block227835.isBIP66());
assertFalse(block227835.isBIP65());
// 227836/00000000000000d0dfd4c9d588d325dce4f32c1b31b7c0064cba7025a9b9adcc: version 2 block
final Block block227836 = new Block(mainnet,
ByteStreams.toByteArray(getClass().getResourceAsStream("block227836.dat")));
assertTrue(block227836.isBIP34());
assertFalse(block227836.isBIP66());
assertFalse(block227836.isBIP65());
// 363703/0000000000000000011b2a4cb91b63886ffe0d2263fd17ac5a9b902a219e0a14: version 3 block
final Block block363703 = new Block(mainnet,
ByteStreams.toByteArray(getClass().getResourceAsStream("block363703.dat")));
assertTrue(block363703.isBIP34());
assertTrue(block363703.isBIP66());
assertFalse(block363703.isBIP65());
// 383616/00000000000000000aab6a2b34e979b09ca185584bd1aecf204f24d150ff55e9: version 4 block
final Block block383616 = new Block(mainnet,
ByteStreams.toByteArray(getClass().getResourceAsStream("block383616.dat")));
assertTrue(block383616.isBIP34());
assertTrue(block383616.isBIP66());
assertTrue(block383616.isBIP65());
}
}