diff --git a/.gitignore b/.gitignore index 0c75ee21..819d7eaf 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ target *.chain *.spvchain *.wallet +/nbproject/private/ +/build/ \ No newline at end of file diff --git a/core/findbugs.xml b/core/findbugs.xml deleted file mode 100644 index 6a3610d9..00000000 --- a/core/findbugs.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/core/pom.xml b/core/pom.xml deleted file mode 100644 index 475c21ce..00000000 --- a/core/pom.xml +++ /dev/null @@ -1,462 +0,0 @@ - - - - - 4.0.0 - - org.altcoinj - altcoinj-parent - 0.13-SNAPSHOT - - - altcoinj-core - - altcoinj - Extension library to bitcoinj to add altcoin support - - jar - - https://altcoinj.github.io - - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - - - - The altcoinj team - ross@dogecoin.com - - - - - - update-protobuf - - - updateProtobuf - true - - - - - - maven-antrun-plugin - - - compile-protoc - generate-sources - - - - - - - - - - - - - - - - - run - - - - - - - - - - - - - - maven-compiler-plugin - - 1.6 - 1.6 - - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - verify - - jar-no-fork - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - - - attach-javadocs - - jar - - - - - - - http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/ - - - true - - - - - - org.apache.maven.plugins - maven-enforcer-plugin - - - enforce - verify - - enforce - - - - - - - - true - - - - - - cglib:cglib-nodep:2.2:jar:null:test:59afed7ab65e7ec6585d5bc60556c3cbd203532b - com.fasterxml.jackson.core:jackson-annotations:2.4.0:jar:null:test:d6a66c7a5f01cf500377bd669507a08cfeba882a - com.fasterxml.jackson.core:jackson-core:2.4.2:jar:null:test:ceb72830d95c512b4b300a38f29febc85bdf6e4b - com.fasterxml.jackson.core:jackson-databind:2.4.2:jar:null:test:8e31266a272ad25ac4c089734d93e8d811652c1f - com.google.code.findbugs:jsr305:2.0.1:jar:null:compile:516c03b21d50a644d538de0f0369c620989cd8f0 - com.google.guava:guava:16.0.1:jar:null:compile:5fa98cd1a63c99a44dd8d3b77e4762b066a5d0c5 - com.google.protobuf:protobuf-java:2.5.0:jar:null:compile:a10732c76bfacdbd633a7eb0f7968b1059a65dfa - com.h2database:h2:1.3.167:jar:null:compile:d3867d586f087e53eb12fc65e5693d8ee9a5da17 - com.lambdaworks:scrypt:1.4.0:jar:null:compile:906506b74f30c8c20bccd9ed4a11112d8941fe87 - com.madgag.spongycastle:core:1.51.0.0:jar:null:compile:0f642963312ea0e615ad65f28adc5a5b3a2a0862 - junit:junit:4.11:jar:null:test:4e031bb61df09069aeb2bffb4019e7a5034a4ee0 - mysql:mysql-connector-java:5.1.33:jar:null:compile:8af455a9a3267e6664cafc87ace71a4e4ef02837 - net.jcip:jcip-annotations:1.0:jar:null:compile:afba4942caaeaf46aab0b976afd57cc7c181467e - org.apache.maven.plugins:maven-clean-plugin:2.6.1:maven-plugin:null:runtime:bfdf7d6c2f8fc8759457e9d54f458ba56ac7b30f - org.apache.maven.plugins:maven-compiler-plugin:3.2:maven-plugin:null:runtime:aec10f274ac07fafab8906cb1aa69669d753b2c2 - org.apache.maven.plugins:maven-dependency-plugin:2.10:maven-plugin:null:runtime:af87ceeb71c6499147c5d27f74c9317bf707538e - org.apache.maven.plugins:maven-deploy-plugin:2.8.2:maven-plugin:null:runtime:3c2d83ecd387e9843142ae92a0439792c1500319 - org.apache.maven.plugins:maven-enforcer-plugin:1.0:maven-plugin:null:runtime:ad032b7593576e9fe9305c73865633e163895b29 - org.apache.maven.plugins:maven-install-plugin:2.5.2:maven-plugin:null:runtime:8a67631619fc3c1d1f036e59362ddce71e1e496f - org.apache.maven.plugins:maven-jar-plugin:2.6:maven-plugin:null:runtime:618f08d0fcdd3929af846ef1b65503b5904f93e3 - org.apache.maven.plugins:maven-javadoc-plugin:2.10.2:maven-plugin:null:runtime:5f391697fa85cecc7e5bac7ce5a6f9d056a58ba3 - org.apache.maven.plugins:maven-resources-plugin:2.7:maven-plugin:null:runtime:94af11389943a480ecec7db01b4ded1b9cdf57c5 - org.apache.maven.plugins:maven-shade-plugin:2.3:maven-plugin:null:runtime:d136adc7abccc9c12adcad6ae7a9bc51b2b7184b - org.apache.maven.plugins:maven-site-plugin:3.4:maven-plugin:null:runtime:659cd5f1dd8bff554cf52603339494cbf7f283c5 - org.apache.maven.plugins:maven-source-plugin:2.4:maven-plugin:null:runtime:46f0d7f7823d729ba300d3f8929900c7e9cb5ac0 - org.apache.maven.plugins:maven-surefire-plugin:2.18.1:maven-plugin:null:runtime:402fd3066fd6d85ea4a1a3e7cd82a7e35037e6e8 - org.easymock:easymock:3.0:jar:null:test:f28a4c31c330f95c9acbf1108cea19952b5c496f - org.eluder.coveralls:coveralls-maven-plugin:3.1.0:maven-plugin:null:runtime:ca9d2915e2b1e99f15c9f54ad653eda893d42a69 - org.hamcrest:hamcrest-core:1.3:jar:null:test:42a25dc3219429f0e5d060061f71acb49bf010a0 - org.jacoco:jacoco-maven-plugin:0.7.4.201502262128:maven-plugin:null:runtime:ee12ed04db135c74d0ae99e9c4e4754ee1582edb - org.objenesis:objenesis:1.2:jar:null:test:bfcb0539a071a4c5a30690388903ac48c0667f2a - org.slf4j:slf4j-api:1.7.6:jar:null:compile:562424e36df3d2327e8e9301a76027fca17d54ea - org.slf4j:slf4j-jdk14:1.7.6:jar:null:test:1a3301a32ea7d90c3d33e9d60edbfdc9589fc748 - org.sonatype.plugins:nexus-staging-maven-plugin:1.6.5:maven-plugin:null:runtime:455ca2aa8cd14a06608f1538bd6a1efd09561563 - postgresql:postgresql:9.1-901.jdbc4:jar:null:compile:153f2f92a786f12fc111d0111f709012df87c808 - - uk.co.froot.maven.enforcer:digest-enforcer-rules:0.0.1:jar:null:runtime:16a9e04f3fe4bb143c42782d07d5faf65b32106f - - - - - - - - - - - uk.co.froot.maven.enforcer - digest-enforcer-rules - 0.0.1 - - - - - - - org.apache.maven.plugins - maven-shade-plugin - - - - package - - shade - - - false - - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - true - bundled - - - - - - - - org.jacoco - jacoco-maven-plugin - 0.7.4.201502262128 - - - **/Protos*.class - org/bitcoinj/jni/* - org/bitcoin/* - - - - - pre-unit-test - - prepare-agent - - - ${project.build.directory}/coverage-reports/jacoco.exec - surefireArgLine - - - - post-unit-test - test - - report - - - ${project.build.directory}/coverage-reports/jacoco.exec - ${project.reporting.outputDirectory}/jacoco - - - - default-report - prepare-package - - report - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - ${surefireArgLine} - alphabetical - - - - - - org.eluder.coveralls - coveralls-maven-plugin - 3.1.0 - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - unzip-lib - package - - unpack - - - false - false - true - - - target/test-classes/ - org.altcoinj - altcoinj-core - ${project.version} - - - - - - unzip-deps - package - - unpack-dependencies - - - target/test-classes/ - false - false - true - - - - - - - - - - junit - junit - 4.11 - test - - - org.easymock - easymock - 3.0 - test - - - - org.slf4j - slf4j-jdk14 - 1.7.6 - test - - - com.fasterxml.jackson.core - jackson-databind - 2.4.2 - test - - - com.h2database - h2 - 1.3.167 - true - - - com.madgag.spongycastle - core - 1.51.0.0 - - - com.google.protobuf - protobuf-java - 2.5.0 - - - com.google.guava - guava - 16.0.1 - - - com.google.code.findbugs - jsr305 - 2.0.1 - - - net.jcip - jcip-annotations - 1.0 - - - com.lambdaworks - scrypt - 1.4.0 - - - - - postgresql - postgresql - 9.1-901.jdbc4 - true - - - - - mysql - mysql-connector-java - 5.1.33 - true - - - org.fusesource.leveldbjni - leveldbjni-all - 1.8 - true - - - org.bitcoinj - orchid - 1.1 - - - org.bitcoinj - bitcoinj-core - 0.13-SNAPSHOT - - - - diff --git a/core/src/main/java/org/altcoinj/params/AbstractDogecoinParams.java b/core/src/main/java/org/altcoinj/params/AbstractDogecoinParams.java deleted file mode 100644 index 5e70bbf4..00000000 --- a/core/src/main/java/org/altcoinj/params/AbstractDogecoinParams.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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.altcoinj.params; - -import java.math.RoundingMode; -import java.util.HashMap; -import java.util.Map; - -import org.bitcoinj.core.NetworkParameters; -import org.bitcoinj.core.Sha256Hash; -import org.bitcoinj.core.Utils; -import org.bitcoinj.utils.MonetaryFormat; - -import static com.google.common.base.Preconditions.checkState; - -/** - * Parameters for the main Dogecoin production network on which people trade goods and services. - */ -public class AbstractDogecoinParams extends NetworkParameters { - /** Standard format for the DOGE denomination. */ - public static final MonetaryFormat DOGE; - /** Standard format for the mDOGE denomination. */ - public static final MonetaryFormat MDOGE; - /** Standard format for the Koinu denomination. */ - public static final MonetaryFormat KOINU; - - public static final int DOGE_TARGET_TIMESPAN = 4 * 60 * 60; // 4 hours per difficulty cycle, on average. - public static final int DOGE_TARGET_TIMESPAN_NEW = 60; // 60s per difficulty cycle, on average. Kicks in after block 145k. - public static final int DOGE_TARGET_SPACING = 1 * 60; // 1 minute per block. - public static final int DOGE_INTERVAL = DOGE_TARGET_TIMESPAN / DOGE_TARGET_SPACING; - public static final int DOGE_INTERVAL_NEW = DOGE_TARGET_TIMESPAN_NEW / DOGE_TARGET_SPACING; - - /** Currency code for base 1 Dogecoin. */ - public static final String CODE_DOGE = "DOGE"; - /** Currency code for base 1/1,000 Dogecoin. */ - public static final String CODE_MDOGE = "mDOGE"; - /** Currency code for base 1/100,000,000 Dogecoin. */ - public static final String CODE_KOINU = "Koinu"; - - private static final Map CURRENCY_CODES = new HashMap(); - - static { - CURRENCY_CODES.put(0, CODE_DOGE); - CURRENCY_CODES.put(3, CODE_MDOGE); - CURRENCY_CODES.put(8, CODE_KOINU); - - DOGE = MonetaryFormat.BTC.replaceCodes(CURRENCY_CODES); - MDOGE = DOGE.shift(3).minDecimals(2).optionalDecimals(2); - KOINU = DOGE.shift(6).minDecimals(0).optionalDecimals(2); - } - - /** The string returned by getId() for the main, production network where people trade things. */ - public static final String ID_DOGE_MAINNET = "org.dogecoin.production"; - /** The string returned by getId() for the testnet. */ - public static final String ID_DOGE_TESTNET = "org.dogecoin.test"; - - protected final int newInterval; - protected final int newTargetTimespan; - protected final int diffChangeTarget; - - public AbstractDogecoinParams(final int setDiffChangeTarget) { - super(); - interval = DOGE_INTERVAL; - newInterval = DOGE_INTERVAL_NEW; - targetTimespan = DOGE_TARGET_TIMESPAN; - newTargetTimespan = DOGE_TARGET_TIMESPAN_NEW; - maxTarget = Utils.decodeCompactBits(0x1e0fffffL); - diffChangeTarget = setDiffChangeTarget; - - packetMagic = 0xc0c0c0c0; - bip32HeaderPub = 0x0488C42E; //The 4 byte header that serializes in base58 to "xpub". (?) - bip32HeaderPriv = 0x0488E1F4; //The 4 byte header that serializes in base58 to "xprv" (?) - } - - /** How many blocks pass between difficulty adjustment periods. After new diff algo. */ - public int getNewInterval() { - return newInterval; - } - - /** - * How much time in seconds is supposed to pass between "interval" blocks. If the actual elapsed time is - * significantly different from this value, the network difficulty formula will produce a different value. - * Dogecoin after block 145k uses 60 seconds. - */ - public int getNewTargetTimespan() { - return newTargetTimespan; - } - - public MonetaryFormat getMonetaryFormat() { - return DOGE; - } -} diff --git a/pom.xml b/pom.xml index 9c514aae..63e33906 100644 --- a/pom.xml +++ b/pom.xml @@ -1,220 +1,42 @@ - + - 4.0.0 - - org.altcoinj - altcoinj-parent - 0.13-SNAPSHOT - pom - - - core - - - - org.sonatype.oss - oss-parent - 7 - - - - scm:git:https://github.com/rnicoll/altcoinj - scm:git:https://github.com/rnicoll/altcoinj - scm:git:https://github.com/rnicoll/altcoinj - - - altcoinj Parent - Provides the common configuration for the AltcoinJ modules - https://github.com/rnicoll/altcoinj/ - - - - Apache 2 - http://www.apache.org/licenses/LICENSE-2.0 - repo - A business-friendly OSS license - - - - - GitHub - https://github.com/rnicoll/altcoinj/issues - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - true - true - - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.3 - true - - ossrh - https://oss.sonatype.org/ - true - - - - - - - maven-clean-plugin - 2.5 - - - maven-compiler-plugin - 3.1 - - - maven-dependency-plugin - 2.8 - - - maven-deploy-plugin - 2.7 - - - maven-enforcer-plugin - 1.2 - - - maven-install-plugin - 2.5.1 - - - maven-jar-plugin - 2.5 - - - maven-javadoc-plugin - 2.9.1 - - - maven-resources-plugin - 2.6 - - - maven-shade-plugin - 2.3 - - - maven-site-plugin - 3.3 - - - maven-source-plugin - 2.1.2 - - - org.codehaus.mojo - cobertura-maven-plugin - 2.6 - - - - - - - org.slf4j - slf4j-api - 1.7.6 - - - - org.slf4j - slf4j-jdk14 - 1.7.6 - runtime - true - - - - - UTF-8 - - 3.0 - 4.8.2 - gen - - - - - doclint-java8-disable - - [1.8,) - - - - - org.apache.maven.plugins - maven-javadoc-plugin - - -Xdoclint:none - - - - - - - release - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - verify - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - - - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.5 - - - sign-artifacts - verify - - sign - - - - - - - - - - + 4.0.0 + org.altcoinj + altcoinj + 1.0-SNAPSHOT + jar + + + org.slf4j + slf4j-api + 1.7.7 + + + org.bitcoinj + bitcoinj-core + 0.13-SNAPSHOT + + + junit + junit + 4.12 + test + jar + + + com.google.protobuf + protobuf-java + 2.5.0 + + + com.lambdaworks + scrypt + 1.4.0 + + + + UTF-8 + 1.6 + 1.6 + + \ No newline at end of file diff --git a/core/src/main/java/org/altcoinj/core/AltcoinBlock.java b/src/main/java/org/altcoinj/core/AltcoinBlock.java similarity index 81% rename from core/src/main/java/org/altcoinj/core/AltcoinBlock.java rename to src/main/java/org/altcoinj/core/AltcoinBlock.java index a3f19bd4..9079c2fd 100644 --- a/core/src/main/java/org/altcoinj/core/AltcoinBlock.java +++ b/src/main/java/org/altcoinj/core/AltcoinBlock.java @@ -15,13 +15,11 @@ * limitations under the License. */ -package org.bitcoinj.core; +package org.altcoinj.core; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.annotation.Nullable; import java.io.ByteArrayOutputStream; @@ -29,11 +27,15 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.OutputStream; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Date; -import java.util.LinkedList; +import java.security.GeneralSecurityException; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.altcoinj.core.ScryptHash; +import static org.altcoinj.core.Utils.scryptDigest; + import static org.bitcoinj.core.Coin.FIFTY_COINS; import static org.bitcoinj.core.Utils.doubleDigest; import static org.bitcoinj.core.Utils.doubleDigestTwoBuffers; @@ -55,11 +57,13 @@ public class AltcoinBlock extends org.bitcoinj.core.Block { private boolean auxpowParsed = false; private boolean auxpowBytesValid = false; - /** AuxPoW header element, if applicable. */ - @Nullable private AuxPoW auxpow; + /** AuxPoW header element, if applicable. */ + @Nullable private AuxPoW auxpow; + + private ScryptHash scryptHash; /** Special case constructor, used for the genesis node, cloneAsHeader and unit tests. */ - AltcoinBlock(NetworkParameters params) { + public AltcoinBlock(NetworkParameters params) { super(params); } @@ -123,18 +127,54 @@ public class AltcoinBlock extends org.bitcoinj.core.Block { super(params, version, prevBlockHash, merkleRoot, time, difficultyTarget, nonce, transactions); } - @Override + private ScryptHash calculateScryptHash() { + try { + ByteArrayOutputStream bos = new UnsafeByteArrayOutputStream(HEADER_SIZE); + writeHeader(bos); + return new ScryptHash(Utils.reverseBytes(scryptDigest(bos.toByteArray()))); + } catch (IOException e) { + throw new RuntimeException(e); // Cannot happen. + } catch (GeneralSecurityException e) { + throw new RuntimeException(e); // Cannot happen. + } + } + + public AuxPoW getAuxPoW() { + // TODO: maybeParseAuxPoW(); + return this.auxpow; + } + + /** + * Returns the Scrypt hash of the block (which for a valid, solved block should be + * below the target). Big endian. + */ + public ScryptHash getScryptHash() { + if (scryptHash == null) + scryptHash = calculateScryptHash(); + return scryptHash; + } + + /** + * Returns the Scrypt hash of the block. + */ + public String getScryptHashAsString() { + return getScryptHash().toString(); + } + protected void parseAuxPoW() throws ProtocolException { if (this.auxpowParsed) return; - if (this.params.isAuxPoWBlockVersion(this.version)) { - // The following is used in dogecoinj, but I don't think we necessarily need it - // payload.length >= 160) { // We have at least 2 headers in an Aux block. Workaround for StoredBlocks - this.auxpow = new AuxPoW(params, payload, cursor, this, parseLazy, parseRetain); - } else { - this.auxpow = null; - } + this.auxpow = null; + if (this.params instanceof AuxPoWNetworkParameters) { + final AuxPoWNetworkParameters altcoinParams = (AuxPoWNetworkParameters)this.params; + if (altcoinParams.isAuxPoWBlockVersion(this.getVersion())) { + // The following is used in dogecoinj, but I don't think we necessarily need it + // payload.length >= 160) { // We have at least 2 headers in an Aux block. Workaround for StoredBlocks + this.auxpow = new AuxPoW(params, payload, cursor, this, parseLazy, parseRetain); + optimalEncodingMessageSize += auxpow.getOptimalEncodingMessageSize(); + } + } this.auxpowParsed = true; this.auxpowBytesValid = parseRetain; @@ -148,6 +188,15 @@ public class AltcoinBlock extends org.bitcoinj.core.Block { length = cursor - offset; } + @Override + protected void parseTransactions() { + if (null != this.auxpow) { + parseTransactions(HEADER_SIZE + auxpow.getMessageSize()); + } else { + parseTransactions(HEADER_SIZE); + } + } + @Override protected void parseLite() throws ProtocolException { // Ignore the header since it has fixed length. If length is not provided we will have to @@ -156,8 +205,8 @@ public class AltcoinBlock extends org.bitcoinj.core.Block { Preconditions.checkState(parseLazy, "Performing lite parse of block transaction as block was initialised from byte array " + "without providing length. This should never need to happen."); + parseAuxPoW(); parseTransactions(); - // TODO: Handle AuxPoW header space length = cursor - offset; } else { transactionBytesValid = !transactionsParsed || parseRetain && length > HEADER_SIZE; diff --git a/core/src/main/java/org/altcoinj/core/AuxPoW.java b/src/main/java/org/altcoinj/core/AuxPoW.java similarity index 98% rename from core/src/main/java/org/altcoinj/core/AuxPoW.java rename to src/main/java/org/altcoinj/core/AuxPoW.java index 82484c49..b8a6b81b 100644 --- a/core/src/main/java/org/altcoinj/core/AuxPoW.java +++ b/src/main/java/org/altcoinj/core/AuxPoW.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.bitcoinj.core; +package org.altcoinj.core; import org.bitcoinj.crypto.TransactionSignature; import org.bitcoinj.script.Script; @@ -126,8 +126,8 @@ public class AuxPoW extends ChildMessage implements Serializable { return; cursor = offset; - transaction = new Transaction(params, payload, cursor, this, parseLazy, parseRetain, Message.UNKNOWN_LENGTH); - cursor += transaction.getOptimalEncodingMessageSize(); + transaction = new Transaction(params, payload, cursor, this, parseLazy, parseRetain, Message.UNKNOWN_LENGTH); + cursor += transaction.getOptimalEncodingMessageSize(); optimalEncodingMessageSize = transaction.getOptimalEncodingMessageSize(); hashBlock = readHash(); diff --git a/core/src/main/java/org/altcoinj/core/MerkleBranch.java b/src/main/java/org/altcoinj/core/MerkleBranch.java similarity index 93% rename from core/src/main/java/org/altcoinj/core/MerkleBranch.java rename to src/main/java/org/altcoinj/core/MerkleBranch.java index 9c6131d1..c1cddadf 100644 --- a/core/src/main/java/org/altcoinj/core/MerkleBranch.java +++ b/src/main/java/org/altcoinj/core/MerkleBranch.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.bitcoinj.core; +package org.altcoinj.core; import static org.bitcoinj.core.Utils.doubleDigestTwoBuffers; import static org.bitcoinj.core.Utils.reverseBytes; @@ -88,14 +88,14 @@ public class MerkleBranch extends ChildMessage implements Serializable { super(params); setParent(parent); - this.branchHashes = hashes; - this.branchSideMask = branchSideMask; + this.branchHashes = hashes; + this.branchSideMask = branchSideMask; } @Override protected void parseLite() throws ProtocolException { - length = calcLength(payload, offset); - cursor = offset + length; + length = calcLength(payload, offset); + cursor = offset + length; } protected static int calcLength(byte[] buf, int offset) { @@ -113,10 +113,10 @@ public class MerkleBranch extends ChildMessage implements Serializable { final int hashCount = (int) readVarInt(); optimalEncodingMessageSize += VarInt.sizeOf(hashCount); - branchHashes = new ArrayList(hashCount); - for (int hashIdx = 0; hashIdx < hashCount; hashIdx++) { - branchHashes.add(readHash()); - } + branchHashes = new ArrayList(hashCount); + for (int hashIdx = 0; hashIdx < hashCount; hashIdx++) { + branchHashes.add(readHash()); + } optimalEncodingMessageSize += 32 * hashCount; branchSideMask = readUint32(); optimalEncodingMessageSize += 4; @@ -125,9 +125,9 @@ public class MerkleBranch extends ChildMessage implements Serializable { @Override protected void bitcoinSerializeToStream(OutputStream stream) throws IOException { stream.write(new VarInt(branchHashes.size()).encode()); - for (Sha256Hash hash: branchHashes) { - stream.write(Utils.reverseBytes(hash.getBytes())); - } + for (Sha256Hash hash: branchHashes) { + stream.write(Utils.reverseBytes(hash.getBytes())); + } Utils.uint32ToByteStreamLE(branchSideMask, stream); } diff --git a/src/main/java/org/altcoinj/core/ScryptHash.java b/src/main/java/org/altcoinj/core/ScryptHash.java new file mode 100644 index 00000000..e715624e --- /dev/null +++ b/src/main/java/org/altcoinj/core/ScryptHash.java @@ -0,0 +1,34 @@ +/** + * Copyright 2015 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.altcoinj.core; + +import org.bitcoinj.core.Sha256Hash; + +/** + * Scrypt hash. Currently extends Sha256Hash (so no real type safety is provided), + * but in time the two classes should have a common superclass rather than one + * extending the other directly. + */ +public class ScryptHash extends Sha256Hash { + + public ScryptHash(byte[] rawHashBytes) { + super(rawHashBytes); + } + + public ScryptHash(String hexString) { + super(hexString); + } +} diff --git a/src/main/java/org/altcoinj/core/Utils.java b/src/main/java/org/altcoinj/core/Utils.java new file mode 100644 index 00000000..f0fc8226 --- /dev/null +++ b/src/main/java/org/altcoinj/core/Utils.java @@ -0,0 +1,33 @@ +/** + * Copyright 2011 Google Inc. + * Copyright 2014 Andreas Schildbach + * + * 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.altcoinj.core; + +import com.lambdaworks.crypto.SCrypt; +import java.security.GeneralSecurityException; + +/** + * + */ +public class Utils { + /** + * Calculates the Scrypt hash of the given byte range. + * The resulting hash is in small endian form. + */ + public static byte[] scryptDigest(byte[] input) throws GeneralSecurityException { + return SCrypt.scrypt(input, input, 1024, 1, 1, 32); + } +} diff --git a/src/main/java/org/altcoinj/params/AbstractDogecoinParams.java b/src/main/java/org/altcoinj/params/AbstractDogecoinParams.java new file mode 100644 index 00000000..5570fed0 --- /dev/null +++ b/src/main/java/org/altcoinj/params/AbstractDogecoinParams.java @@ -0,0 +1,288 @@ +/* + * 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.altcoinj.params; + +import java.io.ByteArrayOutputStream; +import java.math.BigInteger; +import org.bitcoinj.core.AltcoinBlock; + +import org.bitcoinj.core.AuxPoWNetworkParameters; +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.Utils; +import org.bitcoinj.core.VerificationException; +import org.bitcoinj.script.Script; +import org.bitcoinj.script.ScriptOpCodes; +import org.bitcoinj.store.BlockStore; +import org.bitcoinj.store.BlockStoreException; +import org.bitcoinj.utils.MonetaryFormat; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static com.google.common.base.Preconditions.checkState; + +/** + * Parameters for the main Dogecoin production network on which people trade goods and services. + */ +public class AbstractDogecoinParams extends NetworkParameters { + /** Standard format for the DOGE denomination. */ + public static final MonetaryFormat DOGE; + /** Standard format for the mDOGE denomination. */ + public static final MonetaryFormat MDOGE; + /** Standard format for the Koinu denomination. */ + public static final MonetaryFormat KOINU; + + public static final int DIGISHIELD_BLOCK_HEIGHT = 145000; // Block height to use Digishield from + public static final int DOGE_TARGET_TIMESPAN = 4 * 60 * 60; // 4 hours per difficulty cycle, on average. + public static final int DOGE_TARGET_TIMESPAN_NEW = 60; // 60s per difficulty cycle, on average. Kicks in after block 145k. + public static final int DOGE_TARGET_SPACING = 1 * 60; // 1 minute per block. + public static final int DOGE_INTERVAL = DOGE_TARGET_TIMESPAN / DOGE_TARGET_SPACING; + public static final int DOGE_INTERVAL_NEW = DOGE_TARGET_TIMESPAN_NEW / DOGE_TARGET_SPACING; + + /** Currency code for base 1 Dogecoin. */ + public static final String CODE_DOGE = "DOGE"; + /** Currency code for base 1/1,000 Dogecoin. */ + public static final String CODE_MDOGE = "mDOGE"; + /** Currency code for base 1/100,000,000 Dogecoin. */ + public static final String CODE_KOINU = "Koinu"; + + public static final int BLOCK_VERSION_DEFAULT = 0x00000002; + public static final int BLOCK_VERSION_AUXPOW = 0x00620002; + public static final int BLOCK_VERSION_FLAG_AUXPOW = 0x00000100; + + static { + DOGE = MonetaryFormat.BTC.noCode() + .code(0, CODE_DOGE) + .code(3, CODE_MDOGE) + .code(7, CODE_KOINU); + MDOGE = DOGE.shift(3).minDecimals(2).optionalDecimals(2); + KOINU = DOGE.shift(7).minDecimals(0).optionalDecimals(2); + } + + /** The string returned by getId() for the main, production network where people trade things. */ + public static final String ID_DOGE_MAINNET = "org.dogecoin.production"; + /** The string returned by getId() for the testnet. */ + public static final String ID_DOGE_TESTNET = "org.dogecoin.test"; + + protected final int newInterval; + protected final int newTargetTimespan; + protected final int diffChangeTarget; + + protected Logger log = LoggerFactory.getLogger(AbstractDogecoinParams.class); + + public AbstractDogecoinParams(final int setDiffChangeTarget) { + super(); + genesisBlock = createGenesis(this); + interval = DOGE_INTERVAL; + newInterval = DOGE_INTERVAL_NEW; + targetTimespan = DOGE_TARGET_TIMESPAN; + newTargetTimespan = DOGE_TARGET_TIMESPAN_NEW; + maxTarget = Utils.decodeCompactBits(0x1e0fffffL); + diffChangeTarget = setDiffChangeTarget; + + packetMagic = 0xc0c0c0c0; + bip32HeaderPub = 0x0488C42E; //The 4 byte header that serializes in base58 to "xpub". (?) + bip32HeaderPriv = 0x0488E1F4; //The 4 byte header that serializes in base58 to "xprv" (?) + } + + private static AltcoinBlock createGenesis(NetworkParameters params) { + AltcoinBlock genesisBlock = new AltcoinBlock(params); + Transaction t = new Transaction(params); + try { + byte[] bytes = Utils.HEX.decode + ("04ffff001d0104084e696e746f6e646f"); + t.addInput(new TransactionInput(params, t, bytes)); + ByteArrayOutputStream scriptPubKeyBytes = new ByteArrayOutputStream(); + Script.writeBytes(scriptPubKeyBytes, Utils.HEX.decode + ("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9")); + scriptPubKeyBytes.write(ScriptOpCodes.OP_CHECKSIG); + t.addOutput(new TransactionOutput(params, t, COIN.multiply(88), scriptPubKeyBytes.toByteArray())); + } catch (Exception e) { + // Cannot happen. + throw new RuntimeException(e); + } + genesisBlock.addTransaction(t); + return genesisBlock; + } + + /** How many blocks pass between difficulty adjustment periods. After new diff algo. */ + public int getNewInterval() { + return newInterval; + } + + /** + * How much time in seconds is supposed to pass between "interval" blocks. If the actual elapsed time is + * significantly different from this value, the network difficulty formula will produce a different value. + * Dogecoin after block 145k uses 60 seconds. + */ + public int getNewTargetTimespan() { + return newTargetTimespan; + } + + public MonetaryFormat getMonetaryFormat() { + return DOGE; + } + + @Override + public Coin getMaxMoney() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public Coin getMinNonDustOutput() { + return Coin.COIN; + } + + @Override + public String getUriScheme() { + return "dogecoin"; + } + + @Override + public boolean hasMaxMoney() { + return false; + } + + @Override + public void checkDifficultyTransitions(StoredBlock storedPrev, Block nextBlock, BlockStore blockStore) + throws VerificationException, BlockStoreException { + final Block prev = storedPrev.getHeader(); + final int previousHeight = storedPrev.getHeight(); + final boolean digishieldAlgorithm = previousHeight + 1 >= this.getDigishieldBlockHeight(); + final int retargetInterval = digishieldAlgorithm + ? this.getInterval() + : this.getNewInterval(); + + // Is this supposed to be a difficulty transition point? + if ((storedPrev.getHeight() + 1) % retargetInterval != 0) { + // No ... so check the difficulty didn't actually change. + if (nextBlock.getDifficultyTarget() != prev.getDifficultyTarget()) + throw new VerificationException("Unexpected change in difficulty at height " + storedPrev.getHeight() + + ": " + Long.toHexString(nextBlock.getDifficultyTarget()) + " vs " + + Long.toHexString(prev.getDifficultyTarget())); + return; + } + + // We need to find a block far back in the chain. It's OK that this is expensive because it only occurs every + // two weeks after the initial block chain download. + StoredBlock cursor = blockStore.get(prev.getHash()); + int goBack = retargetInterval - 1; + if (cursor.getHeight()+1 != retargetInterval) + goBack = retargetInterval; + + for (int i = 0; i < goBack; i++) { + if (cursor == null) { + // This should never happen. If it does, it means we are following an incorrect or busted chain. + throw new VerificationException( + "Difficulty transition point but we did not find a way back to the genesis block."); + } + cursor = blockStore.get(cursor.getHeader().getPrevBlockHash()); + } + + //We used checkpoints... + if (cursor == null) { + log.debug("Difficulty transition: Hit checkpoint!"); + return; + } + + Block blockIntervalAgo = cursor.getHeader(); + long receivedTargetCompact = nextBlock.getDifficultyTarget(); + long newTargetCompact = this.getNewDifficultyTarget(previousHeight, prev.getTimeSeconds(), + receivedTargetCompact, blockIntervalAgo.getTimeSeconds()); + + if (newTargetCompact != receivedTargetCompact) + throw new VerificationException("Network provided difficulty bits do not match what was calculated: " + + newTargetCompact + " vs " + receivedTargetCompact); + } + + /** + * + * @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. + * @param lastRetargetTime Time of the last difficulty retarget. + * @return New difficulty target as compact bytes. + */ + protected long getNewDifficultyTarget(int previousHeight, long previousBlockTime, + final long lastDifficultyTarget, final long lastRetargetTime) { + final int height = previousHeight + 1; + final boolean digishieldAlgorithm = height >= this.getDigishieldBlockHeight(); + final int retargetTimespan = digishieldAlgorithm + ? this.getNewTargetTimespan() + : this.getTargetTimespan(); + int actualTime = (int) (previousBlockTime - lastRetargetTime); + final int minTimespan; + final int maxTimespan; + + // Limit the adjustment step. + if (digishieldAlgorithm) + { + // Round towards zero to match the C++ implementation. + if (actualTime < retargetTimespan) { + actualTime = (int)Math.ceil(retargetTimespan + (actualTime - retargetTimespan) / 8.0); + } else { + actualTime = (int)Math.floor(retargetTimespan + (actualTime - retargetTimespan) / 8.0); + } + minTimespan = retargetTimespan - (retargetTimespan / 4); + maxTimespan = retargetTimespan + (retargetTimespan / 2); + } + else if (height > 10000) + { + minTimespan = retargetTimespan / 4; + maxTimespan = retargetTimespan * 4; + } + else if (height > 5000) + { + minTimespan = retargetTimespan / 8; + maxTimespan = retargetTimespan * 4; + } + else + { + minTimespan = retargetTimespan / 16; + maxTimespan = retargetTimespan * 4; + } + actualTime = Math.min(maxTimespan, Math.max(minTimespan, actualTime)); + + BigInteger newTarget = Utils.decodeCompactBits(lastDifficultyTarget); + newTarget = newTarget.multiply(BigInteger.valueOf(actualTime)); + newTarget = newTarget.divide(BigInteger.valueOf(retargetTimespan)); + + if (newTarget.compareTo(this.getMaxTarget()) > 0) { + log.info("Difficulty hit proof of work limit: {}", newTarget.toString(16)); + newTarget = this.getMaxTarget(); + } + + int accuracyBytes = (int) (lastDifficultyTarget >>> 24) - 3; + + // The calculated difficulty is to a higher precision than received, so reduce here. + BigInteger mask = BigInteger.valueOf(0xFFFFFFL).shiftLeft(accuracyBytes * 8); + newTarget = newTarget.and(mask); + return Utils.encodeCompactBits(newTarget); + } + + /** + * Get the block height from which the Digishield difficulty calculation + * algorithm is used. + */ + public int getDigishieldBlockHeight() { + return DIGISHIELD_BLOCK_HEIGHT; + } +} diff --git a/core/src/main/java/org/altcoinj/params/DogecoinMainNetParams.java b/src/main/java/org/altcoinj/params/DogecoinMainNetParams.java similarity index 70% rename from core/src/main/java/org/altcoinj/params/DogecoinMainNetParams.java rename to src/main/java/org/altcoinj/params/DogecoinMainNetParams.java index 149d9902..d2ae97bb 100644 --- a/core/src/main/java/org/altcoinj/params/DogecoinMainNetParams.java +++ b/src/main/java/org/altcoinj/params/DogecoinMainNetParams.java @@ -16,12 +16,8 @@ package org.altcoinj.params; -import java.util.Map; - -import org.bitcoinj.core.NetworkParameters; -import org.bitcoinj.core.Sha256Hash; -import org.bitcoinj.core.Utils; -import org.bitcoinj.utils.MonetaryFormat; +import org.altcoinj.core.ScryptHash; +import org.bitcoinj.core.AltcoinBlock; import static com.google.common.base.Preconditions.checkState; @@ -48,6 +44,8 @@ public class DogecoinMainNetParams extends AbstractDogecoinParams { subsidyDecreaseBlockCount = 100000; spendableCoinbaseDepth = 100; + // Note this is an SHA256 hash, not a Scrypt hash. Scrypt hashes are only + // used in difficulty calculations. String genesisHash = genesisBlock.getHashAsString(); checkState(genesisHash.equals("1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691"), genesisHash); @@ -56,25 +54,25 @@ public class DogecoinMainNetParams extends AbstractDogecoinParams { // transactions are handled. Duplicated transactions could occur in the case where a coinbase had the same // extraNonce and the same outputs but appeared at different heights, and greatly complicated re-org handling. // Having these here simplifies block connection logic considerably. - checkpoints.put( 0, new Sha256Hash("1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691")); - checkpoints.put( 42279, new Sha256Hash("8444c3ef39a46222e87584ef956ad2c9ef401578bd8b51e8e4b9a86ec3134d3a")); - checkpoints.put( 42400, new Sha256Hash("557bb7c17ed9e6d4a6f9361cfddf7c1fc0bdc394af7019167442b41f507252b4")); - checkpoints.put(104679, new Sha256Hash("35eb87ae90d44b98898fec8c39577b76cb1eb08e1261cfc10706c8ce9a1d01cf")); - checkpoints.put(128370, new Sha256Hash("3f9265c94cab7dc3bd6a2ad2fb26c8845cb41cff437e0a75ae006997b4974be6")); - checkpoints.put(145000, new Sha256Hash("cc47cae70d7c5c92828d3214a266331dde59087d4a39071fa76ddfff9b7bde72")); - checkpoints.put(165393, new Sha256Hash("7154efb4009e18c1c6a6a79fc6015f48502bcd0a1edd9c20e44cd7cbbe2eeef1")); - checkpoints.put(186774, new Sha256Hash("3c712c49b34a5f34d4b963750d6ba02b73e8a938d2ee415dcda141d89f5cb23a")); - checkpoints.put(199992, new Sha256Hash("3408ff829b7104eebaf61fd2ba2203ef2a43af38b95b353e992ef48f00ebb190")); - checkpoints.put(225000, new Sha256Hash("be148d9c5eab4a33392a6367198796784479720d06bfdd07bd547fe934eea15a")); - checkpoints.put(250000, new Sha256Hash("0e4bcfe8d970979f7e30e2809ab51908d435677998cf759169407824d4f36460")); - checkpoints.put(270639, new Sha256Hash("c587a36dd4f60725b9dd01d99694799bef111fc584d659f6756ab06d2a90d911")); - checkpoints.put(299742, new Sha256Hash("1cc89c0c8a58046bf0222fe131c099852bd9af25a80e07922918ef5fb39d6742")); - checkpoints.put(323141, new Sha256Hash("60c9f919f9b271add6ef5671e9538bad296d79f7fdc6487ba702bf2ba131d31d")); - checkpoints.put(339202, new Sha256Hash("8c29048df5ae9df38a67ea9470fdd404d281a3a5c6f33080cd5bf14aa496ab03")); - checkpoints.put(350000, new Sha256Hash("2bdcba23a47049e69c4fec4c425462e30f3d21d25223bde0ed36be4ea59a7075")); - checkpoints.put(370005, new Sha256Hash("7be5af2c5bdcb79047dcd691ef613b82d4f1c20835677daed936de37a4782e15")); - checkpoints.put(371337, new Sha256Hash("60323982f9c5ff1b5a954eac9dc1269352835f47c2c5222691d80f0d50dcf053")); - checkpoints.put(400002, new Sha256Hash("a5021d69a83f39aef10f3f24f932068d6ff322c654d20562def3fac5703ce3aa")); + checkpoints.put( 0, new ScryptHash("1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691")); + checkpoints.put( 42279, new ScryptHash("8444c3ef39a46222e87584ef956ad2c9ef401578bd8b51e8e4b9a86ec3134d3a")); + checkpoints.put( 42400, new ScryptHash("557bb7c17ed9e6d4a6f9361cfddf7c1fc0bdc394af7019167442b41f507252b4")); + checkpoints.put(104679, new ScryptHash("35eb87ae90d44b98898fec8c39577b76cb1eb08e1261cfc10706c8ce9a1d01cf")); + checkpoints.put(128370, new ScryptHash("3f9265c94cab7dc3bd6a2ad2fb26c8845cb41cff437e0a75ae006997b4974be6")); + checkpoints.put(145000, new ScryptHash("cc47cae70d7c5c92828d3214a266331dde59087d4a39071fa76ddfff9b7bde72")); + checkpoints.put(165393, new ScryptHash("7154efb4009e18c1c6a6a79fc6015f48502bcd0a1edd9c20e44cd7cbbe2eeef1")); + checkpoints.put(186774, new ScryptHash("3c712c49b34a5f34d4b963750d6ba02b73e8a938d2ee415dcda141d89f5cb23a")); + checkpoints.put(199992, new ScryptHash("3408ff829b7104eebaf61fd2ba2203ef2a43af38b95b353e992ef48f00ebb190")); + checkpoints.put(225000, new ScryptHash("be148d9c5eab4a33392a6367198796784479720d06bfdd07bd547fe934eea15a")); + checkpoints.put(250000, new ScryptHash("0e4bcfe8d970979f7e30e2809ab51908d435677998cf759169407824d4f36460")); + checkpoints.put(270639, new ScryptHash("c587a36dd4f60725b9dd01d99694799bef111fc584d659f6756ab06d2a90d911")); + checkpoints.put(299742, new ScryptHash("1cc89c0c8a58046bf0222fe131c099852bd9af25a80e07922918ef5fb39d6742")); + checkpoints.put(323141, new ScryptHash("60c9f919f9b271add6ef5671e9538bad296d79f7fdc6487ba702bf2ba131d31d")); + checkpoints.put(339202, new ScryptHash("8c29048df5ae9df38a67ea9470fdd404d281a3a5c6f33080cd5bf14aa496ab03")); + checkpoints.put(350000, new ScryptHash("2bdcba23a47049e69c4fec4c425462e30f3d21d25223bde0ed36be4ea59a7075")); + checkpoints.put(370005, new ScryptHash("7be5af2c5bdcb79047dcd691ef613b82d4f1c20835677daed936de37a4782e15")); + checkpoints.put(371337, new ScryptHash("60323982f9c5ff1b5a954eac9dc1269352835f47c2c5222691d80f0d50dcf053")); + checkpoints.put(400002, new ScryptHash("a5021d69a83f39aef10f3f24f932068d6ff322c654d20562def3fac5703ce3aa")); dnsSeeds = new String[] { "seed.dogecoin.com", @@ -94,6 +92,12 @@ public class DogecoinMainNetParams extends AbstractDogecoinParams { @Override public String getPaymentProtocolId() { // TODO: CHANGE THIS - return PAYMENT_PROTOCOL_ID_MAINNET; + return ID_DOGE_MAINNET; + } + + @Override + public boolean isAuxPoWBlockVersion(long version) { + return version >= BLOCK_VERSION_AUXPOW + && (version & BLOCK_VERSION_FLAG_AUXPOW) > 0; } } diff --git a/core/src/main/java/org/altcoinj/params/DogecoinTestNet3Params.java b/src/main/java/org/altcoinj/params/DogecoinTestNet3Params.java similarity index 100% rename from core/src/main/java/org/altcoinj/params/DogecoinTestNet3Params.java rename to src/main/java/org/altcoinj/params/DogecoinTestNet3Params.java diff --git a/core/src/main/java/org/altcoinj/params/package-info.java b/src/main/java/org/altcoinj/params/package-info.java similarity index 100% rename from core/src/main/java/org/altcoinj/params/package-info.java rename to src/main/java/org/altcoinj/params/package-info.java diff --git a/core/src/main/java/org/altcoinj/protocols/package-info.java b/src/main/java/org/altcoinj/protocols/package-info.java similarity index 100% rename from core/src/main/java/org/altcoinj/protocols/package-info.java rename to src/main/java/org/altcoinj/protocols/package-info.java diff --git a/core/src/paymentchannel.proto b/src/paymentchannel.proto similarity index 100% rename from core/src/paymentchannel.proto rename to src/paymentchannel.proto diff --git a/core/src/paymentrequest.proto b/src/paymentrequest.proto similarity index 100% rename from core/src/paymentrequest.proto rename to src/paymentrequest.proto diff --git a/core/src/peerseeds.proto b/src/peerseeds.proto similarity index 100% rename from core/src/peerseeds.proto rename to src/peerseeds.proto diff --git a/core/src/storedclientpaymentchannel.proto b/src/storedclientpaymentchannel.proto similarity index 100% rename from core/src/storedclientpaymentchannel.proto rename to src/storedclientpaymentchannel.proto diff --git a/core/src/storedserverpaymentchannel.proto b/src/storedserverpaymentchannel.proto similarity index 100% rename from core/src/storedserverpaymentchannel.proto rename to src/storedserverpaymentchannel.proto diff --git a/core/src/test/java/org/altcoinj/core/AddressTest.java b/src/test/java/org/altcoinj/core/AddressTest.java similarity index 100% rename from core/src/test/java/org/altcoinj/core/AddressTest.java rename to src/test/java/org/altcoinj/core/AddressTest.java diff --git a/core/src/test/java/org/altcoinj/core/AuxPoWTest.java b/src/test/java/org/altcoinj/core/AuxPoWTest.java similarity index 100% rename from core/src/test/java/org/altcoinj/core/AuxPoWTest.java rename to src/test/java/org/altcoinj/core/AuxPoWTest.java diff --git a/core/src/test/java/org/altcoinj/core/DumpedPrivateKeyTest.java b/src/test/java/org/altcoinj/core/DumpedPrivateKeyTest.java similarity index 100% rename from core/src/test/java/org/altcoinj/core/DumpedPrivateKeyTest.java rename to src/test/java/org/altcoinj/core/DumpedPrivateKeyTest.java diff --git a/core/src/test/java/org/altcoinj/core/MerkleBranchTest.java b/src/test/java/org/altcoinj/core/MerkleBranchTest.java similarity index 100% rename from core/src/test/java/org/altcoinj/core/MerkleBranchTest.java rename to src/test/java/org/altcoinj/core/MerkleBranchTest.java diff --git a/core/src/test/java/org/altcoinj/core/PeerGroupTest.java b/src/test/java/org/altcoinj/core/PeerGroupTest.java similarity index 100% rename from core/src/test/java/org/altcoinj/core/PeerGroupTest.java rename to src/test/java/org/altcoinj/core/PeerGroupTest.java diff --git a/core/src/test/java/org/altcoinj/core/TransactionBroadcastTest.java b/src/test/java/org/altcoinj/core/TransactionBroadcastTest.java similarity index 100% rename from core/src/test/java/org/altcoinj/core/TransactionBroadcastTest.java rename to src/test/java/org/altcoinj/core/TransactionBroadcastTest.java diff --git a/core/src/test/java/org/altcoinj/core/VersionedChecksummedBytesTest.java b/src/test/java/org/altcoinj/core/VersionedChecksummedBytesTest.java similarity index 100% rename from core/src/test/java/org/altcoinj/core/VersionedChecksummedBytesTest.java rename to src/test/java/org/altcoinj/core/VersionedChecksummedBytesTest.java diff --git a/core/src/test/java/org/altcoinj/core/WalletTest.java b/src/test/java/org/altcoinj/core/WalletTest.java similarity index 100% rename from core/src/test/java/org/altcoinj/core/WalletTest.java rename to src/test/java/org/altcoinj/core/WalletTest.java diff --git a/src/test/java/org/altcoinj/params/AbstractDogecoinParamsTest.java b/src/test/java/org/altcoinj/params/AbstractDogecoinParamsTest.java new file mode 100644 index 00000000..dc030fc2 --- /dev/null +++ b/src/test/java/org/altcoinj/params/AbstractDogecoinParamsTest.java @@ -0,0 +1,72 @@ +/* + * 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.altcoinj.params; + +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +/** + * + * @author jrn + */ +public class AbstractDogecoinParamsTest { + private static final AbstractDogecoinParams params = DogecoinMainNetParams.get(); + + @Test + public void shouldCalculateBitcoinLikeDifficulty() { + int previousHeight = 239; + long previousBlockTime = 1386475638; // Block 239 + long lastRetargetDifficulty = 0x1e0ffff0; + long lastRetargetTime = 1386474927; // Block 1 + long newDifficulty = params.getNewDifficultyTarget(previousHeight, previousBlockTime, lastRetargetDifficulty, lastRetargetTime); + assertEquals(newDifficulty, 0x1e00ffff); + + previousHeight = 479; + previousBlockTime = 1386475840; + lastRetargetDifficulty = 0x1e0fffff; + lastRetargetTime = 1386475638; // Block 239 + newDifficulty = params.getNewDifficultyTarget(previousHeight, previousBlockTime, lastRetargetDifficulty, lastRetargetTime); + assertEquals(newDifficulty, 0x1e00ffff); + + previousHeight = 9599; + previousBlockTime = 1386954113; + lastRetargetDifficulty = 0x1c1a1206; + lastRetargetTime = 1386942008; // Block 9359 + newDifficulty = params.getNewDifficultyTarget(previousHeight, previousBlockTime, lastRetargetDifficulty, lastRetargetTime); + assertEquals(newDifficulty, 0x1c15ea59); + } + + @Test + public void shouldCalculateDigishieldDifficulty() { + int previousHeight = 145000; + long previousBlockTime = 1395094679; + long lastRetargetDifficulty = 0x1b499dfd; + long lastRetargetTime = 1395094427; + long newDifficulty = params.getNewDifficultyTarget(previousHeight, previousBlockTime, lastRetargetDifficulty, lastRetargetTime); + assertEquals(newDifficulty, 0x1b671062); + } + + @Test + public void shouldCalculateDigishieldDifficultyRounding() { + // Test case for correct rounding of modulated time + int previousHeight = 145001; + long previousBlockTime = 1395094727; + long lastRetargetDifficulty = 0x1b671062; + long lastRetargetTime = 1395094679; + long newDifficulty = params.getNewDifficultyTarget(previousHeight, previousBlockTime, lastRetargetDifficulty, lastRetargetTime); + assertEquals(newDifficulty, 0x1b6558a4); + } +} diff --git a/src/test/java/org/bitcoinj/core/DogecoinBlockTest.java b/src/test/java/org/bitcoinj/core/DogecoinBlockTest.java new file mode 100644 index 00000000..7784a988 --- /dev/null +++ b/src/test/java/org/bitcoinj/core/DogecoinBlockTest.java @@ -0,0 +1,92 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.bitcoinj.core; + +import java.io.IOException; +import org.altcoinj.params.DogecoinMainNetParams; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import org.junit.Before; +import org.junit.Test; + +/** + * + * @author jrn + */ +public class DogecoinBlockTest { + private final NetworkParameters params = DogecoinMainNetParams.get(); + + @Before + public void setUp() throws Exception { + Context context = new Context(params); + } + + @Test + public void shouldParseBlock1() throws IOException { + byte[] payload = Util.getBytes(getClass().getResourceAsStream("dogecoin_block1.bin")); + final AltcoinBlock block = new AltcoinBlock(params, payload); + assertEquals("82bc68038f6034c0596b6e313729793a887fded6e92a31fbdf70863f89d9bea2", block.getHashAsString()); + assertEquals(1, block.getTransactions().size()); + } + + /** + * Test the first hardfork block. + * @throws IOException + */ + @Test + public void shouldParseBlock250000() throws IOException { + byte[] payload = Util.getBytes(getClass().getResourceAsStream("dogecoin_block250000.bin")); + final AltcoinBlock block = new AltcoinBlock(params, payload); + assertEquals(2469341065L, block.getNonce()); + final AuxPoW auxpow = block.getAuxPoW(); + assertNull(auxpow); + + assertEquals(6, block.getTransactions().size()); + assertEquals("0e4bcfe8d970979f7e30e2809ab51908d435677998cf759169407824d4f36460", block.getHashAsString()); + } + + /** + * Confirm parsing of the first merged-mine block. + * + * @throws IOException + */ + @Test + public void shouldParseBlock371337() throws IOException { + byte[] payload = Util.getBytes(getClass().getResourceAsStream("dogecoin_block371337.bin")); + final AltcoinBlock block = new AltcoinBlock(params, payload); + assertEquals("60323982f9c5ff1b5a954eac9dc1269352835f47c2c5222691d80f0d50dcf053", block.getHashAsString()); + assertEquals(0, block.getNonce()); + final AuxPoW auxpow = block.getAuxPoW(); + assertNotNull(auxpow); + final Transaction auxpowCoinbase = auxpow.getCoinbase(); + assertEquals("e5422732b20e9e7ecc243427abbe296e9528d308bb111aae8d30c3465e442de8", auxpowCoinbase.getHashAsString()); + final Block parentBlock = auxpow.getParentBlockHeader(); + assertEquals("45df41e40aba5b2a03d08bd1202a1c02ef3954d8aa22ea6c5ae62fd00f290ea9", parentBlock.getHashAsString()); + assertNull(parentBlock.getTransactions()); + + final MerkleBranch blockchainMerkleBranch = auxpow.getBlockchainBranch(); + Sha256Hash[] expected = new Sha256Hash[] { + new Sha256Hash("b541c848bc001d07d2bdf8643abab61d2c6ae50d5b2495815339a4b30703a46f"), + new Sha256Hash("78d6abe48cee514cf3496f4042039acb7e27616dcfc5de926ff0d6c7e5987be7"), + new Sha256Hash("a0469413ce64d67c43902d54ee3a380eff12ded22ca11cbd3842e15d48298103") + }; + + assertArrayEquals(expected, blockchainMerkleBranch.getHashes().toArray(new Sha256Hash[blockchainMerkleBranch.getSize()])); + + final MerkleBranch coinbaseMerkleBranch = auxpow.getCoinbaseBranch(); + expected = new Sha256Hash[] { + new Sha256Hash("cd3947cd5a0c26fde01b05a3aa3d7a38717be6ae11d27239365024db36a679a9"), + new Sha256Hash("48f9e8fef3411944e27f49ec804462c9e124dca0954c71c8560e8a9dd218a452"), + new Sha256Hash("d11293660392e7c51f69477a6130237c72ecee2d0c1d3dc815841734c370331a") + }; + assertArrayEquals(expected, coinbaseMerkleBranch.getHashes().toArray(new Sha256Hash[coinbaseMerkleBranch.getSize()])); + + System.out.println(block.toString()); + assertEquals(6, block.getTransactions().size()); + } +} diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/core/block169482.dat b/src/test/resources/com/dogecoin/dogecoinj/core/block169482.dat similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/core/block169482.dat rename to src/test/resources/com/dogecoin/dogecoinj/core/block169482.dat diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/core/first-100k-blocks.dat b/src/test/resources/com/dogecoin/dogecoinj/core/first-100k-blocks.dat similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/core/first-100k-blocks.dat rename to src/test/resources/com/dogecoin/dogecoinj/core/first-100k-blocks.dat diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/core/sig_canonical.json b/src/test/resources/com/dogecoin/dogecoinj/core/sig_canonical.json similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/core/sig_canonical.json rename to src/test/resources/com/dogecoin/dogecoinj/core/sig_canonical.json diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/core/sig_noncanonical.json b/src/test/resources/com/dogecoin/dogecoinj/core/sig_noncanonical.json similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/core/sig_noncanonical.json rename to src/test/resources/com/dogecoin/dogecoinj/core/sig_noncanonical.json diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/crypto/comodo-smime.crt b/src/test/resources/com/dogecoin/dogecoinj/crypto/comodo-smime.crt similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/crypto/comodo-smime.crt rename to src/test/resources/com/dogecoin/dogecoinj/crypto/comodo-smime.crt diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/crypto/startssl-client.crt b/src/test/resources/com/dogecoin/dogecoinj/crypto/startssl-client.crt similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/crypto/startssl-client.crt rename to src/test/resources/com/dogecoin/dogecoinj/crypto/startssl-client.crt diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/crypto/startssl-smime.crt b/src/test/resources/com/dogecoin/dogecoinj/crypto/startssl-smime.crt similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/crypto/startssl-smime.crt rename to src/test/resources/com/dogecoin/dogecoinj/crypto/startssl-smime.crt diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/README b/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/README similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/README rename to src/test/resources/com/dogecoin/dogecoinj/protocols/payments/README diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/pki_test.bitcoinpaymentrequest b/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/pki_test.bitcoinpaymentrequest similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/pki_test.bitcoinpaymentrequest rename to src/test/resources/com/dogecoin/dogecoinj/protocols/payments/pki_test.bitcoinpaymentrequest diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-cacert.key b/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-cacert.key similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-cacert.key rename to src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-cacert.key diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-cacerts b/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-cacerts similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-cacerts rename to src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-cacerts diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-expired-cert b/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-expired-cert similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-expired-cert rename to src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-expired-cert diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-valid-cert b/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-valid-cert similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-valid-cert rename to src/test/resources/com/dogecoin/dogecoinj/protocols/payments/test-valid-cert diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/script/script_invalid.json b/src/test/resources/com/dogecoin/dogecoinj/script/script_invalid.json similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/script/script_invalid.json rename to src/test/resources/com/dogecoin/dogecoinj/script/script_invalid.json diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/script/script_valid.json b/src/test/resources/com/dogecoin/dogecoinj/script/script_valid.json similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/script/script_valid.json rename to src/test/resources/com/dogecoin/dogecoinj/script/script_valid.json diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/script/tx_invalid.json b/src/test/resources/com/dogecoin/dogecoinj/script/tx_invalid.json similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/script/tx_invalid.json rename to src/test/resources/com/dogecoin/dogecoinj/script/tx_invalid.json diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/script/tx_valid.json b/src/test/resources/com/dogecoin/dogecoinj/script/tx_valid.json similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/script/tx_valid.json rename to src/test/resources/com/dogecoin/dogecoinj/script/tx_valid.json diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/wallet/deterministic-wallet-serialization.txt b/src/test/resources/com/dogecoin/dogecoinj/wallet/deterministic-wallet-serialization.txt similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/wallet/deterministic-wallet-serialization.txt rename to src/test/resources/com/dogecoin/dogecoinj/wallet/deterministic-wallet-serialization.txt diff --git a/core/src/test/resources/com/dogecoin/dogecoinj/wallet/watching-wallet-serialization.txt b/src/test/resources/com/dogecoin/dogecoinj/wallet/watching-wallet-serialization.txt similarity index 100% rename from core/src/test/resources/com/dogecoin/dogecoinj/wallet/watching-wallet-serialization.txt rename to src/test/resources/com/dogecoin/dogecoinj/wallet/watching-wallet-serialization.txt diff --git a/src/test/resources/org/bitcoinj/core/auxpow_merkle_branch.bin b/src/test/resources/org/bitcoinj/core/auxpow_merkle_branch.bin new file mode 100644 index 00000000..96acc658 Binary files /dev/null and b/src/test/resources/org/bitcoinj/core/auxpow_merkle_branch.bin differ diff --git a/src/test/resources/org/bitcoinj/core/auxpow_merkle_branch2.bin b/src/test/resources/org/bitcoinj/core/auxpow_merkle_branch2.bin new file mode 100644 index 00000000..a1b85ea0 Binary files /dev/null and b/src/test/resources/org/bitcoinj/core/auxpow_merkle_branch2.bin differ diff --git a/src/test/resources/org/bitcoinj/core/dogecoin_block1.bin b/src/test/resources/org/bitcoinj/core/dogecoin_block1.bin new file mode 100644 index 00000000..3dfe1e33 Binary files /dev/null and b/src/test/resources/org/bitcoinj/core/dogecoin_block1.bin differ diff --git a/src/test/resources/org/bitcoinj/core/dogecoin_block250000.bin b/src/test/resources/org/bitcoinj/core/dogecoin_block250000.bin new file mode 100644 index 00000000..879ec368 Binary files /dev/null and b/src/test/resources/org/bitcoinj/core/dogecoin_block250000.bin differ diff --git a/src/test/resources/org/bitcoinj/core/dogecoin_block250000.hex b/src/test/resources/org/bitcoinj/core/dogecoin_block250000.hex new file mode 100644 index 00000000..50777646 --- /dev/null +++ b/src/test/resources/org/bitcoinj/core/dogecoin_block250000.hex @@ -0,0 +1 @@ +02000000f1ed0635084cd33dd84246608bd0f482eae17d10abe9f93d9c63198133da944a41d2a7ac13d1f72806911826dbe4cc76aa4bb6b7d474d614ae8d042b1425e624b9739153b88b561b89272f930601000000010000000000000000000000000000000000000000000000000000000000000000ffffffff270390d003062f503253482f04bf739153085802adce270000000d2f6e6f64655374726174756d2f0000000001e0635c6e5e0b00001976a914e0401fae9ec7f860ceefd71b17205d219f55f28388ac0000000001000000028bc149d040255e7d0056cb2148cf7cd36114a8e58eb9e0fb6b29222c02cdb35b030000006b48304502200df85199a31097d136aea951068217fbe1b2ffa6df30f58553eb5d8898989cc4022100d23ca500cf00ef5ee13d50ad017e56a93f6a46633579af0399277e7cb49a63a101210206b5768096e2f57c0496275891b6eaef12a7a32814aa96bba53e448634cd56f5ffffffffceda415463a4bfcc58d3fdb80de17046e812b93e88bb417481644564a9798fba000000006a47304402205af5dcf4f846f50e3233ab00b37a77e38cf3ee6d41da3aeee7a2cd8c28313c0f02207fb4d22d31e58042be8111886ef988cc5567f1b6e44e83401ffed0b4cb25bedf0121038090fa8c26e0048ec68df957aefc7ea9a358f762fd6fee9229ed6b5aa61e90feffffffff018053669e691300001976a91473cf40aa538f9ed024de0152365dde43a46061cf88ac0000000001000000013e257f3b57b650cdcd7a35b6799fb197ab72d9abb7e9108f4656b65a7495bc91000000008b483045022100994df605ea92e55fcd52b9905932d0714169a84d339b26fd3e89b191cf97be9b022031b4a88fedd13d891c766097ad64f13e66a7a0313a5fe1f3254e4ed763445e400141045bac63545633d14f00b361204e3496462756ef33be08fa53130558c0ec3b25c3da87af5c32427a8f9849f5607cc96fd12880093b53d57ff9d234ea141b181878ffffffff50a9824dab0b0000001976a9144802a6e4deac3aa91bd10107c572ed35b9b8315688ac8754e8b40c0000001976a9147d1d208a1908711d6d958fb05a98ddd027e0f50f88ac77eaef91020000001976a914aeb8aabf73789fd36db28d52eb4ca4f1b245ee6c88ac1964a03a060000001976a9149ce7357e92f48d5c22a31517894645da5046e62188acc755ad440c0000001976a914010aad796d5dd9b2d718f6a5818d103f1573b58788ac4808e2623c0000001976a914658d38097d8585dc353655f2ae306f6117c4d87b88ac924eed59170000001976a914ecdd22e82337671f793fedb7898d5b05ed749d7f88ac534cf4ca0b0000001976a91400e1e813276e2485df18ae1f0c5fe6e8f457e50d88ac5e5bab3f0f0000001976a914316dc54f7606d6d9e3075f192541ec0fca03501388ac45f0cf2a180000001976a914068df4e92ad05012207642a2ebe5fbd9ebad44ad88ac27f5e169170000001976a914adb0596bc0fe58ce700fe1c994068e9b8a0115cc88ac70ea470c0f0000001976a914d070b0f19447d89b1dad5a0f386ca6132e47119288ac4eed95560c0000001976a9149241eda2d88808556ee8e3a724eceb2ea8e1cba388acef99f871ef0000001976a91447360e18965f42e488e397d04b1461a49323bd9a88ac0b529ea5180000001976a91439cb521ee46575772823483719892e02f5eba2bc88ac45d8ded9020000001976a914af36bf435037354092fea16a539be3e9b5e8251388ace2f8f87a020000001976a9145329b59231241f6ad8a60e6711470081c023bb0f88ac6cc953ec770000001976a9144eccec9d3a95e5be5305eefc4ae26b776f6c938288ac8b97d3a30c0000001976a9147324db561127774be7f17f26c0092a14297b722388ac77eaef91020000001976a9148f4988ae9c5c672c4b4639089326707cd6e9accb88ac57d1bae20b0000001976a9144c307f2b885212a775df1b2045e27a0c19b80fa388ac81c35be00b0000001976a914ed5d3cfc425b8ee13fd6ba0090c42dc3229ff37388acf2ec3ef1020000001976a914f39a8cb88d7b3e962dc3e857234a270602bde76388ac48e9b4c7180000001976a9149abbac43b4a450511cd6f6c85fac5be48bb7003f88ac031e933f150000001976a9146dffb899339c43b89ae19b45451fd0e30a69cc6b88ac78a8e3500d0000001976a914744d62be468aec6cabf0becd12d539e5b03d021c88ace1dc155a0d0000001976a9149b7963e633d4c2c6a5642d33d8c690c96a95c45588ac53f30f78610000001976a914dc6c59526919d26b878fc983dc2324768b8fc5e688ac056296ee0b0000001976a914c35fc0bda88b44763a2ad61a679547a2ec430d1b88ac1820fc2f030000001976a914093f8d41de24417adadebee55780cc2504b1616388ac69c59e37750000001976a914379b604d9a326884036bdba05a2f6d0dc1d1f73f88ac71fe5692020000001976a914b71169cd04faa6027e259f93b72c8fdb027fae7688ac91c3b676020000001976a91414ba9b9e56d74dbb84cbcf7936ebd5661b7b3bfe88ac50a13558170000001976a91471293bb3d25409b631226f35e61abcccb81af14b88ac171438f8060000001976a91402cf2f282e656ab6bfdb4257a3399eec69e7705b88ac88f09683020000001976a9149a6f3ca42dd9089a1b4456fa9669229ccf6c270888ac737a1403050000001976a9147c06016cf7038b54b888bf01506a25345fa9ff5288ac2a452d15180000001976a914ed77151b9c2c2826b52de5a5f8ca0bfc7a25bc7988ac3fb8905d020000001976a9149cd65ea7c9c17104873ff6d6be8e4e31772127d888acd1263765030000001976a91446ddf3e3bb4592041a0c77195dbef67f9cb3f47d88ac0f9be2b6040000001976a914c71d12dd8eecb23b09a578e4612935945c48b59f88acc75e680b190000001976a914ab0c0bb720f4808b5b6a2e4a728cff6d1305c90388acbac97680020000001976a914b07d8b10b52c54eb6e450ce057ba294ecbf268c588acc1744b76190000001976a9146968114212b5da4550c4713b3b0a78821938beb488ac20b00b52190000001976a9142fa9682c37fdb9b95d91f07b97f10824c5ef51cc88ace3e2063be40000001976a914e0401fae9ec7f860ceefd71b17205d219f55f28388ac777a4c1c5e0000001976a914741cf53d280ba5b5bd50ea3579e465c4984161a188ac1e460e557c0000001976a914a9ad741e95a2cd0df726dbc14283181e23b4e38488ac7444f70c050000001976a91457ae7d012aafc8b773e61dc5074eb49fcc29937e88ac77da66ce020000001976a9147b10af6a2ee85d650e0b25647405eec4c9ec267788ac48b01178020000001976a914774f17662bb46d30e30b360074165e0b587c910788ac0fccba8b030000001976a914d20ea42fb07fdea184fbc1724794459c30d3848588accc1530610c0000001976a914bd5ed4d4817b9931cd5e4a6ebddb807070aa2a2088ace1aa7268020000001976a9141ba10df81ebe5fb8f887935c52bb789be85eff0f88ace9ef1f51180000001976a91487351b57fcd7ca2b759645a944875295c58b189588ac27cfdd0a030000001976a91429d5a52cb57a3ea89cef80fd412b9e2b34f3ca1a88ac199225e00b0000001976a91485cb3b4f164af2893d6a318d8a78c19c9521f16388ac3f4177b7190000001976a91486bdb6593f205880fb3b0fa4ead31f4f6a483c4188acdd6ea8f1040000001976a9147b9199434d184cf871ba802c307898923cfb114588acfe2ee51a750000001976a9145d530157f041228e9586964e55c3999871efae8c88ac43349a180d0000001976a9144c41e2f7d6450e1534b01134d7a108a3416af90e88ac5ca1f360030000001976a914e5e12425f7a24e797ab3560d7e7f63ebbe0dd0b488acb3cf558df30000001976a914157534d15ec39a4700a674c2f551d352d343a30988acd7262cdf170000001976a9140ab3b001e4379ca97bd11e681ef7da935032394088acb72c5e5ef30100001976a9148f75f94569fee7abe9a90ce0cf6b4eddf6f2a2da88acdfdcda674c0000001976a914c88f1f0710eebf3ec7bf6b2a0abd0c7d1a0de71288acc2f93a09060000001976a914f8783344af8532a73dfa97ebddfcc7527a2c6e5a88ac933b7ec60b0000001976a91443d84415142afbb6ab08ef60efdca30b31583e3988ac17f4f7f2170000001976a91421333564b0cda31763d0e04c310a0d5e31c401b388ac45150e8b020000001976a914f9885ad598f20dea09f7e5b5b4f6297745b9571588ac258b3e531a0000001976a9141d4ecf34bf5d6e7b9b85aa94832666f7dcbb5ad688ac557d4d5b100000001976a914ffaaf69b4fa1322702ded815222364857f0c1d1888ac0736f2ca050000001976a9142a169357ede9c3c368988d9dd178a9ada505cf0188ac516c65c5170000001976a914f425ebb751f3acfb6cfd8f9806d320110ade303d88acd15ebaba020000001976a9143a916f1eb747d84cae79780f70d0c0ea65cb79f788ac8db4243c060000001976a914ad345a8194be2cc456fce87e46a5f048f61f53d488ac9ea9a555020000001976a914eba059c3d9c4ae25b7dfa331d02acb6638ab579188ac8decf359020000001976a914c74caa8578cc83a8b96b839dcd5fff74a6d4b5b988ac087d7912050000001976a9144c7d38826243b36c2bb2163df674088437c7b94988ac627cc06f840000001976a914ac2089c0a48e36fd4094b862582e27004d1b2a8c88ac000000000100000001c5f435857a2f7e6f737d0c555b6930baab118dec52d8fa5647fa9afab7018acd010000006b48304502205bb1280a33590a644ce8e54dae1646e75e228d10d79781dc467ccc4e46e0cc27022100d98c74ef98d02b251fa7c9dfdefa61b8a423f6ad5e57ef9b4666c13fc09692d8012103788f672427c4c7fcbd764f74ba1d210d4c47323eac0e938f87305911f2157df5ffffffff02612f54d5460000001976a91473b87bd3e6c48b1c5407e2136d8ce5e3a63e973688ac5b62a505940000001976a9141d5f0968a3b4bc21179afa87676e698d15669a1888ac0000000001000000015aed3b4f2341acf8c58ed86cb6b87b3a1c4bca86167db922466562bafce660f60a0000006c49304602210089c01fd2e72563a35c2eef3bf6ccc8b1e0470cb70aed79722a52109b120b9bee022100e9127953a83e4f74d937e1e721a7d2959f7eb69910ca0f784c775f7860b7b5c50121028ee732b2a18ecdd8370dc2fdcf1514b4876f0e0be11588106bc92cf6313f0359ffffffff1800e1f505000000001976a91435479ba7008ae6babdff4e776a45ecda652fc7f688ac00e1f505000000001976a91417b28b361b560b8fc5ac0334a675da3df06f89da88ac00e1f505000000001976a914b217c8441318bb05b633aaa4d8a0e2a4ef88b73a88ac00e1f505000000001976a914c0aabc2ee1b7682c4e9874ae3f4873f18f64b67988ac00e1f505000000001976a9141557f4e81c5ea03cd0791c2155dff0551480218288ac00e1f505000000001976a914b7d9dff654e3a139e0cd713062f27f1b43a02a6e88ac0083556d1d0100001976a9145a1691fe88e6c71b1035eb69c44f6f4d717044ff88ac00e1f505000000001976a91486e89a9fc18ccd63b70b019a85b7d0908f6c123588ac00e1f505000000001976a9144ef6e028f071b9ceb785dc7e14eda9a89c7aa4fb88ac00e1f505000000001976a91404f6bc3f0a42ea7a9ab5f9359d0d696d671c1ab988ac00c2eb0b000000001976a9142c78d5a19aa92dc52ba6d6f34b988e2a69cfcaa888ac00e1f505000000001976a9142a14aa985a556947f2f5dfce30ba51a39b239d4e88ac00e1f505000000001976a914f21f66c71ab4751c9e9d75af7c30adb2572afce788ac00e1f505000000001976a91440456d03580707faf461a7bc569ef63543c47a1e88ac00e1f505000000001976a9144da5ace1799936e08625de8df7cf74262d759a6888ac00e1f505000000001976a9143064c76e48663459558757f05b5fdda37b91224288ac00e1f505000000001976a914393ce38521e1be5548b6e3061f37a5a19611ca3388ac00e1f505000000001976a914c513b6ea4174e7b013d96b0df3508c2e2105121d88ac00e1f505000000001976a914276465a8417a4aec7d965a34bde09971646743ab88ac00e1f505000000001976a91458db4ef1139fe51e26ad6bec4ba52ae6fdca9ff888ac00e1f505000000001976a9148c67f5db776574e3b650ae16c856d3ae7176a02e88ac00e1f505000000001976a914b2fc2f43282ab0ff9a20c61f42a3cfd5a307dae288ac00e1f505000000001976a914aebdbf030669c214545961c606b15cfca953e04288ac00e1f505000000001976a914639ec121400c2a4f59d4a48baf8dc408f768ace088ac0000000001000000013b0899ee0de79ca15b44db2efecf4421664879e8192792edfe0ee9b2bb2e089f060000006a47304402203d4c99b7762c278fcb2bbd125c86725b96dcf67802e2c5acc157ab0f27f8e88d02202374c963c38714599d2eded36c689868f02df0a0af341db7fdbf190e87b2f07e012102d4a953ee79ffaf8474b2a7f2eb0c4f5d2d7670468b73046e3c3b55e3ec576e3cffffffff0e00e1f505000000001976a9148ef4817cba8d74195fc233928249dde63ccde50088ac00c2eb0b000000001976a91417b28b361b560b8fc5ac0334a675da3df06f89da88ac00e1f505000000001976a91435479ba7008ae6babdff4e776a45ecda652fc7f688ac00e1f505000000001976a9146f756f696219b4be264514e9753ec5d69cbaade288ac00e1f505000000001976a91486e89a9fc18ccd63b70b019a85b7d0908f6c123588ac00e1f505000000001976a914f21f66c71ab4751c9e9d75af7c30adb2572afce788ac0054ed131d0100001976a9143b8dd3200b6f90fc4c7326fa0697e6df3ac65a4388ac00e1f505000000001976a9142c78d5a19aa92dc52ba6d6f34b988e2a69cfcaa888ac00e1f505000000001976a9144ef6e028f071b9ceb785dc7e14eda9a89c7aa4fb88ac00e1f505000000001976a914393ce38521e1be5548b6e3061f37a5a19611ca3388ac00e1f505000000001976a91458db4ef1139fe51e26ad6bec4ba52ae6fdca9ff888ac00e1f505000000001976a914b2fc2f43282ab0ff9a20c61f42a3cfd5a307dae288ac00e1f505000000001976a914aebdbf030669c214545961c606b15cfca953e04288ac00e1f505000000001976a9144cfa186866e65129b173fa6d9dbff2874d32077888ac00000000 diff --git a/src/test/resources/org/bitcoinj/core/dogecoin_block371337.bin b/src/test/resources/org/bitcoinj/core/dogecoin_block371337.bin new file mode 100644 index 00000000..af16cdfe Binary files /dev/null and b/src/test/resources/org/bitcoinj/core/dogecoin_block371337.bin differ diff --git a/src/test/resources/org/bitcoinj/core/dogecoin_block371337.hex b/src/test/resources/org/bitcoinj/core/dogecoin_block371337.hex new file mode 100644 index 00000000..c8458e1b --- /dev/null +++ b/src/test/resources/org/bitcoinj/core/dogecoin_block371337.hex @@ -0,0 +1 @@ +020162000d6f03470d329026cd1fc720c0609cd378ca8691a117bd1aa46f01fb09b1a8468a15bf6f0b0e83f2e5036684169eafb9406468d4f075c999fb5b2a78fbb827ee41fb11548441361b0000000001000000010000000000000000000000000000000000000000000000000000000000000000ffffffff380345bf09fabe6d6d980ba42120410de0554d42a5b5ee58167bcd86bf7591f429005f24da45fb51cf0800000000000000cdb1f1ff0e000000ffffffff01800c0c2a010000001976a914aa3750aa18b8a0f3f0590731e1fab934856680cf88ac00000000b3e64e02fff596209c498f1b18f798d62f216f11c8462bf3922319000000000003a979a636db2450363972d211aee67b71387a3daaa3051be0fd260c5acd4739cd52a418d29d8a0e56c8714c95a0dc24e1c9624480ec497fe2441941f3fee8f9481a3370c334178415c83d1d0c2deeec727c2330617a47691fc5e79203669312d100000000036fa40307b3a439538195245b0de56a2c1db6ba3a64f8bdd2071d00bc48c841b5e77b98e5c7d6f06f92dec5cf6d61277ecb9a0342406f49f34c51ee8ce4abd678038129485de14238bd1ca12cd2de12ff0e383aee542d90437cd664ce139446a00000000002000000d2ec7dfeb7e8f43fe77aba3368df95ac2088034420402730ee0492a2084217083411b3fc91033bfdeea339bc11b9efc986e161c703e07a9045338c165673f09940fb11548b54021b58cc9ae50601000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0d0389aa050101062f503253482fffffffff010066f33caf050000232102b73438165461b826b30a46078f211aa005d1e7e430b1e0ed461678a5fe516c73ac000000000100000001ef2e86aa5f027e13d7fc1f0bd4a1fc677d698e42850680634ccd1834668ff320010000006b483045022100fcf5dc43afa85978a71e76a9f4c11cd6bf2a7d5677212f9001ad085d420a5d3a022068982e1e53e94fc6007cf8b60ff3919bcaf7f0b70fefb79112cb840777d8c7cf0121022b050b740dd02c1b4e1e7cdbffe6d836d987c9db4c4db734b58526f08942193bffffffff02004e7253000000001976a91435cb1f77e88e96fb3094d84e8d3b7789a092636d88ac00d4b7e8b00700001976a9146ca1f634daa4efc7871abab945c7cefd282b481f88ac0000000001000000010a6c24bbc92fd0ec32bb5b0a051c44eba0c1325f0b24d9523c109f8bb1281f49000000006a4730440220608577619fb3a0b826f09df5663ffbf121c8e0164f43b73d9affe2f9e4576bd0022040782c9a7df0a20afe1a7e3578bf27e1331c862253af21ced4fde5ef1b44b787012103e4f91ad831a87cc532249944bc7138a355f7d0aac25dc4737a8701181ce680a5ffffffff010019813f0d0000001976a91481db1aa49ebc6a71cad96949eb28e22af85eb0bd88ac0000000001000000017b82db0f644ecff378217d9b8dc0de8817eaf85ceefacab23bf344e2e495dca5010000006b483045022100f07ced6bfdbd6cdeb8b2c8fc92b9803f5798754b5b6c454c8f084198bea303f402205616f84d7ec882af9c34a3fd2457ca3fb81ec5a463a963a6e684edee427d4525012102c056b10494520dbd7b37e2e6bb8f72f98d73a609a926901221bfb114fa1d5a80ffffffff02f0501a22000000001976a914ca63ded8b23d0252158a3bdc816747ef89fb438988ac80b65ea1350700001976a914fb26a7c16ace531a8e7bbd925e46c67c3150c1c888ac000000000100000001c9bdba900e1579ebf4e44415fe8b9abec57a763f8c70a30604bea7fbe7c55d42000000006a47304402204ccbeeace0630e72102fdaf0836e41f8f6dcdde6a178f0fbc2d96a4d17a1df8f02207e4a91203a2abd87fdddee96510482ef96535741b6c17a1acae93c977ad248e5012103e0747583a342b76a5de9c21db138b9640d49b4f3b67a306d3b3f217416d49b55ffffffff020058850c020000001976a9144417c63a91208a02a5f46a0f7a2b806adc7d19a788ac0042dc06030000001976a9147b61c5adef0d559e5acf2901c2989294624b651988ac0000000001000000017c1423b198dfc3da37ae9a5fc11a3720e4343b3049d3b289b8285eb04595c04b000000006b483045022100b0c1cb9608bf644d7a8916bf61f36ced95bd045e97612804ca774f60e05e7bde022017c12255eecc474c8d8b05d0910013b2df8703af68212cf0962b6b8ee0e101ee01210341e154088c23b8ea943bca94c1d4f65361668a242b168522f00199365414b46affffffff01019891ad000000001976a91481db1aa49ebc6a71cad96949eb28e22af85eb0bd88ac00000000 diff --git a/core/src/wallet.proto b/src/wallet.proto similarity index 100% rename from core/src/wallet.proto rename to src/wallet.proto