mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-25 07:27:18 +01:00
Merge branch 'cbeams'
* cbeams: Polish FeePolicy Use BitcoinNetwork vs. BitcoinJ's NetworkParameters Use #ofType in commandline parsing for type safety Introduce customized JOptCommandLinePropertySource Expose network information to GUI cleanly Conflicts: src/main/java/io/bitsquare/msg/tomp2p/TomP2PNode.java
This commit is contained in:
commit
f4eeb81390
22 changed files with 320 additions and 296 deletions
|
@ -22,13 +22,13 @@ import io.bitsquare.btc.UserAgent;
|
|||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.gui.ViewCB;
|
||||
import io.bitsquare.persistence.Persistence;
|
||||
import io.bitsquare.util.spring.JOptCommandLinePropertySource;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import joptsimple.OptionSet;
|
||||
import org.springframework.core.env.JOptCommandLinePropertySource;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.PropertiesPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
|
@ -64,7 +64,7 @@ public class BitsquareEnvironment extends StandardEnvironment {
|
|||
private final String appDataDir;
|
||||
|
||||
public BitsquareEnvironment(OptionSet options) {
|
||||
this(new JOptCommandLinePropertySource(BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME, checkNotNull(options)));
|
||||
this(new JOptCommandLinePropertySource(BITSQUARE_CLASSPATH_PROPERTY_SOURCE_NAME, checkNotNull(options)));
|
||||
}
|
||||
|
||||
BitsquareEnvironment(PropertySource commandLineProperties) {
|
||||
|
|
|
@ -32,8 +32,8 @@ public class BootstrapNodeMain extends BitsquareExecutable {
|
|||
|
||||
protected void customizeOptionParsing(OptionParser parser) {
|
||||
parser.accepts(Node.NAME_KEY, "Name of this node").withRequiredArg().isRequired();
|
||||
parser.accepts(Node.PORT_KEY, "Port to listen on").withRequiredArg()
|
||||
.defaultsTo(String.valueOf(Node.DEFAULT_PORT));
|
||||
parser.accepts(Node.PORT_KEY, "Port to listen on").withRequiredArg().ofType(int.class)
|
||||
.defaultsTo(Node.DEFAULT_PORT);
|
||||
}
|
||||
|
||||
protected void doExecute(OptionSet options) {
|
||||
|
|
|
@ -19,15 +19,15 @@ package io.bitsquare.app.gui;
|
|||
|
||||
import io.bitsquare.app.BitsquareEnvironment;
|
||||
import io.bitsquare.app.BitsquareExecutable;
|
||||
import io.bitsquare.btc.BitcoinModule;
|
||||
import io.bitsquare.btc.BitcoinNetwork;
|
||||
import io.bitsquare.network.BootstrapNodes;
|
||||
import io.bitsquare.network.Node;
|
||||
import io.bitsquare.util.joptsimple.EnumValueConverter;
|
||||
|
||||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
|
||||
import static io.bitsquare.app.BitsquareEnvironment.*;
|
||||
import static io.bitsquare.btc.BitcoinModule.BITCOIN_NETWORK_KEY;
|
||||
import static io.bitsquare.msg.tomp2p.TomP2PMessageModule.*;
|
||||
import static io.bitsquare.network.Node.*;
|
||||
|
||||
|
@ -44,11 +44,14 @@ public class BitsquareAppMain extends BitsquareExecutable {
|
|||
parser.accepts(APP_DATA_DIR_KEY, "Application data directory").withRequiredArg()
|
||||
.defaultsTo(DEFAULT_APP_DATA_DIR);
|
||||
parser.accepts(NAME_KEY, "Name of this node").withRequiredArg();
|
||||
parser.accepts(PORT_KEY, "Port to listen on").withRequiredArg().defaultsTo(String.valueOf(Node.DEFAULT_PORT));
|
||||
parser.accepts(BITCOIN_NETWORK_KEY).withRequiredArg().defaultsTo(BitcoinModule.DEFAULT_BITCOIN_NETWORK);
|
||||
parser.accepts(PORT_KEY, "Port to listen on").withRequiredArg().ofType(int.class).defaultsTo(Node.DEFAULT_PORT);
|
||||
parser.accepts(BitcoinNetwork.KEY).withRequiredArg().ofType(BitcoinNetwork.class)
|
||||
.withValuesConvertedBy(new EnumValueConverter(BitcoinNetwork.class))
|
||||
.defaultsTo(BitcoinNetwork.DEFAULT);
|
||||
parser.accepts(BOOTSTRAP_NODE_NAME_KEY).withRequiredArg().defaultsTo(BootstrapNodes.DEFAULT.getName());
|
||||
parser.accepts(BOOTSTRAP_NODE_IP_KEY).withRequiredArg().defaultsTo(BootstrapNodes.DEFAULT.getIp());
|
||||
parser.accepts(BOOTSTRAP_NODE_PORT_KEY).withRequiredArg().defaultsTo(BootstrapNodes.DEFAULT.getPortAsString());
|
||||
parser.accepts(BOOTSTRAP_NODE_PORT_KEY).withRequiredArg().ofType(int.class)
|
||||
.defaultsTo(BootstrapNodes.DEFAULT.getPort());
|
||||
parser.accepts(NETWORK_INTERFACE_KEY, "Network interface").withRequiredArg();
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,6 @@ import static com.google.inject.name.Names.named;
|
|||
|
||||
public class BitcoinModule extends BitsquareModule {
|
||||
|
||||
public static final String BITCOIN_NETWORK_KEY = "bitcoin.network";
|
||||
public static final String DEFAULT_BITCOIN_NETWORK = BitcoinNetwork.TESTNET.toString();
|
||||
|
||||
public BitcoinModule(Environment env) {
|
||||
super(env);
|
||||
|
@ -43,7 +41,8 @@ public class BitcoinModule extends BitsquareModule {
|
|||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(NetworkParameters.class).toInstance(network());
|
||||
bind(BitcoinNetwork.class).toInstance(
|
||||
env.getProperty(BitcoinNetwork.KEY, BitcoinNetwork.class, BitcoinNetwork.DEFAULT));
|
||||
bind(FeePolicy.class).asEagerSingleton();
|
||||
|
||||
bindConstant().annotatedWith(named(UserAgent.NAME_KEY)).to(env.getRequiredProperty(UserAgent.NAME_KEY));
|
||||
|
@ -63,21 +62,5 @@ public class BitcoinModule extends BitsquareModule {
|
|||
protected void doClose(Injector injector) {
|
||||
injector.getInstance(WalletService.class).shutDown();
|
||||
}
|
||||
|
||||
private NetworkParameters network() {
|
||||
BitcoinNetwork network = BitcoinNetwork.valueOf(
|
||||
env.getProperty(BITCOIN_NETWORK_KEY, DEFAULT_BITCOIN_NETWORK).toUpperCase());
|
||||
|
||||
switch (network) {
|
||||
case MAINNET:
|
||||
return MainNetParams.get();
|
||||
case TESTNET:
|
||||
return TestNet3Params.get();
|
||||
case REGTEST:
|
||||
return RegTestParams.get();
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown bitcoin network: " + network);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,27 @@
|
|||
|
||||
package io.bitsquare.btc;
|
||||
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
import org.bitcoinj.params.MainNetParams;
|
||||
import org.bitcoinj.params.RegTestParams;
|
||||
import org.bitcoinj.params.TestNet3Params;
|
||||
|
||||
public enum BitcoinNetwork {
|
||||
MAINNET, TESTNET, REGTEST;
|
||||
|
||||
MAINNET(MainNetParams.get()),
|
||||
TESTNET(TestNet3Params.get()),
|
||||
REGTEST(RegTestParams.get());
|
||||
|
||||
public static final String KEY = "bitcoin.network";
|
||||
public static final BitcoinNetwork DEFAULT = TESTNET;
|
||||
|
||||
private final NetworkParameters parameters;
|
||||
|
||||
BitcoinNetwork(NetworkParameters parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
public NetworkParameters getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,14 +17,12 @@
|
|||
|
||||
package io.bitsquare.btc;
|
||||
|
||||
import io.bitsquare.BitsquareException;
|
||||
|
||||
import org.bitcoinj.core.Address;
|
||||
import org.bitcoinj.core.AddressFormatException;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.bitcoinj.params.MainNetParams;
|
||||
import org.bitcoinj.params.RegTestParams;
|
||||
import org.bitcoinj.params.TestNet3Params;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
@ -32,77 +30,60 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class FeePolicy {
|
||||
|
||||
public static final Coin TX_FEE = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||
|
||||
// The min. REGISTRATION_FEE calculated with Transaction.MIN_NONDUST_OUTPUT would be 0.00015460 which might lead
|
||||
// to problems for the spending wallet.
|
||||
// The min. REGISTRATION_FEE calculated with Transaction.MIN_NONDUST_OUTPUT would be
|
||||
// 0.00015460 which might lead to problems for the spending wallet.
|
||||
// Some web wallets don't allow more then 4 decimal places (need more investigation)
|
||||
// So we use 0.0002 as that fits also to our 4 decimal places restriction for BTC values.
|
||||
// The remaining 0.0000454 BTC is given to miners at the moment as it is lower then dust.
|
||||
public static final Coin REGISTRATION_FEE = TX_FEE.add(TX_FEE);
|
||||
|
||||
public static final Coin CREATE_OFFER_FEE = REGISTRATION_FEE; // 0.0002
|
||||
public static final Coin TAKE_OFFER_FEE = CREATE_OFFER_FEE;
|
||||
private static final Logger log = LoggerFactory.getLogger(FeePolicy.class);
|
||||
|
||||
// those are just dummy yet. trading fees will go probably to arbiters
|
||||
// Not used at the moment
|
||||
// private static final String registrationFeeAddress = "mvkDXt4QmN4Nq9dRUsRigBCaovde9nLkZR";
|
||||
|
||||
//
|
||||
private static String createOfferFeeAddress;
|
||||
private static String takeOfferFeeAddress;
|
||||
|
||||
private final NetworkParameters params;
|
||||
private final BitcoinNetwork bitcoinNetwork;
|
||||
private final String createOfferFeeAddress;
|
||||
private final String takeOfferFeeAddress;
|
||||
|
||||
@Inject
|
||||
public FeePolicy(NetworkParameters params) {
|
||||
this.params = params;
|
||||
public FeePolicy(BitcoinNetwork bitcoinNetwork) {
|
||||
this.bitcoinNetwork = bitcoinNetwork;
|
||||
|
||||
if (params.equals(TestNet3Params.get())) {
|
||||
switch (bitcoinNetwork) {
|
||||
case TESTNET:
|
||||
createOfferFeeAddress = "mmm8BdTcHoc5wi75RmiQYsJ2Tr1NoZmM84";
|
||||
takeOfferFeeAddress = "mmm8BdTcHoc5wi75RmiQYsJ2Tr1NoZmM84";
|
||||
}
|
||||
else if (params.equals(MainNetParams.get())) {
|
||||
break;
|
||||
case MAINNET:
|
||||
// bitsquare donation address used for the moment...
|
||||
createOfferFeeAddress = "1BVxNn3T12veSK6DgqwU4Hdn7QHcDDRag7";
|
||||
takeOfferFeeAddress = "1BVxNn3T12veSK6DgqwU4Hdn7QHcDDRag7";
|
||||
}
|
||||
else if (params.equals(RegTestParams.get())) {
|
||||
break;
|
||||
case REGTEST:
|
||||
createOfferFeeAddress = "n2upbsaKAe4PD3cc4JfS7UCqPC5oNd7Ckg";
|
||||
takeOfferFeeAddress = "n2upbsaKAe4PD3cc4JfS7UCqPC5oNd7Ckg";
|
||||
break;
|
||||
default:
|
||||
throw new BitsquareException("Unknown bitcoin network: %s", bitcoinNetwork);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO who is receiver? other users or dev address? use donation option list?
|
||||
// Not used at the moment
|
||||
// (dev, other users, wikileaks, tor, sub projects (bitcoinj, tomp2p,...)...)
|
||||
/* public Address getAddressForRegistrationFee() {
|
||||
try {
|
||||
return new Address(params, registrationFeeAddress);
|
||||
} catch (AddressFormatException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}*/
|
||||
|
||||
//TODO get address form arbitrator list
|
||||
public Address getAddressForCreateOfferFee() {
|
||||
try {
|
||||
return new Address(params, createOfferFeeAddress);
|
||||
} catch (AddressFormatException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
return new Address(bitcoinNetwork.getParameters(), createOfferFeeAddress);
|
||||
} catch (AddressFormatException ex) {
|
||||
throw new BitsquareException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO get address form the intersection of both traders arbitrator lists
|
||||
public Address getAddressForTakeOfferFee() {
|
||||
try {
|
||||
return new Address(params, takeOfferFeeAddress);
|
||||
} catch (AddressFormatException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
return new Address(bitcoinNetwork.getParameters(), takeOfferFeeAddress);
|
||||
} catch (AddressFormatException ex) {
|
||||
throw new BitsquareException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,10 +123,10 @@ public class WalletService {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public WalletService(NetworkParameters params, FeePolicy feePolicy, SignatureService signatureService,
|
||||
public WalletService(BitcoinNetwork bitcoinNetwork, FeePolicy feePolicy, SignatureService signatureService,
|
||||
Persistence persistence, UserAgent userAgent,
|
||||
@Named(DIR_KEY) File walletDir, @Named(PREFIX_KEY) String walletPrefix) {
|
||||
this.params = params;
|
||||
this.params = bitcoinNetwork.getParameters();
|
||||
this.feePolicy = feePolicy;
|
||||
this.signatureService = signatureService;
|
||||
this.persistence = persistence;
|
||||
|
|
|
@ -141,6 +141,7 @@ public class PreferencesViewCB extends CachedViewCB {
|
|||
tab.setContent(view);
|
||||
((TabPane) root).getSelectionModel().select(tab);
|
||||
Initializable childController = loader.getController();
|
||||
if (childController instanceof ViewCB)
|
||||
((ViewCB) childController).setParent(this);
|
||||
|
||||
return childController;
|
||||
|
|
|
@ -1,136 +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.gui.main.preferences.network;
|
||||
|
||||
import io.bitsquare.BitsquareException;
|
||||
import io.bitsquare.gui.PresentationModel;
|
||||
import io.bitsquare.msg.tomp2p.BootstrappedPeerFactory;
|
||||
import io.bitsquare.msg.tomp2p.TomP2PNode;
|
||||
import io.bitsquare.network.BootstrapState;
|
||||
import io.bitsquare.network.Node;
|
||||
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
|
||||
import net.tomp2p.peers.PeerSocketAddress;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class NetworkPreferencesPM extends PresentationModel {
|
||||
private static final Logger log = LoggerFactory.getLogger(NetworkPreferencesPM.class);
|
||||
|
||||
final String bitcoinNetworkType;
|
||||
final String p2pNetworkConnection;
|
||||
final String p2pNetworkAddress;
|
||||
final String bootstrapAddress;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
NetworkPreferencesPM(NetworkParameters networkParameters,
|
||||
BootstrappedPeerFactory bootstrappedPeerFactory,
|
||||
TomP2PNode tomP2PNode,
|
||||
@Named(BootstrappedPeerFactory.BOOTSTRAP_NODE_KEY) Node bootstrapNode) {
|
||||
|
||||
switch (networkParameters.getId()) {
|
||||
case NetworkParameters.ID_REGTEST:
|
||||
bitcoinNetworkType = "Regtest";
|
||||
break;
|
||||
case NetworkParameters.ID_TESTNET:
|
||||
bitcoinNetworkType = "Testnet";
|
||||
break;
|
||||
case NetworkParameters.ID_MAINNET:
|
||||
bitcoinNetworkType = "Mainnet";
|
||||
break;
|
||||
default:
|
||||
bitcoinNetworkType = "Undefined";
|
||||
throw new BitsquareException("Invalid networkParameters " + networkParameters.getId());
|
||||
}
|
||||
|
||||
PeerSocketAddress socketAddress = tomP2PNode.getPeerDHT().peerAddress().peerSocketAddress();
|
||||
p2pNetworkAddress = "IP: " + socketAddress.inetAddress().getHostAddress()
|
||||
+ ", TCP port: " + socketAddress.tcpPort()
|
||||
+ ", UDP port: " + socketAddress.udpPort();
|
||||
|
||||
bootstrapAddress = "ID: " + bootstrapNode.getName()
|
||||
+ ", IP: " + bootstrapNode.getIp()
|
||||
+ ", Port: " + bootstrapNode.getPortAsString();
|
||||
|
||||
BootstrapState state = bootstrappedPeerFactory.bootstrapState.get();
|
||||
if (state == BootstrapState.DIRECT_SUCCESS)
|
||||
p2pNetworkConnection = "Direct connection";
|
||||
else if (state == BootstrapState.NAT_SUCCESS)
|
||||
p2pNetworkConnection = "Connected with automatic port forwarding";
|
||||
else if (state == BootstrapState.RELAY_SUCCESS)
|
||||
p2pNetworkConnection = "Relayed by other peers";
|
||||
else
|
||||
throw new BitsquareException("Invalid BootstrapState " + state);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
}
|
|
@ -38,7 +38,7 @@
|
|||
<Insets top="10"/>
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<TextField fx:id="bitcoinNetworkType" GridPane.rowIndex="0" GridPane.columnIndex="1"
|
||||
<TextField fx:id="bitcoinNetwork" GridPane.rowIndex="0" GridPane.columnIndex="1"
|
||||
mouseTransparent="true" editable="false" focusTraversable="false">
|
||||
<GridPane.margin>
|
||||
<Insets top="10"/>
|
||||
|
@ -46,11 +46,11 @@
|
|||
</TextField>
|
||||
|
||||
<Label text="P2P network connection:" GridPane.rowIndex="1"/>
|
||||
<TextField fx:id="p2pNetworkConnection" GridPane.rowIndex="1" GridPane.columnIndex="1"
|
||||
<TextField fx:id="connectionType" GridPane.rowIndex="1" GridPane.columnIndex="1"
|
||||
mouseTransparent="true" editable="false" focusTraversable="false"/>
|
||||
|
||||
<Label text="My external visible P2P network address:" GridPane.rowIndex="2"/>
|
||||
<TextField fx:id="p2pNetworkAddress" GridPane.rowIndex="2" GridPane.columnIndex="1"
|
||||
<TextField fx:id="nodeAddress" GridPane.rowIndex="2" GridPane.columnIndex="1"
|
||||
mouseTransparent="true" editable="false" focusTraversable="false"/>
|
||||
|
||||
<Label text="P2P bootstrap node address:" GridPane.rowIndex="3">
|
||||
|
@ -58,7 +58,7 @@
|
|||
<Insets bottom="-15"/>
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<TextField fx:id="bootstrapAddress" GridPane.rowIndex="3" GridPane.columnIndex="1"
|
||||
<TextField fx:id="bootstrapNodeAddress" GridPane.rowIndex="3" GridPane.columnIndex="1"
|
||||
mouseTransparent="true" editable="false" focusTraversable="false">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="-15"/>
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
|
||||
package io.bitsquare.gui.main.preferences.network;
|
||||
|
||||
import io.bitsquare.gui.CachedViewCB;
|
||||
import io.bitsquare.btc.BitcoinNetwork;
|
||||
import io.bitsquare.network.ClientNode;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
|
@ -26,62 +27,28 @@ import java.util.ResourceBundle;
|
|||
import javax.inject.Inject;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.*;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
public class NetworkPreferencesViewCB implements Initializable {
|
||||
|
||||
/**
|
||||
* This UI is not cached as it is normally only needed once.
|
||||
*/
|
||||
public class NetworkPreferencesViewCB extends CachedViewCB<NetworkPreferencesPM> {
|
||||
private final String bitcoinNetworkValue;
|
||||
private final ClientNode clientNode;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(NetworkPreferencesViewCB.class);
|
||||
|
||||
@FXML TextField bitcoinNetworkType, p2pNetworkConnection, p2pNetworkAddress, bootstrapAddress;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@FXML TextField bitcoinNetwork, connectionType, nodeAddress, bootstrapNodeAddress;
|
||||
|
||||
@Inject
|
||||
private NetworkPreferencesViewCB(NetworkPreferencesPM presentationModel) {
|
||||
super(presentationModel);
|
||||
public NetworkPreferencesViewCB(BitcoinNetwork bitcoinNetwork, ClientNode clientNode) {
|
||||
this.bitcoinNetworkValue = bitcoinNetwork.toString();
|
||||
this.clientNode = clientNode;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
super.initialize(url, rb);
|
||||
bitcoinNetwork.setText(bitcoinNetworkValue);
|
||||
nodeAddress.setText(clientNode.getAddress().toString());
|
||||
bootstrapNodeAddress.setText(clientNode.getBootstrapNodeAddress().toString());
|
||||
connectionType.setText(clientNode.getConnectionType().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
|
||||
bitcoinNetworkType.setText(presentationModel.bitcoinNetworkType);
|
||||
p2pNetworkConnection.setText(presentationModel.p2pNetworkConnection);
|
||||
p2pNetworkAddress.setText(presentationModel.p2pNetworkAddress);
|
||||
bootstrapAddress.setText(presentationModel.bootstrapAddress);
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
@Override
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
|
||||
package io.bitsquare.gui.util.validation;
|
||||
|
||||
import io.bitsquare.btc.BitcoinNetwork;
|
||||
|
||||
import org.bitcoinj.core.Address;
|
||||
import org.bitcoinj.core.AddressFormatException;
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
@ -33,7 +34,8 @@ import org.slf4j.LoggerFactory;
|
|||
*/
|
||||
public final class BtcAddressValidator extends InputValidator {
|
||||
private static final Logger log = LoggerFactory.getLogger(BtcAddressValidator.class);
|
||||
private final NetworkParameters networkParameters;
|
||||
|
||||
private final BitcoinNetwork bitcoinNetwork;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -41,8 +43,8 @@ public final class BtcAddressValidator extends InputValidator {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public BtcAddressValidator(NetworkParameters networkParameters) {
|
||||
this.networkParameters = networkParameters;
|
||||
public BtcAddressValidator(BitcoinNetwork bitcoinNetwork) {
|
||||
this.bitcoinNetwork = bitcoinNetwork;
|
||||
}
|
||||
|
||||
|
||||
|
@ -67,7 +69,7 @@ public final class BtcAddressValidator extends InputValidator {
|
|||
|
||||
private ValidationResult validateBtcAddress(String input) {
|
||||
try {
|
||||
new Address(networkParameters, input);
|
||||
new Address(bitcoinNetwork.getParameters(), input);
|
||||
return new ValidationResult(true);
|
||||
} catch (AddressFormatException e) {
|
||||
return new ValidationResult(false, "Bitcoin address is a valid format");
|
||||
|
|
|
@ -70,10 +70,10 @@ import org.slf4j.LoggerFactory;
|
|||
/**
|
||||
* Creates a DHT peer and bootstraps to the network via a bootstrap node
|
||||
*/
|
||||
public class BootstrappedPeerFactory {
|
||||
class BootstrappedPeerFactory {
|
||||
private static final Logger log = LoggerFactory.getLogger(BootstrappedPeerFactory.class);
|
||||
|
||||
public static final String BOOTSTRAP_NODE_KEY = "bootstrapNode";
|
||||
static final String BOOTSTRAP_NODE_KEY = "bootstrapNode";
|
||||
static final String NETWORK_INTERFACE_KEY = "interface";
|
||||
static final String NETWORK_INTERFACE_UNSPECIFIED = "<unspecified>";
|
||||
|
||||
|
@ -84,7 +84,8 @@ public class BootstrappedPeerFactory {
|
|||
private final Persistence persistence;
|
||||
|
||||
private final SettableFuture<PeerDHT> settableFuture = SettableFuture.create();
|
||||
public final ObjectProperty<BootstrapState> bootstrapState = new SimpleObjectProperty<>();
|
||||
|
||||
private final ObjectProperty<BootstrapState> bootstrapState = new SimpleObjectProperty<>();
|
||||
private Peer peer;
|
||||
private PeerDHT peerDHT;
|
||||
|
||||
|
@ -342,6 +343,14 @@ public class BootstrappedPeerFactory {
|
|||
}
|
||||
}
|
||||
|
||||
public Node getBootstrapNode() {
|
||||
return bootstrapNode;
|
||||
}
|
||||
|
||||
public ObjectProperty<BootstrapState> getBootstrapState() {
|
||||
return bootstrapState;
|
||||
}
|
||||
|
||||
private void setState(BootstrapState bootstrapState, String message) {
|
||||
setState(bootstrapState, message, true);
|
||||
}
|
||||
|
|
|
@ -20,10 +20,13 @@ package io.bitsquare.msg.tomp2p;
|
|||
import io.bitsquare.msg.MessageModule;
|
||||
import io.bitsquare.msg.MessageService;
|
||||
import io.bitsquare.network.BootstrapNodes;
|
||||
import io.bitsquare.network.ClientNode;
|
||||
import io.bitsquare.network.Node;
|
||||
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import static io.bitsquare.msg.tomp2p.BootstrappedPeerFactory.*;
|
||||
|
@ -43,13 +46,14 @@ public class TomP2PMessageModule extends MessageModule {
|
|||
protected void doConfigure() {
|
||||
bind(int.class).annotatedWith(Names.named(Node.PORT_KEY)).toInstance(
|
||||
env.getProperty(Node.PORT_KEY, Integer.class, Node.DEFAULT_PORT));
|
||||
bind(TomP2PNode.class).asEagerSingleton();
|
||||
bind(TomP2PNode.class).in(Singleton.class);
|
||||
bind(ClientNode.class).to(TomP2PNode.class);
|
||||
|
||||
bind(Node.class).annotatedWith(Names.named(BOOTSTRAP_NODE_KEY)).toInstance(
|
||||
Node.at(
|
||||
env.getProperty(BOOTSTRAP_NODE_NAME_KEY, BootstrapNodes.DEFAULT.getName()),
|
||||
env.getProperty(BOOTSTRAP_NODE_IP_KEY, BootstrapNodes.DEFAULT.getIp()),
|
||||
env.getProperty(BOOTSTRAP_NODE_PORT_KEY, BootstrapNodes.DEFAULT.getPortAsString())
|
||||
env.getProperty(BOOTSTRAP_NODE_PORT_KEY, int.class, BootstrapNodes.DEFAULT.getPort())
|
||||
)
|
||||
);
|
||||
bindConstant().annotatedWith(Names.named(NETWORK_INTERFACE_KEY)).to(
|
||||
|
|
|
@ -20,6 +20,10 @@ package io.bitsquare.msg.tomp2p;
|
|||
import io.bitsquare.BitsquareException;
|
||||
import io.bitsquare.msg.MessageBroker;
|
||||
import io.bitsquare.msg.listeners.BootstrapListener;
|
||||
import io.bitsquare.network.BootstrapState;
|
||||
import io.bitsquare.network.ClientNode;
|
||||
import io.bitsquare.network.ConnectionType;
|
||||
import io.bitsquare.network.Node;
|
||||
import io.bitsquare.network.tomp2p.TomP2PPeer;
|
||||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
|
@ -51,6 +55,7 @@ import net.tomp2p.futures.FutureDirect;
|
|||
import net.tomp2p.futures.FuturePeerConnection;
|
||||
import net.tomp2p.peers.Number160;
|
||||
import net.tomp2p.peers.PeerAddress;
|
||||
import net.tomp2p.peers.PeerSocketAddress;
|
||||
import net.tomp2p.storage.Data;
|
||||
import net.tomp2p.utils.Utils;
|
||||
|
||||
|
@ -67,7 +72,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
* This class is offering generic functionality of TomP2P needed for Bitsquare, like data and domain protection.
|
||||
* It does not handle any domain aspects of Bitsquare.
|
||||
*/
|
||||
public class TomP2PNode {
|
||||
public class TomP2PNode implements ClientNode {
|
||||
private static final Logger log = LoggerFactory.getLogger(TomP2PNode.class);
|
||||
|
||||
private KeyPair keyPair;
|
||||
|
@ -115,7 +120,7 @@ public class TomP2PNode {
|
|||
checkNotNull(keyPair, "keyPair must not be null.");
|
||||
checkNotNull(messageBroker, "messageBroker must not be null.");
|
||||
|
||||
bootstrappedPeerFactory.bootstrapState.addListener((ov, oldValue, newValue) ->
|
||||
bootstrappedPeerFactory.getBootstrapState().addListener((ov, oldValue, newValue) ->
|
||||
bootstrapListener.onBootstrapStateChanged(newValue));
|
||||
|
||||
SettableFuture<PeerDHT> bootstrapFuture = bootstrappedPeerFactory.start();
|
||||
|
@ -155,11 +160,6 @@ public class TomP2PNode {
|
|||
peerDHT.shutdown();
|
||||
}
|
||||
|
||||
public PeerDHT getPeerDHT() {
|
||||
return peerDHT;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Generic DHT methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -373,4 +373,33 @@ public class TomP2PNode {
|
|||
log.debug("storePeerAddress " + peerDHT.peerAddress().toString());
|
||||
return putDomainProtectedData(locationKey, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionType getConnectionType() {
|
||||
BootstrapState bootstrapState = bootstrappedPeerFactory.getBootstrapState().get();
|
||||
switch (bootstrapState) {
|
||||
case DIRECT_SUCCESS:
|
||||
return ConnectionType.DIRECT;
|
||||
case NAT_SUCCESS:
|
||||
return ConnectionType.NAT;
|
||||
case RELAY_SUCCESS:
|
||||
return ConnectionType.RELAY;
|
||||
default:
|
||||
throw new BitsquareException("Invalid bootstrap state: %s", bootstrapState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getAddress() {
|
||||
PeerSocketAddress socketAddress = peerDHT.peerAddress().peerSocketAddress();
|
||||
return Node.at(
|
||||
peerDHT.peerID().toString(),
|
||||
socketAddress.inetAddress().getHostAddress(),
|
||||
socketAddress.tcpPort());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getBootstrapNodeAddress() {
|
||||
return bootstrappedPeerFactory.getBootstrapNode();
|
||||
}
|
||||
}
|
||||
|
|
26
src/main/java/io/bitsquare/network/ClientNode.java
Normal file
26
src/main/java/io/bitsquare/network/ClientNode.java
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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.network;
|
||||
|
||||
public interface ClientNode {
|
||||
ConnectionType getConnectionType();
|
||||
|
||||
Node getAddress();
|
||||
|
||||
Node getBootstrapNodeAddress();
|
||||
}
|
22
src/main/java/io/bitsquare/network/ConnectionType.java
Normal file
22
src/main/java/io/bitsquare/network/ConnectionType.java
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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.network;
|
||||
|
||||
public enum ConnectionType {
|
||||
UNKNOWN, DIRECT, NAT, RELAY
|
||||
}
|
|
@ -64,10 +64,6 @@ public final class Node {
|
|||
return port;
|
||||
}
|
||||
|
||||
public String getPortAsString() {
|
||||
return String.valueOf(port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a copy of this node with the port updated to the given value.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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.util.joptsimple;
|
||||
|
||||
import com.google.common.base.Enums;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import joptsimple.ValueConverter;
|
||||
|
||||
import static org.springframework.util.StringUtils.collectionToDelimitedString;
|
||||
|
||||
/**
|
||||
* A {@link joptsimple.ValueConverter} that supports case-insensitive conversion from
|
||||
* String to an enum label. Useful in conjunction with {@link joptsimple.ArgumentAcceptingOptionSpec#ofType(Class)}
|
||||
* when the type in question is an enum.
|
||||
*/
|
||||
public class EnumValueConverter implements ValueConverter<Enum> {
|
||||
|
||||
private final Class<? extends Enum> enumType;
|
||||
|
||||
public EnumValueConverter(Class<? extends Enum> enumType) {
|
||||
this.enumType = enumType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to resolve an enum of the specified type by looking for a label with the
|
||||
* given value, trying all case variations in the process.
|
||||
* @return the matching enum label (if any)
|
||||
* @throws IllegalArgumentException if no such label matching the given value is found.
|
||||
*/
|
||||
@Override
|
||||
public Enum convert(String value) {
|
||||
Set<String> candidates = Sets.newHashSet(value, value.toUpperCase(), value.toLowerCase());
|
||||
for (String candidate : candidates) {
|
||||
Optional<? extends Enum> result = Enums.getIfPresent(enumType, candidate);
|
||||
if (result.isPresent())
|
||||
return result.get();
|
||||
}
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"No enum constant %s.[%s]", enumType.getName(), collectionToDelimitedString(candidates, "|")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Enum> valueType() {
|
||||
return enumType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String valuePattern() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.util.spring;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import joptsimple.OptionSet;
|
||||
|
||||
/**
|
||||
* Customizes {@link io.bitsquare.util.spring.JOptCommandLinePropertySource#getOptionValues(String)}
|
||||
* to allow for proper use of {@link joptsimple.ArgumentAcceptingOptionSpec#ofType(Class)}.
|
||||
* To be removed once https://github.com/spring-projects/spring-framework/pull/693 has
|
||||
* been merged and made available in a release.
|
||||
*/
|
||||
public class JOptCommandLinePropertySource extends org.springframework.core.env.JOptCommandLinePropertySource {
|
||||
|
||||
public JOptCommandLinePropertySource(String name, OptionSet options) {
|
||||
super(name, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getOptionValues(String name) {
|
||||
List<?> argValues = this.source.valuesOf(name);
|
||||
List<String> stringArgValues = new ArrayList<>();
|
||||
for (Object argValue : argValues) {
|
||||
stringArgValues.add(argValue instanceof String ? (String) argValue : argValue.toString());
|
||||
}
|
||||
if (stringArgValues.isEmpty()) {
|
||||
return (this.source.has(name) ? Collections.<String>emptyList() : null);
|
||||
}
|
||||
return Collections.unmodifiableList(stringArgValues);
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
package io.bitsquare.msg;
|
||||
|
||||
import io.bitsquare.network.BootstrapNodes;
|
||||
import io.bitsquare.network.ConnectionType;
|
||||
import io.bitsquare.network.Node;
|
||||
import io.bitsquare.util.Repeat;
|
||||
import io.bitsquare.util.RepeatRule;
|
||||
|
@ -80,10 +81,6 @@ import static org.junit.Assert.*;
|
|||
public class TomP2PTests {
|
||||
private static final Logger log = LoggerFactory.getLogger(TomP2PTests.class);
|
||||
|
||||
private enum ConnectionType {
|
||||
UNKNOWN, DIRECT, NAT, RELAY
|
||||
}
|
||||
|
||||
// If you want to test in one specific connection mode define it directly, otherwise use UNKNOWN
|
||||
private static final ConnectionType FORCED_CONNECTION_TYPE = ConnectionType.DIRECT;
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@ public class NodeTests {
|
|||
assertThat(node1a.hashCode(), not(equalTo(node2.hashCode())));
|
||||
|
||||
assertThat(node1a.getPort(), equalTo(Node.DEFAULT_PORT));
|
||||
assertThat(node1a.getPortAsString(), equalTo(String.valueOf(Node.DEFAULT_PORT)));
|
||||
|
||||
Node node3a = Node.at("bitsquare3.example.com", "203.0.113.3", 1234);
|
||||
Node node3b = Node.at("bitsquare3.example.com", "203.0.113.3", "1234");
|
||||
|
|
Loading…
Add table
Reference in a new issue