mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-13 10:45:51 +00:00
Added extension points for altcoin support via subclassing.
This commit is contained in:
parent
c2d3cec6b0
commit
7a3aa74c6e
@ -829,9 +829,11 @@ public abstract class AbstractBlockChain {
|
|||||||
private static final Date testnetDiffDate = new Date(1329264000000L);
|
private static final Date testnetDiffDate = new Date(1329264000000L);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throws an exception if the blocks difficulty is not correct.
|
* Throws an exception if the block's difficulty is not correct.
|
||||||
|
*
|
||||||
|
* @throws VerificationException if the block's difficulty is not correct.
|
||||||
*/
|
*/
|
||||||
private void checkDifficultyTransitions(StoredBlock storedPrev, Block nextBlock) throws BlockStoreException, VerificationException {
|
protected void checkDifficultyTransitions(StoredBlock storedPrev, Block nextBlock) throws BlockStoreException, VerificationException {
|
||||||
checkState(lock.isHeldByCurrentThread());
|
checkState(lock.isHeldByCurrentThread());
|
||||||
Block prev = storedPrev.getHeader();
|
Block prev = storedPrev.getHeader();
|
||||||
|
|
||||||
|
@ -643,7 +643,7 @@ public class Block extends Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if the hash of the block is OK (lower than difficulty target). */
|
/** Returns true if the hash of the block is OK (lower than difficulty target). */
|
||||||
private boolean checkProofOfWork(boolean throwException) throws VerificationException {
|
protected boolean checkProofOfWork(boolean throwException) throws VerificationException {
|
||||||
// This part is key - it is what proves the block was as difficult to make as it claims
|
// This part is key - it is what proves the block was as difficult to make as it claims
|
||||||
// to be. Note however that in the context of this function, the block can claim to be
|
// to be. Note however that in the context of this function, the block can claim to be
|
||||||
// as difficult as it wants to be .... if somebody was able to take control of our network
|
// as difficult as it wants to be .... if somebody was able to take control of our network
|
||||||
|
@ -297,12 +297,12 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
}
|
}
|
||||||
// All values were already checked for being non-negative (as it is verified in Transaction.verify())
|
// All values were already checked for being non-negative (as it is verified in Transaction.verify())
|
||||||
// but we check again here just for defence in depth. Transactions with zero output value are OK.
|
// but we check again here just for defence in depth. Transactions with zero output value are OK.
|
||||||
if (valueOut.signum() < 0 || valueOut.compareTo(NetworkParameters.MAX_MONEY) > 0)
|
if (valueOut.signum() < 0 || valueOut.compareTo(this.params.getMaxMoney()) > 0)
|
||||||
throw new VerificationException("Transaction output value out of range");
|
throw new VerificationException("Transaction output value out of range");
|
||||||
if (isCoinBase) {
|
if (isCoinBase) {
|
||||||
coinbaseValue = valueOut;
|
coinbaseValue = valueOut;
|
||||||
} else {
|
} else {
|
||||||
if (valueIn.compareTo(valueOut) < 0 || valueIn.compareTo(NetworkParameters.MAX_MONEY) > 0)
|
if (valueIn.compareTo(valueOut) < 0 || valueIn.compareTo(this.params.getMaxMoney()) > 0)
|
||||||
throw new VerificationException("Transaction input value out of range");
|
throw new VerificationException("Transaction input value out of range");
|
||||||
totalFees = totalFees.add(valueIn.subtract(valueOut));
|
totalFees = totalFees.add(valueIn.subtract(valueOut));
|
||||||
}
|
}
|
||||||
@ -314,7 +314,7 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
listScriptVerificationResults.add(future);
|
listScriptVerificationResults.add(future);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (totalFees.compareTo(NetworkParameters.MAX_MONEY) > 0 || block.getBlockInflation(height).add(totalFees).compareTo(coinbaseValue) < 0)
|
if (totalFees.compareTo(this.params.getMaxMoney()) > 0 || block.getBlockInflation(height).add(totalFees).compareTo(coinbaseValue) < 0)
|
||||||
throw new VerificationException("Transaction fees out of range");
|
throw new VerificationException("Transaction fees out of range");
|
||||||
for (Future<VerificationException> future : listScriptVerificationResults) {
|
for (Future<VerificationException> future : listScriptVerificationResults) {
|
||||||
VerificationException e;
|
VerificationException e;
|
||||||
@ -427,12 +427,12 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
}
|
}
|
||||||
// All values were already checked for being non-negative (as it is verified in Transaction.verify())
|
// All values were already checked for being non-negative (as it is verified in Transaction.verify())
|
||||||
// but we check again here just for defence in depth. Transactions with zero output value are OK.
|
// but we check again here just for defence in depth. Transactions with zero output value are OK.
|
||||||
if (valueOut.signum() < 0 || valueOut.compareTo(NetworkParameters.MAX_MONEY) > 0)
|
if (valueOut.signum() < 0 || valueOut.compareTo(this.params.getMaxMoney()) > 0)
|
||||||
throw new VerificationException("Transaction output value out of range");
|
throw new VerificationException("Transaction output value out of range");
|
||||||
if (isCoinBase) {
|
if (isCoinBase) {
|
||||||
coinbaseValue = valueOut;
|
coinbaseValue = valueOut;
|
||||||
} else {
|
} else {
|
||||||
if (valueIn.compareTo(valueOut) < 0 || valueIn.compareTo(NetworkParameters.MAX_MONEY) > 0)
|
if (valueIn.compareTo(valueOut) < 0 || valueIn.compareTo(this.params.getMaxMoney()) > 0)
|
||||||
throw new VerificationException("Transaction input value out of range");
|
throw new VerificationException("Transaction input value out of range");
|
||||||
totalFees = totalFees.add(valueIn.subtract(valueOut));
|
totalFees = totalFees.add(valueIn.subtract(valueOut));
|
||||||
}
|
}
|
||||||
@ -444,7 +444,7 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
listScriptVerificationResults.add(future);
|
listScriptVerificationResults.add(future);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (totalFees.compareTo(NetworkParameters.MAX_MONEY) > 0 ||
|
if (totalFees.compareTo(this.params.getMaxMoney()) > 0 ||
|
||||||
newBlock.getHeader().getBlockInflation(newBlock.getHeight()).add(totalFees).compareTo(coinbaseValue) < 0)
|
newBlock.getHeader().getBlockInflation(newBlock.getHeight()).add(totalFees).compareTo(coinbaseValue) < 0)
|
||||||
throw new VerificationException("Transaction fees out of range");
|
throw new VerificationException("Transaction fees out of range");
|
||||||
txOutChanges = new TransactionOutputChanges(txOutsCreated, txOutsSpent);
|
txOutChanges = new TransactionOutputChanges(txOutsCreated, txOutsSpent);
|
||||||
|
@ -22,6 +22,10 @@ import org.bitcoinj.net.discovery.*;
|
|||||||
import org.bitcoinj.params.*;
|
import org.bitcoinj.params.*;
|
||||||
import org.bitcoinj.script.*;
|
import org.bitcoinj.script.*;
|
||||||
|
|
||||||
|
import org.bitcoinj.store.BlockStore;
|
||||||
|
import org.bitcoinj.store.BlockStoreException;
|
||||||
|
import org.bitcoinj.utils.MonetaryFormat;
|
||||||
|
|
||||||
import javax.annotation.*;
|
import javax.annotation.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.math.*;
|
import java.math.*;
|
||||||
@ -374,4 +378,34 @@ public abstract class NetworkParameters implements Serializable {
|
|||||||
public int getBip32HeaderPriv() {
|
public int getBip32HeaderPriv() {
|
||||||
return bip32HeaderPriv;
|
return bip32HeaderPriv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of coins that will be produced in total, on this
|
||||||
|
* network. Where not applicable, a very large number of coins is returned
|
||||||
|
* instead (i.e. the main coin issue for Dogecoin).
|
||||||
|
*/
|
||||||
|
public abstract Coin getMaxMoney();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any standard (ie pay-to-address) output smaller than this value will
|
||||||
|
* most likely be rejected by the network.
|
||||||
|
*/
|
||||||
|
public abstract Coin getMinNonDustOutput();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The monetary object for this currency.
|
||||||
|
*/
|
||||||
|
public abstract MonetaryFormat getMonetaryFormat();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scheme part for URIs, for example "bitcoin".
|
||||||
|
*/
|
||||||
|
public abstract String getUriScheme();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this network has a maximum number of coins (finite supply) or
|
||||||
|
* not. Always returns true for Bitcoin, but exists to be overriden for other
|
||||||
|
* networks.
|
||||||
|
*/
|
||||||
|
public abstract boolean hasMaxMoney();
|
||||||
}
|
}
|
||||||
|
@ -3080,7 +3080,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
try {
|
try {
|
||||||
checkNotNull(selector);
|
checkNotNull(selector);
|
||||||
List<TransactionOutput> candidates = calculateAllSpendCandidates(true, false);
|
List<TransactionOutput> candidates = calculateAllSpendCandidates(true, false);
|
||||||
CoinSelection selection = selector.select(NetworkParameters.MAX_MONEY, candidates);
|
CoinSelection selection = selector.select(params.getMaxMoney(), candidates);
|
||||||
return selection.valueGathered;
|
return selection.valueGathered;
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
@ -3663,7 +3663,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
// of the total value we can currently spend as determined by the selector, and then subtracting the fee.
|
// of the total value we can currently spend as determined by the selector, and then subtracting the fee.
|
||||||
checkState(req.tx.getOutputs().size() == 1, "Empty wallet TX must have a single output only.");
|
checkState(req.tx.getOutputs().size() == 1, "Empty wallet TX must have a single output only.");
|
||||||
CoinSelector selector = req.coinSelector == null ? coinSelector : req.coinSelector;
|
CoinSelector selector = req.coinSelector == null ? coinSelector : req.coinSelector;
|
||||||
bestCoinSelection = selector.select(NetworkParameters.MAX_MONEY, candidates);
|
bestCoinSelection = selector.select(params.getMaxMoney(), candidates);
|
||||||
candidates = null; // Selector took ownership and might have changed candidates. Don't access again.
|
candidates = null; // Selector took ownership and might have changed candidates. Don't access again.
|
||||||
req.tx.getOutput(0).setValue(bestCoinSelection.valueGathered);
|
req.tx.getOutput(0).setValue(bestCoinSelection.valueGathered);
|
||||||
log.info(" emptying {}", bestCoinSelection.valueGathered.toFriendlyString());
|
log.info(" emptying {}", bestCoinSelection.valueGathered.toFriendlyString());
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* 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.bitcoinj.params;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Coin;
|
||||||
|
import org.bitcoinj.core.NetworkParameters;
|
||||||
|
import org.bitcoinj.core.Sha256Hash;
|
||||||
|
import org.bitcoinj.core.Transaction;
|
||||||
|
import org.bitcoinj.core.Utils;
|
||||||
|
import org.bitcoinj.utils.MonetaryFormat;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters for Bitcoin-like networks.
|
||||||
|
*/
|
||||||
|
public abstract class AbstractBitcoinNetParams extends NetworkParameters {
|
||||||
|
/**
|
||||||
|
* Scheme part for Bitcoin URIs.
|
||||||
|
*/
|
||||||
|
public static final String BITCOIN_SCHEME = "bitcoin";
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(AbstractBitcoinNetParams.class);
|
||||||
|
|
||||||
|
public AbstractBitcoinNetParams() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 String getUriScheme() {
|
||||||
|
return BITCOIN_SCHEME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasMaxMoney() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -27,7 +27,7 @@ import static com.google.common.base.Preconditions.*;
|
|||||||
/**
|
/**
|
||||||
* Parameters for the main production network on which people trade goods and services.
|
* Parameters for the main production network on which people trade goods and services.
|
||||||
*/
|
*/
|
||||||
public class MainNetParams extends NetworkParameters {
|
public class MainNetParams extends AbstractBitcoinNetParams {
|
||||||
public MainNetParams() {
|
public MainNetParams() {
|
||||||
super();
|
super();
|
||||||
interval = INTERVAL;
|
interval = INTERVAL;
|
||||||
|
@ -31,9 +31,9 @@ import java.util.Set;
|
|||||||
*/
|
*/
|
||||||
public class Networks {
|
public class Networks {
|
||||||
/** Registered networks */
|
/** Registered networks */
|
||||||
private static Set<NetworkParameters> networks = ImmutableSet.of(TestNet3Params.get(), MainNetParams.get());
|
private static Set<? extends NetworkParameters> networks = ImmutableSet.of(TestNet3Params.get(), MainNetParams.get());
|
||||||
|
|
||||||
public static Set<NetworkParameters> get() {
|
public static Set<? extends NetworkParameters> get() {
|
||||||
return networks;
|
return networks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.bitcoinj.params;
|
package org.bitcoinj.params;
|
||||||
|
|
||||||
import org.bitcoinj.core.NetworkParameters;
|
|
||||||
import org.bitcoinj.core.Utils;
|
import org.bitcoinj.core.Utils;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
@ -25,7 +24,7 @@ import static com.google.common.base.Preconditions.checkState;
|
|||||||
* Parameters for the old version 2 testnet. This is not useful to you - it exists only because some unit tests are
|
* Parameters for the old version 2 testnet. This is not useful to you - it exists only because some unit tests are
|
||||||
* based on it.
|
* based on it.
|
||||||
*/
|
*/
|
||||||
public class TestNet2Params extends NetworkParameters {
|
public class TestNet2Params extends AbstractBitcoinNetParams {
|
||||||
public TestNet2Params() {
|
public TestNet2Params() {
|
||||||
super();
|
super();
|
||||||
id = ID_TESTNET;
|
id = ID_TESTNET;
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
package org.bitcoinj.params;
|
package org.bitcoinj.params;
|
||||||
|
|
||||||
import org.bitcoinj.core.NetworkParameters;
|
|
||||||
import org.bitcoinj.core.Utils;
|
import org.bitcoinj.core.Utils;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
@ -26,7 +25,7 @@ import static com.google.common.base.Preconditions.checkState;
|
|||||||
* Parameters for the testnet, a separate public instance of Bitcoin that has relaxed rules suitable for development
|
* Parameters for the testnet, a separate public instance of Bitcoin that has relaxed rules suitable for development
|
||||||
* and testing of applications and new Bitcoin versions.
|
* and testing of applications and new Bitcoin versions.
|
||||||
*/
|
*/
|
||||||
public class TestNet3Params extends NetworkParameters {
|
public class TestNet3Params extends AbstractBitcoinNetParams {
|
||||||
public TestNet3Params() {
|
public TestNet3Params() {
|
||||||
super();
|
super();
|
||||||
id = ID_TESTNET;
|
id = ID_TESTNET;
|
||||||
|
@ -24,7 +24,7 @@ import java.math.BigInteger;
|
|||||||
* Network parameters used by the bitcoinj unit tests (and potentially your own). This lets you solve a block using
|
* Network parameters used by the bitcoinj unit tests (and potentially your own). This lets you solve a block using
|
||||||
* {@link org.bitcoinj.core.Block#solve()} by setting difficulty to the easiest possible.
|
* {@link org.bitcoinj.core.Block#solve()} by setting difficulty to the easiest possible.
|
||||||
*/
|
*/
|
||||||
public class UnitTestParams extends NetworkParameters {
|
public class UnitTestParams extends AbstractBitcoinNetParams {
|
||||||
// A simple static key/address for re-use in unit tests, to speed things up.
|
// A simple static key/address for re-use in unit tests, to speed things up.
|
||||||
public static ECKey TEST_KEY = new ECKey();
|
public static ECKey TEST_KEY = new ECKey();
|
||||||
public static Address TEST_ADDRESS;
|
public static Address TEST_ADDRESS;
|
||||||
|
@ -193,6 +193,7 @@ public class StoredPaymentChannelServerStates implements WalletExtension {
|
|||||||
ServerState.StoredServerPaymentChannels.Builder builder = ServerState.StoredServerPaymentChannels.newBuilder();
|
ServerState.StoredServerPaymentChannels.Builder builder = ServerState.StoredServerPaymentChannels.newBuilder();
|
||||||
for (StoredServerChannel channel : mapChannels.values()) {
|
for (StoredServerChannel channel : mapChannels.values()) {
|
||||||
// First a few asserts to make sure things won't break
|
// First a few asserts to make sure things won't break
|
||||||
|
// TODO: Pull MAX_MONEY from network parameters
|
||||||
checkState(channel.bestValueToMe.signum() >= 0 && channel.bestValueToMe.compareTo(NetworkParameters.MAX_MONEY) < 0);
|
checkState(channel.bestValueToMe.signum() >= 0 && channel.bestValueToMe.compareTo(NetworkParameters.MAX_MONEY) < 0);
|
||||||
checkState(channel.refundTransactionUnlockTimeSecs > 0);
|
checkState(channel.refundTransactionUnlockTimeSecs > 0);
|
||||||
checkNotNull(channel.myKey.getPrivKeyBytes());
|
checkNotNull(channel.myKey.getPrivKeyBytes());
|
||||||
|
@ -400,7 +400,7 @@ public class PaymentSession {
|
|||||||
}
|
}
|
||||||
// This won't ever happen in practice. It would only happen if the user provided outputs
|
// This won't ever happen in practice. It would only happen if the user provided outputs
|
||||||
// that are obviously invalid. Still, we don't want to silently overflow.
|
// that are obviously invalid. Still, we don't want to silently overflow.
|
||||||
if (totalValue.compareTo(NetworkParameters.MAX_MONEY) > 0)
|
if (params.hasMaxMoney() && totalValue.compareTo(params.getMaxMoney()) > 0)
|
||||||
throw new PaymentProtocolException.InvalidOutputs("The outputs are way too big.");
|
throw new PaymentProtocolException.InvalidOutputs("The outputs are way too big.");
|
||||||
} catch (InvalidProtocolBufferException e) {
|
} catch (InvalidProtocolBufferException e) {
|
||||||
throw new PaymentProtocolException(e);
|
throw new PaymentProtocolException(e);
|
||||||
|
@ -20,6 +20,7 @@ import org.bitcoinj.core.Address;
|
|||||||
import org.bitcoinj.core.AddressFormatException;
|
import org.bitcoinj.core.AddressFormatException;
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
import org.bitcoinj.core.NetworkParameters;
|
import org.bitcoinj.core.NetworkParameters;
|
||||||
|
import org.bitcoinj.params.AbstractBitcoinNetParams;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -91,6 +92,12 @@ public class BitcoinURI {
|
|||||||
public static final String FIELD_ADDRESS = "address";
|
public static final String FIELD_ADDRESS = "address";
|
||||||
public static final String FIELD_PAYMENT_REQUEST_URL = "r";
|
public static final String FIELD_PAYMENT_REQUEST_URL = "r";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URI for Bitcoin network. Use {@link org.bitcoinj.params.AbstractBitcoinNetParams.BITCOIN_SCHEME} if you specifically
|
||||||
|
* need Bitcoin, or use {@link org.bitcoinj.core.NetworkParams.getUriScheme()} to get the scheme
|
||||||
|
* from network parameters.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public static final String BITCOIN_SCHEME = "bitcoin";
|
public static final String BITCOIN_SCHEME = "bitcoin";
|
||||||
private static final String ENCODED_SPACE_CHARACTER = "%20";
|
private static final String ENCODED_SPACE_CHARACTER = "%20";
|
||||||
private static final String AMPERSAND_SEPARATOR = "&";
|
private static final String AMPERSAND_SEPARATOR = "&";
|
||||||
@ -124,6 +131,10 @@ public class BitcoinURI {
|
|||||||
checkNotNull(input);
|
checkNotNull(input);
|
||||||
log.debug("Attempting to parse '{}' for {}", input, params == null ? "any" : params.getId());
|
log.debug("Attempting to parse '{}' for {}", input, params == null ? "any" : params.getId());
|
||||||
|
|
||||||
|
String scheme = null == params
|
||||||
|
? AbstractBitcoinNetParams.BITCOIN_SCHEME
|
||||||
|
: params.getUriScheme();
|
||||||
|
|
||||||
// Attempt to form the URI (fail fast syntax checking to official standards).
|
// Attempt to form the URI (fail fast syntax checking to official standards).
|
||||||
URI uri;
|
URI uri;
|
||||||
try {
|
try {
|
||||||
@ -141,11 +152,13 @@ public class BitcoinURI {
|
|||||||
// For instance with : bitcoin:129mVqKUmJ9uwPxKJBnNdABbuaaNfho4Ha?amount=0.06&label=Tom%20%26%20Jerry
|
// For instance with : bitcoin:129mVqKUmJ9uwPxKJBnNdABbuaaNfho4Ha?amount=0.06&label=Tom%20%26%20Jerry
|
||||||
// the & (%26) in Tom and Jerry gets interpreted as a separator and the label then gets parsed
|
// the & (%26) in Tom and Jerry gets interpreted as a separator and the label then gets parsed
|
||||||
// as 'Tom ' instead of 'Tom & Jerry')
|
// as 'Tom ' instead of 'Tom & Jerry')
|
||||||
|
String blockchainInfoScheme = scheme + "://";
|
||||||
|
String correctScheme = scheme + ":";
|
||||||
String schemeSpecificPart;
|
String schemeSpecificPart;
|
||||||
if (input.startsWith("bitcoin://")) {
|
if (input.startsWith(blockchainInfoScheme)) {
|
||||||
schemeSpecificPart = input.substring("bitcoin://".length());
|
schemeSpecificPart = input.substring(blockchainInfoScheme.length());
|
||||||
} else if (input.startsWith("bitcoin:")) {
|
} else if (input.startsWith(correctScheme)) {
|
||||||
schemeSpecificPart = input.substring("bitcoin:".length());
|
schemeSpecificPart = input.substring(correctScheme.length());
|
||||||
} else {
|
} else {
|
||||||
throw new BitcoinURIParseException("Unsupported URI scheme: " + uri.getScheme());
|
throw new BitcoinURIParseException("Unsupported URI scheme: " + uri.getScheme());
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ public class DefaultCoinSelector implements CoinSelector {
|
|||||||
ArrayList<TransactionOutput> sortedOutputs = new ArrayList<TransactionOutput>(candidates);
|
ArrayList<TransactionOutput> sortedOutputs = new ArrayList<TransactionOutput>(candidates);
|
||||||
// When calculating the wallet balance, we may be asked to select all possible coins, if so, avoid sorting
|
// When calculating the wallet balance, we may be asked to select all possible coins, if so, avoid sorting
|
||||||
// them in order to improve performance.
|
// them in order to improve performance.
|
||||||
|
// TODO: Take in network parameters when instanatiated, and then test against the current network. Or just have a boolean parameter for "give me everything"
|
||||||
if (!target.equals(NetworkParameters.MAX_MONEY)) {
|
if (!target.equals(NetworkParameters.MAX_MONEY)) {
|
||||||
sortOutputs(sortedOutputs);
|
sortOutputs(sortedOutputs);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user