From efc1f06c4d687ef8321a06b058bc3d27dc8d4efb Mon Sep 17 00:00:00 2001 From: Mike Rosseel Date: Fri, 2 Jun 2017 15:11:48 +0200 Subject: [PATCH 1/4] add litecoin regtest params --- .../params/AbstractLitecoinParams.java | 22 +-- .../libdohj/params/LitecoinRegTestParams.java | 160 ++++++++++++++++++ .../params/LitecoinRegTestParamsTest.java | 42 +++++ 3 files changed, 209 insertions(+), 15 deletions(-) create mode 100644 core/src/main/java/org/libdohj/params/LitecoinRegTestParams.java create mode 100644 core/src/test/java/org/libdohj/params/LitecoinRegTestParamsTest.java diff --git a/core/src/main/java/org/libdohj/params/AbstractLitecoinParams.java b/core/src/main/java/org/libdohj/params/AbstractLitecoinParams.java index bb41f23eb..8e9cba8ff 100644 --- a/core/src/main/java/org/libdohj/params/AbstractLitecoinParams.java +++ b/core/src/main/java/org/libdohj/params/AbstractLitecoinParams.java @@ -16,26 +16,16 @@ package org.libdohj.params; -import java.math.BigInteger; -import org.bitcoinj.core.AltcoinBlock; - -import org.bitcoinj.core.Block; -import org.bitcoinj.core.Coin; -import static org.bitcoinj.core.Coin.COIN; -import org.bitcoinj.core.NetworkParameters; -import org.bitcoinj.core.Sha256Hash; -import org.bitcoinj.core.VerificationException; +import org.bitcoinj.core.*; import org.bitcoinj.store.BlockStore; import org.bitcoinj.store.BlockStoreException; -import org.bitcoinj.core.StoredBlock; -import org.bitcoinj.core.Utils; import org.bitcoinj.utils.MonetaryFormat; import org.libdohj.core.AltcoinNetworkParameters; import org.libdohj.core.AltcoinSerializer; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; - +import java.math.BigInteger; +import static org.bitcoinj.core.Coin.COIN; /** * Common parameters for Litecoin networks. @@ -51,7 +41,7 @@ public abstract class AbstractLitecoinParams extends NetworkParameters implement public static final int LITE_TARGET_TIMESPAN = (int) (3.5 * 24 * 60 * 60); // 3.5 days public static final int LITE_TARGET_SPACING = (int) (2.5 * 60); // 2.5 minutes public static final int LITE_INTERVAL = LITE_TARGET_TIMESPAN / LITE_TARGET_SPACING; - + /** * The maximum number of coins to be generated */ @@ -82,6 +72,8 @@ public abstract class AbstractLitecoinParams extends NetworkParameters implement public static final String ID_LITE_MAINNET = "org.litecoin.production"; /** The string returned by getId() for the testnet. */ public static final String ID_LITE_TESTNET = "org.litecoin.test"; + /** The string returned by getId() for regtest. */ + public static final String ID_LITE_REGTEST = "regtest"; public static final int LITECOIN_PROTOCOL_VERSION_MINIMUM = 70002; public static final int LITECOIN_PROTOCOL_VERSION_CURRENT = 70003; @@ -249,7 +241,7 @@ protected long calculateNewDifficultyTargetInner(int previousHeight, final Block } /** - * + * * @param previousHeight Height of the block immediately previous to the one we're calculating difficulty of. * @param previousBlockTime Time of the block immediately previous to the one we're calculating difficulty of. * @param lastDifficultyTarget Compact difficulty target of the last retarget block. diff --git a/core/src/main/java/org/libdohj/params/LitecoinRegTestParams.java b/core/src/main/java/org/libdohj/params/LitecoinRegTestParams.java new file mode 100644 index 000000000..b8f04252b --- /dev/null +++ b/core/src/main/java/org/libdohj/params/LitecoinRegTestParams.java @@ -0,0 +1,160 @@ +/* + * Copyright 2013 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.libdohj.params; + +import org.bitcoinj.core.Block; +import org.bitcoinj.core.StoredBlock; +import org.bitcoinj.core.VerificationException; +import org.bitcoinj.store.BlockStore; +import org.bitcoinj.store.BlockStoreException; + +import java.math.BigInteger; + +import static com.google.common.base.Preconditions.checkState; + +/** + * Network parameters for the regression test mode of bitcoind in which all blocks are trivially solvable. + */ +public class LitecoinRegTestParams extends LitecoinTestNet3Params { + private static final BigInteger MAX_TARGET = new BigInteger("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16); + + public LitecoinRegTestParams() { + super(); + // Difficulty adjustments are disabled for regtest. + // By setting the block interval for difficulty adjustments to Integer.MAX_VALUE we make sure difficulty never changes. + interval = Integer.MAX_VALUE; + maxTarget = MAX_TARGET; + subsidyDecreaseBlockCount = 150; + port = 19444; + id = ID_LITE_REGTEST; + packetMagic = 0xfabfb5da; + } + + @Override + public boolean allowEmptyPeerChain() { + return true; + } + + private static Block genesis; + + + /* + CRegTestParams() { + strNetworkID = "regtest"; + consensus.nSubsidyHalvingInterval = 150; + consensus.nMajorityEnforceBlockUpgrade = 750; + consensus.nMajorityRejectBlockOutdated = 950; + consensus.nMajorityWindow = 1000; + consensus.BIP34Height = -1; // BIP34 has not necessarily activated on regtest + consensus.BIP34Hash = uint256(); + consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.nPowTargetTimespan = 3.5 * 24 * 60 * 60; // two weeks + consensus.nPowTargetSpacing = 2.5 * 60; + consensus.fPowAllowMinDifficultyBlocks = true; + consensus.fPowNoRetargeting = true; + consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains + consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016) + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 999999999999ULL; + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 999999999999ULL; + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1; + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 999999999999ULL; + + // The best chain should have at least this much work. + consensus.nMinimumChainWork = uint256S("0x00"); + + pchMessageStart[0] = 0xfa; + pchMessageStart[1] = 0xbf; + pchMessageStart[2] = 0xb5; + pchMessageStart[3] = 0xda; + nDefaultPort = 19444; + nPruneAfterHeight = 1000; + + genesis = CreateGenesisBlock(1296688602, 0, 0x207fffff, 1, 50 * COIN); + consensus.hashGenesisBlock = genesis.GetHash(); + assert(consensus.hashGenesisBlock == uint256S("0x530827f38f93b43ed12af0b3ad25a288dc02ed74d6d7857862df51fc56c416f9")); + assert(genesis.hashMerkleRoot == uint256S("0x97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9")); + + vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds. + vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds. + + fMiningRequiresPeers = false; + fDefaultConsistencyChecks = true; + fRequireStandard = false; + fMineBlocksOnDemand = true; + fTestnetToBeDeprecatedFieldRPC = false; + + checkpointData = (CCheckpointData){ + boost::assign::map_list_of + ( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")), + 0, + 0, + 0 + }; + + base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,111); + base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,196); + base58Prefixes[SCRIPT_ADDRESS2] = std::vector(1,58); + base58Prefixes[SECRET_KEY] = std::vector(1,239); + base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container >(); + base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container >(); + } + */ + + @Override + public Block getGenesisBlock() { + synchronized (LitecoinRegTestParams.class) { + if (genesis == null) { + genesis = super.getGenesisBlock(); + genesis.setNonce(0); + genesis.setDifficultyTarget(0x207fffffL); + genesis.setTime(1296688602L); + checkState(genesis.getVersion() == 1); + checkState(genesis.getMerkleRoot().toString().equals("97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9")); + checkState(genesis.getHashAsString().toLowerCase().equals("530827f38f93b43ed12af0b3ad25a288dc02ed74d6d7857862df51fc56c416f9")); + genesis.verifyHeader(); + } + return genesis; + } + } + + private static LitecoinRegTestParams instance; + + public static synchronized LitecoinRegTestParams get() { + if (instance == null) { + instance = new LitecoinRegTestParams(); + } + return instance; + } + + @Override + public String getPaymentProtocolId() { + return ID_LITE_REGTEST; + } + + @Override + /** the testnet rules don't work for regtest, where difficulty stays the same */ + public long calculateNewDifficultyTarget(StoredBlock storedPrev, Block nextBlock, BlockStore blockStore) + throws VerificationException, BlockStoreException { + final Block prev = storedPrev.getHeader(); + return prev.getDifficultyTarget(); + } +} diff --git a/core/src/test/java/org/libdohj/params/LitecoinRegTestParamsTest.java b/core/src/test/java/org/libdohj/params/LitecoinRegTestParamsTest.java new file mode 100644 index 000000000..f2b5c6f77 --- /dev/null +++ b/core/src/test/java/org/libdohj/params/LitecoinRegTestParamsTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2015 J. Ross Nicoll + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.libdohj.params; + +import org.bitcoinj.core.Block; +import org.bitcoinj.core.Context; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * + * @author Ross Nicoll + */ +public class LitecoinRegTestParamsTest { + private static final LitecoinRegTestParams params = LitecoinRegTestParams.get(); + + @Before + public void setUp() throws Exception { + Context context = new Context(params); + } + + @Test + public void testRegTestGenesisBlock() { + Block genesis = params.getGenesisBlock(); + assertEquals("530827f38f93b43ed12af0b3ad25a288dc02ed74d6d7857862df51fc56c416f9", genesis.getHashAsString()); + } +} From 5b6486393c944a22cab299a16bf45b91490a4064 Mon Sep 17 00:00:00 2001 From: Mike Rosseel Date: Fri, 2 Jun 2017 15:17:41 +0200 Subject: [PATCH 2/4] more javadoc --- .../java/org/libdohj/params/LitecoinRegTestParams.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/libdohj/params/LitecoinRegTestParams.java b/core/src/main/java/org/libdohj/params/LitecoinRegTestParams.java index b8f04252b..1f338ecea 100644 --- a/core/src/main/java/org/libdohj/params/LitecoinRegTestParams.java +++ b/core/src/main/java/org/libdohj/params/LitecoinRegTestParams.java @@ -52,7 +52,10 @@ public boolean allowEmptyPeerChain() { private static Block genesis; - /* + /* Extract from Litecoin source code, definition of regtest params. + Commit Hash: 3b4ed770f88229b11bf62b90f128f3054b17ab36 + File: src/chainparams.cpp + CRegTestParams() { strNetworkID = "regtest"; consensus.nSubsidyHalvingInterval = 150; @@ -117,8 +120,7 @@ public boolean allowEmptyPeerChain() { base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container >(); base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container >(); } - */ - + */ @Override public Block getGenesisBlock() { synchronized (LitecoinRegTestParams.class) { From 62c47eec0216ac808be179a26ec0d62a02199f5f Mon Sep 17 00:00:00 2001 From: Mike Rosseel Date: Mon, 19 Jun 2017 09:31:22 +0200 Subject: [PATCH 3/4] fixing PR comments --- .../libdohj/params/LitecoinRegTestParams.java | 73 +------------------ .../params/LitecoinRegTestParamsTest.java | 2 +- 2 files changed, 5 insertions(+), 70 deletions(-) diff --git a/core/src/main/java/org/libdohj/params/LitecoinRegTestParams.java b/core/src/main/java/org/libdohj/params/LitecoinRegTestParams.java index 1f338ecea..f68467948 100644 --- a/core/src/main/java/org/libdohj/params/LitecoinRegTestParams.java +++ b/core/src/main/java/org/libdohj/params/LitecoinRegTestParams.java @@ -52,75 +52,10 @@ public boolean allowEmptyPeerChain() { private static Block genesis; - /* Extract from Litecoin source code, definition of regtest params. - Commit Hash: 3b4ed770f88229b11bf62b90f128f3054b17ab36 - File: src/chainparams.cpp - - CRegTestParams() { - strNetworkID = "regtest"; - consensus.nSubsidyHalvingInterval = 150; - consensus.nMajorityEnforceBlockUpgrade = 750; - consensus.nMajorityRejectBlockOutdated = 950; - consensus.nMajorityWindow = 1000; - consensus.BIP34Height = -1; // BIP34 has not necessarily activated on regtest - consensus.BIP34Hash = uint256(); - consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - consensus.nPowTargetTimespan = 3.5 * 24 * 60 * 60; // two weeks - consensus.nPowTargetSpacing = 2.5 * 60; - consensus.fPowAllowMinDifficultyBlocks = true; - consensus.fPowNoRetargeting = true; - consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains - consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016) - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 999999999999ULL; - consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0; - consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0; - consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 999999999999ULL; - consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1; - consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0; - consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 999999999999ULL; - - // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x00"); - - pchMessageStart[0] = 0xfa; - pchMessageStart[1] = 0xbf; - pchMessageStart[2] = 0xb5; - pchMessageStart[3] = 0xda; - nDefaultPort = 19444; - nPruneAfterHeight = 1000; - - genesis = CreateGenesisBlock(1296688602, 0, 0x207fffff, 1, 50 * COIN); - consensus.hashGenesisBlock = genesis.GetHash(); - assert(consensus.hashGenesisBlock == uint256S("0x530827f38f93b43ed12af0b3ad25a288dc02ed74d6d7857862df51fc56c416f9")); - assert(genesis.hashMerkleRoot == uint256S("0x97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9")); - - vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds. - vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds. - - fMiningRequiresPeers = false; - fDefaultConsistencyChecks = true; - fRequireStandard = false; - fMineBlocksOnDemand = true; - fTestnetToBeDeprecatedFieldRPC = false; - - checkpointData = (CCheckpointData){ - boost::assign::map_list_of - ( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")), - 0, - 0, - 0 - }; - - base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,111); - base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,196); - base58Prefixes[SCRIPT_ADDRESS2] = std::vector(1,58); - base58Prefixes[SECRET_KEY] = std::vector(1,239); - base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container >(); - base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container >(); - } - */ + /** + * Extract from Litecoin source code, definition of regtest params. + * https://github.com/litecoin-project/litecoin/blob/edc66b374ea68107c721062152dd95e6aa037d53/src/chainparams.cpp + */ @Override public Block getGenesisBlock() { synchronized (LitecoinRegTestParams.class) { diff --git a/core/src/test/java/org/libdohj/params/LitecoinRegTestParamsTest.java b/core/src/test/java/org/libdohj/params/LitecoinRegTestParamsTest.java index f2b5c6f77..1755dac0e 100644 --- a/core/src/test/java/org/libdohj/params/LitecoinRegTestParamsTest.java +++ b/core/src/test/java/org/libdohj/params/LitecoinRegTestParamsTest.java @@ -24,7 +24,7 @@ /** * - * @author Ross Nicoll + * @author Mike Rosseel */ public class LitecoinRegTestParamsTest { private static final LitecoinRegTestParams params = LitecoinRegTestParams.get(); From 25ef90c1056da80f70b64ce9a753fb449418643c Mon Sep 17 00:00:00 2001 From: Mike Rosseel Date: Thu, 22 Jun 2017 15:33:18 +0200 Subject: [PATCH 4/4] fix BIP91 error, #25 --- .../java/org/bitcoinj/core/AltcoinBlock.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/core/AltcoinBlock.java b/core/src/main/java/org/bitcoinj/core/AltcoinBlock.java index 62e320cf5..51a2679cf 100644 --- a/core/src/main/java/org/bitcoinj/core/AltcoinBlock.java +++ b/core/src/main/java/org/bitcoinj/core/AltcoinBlock.java @@ -18,7 +18,9 @@ package org.bitcoinj.core; import org.libdohj.core.AltcoinNetworkParameters; -import com.google.common.base.Preconditions; +import org.libdohj.core.AuxPoWNetworkParameters; +import org.libdohj.core.ScryptHash; +import org.libdohj.params.AbstractLitecoinParams; import javax.annotation.Nullable; import java.io.ByteArrayOutputStream; @@ -28,13 +30,9 @@ import java.security.GeneralSecurityException; import java.util.BitSet; import java.util.List; -import static org.bitcoinj.core.Coin.FIFTY_COINS; - -import org.libdohj.core.ScryptHash; -import static org.libdohj.core.Utils.scryptDigest; import static org.bitcoinj.core.Utils.reverseBytes; -import org.libdohj.core.AuxPoWNetworkParameters; +import static org.libdohj.core.Utils.scryptDigest; /** *

A block is a group of transactions, and is one of the fundamental data structures of the Bitcoin system. @@ -172,8 +170,8 @@ public long getChainID() { /** * Return flags from block version of an AuxPoW-enabled chain. - * - * @return flags as a bitset. + * + * @return flags as a bitset. */ public BitSet getVersionFlags() { final BitSet bitset = new BitSet(BYTE_BITS); @@ -207,7 +205,9 @@ public static long getBaseVersion(final long rawVersion) { @Override public long getVersion() { // TODO: Can we cache the individual parts on parse? - if (this.params instanceof AltcoinNetworkParameters) { + if(this.params instanceof AbstractLitecoinParams) { + return super.getVersion(); + }else if (this.params instanceof AltcoinNetworkParameters) { // AuxPoW networks use the higher block version bits for flags and // chain ID. return getBaseVersion(super.getVersion());