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