diff --git a/gui/src/main/java/io/bitsquare/gui/util/validation/IOPAddressValidator.java b/gui/src/main/java/io/bitsquare/gui/util/validation/IOPAddressValidator.java new file mode 100644 index 0000000000..21a578d56a --- /dev/null +++ b/gui/src/main/java/io/bitsquare/gui/util/validation/IOPAddressValidator.java @@ -0,0 +1,368 @@ +/* + * This file is part of Bitsquare. + * + * Bitsquare is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bitsquare is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bitsquare. If not, see . + */ + +package io.bitsquare.gui.util.validation; + + + +import static com.google.common.base.Preconditions.checkState; + +import java.math.BigInteger; +import java.net.URI; +import java.util.concurrent.TimeUnit; + +import org.bitcoinj.core.Address; +import org.bitcoinj.core.AddressFormatException; +import org.bitcoinj.core.Block; +import org.bitcoinj.core.Coin; +import org.bitcoinj.core.ECKey; +import org.bitcoinj.core.NetworkParameters; +import org.bitcoinj.core.Sha256Hash; +import org.bitcoinj.core.StoredBlock; +import org.bitcoinj.core.Transaction; +import org.bitcoinj.core.Utils; +import org.bitcoinj.core.VerificationException; +import org.bitcoinj.net.discovery.HttpDiscovery; +import org.bitcoinj.store.BlockStore; +import org.bitcoinj.store.BlockStoreException; +import org.bitcoinj.utils.MonetaryFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Stopwatch; + + +public final class IOPAddressValidator extends InputValidator { + + private static final Logger log = LoggerFactory.getLogger(IOPAddressValidator.class); + private static final NetworkParameters p = IoP_MainNetParams.get(); + + @Override + public ValidationResult validate(String input) { + + ValidationResult validationResult = super.validate(input); + + if (!validationResult.isValid) { + return new ValidationResult(false, "Not must blank!!!"); + }else{ + + try { + new Address(p, input); + return new ValidationResult(true); + } catch (AddressFormatException e) { + log.error(e.getMessage()); + return new ValidationResult(false, "Sorry Invalid IOP Address!!!"); + } + + } + + } + +} + + + +/* IoP_MainNetParams */ + +class IoP_MainNetParams extends IOPNetworkParameters{ + + + public IoP_MainNetParams() { + super(); + interval = INTERVAL; + targetTimespan = TARGET_TIMESPAN; + maxTarget = Utils.decodeCompactBits(0x1d00ffffL); + dumpedPrivateKeyHeader = 49; + addressHeader = 117; + p2shHeader = 174; + acceptableAddressCodes = new int[] { addressHeader, p2shHeader }; + port = 4877; + packetMagic = 0xfdb0bbd3L; + bip32HeaderPub = 0x2780915F; //The 4 byte header that serializes in base58 to "xpub". + bip32HeaderPriv = 0xAE3416F6; //The 4 byte header that serializes in base58 to "xprv" + + genesisBlock.setDifficultyTarget(0x1d00ffffL); + genesisBlock.setTime(1463452181L); + genesisBlock.setNonce(1875087468); + //NetworkParametersGetter.setSupportedBlockchain(SupportedBlockchain.INTERNET_OF_PEOPLE); + id ="org.IoP.production"; + subsidyDecreaseBlockCount = 210000; + // the amount of blocks premined that are taking into consideration when calculating the subsidy + // subsidyPremineDecreaseBlockCount = 42000; + spendableCoinbaseDepth = 100; + String genesisHash = genesisBlock.getHashAsString(); + // checkState(genesisHash.equals("00000000bf5f2ee556cb9be8be64e0776af14933438dbb1af72c41bfb6c82db3"), genesisHash); + + // This contains (at a minimum) the blocks which are not BIP30 compliant. BIP30 changed how duplicate + // 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, Sha256Hash.wrap("00000000bf5f2ee556cb9be8be64e0776af14933438dbb1af72c41bfb6c82db3")); + + dnsSeeds = new String[] { + "ham1.fermat.cloud", + "ham2.fermat.cloud", + "ham3.fermat.cloud", + "ham4.fermat.cloud", + "ham5.fermat.cloud" + }; + + ; + + httpSeeds = new HttpDiscovery.Details[] { + // Andreas Schildbach + new HttpDiscovery.Details( + //new ECKey(), + ECKey.fromPublicOnly(Utils.HEX.decode("027a79143a4de36341494d21b6593015af6b2500e720ad2eda1c0b78165f4f38c4")), + URI.create("http://httpseed.blockchain.schildbach.de/peers") + ) + }; + + addrSeeds = new int[] { + 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57, + 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018, + 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041, + 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445, + 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b, + 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652, + 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959, + 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63, + 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae, + 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5, + 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad, + 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153, + 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445, + 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5, + 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661, + 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf, + 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56, + 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144, + 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e, + 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742, + 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc, + 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5, + 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254, + 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163, + 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d, + 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b, + 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53, + 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc, + 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5, + 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80, + 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544, + 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3, + 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b, + 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6, + 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555, + 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047, + 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c, + 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c, + 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1, + 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad, + }; + } + + private static IoP_MainNetParams instance; + public static synchronized IoP_MainNetParams get() { + if (instance == null) { + instance = new IoP_MainNetParams(); + } + return instance; + } + + @Override + public String getPaymentProtocolId() { + return PAYMENT_PROTOCOL_ID_MAINNET; + } + + /* + @Override + public int getProtocolVersionNum(ProtocolVersion arg0) { + // TODO Auto-generated method stub + return 1; + }*/ + + + +} + +/* IoP_MainNetParams */ + + +/* IOPNetworkParameters */ + + + abstract class IOPNetworkParameters extends NetworkParameters{ + + private static final Logger log = LoggerFactory.getLogger(IOPNetworkParameters.class); + + + public static final byte[] SATOSHI_KEY = Utils.HEX.decode("04db0f57cd33acb1bbef6088ace7cfd417d943936f9594eaa9d25e62e5af4a43ffb31830cbcc9c499b935e2961e3e77b5644cfbb316096d0d931b34427f8fab682"); + + /** The string returned by getId() for the main, production network where people trade things. */ + public static final String ID_MAINNET = "org.IoP.production"; + /** The string returned by getId() for the testnet. */ + public static final String ID_TESTNET = "org.IoP.test"; + /** The string returned by getId() for regtest mode. */ + public static final String ID_REGTEST = "org.IoP.regtest"; + /** Unit test network. */ + public static final String ID_UNITTESTNET = "org.IoP.unittest"; + + public static final String BITCOIN_SCHEME = "bitcoin"; + public static final int REWARD_HALVING_INTERVAL = 210000; + + public static final int MAINNET_MAJORITY_WINDOW = 1000; + public static final int MAINNET_MAJORITY_REJECT_BLOCK_OUTDATED = 950; + public static final int MAINNET_MAJORITY_ENFORCE_BLOCK_UPGRADE = 750; + + + + public IOPNetworkParameters() { + super(); +// getMajorityEnforceBlockUpgrade(); +// majorityEnforceBlockUpgrade = MAINNET_MAJORITY_ENFORCE_BLOCK_UPGRADE; +// majorityRejectBlockOutdated = MAINNET_MAJORITY_REJECT_BLOCK_OUTDATED; +// majorityWindow = MAINNET_MAJORITY_WINDOW; + } + + /** + * Checks if we are at a reward halving point. + * @param height The height of the previous stored block + * @return If this is a reward halving point + */ + public final boolean isRewardHalvingPoint(final int height) { + return ((height + 1) % REWARD_HALVING_INTERVAL) == 0; + } + + /** + * Checks if we are at a difficulty transition point. + * @param height The height of the previous stored block + * @return If this is a difficulty transition point + */ + public final boolean isDifficultyTransitionPoint(final int height) { + return ((height + 1) % this.getInterval()) == 0; + } + + @Override + public void checkDifficultyTransitions(final StoredBlock storedPrev, final Block nextBlock, + final BlockStore blockStore) throws VerificationException, BlockStoreException { + final Block prev = storedPrev.getHeader(); + + // Is this supposed to be a difficulty transition point? + if (!isDifficultyTransitionPoint(storedPrev.getHeight())) { + + // 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. + final Stopwatch watch = Stopwatch.createStarted(); + Sha256Hash hash = prev.getHash(); + StoredBlock cursor = null; + final int interval = this.getInterval(); + for (int i = 0; i < interval; i++) { + cursor = blockStore.get(hash); + 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 last transition point. Not found: " + hash); + } + hash = cursor.getHeader().getPrevBlockHash(); + } + checkState(cursor != null && isDifficultyTransitionPoint(cursor.getHeight() - 1), + "Didn't arrive at a transition point."); + watch.stop(); + if (watch.elapsed(TimeUnit.MILLISECONDS) > 50) + log.info("Difficulty transition traversal took {}", watch); + + Block blockIntervalAgo = cursor.getHeader(); + int timespan = (int) (prev.getTimeSeconds() - blockIntervalAgo.getTimeSeconds()); + // Limit the adjustment step. + final int targetTimespan = this.getTargetTimespan(); + if (timespan < targetTimespan / 4) + timespan = targetTimespan / 4; + if (timespan > targetTimespan * 4) + timespan = targetTimespan * 4; + + BigInteger newTarget = Utils.decodeCompactBits(prev.getDifficultyTarget()); + newTarget = newTarget.multiply(BigInteger.valueOf(timespan)); + newTarget = newTarget.divide(BigInteger.valueOf(targetTimespan)); + + if (newTarget.compareTo(this.getMaxTarget()) > 0) { + log.info("Difficulty hit proof of work limit: {}", newTarget.toString(16)); + newTarget = this.getMaxTarget(); + } + + int accuracyBytes = (int) (nextBlock.getDifficultyTarget() >>> 24) - 3; + long receivedTargetCompact = nextBlock.getDifficultyTarget(); + + // 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); + long newTargetCompact = Utils.encodeCompactBits(newTarget); + + if (newTargetCompact != receivedTargetCompact) + throw new VerificationException("Network provided difficulty bits do not match what was calculated: " + + Long.toHexString(newTargetCompact) + " vs " + Long.toHexString(receivedTargetCompact)); + } + + @Override + public Coin getMaxMoney() { + return MAX_MONEY; + } + + @Override + public Coin getMinNonDustOutput() { + return Transaction.MIN_NONDUST_OUTPUT; + } + + @Override + public MonetaryFormat getMonetaryFormat() { + return new MonetaryFormat(); + } + +// +// @Override +// public int getProtocolVersionNum(final ProtocolVersion version) { +// return version.getBitcoinProtocolVersion(); +// } +// +// +// @Override +// public BitcoinSerializer getSerializer(boolean parseRetain) { +// return new BitcoinSerializer(this, parseRetain); +// } + + @Override + public String getUriScheme() { + return BITCOIN_SCHEME; + } + + @Override + public boolean hasMaxMoney() { + return true; + } + + + +} + diff --git a/gui/src/test/java/io/bitsquare/gui/util/validation/IOPAddressValidatorTest.java b/gui/src/test/java/io/bitsquare/gui/util/validation/IOPAddressValidatorTest.java new file mode 100644 index 0000000000..db87c164c5 --- /dev/null +++ b/gui/src/test/java/io/bitsquare/gui/util/validation/IOPAddressValidatorTest.java @@ -0,0 +1,20 @@ +package io.bitsquare.gui.util.validation; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class IOPAddressValidatorTest { + + @Test + public void testIOP() { + + IOPAddressValidator validator = new IOPAddressValidator(); + + assertTrue(validator.validate("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem").isValid); + assertTrue(validator.validate("pKbz7iRUSiUaTgh4UuwQCnc6pWZnyCGWxM").isValid); + + } + + +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 3e556c82e3..cf1da366c2 100644 --- a/pom.xml +++ b/pom.xml @@ -1,196 +1,197 @@ - - - 4.0.0 - - io.bitsquare - parent - pom - 0.4.9.8 - Bitsquare - The decentralized bitcoin exchange - https://bitsquare.io - - - bitsquare.io - - - - - GNU AFFERO GENERAL PUBLIC LICENSE - http://www.gnu.org/licenses/agpl-3.0.html - repo - - - - - GitHub - https://github.com/bitsquare/bitsquare/issues - - - - scm:git:https://github.com/bitsquare/bitsquare - scm:git:https://github.com/bitsquare/bitsquare - scm:git:https://github.com/bitsquare/bitsquare - - - - UTF-8 - - - - common - core - jsocks - jtorctl - jtorproxy - network - gui - headless - seednode - monitor - statistics - pricefeed - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.1 - - 1.8 - 1.8 - - - - - - - - - - - sonatype-oss-snapshot - - https://oss.sonatype.org/content/repositories/snapshots - - - - - - - org.bitcoinj - bitcoinj-core - 0.13.1.7 - - - - - com.google.inject - guice - 3.0 - - - - - org.bouncycastle - bcprov-jdk15on - 1.53 - - - - - commons-io - commons-io - 2.4 - - - org.apache.commons - commons-lang3 - 3.4 - - - com.google.guava - guava - 18.0 - - - org.fxmisc.easybind - easybind - 1.0.3 - - - org.reactfx - reactfx - 2.0-SNAPSHOT - - - org.jetbrains - annotations - 13.0 - - - com.google.code.findbugs - jsr305 - 3.0.1 - - - - - org.slf4j - slf4j-api - 1.7.12 - - - ch.qos.logback - logback-core - 1.1.3 - - - ch.qos.logback - logback-classic - 1.1.3 - - - - - junit - junit - 4.11 - test - - - org.mockito - mockito-core - 1.10.19 - test - - - org.springframework - spring-test - 4.1.1.RELEASE - test - - - + + + 4.0.0 + + io.bitsquare + parent + pom + 0.4.9.8 + Bitsquare - The decentralized bitcoin exchange + https://bitsquare.io + + + bitsquare.io + + + + + GNU AFFERO GENERAL PUBLIC LICENSE + http://www.gnu.org/licenses/agpl-3.0.html + repo + + + + + GitHub + https://github.com/bitsquare/bitsquare/issues + + + + scm:git:https://github.com/bitsquare/bitsquare + scm:git:https://github.com/bitsquare/bitsquare + scm:git:https://github.com/bitsquare/bitsquare + + + + UTF-8 + + + + common + core + jsocks + jtorctl + jtorproxy + network + gui + headless + seednode + monitor + statistics + pricefeed + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + + + + + + + + sonatype-oss-snapshot + + https://oss.sonatype.org/content/repositories/snapshots + + + + + + + org.bitcoinj + bitcoinj-core + + 0.13.1 + + + + + com.google.inject + guice + 3.0 + + + + + org.bouncycastle + bcprov-jdk15on + 1.53 + + + + + commons-io + commons-io + 2.4 + + + org.apache.commons + commons-lang3 + 3.4 + + + com.google.guava + guava + 18.0 + + + org.fxmisc.easybind + easybind + 1.0.3 + + + org.reactfx + reactfx + 2.0-SNAPSHOT + + + org.jetbrains + annotations + 13.0 + + + com.google.code.findbugs + jsr305 + 3.0.1 + + + + + org.slf4j + slf4j-api + 1.7.12 + + + ch.qos.logback + logback-core + 1.1.3 + + + ch.qos.logback + logback-classic + 1.1.3 + + + + + junit + junit + 4.11 + test + + + org.mockito + mockito-core + 1.10.19 + test + + + org.springframework + spring-test + 4.1.1.RELEASE + test + + +