mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-20 10:22:18 +01:00
Remove UTXOProvider -> use CoinSelector instead. Add prog args for block and wallet notification ports for rpc to support 2 apps
This commit is contained in:
parent
7ea1718d86
commit
dd591a44da
@ -80,7 +80,7 @@ public class BitsquareEnvironment extends StandardEnvironment {
|
||||
private final String btcNetworkDir;
|
||||
private final String logLevel, providers;
|
||||
private BitcoinNetwork bitcoinNetwork;
|
||||
private final String btcNodes, seedNodes, ignoreDevMsg, useTorForBtc, rpcUser, rpcPassword, rpcPort,
|
||||
private final String btcNodes, seedNodes, ignoreDevMsg, useTorForBtc, rpcUser, rpcPassword, rpcPort, rpcBlockPort, rpcWalletPort,
|
||||
myAddress, banList, dumpStatistics, maxMemory, socks5ProxyBtcAddress, socks5ProxyHttpAddress;
|
||||
|
||||
public BitsquareEnvironment(OptionSet options) {
|
||||
@ -162,6 +162,13 @@ public class BitsquareEnvironment extends StandardEnvironment {
|
||||
rpcPort = commandLineProperties.containsProperty(RpcOptionKeys.RPC_PORT) ?
|
||||
(String) commandLineProperties.getProperty(RpcOptionKeys.RPC_PORT) :
|
||||
"";
|
||||
rpcBlockPort = commandLineProperties.containsProperty(RpcOptionKeys.RPC_BLOCK_PORT) ?
|
||||
(String) commandLineProperties.getProperty(RpcOptionKeys.RPC_BLOCK_PORT) :
|
||||
"";
|
||||
rpcWalletPort = commandLineProperties.containsProperty(RpcOptionKeys.RPC_WALLET_PORT) ?
|
||||
(String) commandLineProperties.getProperty(RpcOptionKeys.RPC_WALLET_PORT) :
|
||||
"";
|
||||
|
||||
myAddress = commandLineProperties.containsProperty(NetworkOptionKeys.MY_ADDRESS) ?
|
||||
(String) commandLineProperties.getProperty(NetworkOptionKeys.MY_ADDRESS) :
|
||||
"";
|
||||
@ -258,6 +265,8 @@ public class BitsquareEnvironment extends StandardEnvironment {
|
||||
setProperty(RpcOptionKeys.RPC_USER, rpcUser);
|
||||
setProperty(RpcOptionKeys.RPC_PASSWORD, rpcPassword);
|
||||
setProperty(RpcOptionKeys.RPC_PORT, rpcPort);
|
||||
setProperty(RpcOptionKeys.RPC_BLOCK_PORT, rpcBlockPort);
|
||||
setProperty(RpcOptionKeys.RPC_WALLET_PORT, rpcWalletPort);
|
||||
|
||||
setProperty(AppOptionKeys.BTC_NODES, btcNodes);
|
||||
setProperty(AppOptionKeys.USE_TOR_FOR_BTC, useTorForBtc);
|
||||
|
@ -119,6 +119,10 @@ public abstract class BitsquareExecutable {
|
||||
.withRequiredArg();
|
||||
parser.accepts(RpcOptionKeys.RPC_PORT, description("Bitcoind rpc port", ""))
|
||||
.withRequiredArg();
|
||||
parser.accepts(RpcOptionKeys.RPC_BLOCK_PORT, description("Bitcoind rpc port for block notifications", ""))
|
||||
.withRequiredArg();
|
||||
parser.accepts(RpcOptionKeys.RPC_WALLET_PORT, description("Bitcoind rpc port for wallet notifications", ""))
|
||||
.withRequiredArg();
|
||||
|
||||
parser.accepts(BtcOptionKeys.BTC_NETWORK, description("Bitcoin network", BitcoinNetwork.DEFAULT))
|
||||
.withRequiredArg()
|
||||
|
@ -23,7 +23,10 @@ import io.bitsquare.app.AppOptionKeys;
|
||||
import io.bitsquare.btc.provider.fee.FeeService;
|
||||
import io.bitsquare.btc.provider.price.PriceFeedService;
|
||||
import io.bitsquare.btc.provider.squ.SquUtxoFeedService;
|
||||
import io.bitsquare.btc.wallet.*;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.SquWalletService;
|
||||
import io.bitsquare.btc.wallet.TradeWalletService;
|
||||
import io.bitsquare.btc.wallet.WalletsSetup;
|
||||
import io.bitsquare.http.HttpClient;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -66,7 +69,6 @@ public class BitcoinModule extends AppModule {
|
||||
bind(SquUtxoFeedService.class).in(Singleton.class);
|
||||
bind(PriceFeedService.class).in(Singleton.class);
|
||||
bind(FeeService.class).in(Singleton.class);
|
||||
bind(SquUTXOProvider.class).in(Singleton.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ public abstract class BsDefaultCoinSelector implements CoinSelector {
|
||||
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
|
||||
// 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"
|
||||
// TODO: Take in network parameters when instantiated, and then test against the current network. Or just have a boolean parameter for "give me everything"
|
||||
if (!target.equals(NetworkParameters.MAX_MONEY)) {
|
||||
sortOutputs(sortedOutputs);
|
||||
}
|
||||
|
@ -17,13 +17,20 @@
|
||||
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import io.bitsquare.dao.blockchain.SquUTXO;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.bitcoinj.core.TransactionConfidence;
|
||||
import org.bitcoinj.core.TransactionOutput;
|
||||
import org.bitcoinj.params.RegTestParams;
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* We use a specialized version of the CoinSelector based on the DefaultCoinSelector implementation.
|
||||
* We lookup for spendable outputs which matches our address of our address.
|
||||
@ -33,18 +40,26 @@ class SquCoinSelector extends BsDefaultCoinSelector {
|
||||
|
||||
private final boolean permitForeignPendingTx;
|
||||
|
||||
private Map<Script, Set<SquUTXO>> utxoSetByScriptMap = new HashMap<>();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public SquCoinSelector() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
public SquCoinSelector(boolean permitForeignPendingTx) {
|
||||
this.permitForeignPendingTx = permitForeignPendingTx;
|
||||
}
|
||||
|
||||
public void setUtxoSet(Set<SquUTXO> utxoSet) {
|
||||
utxoSet.stream().forEach(utxo -> {
|
||||
Script script = utxo.getScript();
|
||||
if (!utxoSetByScriptMap.containsKey(script))
|
||||
utxoSetByScriptMap.put(script, new HashSet<>());
|
||||
|
||||
utxoSetByScriptMap.get(script).add(utxo);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSelectable(Transaction tx) {
|
||||
TransactionConfidence confidence = tx.getConfidence();
|
||||
@ -62,7 +77,12 @@ class SquCoinSelector extends BsDefaultCoinSelector {
|
||||
|
||||
@Override
|
||||
protected boolean selectOutput(TransactionOutput transactionOutput) {
|
||||
return (transactionOutput.getScriptPubKey().isSentToAddress() ||
|
||||
transactionOutput.getScriptPubKey().isPayToScriptHash());
|
||||
Script scriptPubKey = transactionOutput.getScriptPubKey();
|
||||
if (scriptPubKey.isSentToAddress() || scriptPubKey.isPayToScriptHash()) {
|
||||
return utxoSetByScriptMap.containsKey(scriptPubKey);
|
||||
} else {
|
||||
log.warn("transactionOutput.getScriptPubKey() not isSentToAddress or isPayToScriptHash");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import io.bitsquare.user.Preferences;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.*;
|
||||
|
||||
public class SquUTXOProvider implements UTXOProvider {
|
||||
private static final Logger log = LoggerFactory.getLogger(SquUTXOProvider.class);
|
||||
|
||||
private Map<String, Set<UTXO>> utxoSetByAddressMap = new HashMap<>();
|
||||
private NetworkParameters parameters;
|
||||
|
||||
private int chainHeadHeight;
|
||||
|
||||
@Inject
|
||||
public SquUTXOProvider(Preferences preferences) {
|
||||
this.parameters = preferences.getBitcoinNetwork().getParameters();
|
||||
}
|
||||
|
||||
public void setUtxoSet(Set<UTXO> utxoSet) {
|
||||
utxoSet.stream().forEach(utxo -> {
|
||||
String address = utxo.getAddress();
|
||||
if (!utxoSetByAddressMap.containsKey(address))
|
||||
utxoSetByAddressMap.put(address, new HashSet<>());
|
||||
|
||||
utxoSetByAddressMap.get(address).add(utxo);
|
||||
});
|
||||
|
||||
log.info("utxoSetByAddressMap " + utxoSetByAddressMap.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UTXO> getOpenTransactionOutputs(List<Address> addresses) throws UTXOProviderException {
|
||||
List<UTXO> result = new ArrayList<>();
|
||||
addresses.stream()
|
||||
.filter(address -> utxoSetByAddressMap.containsKey(address.toString()))
|
||||
.forEach(address -> result.addAll(utxoSetByAddressMap.get(address.toString())));
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setChainHeadHeight(int chainHeadHeight) {
|
||||
this.chainHeadHeight = chainHeadHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChainHeadHeight() throws UTXOProviderException {
|
||||
return chainHeadHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkParameters getParams() {
|
||||
return parameters;
|
||||
}
|
||||
}
|
@ -52,7 +52,6 @@ public class SquWalletService extends WalletService {
|
||||
private static final Logger log = LoggerFactory.getLogger(SquWalletService.class);
|
||||
|
||||
private final BlockchainService blockchainService;
|
||||
private final SquUTXOProvider squUTXOProvider;
|
||||
private final SquCoinSelector squCoinSelector;
|
||||
|
||||
|
||||
@ -63,23 +62,18 @@ public class SquWalletService extends WalletService {
|
||||
@Inject
|
||||
public SquWalletService(WalletsSetup walletsSetup,
|
||||
BlockchainService blockchainService,
|
||||
SquUTXOProvider squUTXOProvider,
|
||||
Preferences preferences,
|
||||
FeeService feeService) {
|
||||
super(walletsSetup,
|
||||
preferences,
|
||||
feeService);
|
||||
this.blockchainService = blockchainService;
|
||||
this.squUTXOProvider = squUTXOProvider;
|
||||
this.squCoinSelector = new SquCoinSelector();
|
||||
this.squCoinSelector = new SquCoinSelector(true);
|
||||
|
||||
walletsSetup.addSetupCompletedHandler(() -> {
|
||||
wallet = walletsSetup.getSquWallet();
|
||||
wallet.setCoinSelector(squCoinSelector);
|
||||
|
||||
//TODO
|
||||
wallet.setUTXOProvider(squUTXOProvider);
|
||||
|
||||
wallet.addEventListener(new BitsquareWalletEventListener());
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
@ -167,12 +161,11 @@ public class SquWalletService extends WalletService {
|
||||
}
|
||||
|
||||
private void applyUtxoSetToUTXOProvider(Map<String, Map<Integer, SquUTXO>> utxoByTxIdMap) {
|
||||
squUTXOProvider.setChainHeadHeight(blockchainService.getChainHeadHeight());
|
||||
Set<UTXO> utxoSet = new HashSet<>();
|
||||
Set<SquUTXO> utxoSet = new HashSet<>();
|
||||
utxoByTxIdMap.entrySet().stream()
|
||||
.forEach(e -> e.getValue().entrySet().stream()
|
||||
.forEach(u -> utxoSet.add(u.getValue())));
|
||||
squUTXOProvider.setUtxoSet(utxoSet);
|
||||
squCoinSelector.setUtxoSet(utxoSet);
|
||||
}
|
||||
|
||||
|
||||
@ -253,7 +246,6 @@ public class SquWalletService extends WalletService {
|
||||
public Transaction getPreparedBurnFeeTx(Coin fee) throws WalletException, TransactionVerificationException,
|
||||
InsufficientMoneyException, ChangeBelowDustException {
|
||||
Transaction tx = new Transaction(params);
|
||||
SquCoinSelector squCoinSelector = new SquCoinSelector();
|
||||
CoinSelection coinSelection = squCoinSelector.select(fee, getTransactionOutputsFromUtxoProvider());
|
||||
coinSelection.gathered.stream().forEach(tx::addInput);
|
||||
Coin change = squCoinSelector.getChange(fee, coinSelection);
|
||||
|
@ -54,6 +54,8 @@ public class DaoModule extends AppModule {
|
||||
bindConstant().annotatedWith(named(RpcOptionKeys.RPC_USER)).to(env.getRequiredProperty(RpcOptionKeys.RPC_USER));
|
||||
bindConstant().annotatedWith(named(RpcOptionKeys.RPC_PASSWORD)).to(env.getRequiredProperty(RpcOptionKeys.RPC_PASSWORD));
|
||||
bindConstant().annotatedWith(named(RpcOptionKeys.RPC_PORT)).to(env.getRequiredProperty(RpcOptionKeys.RPC_PORT));
|
||||
bindConstant().annotatedWith(named(RpcOptionKeys.RPC_BLOCK_PORT)).to(env.getRequiredProperty(RpcOptionKeys.RPC_BLOCK_PORT));
|
||||
bindConstant().annotatedWith(named(RpcOptionKeys.RPC_WALLET_PORT)).to(env.getRequiredProperty(RpcOptionKeys.RPC_WALLET_PORT));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,8 @@ public class BlockchainRpcService extends BlockchainService {
|
||||
private final String rpcUser;
|
||||
private final String rpcPassword;
|
||||
private final String rpcPort;
|
||||
private final String rpcBlockPort;
|
||||
private final String rpcWalletPort;
|
||||
private final ListeningExecutorService setupExecutorService = Utilities.getListeningExecutorService("BlockchainRpcService.setup", 1, 1, 5);
|
||||
private final ListeningExecutorService rpcRequestsExecutor = Utilities.getListeningExecutorService("BlockchainRpcService.requests", 1, 1, 10);
|
||||
|
||||
@ -75,10 +77,14 @@ public class BlockchainRpcService extends BlockchainService {
|
||||
@Inject
|
||||
public BlockchainRpcService(@Named(RpcOptionKeys.RPC_USER) String rpcUser,
|
||||
@Named(RpcOptionKeys.RPC_PASSWORD) String rpcPassword,
|
||||
@Named(RpcOptionKeys.RPC_PORT) String rpcPort) {
|
||||
@Named(RpcOptionKeys.RPC_PORT) String rpcPort,
|
||||
@Named(RpcOptionKeys.RPC_BLOCK_PORT) String rpcBlockPort,
|
||||
@Named(RpcOptionKeys.RPC_WALLET_PORT) String rpcWalletPort) {
|
||||
this.rpcUser = rpcUser;
|
||||
this.rpcPassword = rpcPassword;
|
||||
this.rpcPort = rpcPort;
|
||||
this.rpcBlockPort = rpcBlockPort;
|
||||
this.rpcWalletPort = rpcWalletPort;
|
||||
}
|
||||
|
||||
|
||||
@ -98,9 +104,11 @@ public class BlockchainRpcService extends BlockchainService {
|
||||
try (FileInputStream fileInputStream = new FileInputStream(new File(resource.toURI()))) {
|
||||
try (InputStream inputStream = new BufferedInputStream(fileInputStream)) {
|
||||
nodeConfig.load(inputStream);
|
||||
nodeConfig.setProperty("node.bitcoind.rpc.port", rpcPort);
|
||||
nodeConfig.setProperty("node.bitcoind.rpc.user", rpcUser);
|
||||
nodeConfig.setProperty("node.bitcoind.rpc.password", rpcPassword);
|
||||
nodeConfig.setProperty("node.bitcoind.rpc.port", rpcPort);
|
||||
nodeConfig.setProperty("node.bitcoind.notification.block.port", rpcBlockPort);
|
||||
nodeConfig.setProperty("node.bitcoind.notification.wallet.port", rpcWalletPort);
|
||||
BtcdClientImpl client = new BtcdClientImpl(httpProvider, nodeConfig);
|
||||
daemon = new BtcdDaemonImpl(client);
|
||||
log.info("Setup took {} ms", System.currentTimeMillis() - startTs);
|
||||
|
@ -32,7 +32,7 @@ public class BlockchainRpcServiceMain {
|
||||
Log.setLevel(Level.WARN);
|
||||
|
||||
// regtest uses port 18332, mainnet 8332
|
||||
BlockchainRpcService blockchainRpcService = new BlockchainRpcService(args[0], args[1], args[2]);
|
||||
BlockchainRpcService blockchainRpcService = new BlockchainRpcService(args[0], args[1], args[2], args[3], args[4]);
|
||||
blockchainRpcService.onAllServicesInitialized();
|
||||
}
|
||||
}
|
||||
|
@ -4,4 +4,6 @@ public class RpcOptionKeys {
|
||||
public static final String RPC_USER = "rpcUser";
|
||||
public static final String RPC_PASSWORD = "rpcPassword";
|
||||
public static final String RPC_PORT = "rpcPort";
|
||||
public static final String RPC_BLOCK_PORT = "rpcBlockPort";
|
||||
public static final String RPC_WALLET_PORT = "rpcWalletPort";
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
node.bitcoind.rpc.protocol = http
|
||||
node.bitcoind.rpc.host = 127.0.0.1
|
||||
node.bitcoind.http.auth_scheme = Basic
|
||||
node.bitcoind.notification.alert.port = 5158
|
||||
node.bitcoind.notification.block.port = 5159
|
||||
node.bitcoind.notification.wallet.port = 5160
|
||||
#node.bitcoind.notification.alert.port = 5158
|
||||
|
||||
|
||||
# we pass the port/user/pw via prog arg
|
||||
|
||||
#node.bitcoind.notification.block.port = 5159
|
||||
#node.bitcoind.notification.wallet.port = 5160
|
||||
|
||||
# regtest
|
||||
# node.bitcoind.rpc.port = 18332
|
||||
# mainnet
|
||||
|
Loading…
Reference in New Issue
Block a user