mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-08-24 06:19:23 -04:00
Remove security features at P2PNode for to exclude problems in that area. Use new bootstrap and Seednode code recommended form Thomas Bocek
This commit is contained in:
parent
95b2c8a4c0
commit
c102b2a978
6 changed files with 176 additions and 53 deletions
|
@ -33,8 +33,6 @@ import net.tomp2p.peers.Number160;
|
||||||
import net.tomp2p.peers.PeerAddress;
|
import net.tomp2p.peers.PeerAddress;
|
||||||
import net.tomp2p.peers.PeerMapChangeListener;
|
import net.tomp2p.peers.PeerMapChangeListener;
|
||||||
import net.tomp2p.peers.PeerStatatistic;
|
import net.tomp2p.peers.PeerStatatistic;
|
||||||
import net.tomp2p.relay.RconRPC;
|
|
||||||
import net.tomp2p.relay.RelayRPC;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -116,14 +114,8 @@ public class SeedNode extends Thread {
|
||||||
peer = new PeerBuilder(
|
peer = new PeerBuilder(
|
||||||
Number160.createHash(seedNodeAddress.getId())).ports(seedNodeAddress.getPort()).start();
|
Number160.createHash(seedNodeAddress.getId())).ports(seedNodeAddress.getPort()).start();
|
||||||
|
|
||||||
// Need to add all features the clients will use (otherwise msg type is UNKNOWN_ID)
|
|
||||||
new PeerBuilderDHT(peer).start();
|
new PeerBuilderDHT(peer).start();
|
||||||
//PeerNAT nodeBehindNat = new PeerBuilderNAT(peer).start();
|
new PeerBuilderNAT(peer).start();
|
||||||
new PeerBuilderNAT(peer);
|
|
||||||
RconRPC rconRPC = new RconRPC(peer);
|
|
||||||
new RelayRPC(peer, rconRPC);
|
|
||||||
//new PeerBuilderTracker(peer);
|
|
||||||
//nodeBehindNat.startSetupRelay(new FutureRelay());
|
|
||||||
|
|
||||||
log.debug("Peer started. " + peer.peerAddress());
|
log.debug("Peer started. " + peer.peerAddress());
|
||||||
|
|
||||||
|
|
|
@ -124,21 +124,31 @@ public class BSFormatter {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public String formatCoin(Coin coin) {
|
public String formatCoin(Coin coin) {
|
||||||
try {
|
if (coin != null) {
|
||||||
return coinFormat.noCode().format(coin).toString();
|
try {
|
||||||
} catch (Throwable t) {
|
return coinFormat.noCode().format(coin).toString();
|
||||||
log.warn("Exception at formatBtc: " + t.toString());
|
} catch (Throwable t) {
|
||||||
|
log.warn("Exception at formatBtc: " + t.toString());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String formatCoinWithCode(Coin coin) {
|
public String formatCoinWithCode(Coin coin) {
|
||||||
try {
|
if (coin != null) {
|
||||||
// we don't use the code feature from coinFormat as it does automatic switching between mBTC and BTC and
|
try {
|
||||||
// pre and post fixing
|
// we don't use the code feature from coinFormat as it does automatic switching between mBTC and BTC and
|
||||||
return coinFormat.postfixCode().format(coin).toString();
|
// pre and post fixing
|
||||||
} catch (Throwable t) {
|
return coinFormat.postfixCode().format(coin).toString();
|
||||||
log.warn("Exception at formatBtcWithCode: " + t.toString());
|
} catch (Throwable t) {
|
||||||
|
log.warn("Exception at formatBtcWithCode: " + t.toString());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,19 +201,29 @@ public class BSFormatter {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public String formatFiat(Fiat fiat) {
|
public String formatFiat(Fiat fiat) {
|
||||||
try {
|
if (fiat != null) {
|
||||||
return fiatFormat.noCode().format(fiat).toString();
|
try {
|
||||||
} catch (Throwable t) {
|
return fiatFormat.noCode().format(fiat).toString();
|
||||||
log.warn("Exception at formatFiat: " + t.toString());
|
} catch (Throwable t) {
|
||||||
|
log.warn("Exception at formatFiat: " + t.toString());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String formatFiatWithCode(Fiat fiat) {
|
public String formatFiatWithCode(Fiat fiat) {
|
||||||
try {
|
if (fiat != null) {
|
||||||
return fiatFormat.postfixCode().format(fiat).toString();
|
try {
|
||||||
} catch (Throwable t) {
|
return fiatFormat.postfixCode().format(fiat).toString();
|
||||||
log.warn("Exception at formatFiatWithCode: " + t.toString());
|
} catch (Throwable t) {
|
||||||
|
log.warn("Exception at formatFiatWithCode: " + t.toString());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class BSResources {
|
||||||
try {
|
try {
|
||||||
return BSResources.getResourceBundle().getString(key);
|
return BSResources.getResourceBundle().getString(key);
|
||||||
} catch (MissingResourceException e) {
|
} catch (MissingResourceException e) {
|
||||||
log.warn("Missing resource for key: " + key);
|
log.trace("Missing resource for key: " + key);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ import net.tomp2p.futures.BaseFutureListener;
|
||||||
import net.tomp2p.futures.FutureBootstrap;
|
import net.tomp2p.futures.FutureBootstrap;
|
||||||
import net.tomp2p.futures.FutureDiscover;
|
import net.tomp2p.futures.FutureDiscover;
|
||||||
import net.tomp2p.nat.FutureNAT;
|
import net.tomp2p.nat.FutureNAT;
|
||||||
|
import net.tomp2p.nat.FutureRelayNAT;
|
||||||
import net.tomp2p.nat.PeerBuilderNAT;
|
import net.tomp2p.nat.PeerBuilderNAT;
|
||||||
import net.tomp2p.nat.PeerNAT;
|
import net.tomp2p.nat.PeerNAT;
|
||||||
import net.tomp2p.p2p.Peer;
|
import net.tomp2p.p2p.Peer;
|
||||||
|
@ -112,6 +113,43 @@ public class BootstrappedPeerFactory {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public ListenableFuture<PeerDHT> start(int port) {
|
public ListenableFuture<PeerDHT> start(int port) {
|
||||||
|
try {
|
||||||
|
Peer peer = new PeerBuilder(keyPair).ports(port).behindFirewall().start();
|
||||||
|
PeerDHT peerDHT = new PeerBuilderDHT(peer).storageLayer(new StorageLayer(storage)).start();
|
||||||
|
PeerNAT peerNAT = new PeerBuilderNAT(peer).start();
|
||||||
|
|
||||||
|
// PeerAddress relay = new PeerAddress(new Number160(new Random(43L)), InetAddress.getByName("relay-ip"),
|
||||||
|
// 5000, 5000);
|
||||||
|
// peerNAT.addRelay(relay);
|
||||||
|
|
||||||
|
PeerAddress masterNodeAddress = new PeerAddress(Number160.createHash(seedNodeAddress.getId()),
|
||||||
|
InetAddress.getByName(seedNodeAddress.getIp()),
|
||||||
|
seedNodeAddress.getPort(),
|
||||||
|
seedNodeAddress.getPort());
|
||||||
|
FutureDiscover fd = peer.discover().peerAddress(masterNodeAddress).start();
|
||||||
|
FutureNAT fn = peerNAT.startSetupPortforwarding(fd);
|
||||||
|
FutureRelayNAT frn = peerNAT.startRelay(fd, fn);
|
||||||
|
|
||||||
|
frn.awaitUninterruptibly();
|
||||||
|
if (frn.isSuccess()) {
|
||||||
|
log.info("Bootstrap in relay mode succesful");
|
||||||
|
settableFuture.set(peerDHT);
|
||||||
|
return settableFuture;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.error("Bootstrap in relay mode failed " + frn.failedReason());
|
||||||
|
settableFuture.setException(new Exception("Bootstrap in relay mode failed " + frn.failedReason()));
|
||||||
|
return settableFuture;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Bootstrap in relay mode failed " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
settableFuture.setException(e);
|
||||||
|
return settableFuture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListenableFuture<PeerDHT> startOld(int port) {
|
||||||
try {
|
try {
|
||||||
/* ChannelServerConficuration csc = PeerBuilder.createDefaultChannelServerConfiguration();
|
/* ChannelServerConficuration csc = PeerBuilder.createDefaultChannelServerConfiguration();
|
||||||
csc.idleTCPSeconds(20).idleUDPSeconds(20).connectionTimeoutTCPMillis(20000);
|
csc.idleTCPSeconds(20).idleUDPSeconds(20).connectionTimeoutTCPMillis(20000);
|
||||||
|
@ -184,6 +222,11 @@ public class BootstrappedPeerFactory {
|
||||||
return settableFuture;
|
return settableFuture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Private
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private PeerAddress getBootstrapAddress() {
|
private PeerAddress getBootstrapAddress() {
|
||||||
try {
|
try {
|
||||||
return new PeerAddress(Number160.createHash(seedNodeAddress.getId()),
|
return new PeerAddress(Number160.createHash(seedNodeAddress.getId()),
|
||||||
|
|
|
@ -235,6 +235,9 @@ public class MessageFacade implements MessageBroker {
|
||||||
try {
|
try {
|
||||||
Object offerDataObject = offerData.object();
|
Object offerDataObject = offerData.object();
|
||||||
if (offerDataObject instanceof Offer) {
|
if (offerDataObject instanceof Offer) {
|
||||||
|
log.trace("Remove offer from DHT was successful. Removed data: [key: " +
|
||||||
|
locationKey + ", " +
|
||||||
|
"offer: " + (Offer) offerDataObject + "]");
|
||||||
orderBookListener.onOfferRemoved((Offer) offerDataObject);
|
orderBookListener.onOfferRemoved((Offer) offerDataObject);
|
||||||
}
|
}
|
||||||
} catch (ClassNotFoundException | IOException e) {
|
} catch (ClassNotFoundException | IOException e) {
|
||||||
|
@ -244,13 +247,10 @@ public class MessageFacade implements MessageBroker {
|
||||||
});
|
});
|
||||||
writeInvalidationTimestampToDHT(locationKey);
|
writeInvalidationTimestampToDHT(locationKey);
|
||||||
});
|
});
|
||||||
|
|
||||||
log.trace("Remove offer from DHT was successful. Removed data: [key: " + locationKey + ", " +
|
|
||||||
"value: " + offerData + "]");
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log.error("Remove offer from DHT was not successful. locationKey: " + locationKey + ", " +
|
log.error("Remove offer from DHT failed. Cause: future.isSuccess() = false, locationKey: " +
|
||||||
"Reason: " + future.failedReason());
|
locationKey + ", Reason: " + future.failedReason());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import net.tomp2p.connection.DSASignatureFactory;
|
import net.tomp2p.connection.DSASignatureFactory;
|
||||||
|
import net.tomp2p.connection.PeerConnection;
|
||||||
import net.tomp2p.dht.FutureGet;
|
import net.tomp2p.dht.FutureGet;
|
||||||
import net.tomp2p.dht.FuturePut;
|
import net.tomp2p.dht.FuturePut;
|
||||||
import net.tomp2p.dht.FutureRemove;
|
import net.tomp2p.dht.FutureRemove;
|
||||||
|
@ -138,53 +139,43 @@ public class P2PNode {
|
||||||
// Generic DHT methods
|
// Generic DHT methods
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// The data and the domain are protected by that key pair.
|
// TODO remove all security features for the moment. There are some problems with a "wrong signature!" msg in
|
||||||
|
// the logs
|
||||||
public FuturePut putDomainProtectedData(Number160 locationKey, Data data) {
|
public FuturePut putDomainProtectedData(Number160 locationKey, Data data) {
|
||||||
data.protectEntry(keyPair);
|
return peerDHT.put(locationKey).data(data).start();
|
||||||
final Number160 ownerKeyHash = Utils.makeSHAHash(keyPair.getPublic().getEncoded());
|
|
||||||
return peerDHT.put(locationKey).data(data).keyPair(keyPair).domainKey(ownerKeyHash).protectDomain().start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No protection, everybody can write.
|
|
||||||
public FuturePut putData(Number160 locationKey, Data data) {
|
public FuturePut putData(Number160 locationKey, Data data) {
|
||||||
return peerDHT.put(locationKey).data(data).start();
|
return peerDHT.put(locationKey).data(data).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not public readable. Only users with the public key of the peer who stored the data can read that data
|
|
||||||
public FutureGet getDomainProtectedData(Number160 locationKey, PublicKey publicKey) {
|
public FutureGet getDomainProtectedData(Number160 locationKey, PublicKey publicKey) {
|
||||||
final Number160 ownerKeyHash = Utils.makeSHAHash(publicKey.getEncoded());
|
return peerDHT.get(locationKey).start();
|
||||||
return peerDHT.get(locationKey).domainKey(ownerKeyHash).start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No protection, everybody can read.
|
|
||||||
public FutureGet getData(Number160 locationKey) {
|
public FutureGet getData(Number160 locationKey) {
|
||||||
return peerDHT.get(locationKey).start();
|
return peerDHT.get(locationKey).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// No domain protection, but entry protection
|
|
||||||
public FuturePut addProtectedData(Number160 locationKey, Data data) {
|
public FuturePut addProtectedData(Number160 locationKey, Data data) {
|
||||||
data.protectEntry(keyPair);
|
return peerDHT.add(locationKey).data(data).start();
|
||||||
log.trace("addProtectedData with contentKey " + data.hash().toString());
|
|
||||||
return peerDHT.add(locationKey).data(data).keyPair(keyPair).start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No domain protection, but entry protection
|
|
||||||
public FutureRemove removeFromDataMap(Number160 locationKey, Data data) {
|
public FutureRemove removeFromDataMap(Number160 locationKey, Data data) {
|
||||||
Number160 contentKey = data.hash();
|
Number160 contentKey = data.hash();
|
||||||
log.trace("removeFromDataMap with contentKey " + contentKey.toString());
|
log.trace("removeFromDataMap with contentKey " + contentKey.toString());
|
||||||
return peerDHT.remove(locationKey).contentKey(contentKey).keyPair(keyPair).start();
|
return peerDHT.remove(locationKey).contentKey(contentKey).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Public readable
|
|
||||||
public FutureGet getDataMap(Number160 locationKey) {
|
public FutureGet getDataMap(Number160 locationKey) {
|
||||||
return peerDHT.get(locationKey).all().start();
|
return peerDHT.get(locationKey).all().start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send signed payLoad to peer
|
|
||||||
public FutureDirect sendData(PeerAddress peerAddress, Object payLoad) {
|
public FutureDirect sendData(PeerAddress peerAddress, Object payLoad) {
|
||||||
// use 30 seconds as max idle time before connection get closed
|
log.trace("sendData");
|
||||||
FuturePeerConnection futurePeerConnection = peerDHT.peer().createPeerConnection(peerAddress, 30000);
|
FuturePeerConnection futurePeerConnection = peerDHT.peer().createPeerConnection(peerAddress,
|
||||||
FutureDirect futureDirect = peerDHT.peer().sendDirect(futurePeerConnection).object(payLoad).sign().start();
|
PeerConnection.HEART_BEAT_MILLIS);
|
||||||
|
FutureDirect futureDirect = peerDHT.peer().sendDirect(futurePeerConnection).object(payLoad).start();
|
||||||
futureDirect.addListener(new BaseFutureListener<BaseFuture>() {
|
futureDirect.addListener(new BaseFutureListener<BaseFuture>() {
|
||||||
@Override
|
@Override
|
||||||
public void operationComplete(BaseFuture future) throws Exception {
|
public void operationComplete(BaseFuture future) throws Exception {
|
||||||
|
@ -205,6 +196,82 @@ public class P2PNode {
|
||||||
return futureDirect;
|
return futureDirect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// public FuturePut putDomainProtectedData(Number160 locationKey, Data data) {
|
||||||
|
// log.trace("putDomainProtectedData");
|
||||||
|
// data.protectEntry(keyPair);
|
||||||
|
// final Number160 ownerKeyHash = Utils.makeSHAHash(keyPair.getPublic().getEncoded());
|
||||||
|
// return peerDHT.put(locationKey).data(data).keyPair(keyPair).domainKey(ownerKeyHash).protectDomain().start();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // No protection, everybody can write.
|
||||||
|
// public FuturePut putData(Number160 locationKey, Data data) {
|
||||||
|
// log.trace("putData");
|
||||||
|
// return peerDHT.put(locationKey).data(data).start();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Not public readable. Only users with the public key of the peer who stored the data can read that data
|
||||||
|
// public FutureGet getDomainProtectedData(Number160 locationKey, PublicKey publicKey) {
|
||||||
|
// log.trace("getDomainProtectedData");
|
||||||
|
// final Number160 ownerKeyHash = Utils.makeSHAHash(publicKey.getEncoded());
|
||||||
|
// return peerDHT.get(locationKey).domainKey(ownerKeyHash).start();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // No protection, everybody can read.
|
||||||
|
// public FutureGet getData(Number160 locationKey) {
|
||||||
|
// log.trace("getData");
|
||||||
|
// return peerDHT.get(locationKey).start();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // No domain protection, but entry protection
|
||||||
|
// public FuturePut addProtectedData(Number160 locationKey, Data data) {
|
||||||
|
// log.trace("addProtectedData");
|
||||||
|
// data.protectEntry(keyPair);
|
||||||
|
// log.trace("addProtectedData with contentKey " + data.hash().toString());
|
||||||
|
// return peerDHT.add(locationKey).data(data).keyPair(keyPair).start();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // No domain protection, but entry protection
|
||||||
|
// public FutureRemove removeFromDataMap(Number160 locationKey, Data data) {
|
||||||
|
// log.trace("removeFromDataMap");
|
||||||
|
// Number160 contentKey = data.hash();
|
||||||
|
// log.trace("removeFromDataMap with contentKey " + contentKey.toString());
|
||||||
|
// return peerDHT.remove(locationKey).contentKey(contentKey).keyPair(keyPair).start();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Public readable
|
||||||
|
// public FutureGet getDataMap(Number160 locationKey) {
|
||||||
|
// log.trace("getDataMap");
|
||||||
|
// return peerDHT.get(locationKey).all().start();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Send signed payLoad to peer
|
||||||
|
// public FutureDirect sendData(PeerAddress peerAddress, Object payLoad) {
|
||||||
|
// // use 30 seconds as max idle time before connection get closed
|
||||||
|
// FuturePeerConnection futurePeerConnection = peerDHT.peer().createPeerConnection(peerAddress, 30000);
|
||||||
|
// FutureDirect futureDirect = peerDHT.peer().sendDirect(futurePeerConnection).object(payLoad).sign().start();
|
||||||
|
// futureDirect.addListener(new BaseFutureListener<BaseFuture>() {
|
||||||
|
// @Override
|
||||||
|
// public void operationComplete(BaseFuture future) throws Exception {
|
||||||
|
// if (futureDirect.isSuccess()) {
|
||||||
|
// log.debug("sendMessage completed");
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// log.error("sendData failed with Reason " + futureDirect.failedReason());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void exceptionCaught(Throwable t) throws Exception {
|
||||||
|
// log.error("Exception at sendData " + t.toString());
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// return futureDirect;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Private
|
// Private
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -285,6 +352,7 @@ public class P2PNode {
|
||||||
private FuturePut storePeerAddress() throws IOException {
|
private FuturePut storePeerAddress() throws IOException {
|
||||||
Number160 locationKey = Utils.makeSHAHash(keyPair.getPublic().getEncoded());
|
Number160 locationKey = Utils.makeSHAHash(keyPair.getPublic().getEncoded());
|
||||||
Data data = new Data(peerDHT.peerAddress());
|
Data data = new Data(peerDHT.peerAddress());
|
||||||
|
log.debug("storePeerAddress " + peerDHT.peerAddress().toString());
|
||||||
return putDomainProtectedData(locationKey, data);
|
return putDomainProtectedData(locationKey, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue