mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-11-16 15:58:08 +00:00
parent
a723c0d86b
commit
1b864368e1
39 changed files with 262 additions and 105 deletions
|
@ -360,6 +360,7 @@ configure(project(':p2p')) {
|
||||||
testImplementation "ch.qos.logback:logback-core:$logbackVersion"
|
testImplementation "ch.qos.logback:logback-core:$logbackVersion"
|
||||||
testImplementation "org.apache.commons:commons-lang3:$langVersion"
|
testImplementation "org.apache.commons:commons-lang3:$langVersion"
|
||||||
testImplementation("org.mockito:mockito-core:$mockitoVersion")
|
testImplementation("org.mockito:mockito-core:$mockitoVersion")
|
||||||
|
testImplementation("org.mockito:mockito-junit-jupiter:$mockitoVersion")
|
||||||
|
|
||||||
implementation "org.openjfx:javafx-base:$javafxVersion:$os"
|
implementation "org.openjfx:javafx-base:$javafxVersion:$os"
|
||||||
implementation "org.openjfx:javafx-graphics:$javafxVersion:$os"
|
implementation "org.openjfx:javafx-graphics:$javafxVersion:$os"
|
||||||
|
|
|
@ -132,7 +132,7 @@ public class SignedWitnessService {
|
||||||
} else {
|
} else {
|
||||||
p2PService.addP2PServiceListener(new BootstrapListener() {
|
p2PService.addP2PServiceListener(new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onDataReceived() {
|
||||||
onBootstrapComplete();
|
onBootstrapComplete();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -200,7 +200,7 @@ public class AccountAgeWitnessService {
|
||||||
} else {
|
} else {
|
||||||
p2PService.addP2PServiceListener(new BootstrapListener() {
|
p2PService.addP2PServiceListener(new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onDataReceived() {
|
||||||
onBootStrapped();
|
onBootStrapped();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class AppStartupState {
|
||||||
|
|
||||||
p2PService.addP2PServiceListener(new BootstrapListener() {
|
p2PService.addP2PServiceListener(new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onDataReceived() {
|
||||||
updatedDataReceived.set(true);
|
updatedDataReceived.set(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -151,7 +151,7 @@ public class OfferBookService {
|
||||||
if (dumpStatistics) {
|
if (dumpStatistics) {
|
||||||
p2PService.addP2PServiceListener(new BootstrapListener() {
|
p2PService.addP2PServiceListener(new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onDataReceived() {
|
||||||
addOfferBookChangedListener(new OfferBookChangedListener() {
|
addOfferBookChangedListener(new OfferBookChangedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onAdded(Offer offer) {
|
public void onAdded(Offer offer) {
|
||||||
|
|
|
@ -295,7 +295,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||||
} else {
|
} else {
|
||||||
p2PService.addP2PServiceListener(new BootstrapListener() {
|
p2PService.addP2PServiceListener(new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onDataReceived() {
|
||||||
onBootstrapComplete();
|
onBootstrapComplete();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class TriggerPriceService {
|
||||||
} else {
|
} else {
|
||||||
p2PService.addP2PServiceListener(new BootstrapListener() {
|
p2PService.addP2PServiceListener(new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onDataReceived() {
|
||||||
onBootstrapComplete();
|
onBootstrapComplete();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -264,7 +264,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
||||||
|
|
||||||
p2PService.addP2PServiceListener(new BootstrapListener() {
|
p2PService.addP2PServiceListener(new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onDataReceived() {
|
||||||
tryApplyMessages();
|
tryApplyMessages();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -151,7 +151,7 @@ public abstract class DisputeAgentManager<T extends DisputeAgent> {
|
||||||
else
|
else
|
||||||
p2PService.addP2PServiceListener(new BootstrapListener() {
|
p2PService.addP2PServiceListener(new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onDataReceived() {
|
||||||
startRepublishDisputeAgent();
|
startRepublishDisputeAgent();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -63,7 +63,7 @@ public class CleanupMailboxMessages {
|
||||||
} else {
|
} else {
|
||||||
p2PService.addP2PServiceListener(new BootstrapListener() {
|
p2PService.addP2PServiceListener(new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onDataReceived() {
|
||||||
cleanupMailboxMessages(trades);
|
cleanupMailboxMessages(trades);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class CleanupMailboxMessagesService {
|
||||||
} else {
|
} else {
|
||||||
p2PService.addP2PServiceListener(new BootstrapListener() {
|
p2PService.addP2PServiceListener(new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onDataReceived() {
|
||||||
cleanupMailboxMessages(trades);
|
cleanupMailboxMessages(trades);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -310,7 +310,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
||||||
} else {
|
} else {
|
||||||
p2PService.addP2PServiceListener(new BootstrapListener() {
|
p2PService.addP2PServiceListener(new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onDataReceived() {
|
||||||
initPersistedTrades();
|
initPersistedTrades();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -449,7 +449,7 @@ public class MainViewModel implements ViewModel, HavenoSetup.HavenoSetupListener
|
||||||
} else {
|
} else {
|
||||||
p2PService.addP2PServiceListener(new BootstrapListener() {
|
p2PService.addP2PServiceListener(new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onDataReceived() {
|
||||||
setupInvalidOpenOffersHandler();
|
setupInvalidOpenOffersHandler();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -527,7 +527,7 @@ public class MainViewModel implements ViewModel, HavenoSetup.HavenoSetupListener
|
||||||
} else {
|
} else {
|
||||||
p2PService.addP2PServiceListener(new BootstrapListener() {
|
p2PService.addP2PServiceListener(new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onDataReceived() {
|
||||||
accountAgeWitnessService.publishMyAccountAgeWitness(aliPayAccount.getPaymentAccountPayload());
|
accountAgeWitnessService.publishMyAccountAgeWitness(aliPayAccount.getPaymentAccountPayload());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -208,7 +208,7 @@ public abstract class TradeStepView extends AnchorPane {
|
||||||
} else {
|
} else {
|
||||||
bootstrapListener = new BootstrapListener() {
|
bootstrapListener = new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onDataReceived() {
|
||||||
registerSubscriptions();
|
registerSubscriptions();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1994,6 +1994,11 @@
|
||||||
<sha256 value="836069ca9e8ee3c56e48376222da291263f137bd3fd16d84fdd47efcc3f286e2" origin="Generated by Gradle"/>
|
<sha256 value="836069ca9e8ee3c56e48376222da291263f137bd3fd16d84fdd47efcc3f286e2" origin="Generated by Gradle"/>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
|
<component group="org.junit.jupiter" name="junit-jupiter-api" version="5.10.1">
|
||||||
|
<artifact name="junit-jupiter-api-5.10.1.jar">
|
||||||
|
<sha256 value="60d5c398c32dc7039b99282514ad6064061d8417cf959a1f6bd2038cc907c913" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
<component group="org.junit.jupiter" name="junit-jupiter-api" version="5.7.0">
|
<component group="org.junit.jupiter" name="junit-jupiter-api" version="5.7.0">
|
||||||
<artifact name="junit-jupiter-api-5.7.0.jar">
|
<artifact name="junit-jupiter-api-5.7.0.jar">
|
||||||
<sha256 value="b03f78e0daeed2d77a0af9bcd662b4cdb9693f7ee72e01a539b508b84c63d182" origin="Generated by Gradle"/>
|
<sha256 value="b03f78e0daeed2d77a0af9bcd662b4cdb9693f7ee72e01a539b508b84c63d182" origin="Generated by Gradle"/>
|
||||||
|
@ -2007,6 +2012,11 @@
|
||||||
<sha256 value="f767a170f97127b0ad3582bf3358eabbbbe981d9f96411853e629d9276926fd5" origin="Generated by Gradle"/>
|
<sha256 value="f767a170f97127b0ad3582bf3358eabbbbe981d9f96411853e629d9276926fd5" origin="Generated by Gradle"/>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
|
<component group="org.junit.jupiter" name="junit-jupiter-engine" version="5.10.1">
|
||||||
|
<artifact name="junit-jupiter-engine-5.10.1.jar">
|
||||||
|
<sha256 value="02930dfe495f93fe70b26550ace3a28f7e1b900c84426c2e4626ce020c7282d6" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
<component group="org.junit.jupiter" name="junit-jupiter-engine" version="5.7.0">
|
<component group="org.junit.jupiter" name="junit-jupiter-engine" version="5.7.0">
|
||||||
<artifact name="junit-jupiter-engine-5.7.0.jar">
|
<artifact name="junit-jupiter-engine-5.7.0.jar">
|
||||||
<sha256 value="dfa26af94644ac2612dde6625852fcb550a0d21caa243257de54cba738ba87af" origin="Generated by Gradle"/>
|
<sha256 value="dfa26af94644ac2612dde6625852fcb550a0d21caa243257de54cba738ba87af" origin="Generated by Gradle"/>
|
||||||
|
@ -2020,6 +2030,11 @@
|
||||||
<sha256 value="74cfc49388f760413ff348ca2c9ab39527484b57deecd157f2275a5f8a5fe971" origin="Generated by Gradle"/>
|
<sha256 value="74cfc49388f760413ff348ca2c9ab39527484b57deecd157f2275a5f8a5fe971" origin="Generated by Gradle"/>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
|
<component group="org.junit.jupiter" name="junit-jupiter-params" version="5.10.1">
|
||||||
|
<artifact name="junit-jupiter-params-5.10.1.jar">
|
||||||
|
<sha256 value="c8cf62debcbb354deefe1ffd0671eff785514907567d22a615ff8a8de4522b21" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
<component group="org.junit.jupiter" name="junit-jupiter-params" version="5.7.0">
|
<component group="org.junit.jupiter" name="junit-jupiter-params" version="5.7.0">
|
||||||
<artifact name="junit-jupiter-params-5.7.0.jar">
|
<artifact name="junit-jupiter-params-5.7.0.jar">
|
||||||
<sha256 value="ca9f555c37b9bf79effd2e834af549e4feb52ad8ac9e348fe5b430d4d8a482b7" origin="Generated by Gradle"/>
|
<sha256 value="ca9f555c37b9bf79effd2e834af549e4feb52ad8ac9e348fe5b430d4d8a482b7" origin="Generated by Gradle"/>
|
||||||
|
@ -2033,6 +2048,11 @@
|
||||||
<sha256 value="bde91900a5ce5d6663bb44bc708494b35daefcd73e1bb7afa61a4affe38ea97d" origin="Generated by Gradle"/>
|
<sha256 value="bde91900a5ce5d6663bb44bc708494b35daefcd73e1bb7afa61a4affe38ea97d" origin="Generated by Gradle"/>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
|
<component group="org.junit.platform" name="junit-platform-commons" version="1.10.1">
|
||||||
|
<artifact name="junit-platform-commons-1.10.1.jar">
|
||||||
|
<sha256 value="7d9855ee3f3f71f015eb1479559bf923783243c24fbfbd8b29bed8e8099b5672" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
<component group="org.junit.platform" name="junit-platform-commons" version="1.7.0">
|
<component group="org.junit.platform" name="junit-platform-commons" version="1.7.0">
|
||||||
<artifact name="junit-platform-commons-1.7.0.jar">
|
<artifact name="junit-platform-commons-1.7.0.jar">
|
||||||
<sha256 value="5330ee87cc7586e6e25175a34e9251624ff12ff525269d3415d0b4ca519b6fea" origin="Generated by Gradle"/>
|
<sha256 value="5330ee87cc7586e6e25175a34e9251624ff12ff525269d3415d0b4ca519b6fea" origin="Generated by Gradle"/>
|
||||||
|
@ -2054,6 +2074,11 @@
|
||||||
<sha256 value="624a3d745ef1d28e955a6a67af8edba0fdfc5c9bad680a73f67a70bb950a683d" origin="Generated by Gradle"/>
|
<sha256 value="624a3d745ef1d28e955a6a67af8edba0fdfc5c9bad680a73f67a70bb950a683d" origin="Generated by Gradle"/>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
|
<component group="org.junit.platform" name="junit-platform-engine" version="1.10.1">
|
||||||
|
<artifact name="junit-platform-engine-1.10.1.jar">
|
||||||
|
<sha256 value="baa48e470d6dee7369a0a8820c51da89c1463279eda6e13a304d11f45922c760" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
<component group="org.junit.platform" name="junit-platform-engine" version="1.7.0">
|
<component group="org.junit.platform" name="junit-platform-engine" version="1.7.0">
|
||||||
<artifact name="junit-platform-engine-1.7.0.jar">
|
<artifact name="junit-platform-engine-1.7.0.jar">
|
||||||
<sha256 value="75f21a20dc594afdc875736725b408cec6d0344874d29f34b2dd3075500236f2" origin="Generated by Gradle"/>
|
<sha256 value="75f21a20dc594afdc875736725b408cec6d0344874d29f34b2dd3075500236f2" origin="Generated by Gradle"/>
|
||||||
|
@ -2450,6 +2475,11 @@
|
||||||
<sha256 value="0323f591b04d3a0d7ca9ebeebb9e9f34a07c0ec9169b7444ee3951b71d4cad56" origin="Generated by Gradle"/>
|
<sha256 value="0323f591b04d3a0d7ca9ebeebb9e9f34a07c0ec9169b7444ee3951b71d4cad56" origin="Generated by Gradle"/>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
|
<component group="org.mockito" name="mockito-junit-jupiter" version="5.10.0">
|
||||||
|
<artifact name="mockito-junit-jupiter-5.10.0.jar">
|
||||||
|
<sha256 value="24ae25cde73401edf029790534fe9f92c1304eb52e46a9e57cf2b6b937ae8c43" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
<component group="org.objenesis" name="objenesis" version="3.1">
|
<component group="org.objenesis" name="objenesis" version="3.1">
|
||||||
<artifact name="objenesis-3.1.jar">
|
<artifact name="objenesis-3.1.jar">
|
||||||
<sha256 value="cdb3d038c188de6f46ffd5cd930be2d5e5dba59c53b26437995d534e3db2fb80" origin="Generated by Gradle"/>
|
<sha256 value="cdb3d038c188de6f46ffd5cd930be2d5e5dba59c53b26437995d534e3db2fb80" origin="Generated by Gradle"/>
|
||||||
|
@ -2568,6 +2598,11 @@
|
||||||
<sha256 value="a96e671816c1ff8803bdec74c9241f025bdfb277da5d2b4ee02266405936f994" origin="Generated by Gradle"/>
|
<sha256 value="a96e671816c1ff8803bdec74c9241f025bdfb277da5d2b4ee02266405936f994" origin="Generated by Gradle"/>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
|
<component group="org.opentest4j" name="opentest4j" version="1.3.0">
|
||||||
|
<artifact name="opentest4j-1.3.0.jar">
|
||||||
|
<sha256 value="48e2df636cab6563ced64dcdff8abb2355627cb236ef0bf37598682ddf742f1b" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
<component group="org.ow2" name="ow2" version="1.5">
|
<component group="org.ow2" name="ow2" version="1.5">
|
||||||
<artifact name="ow2-1.5.pom">
|
<artifact name="ow2-1.5.pom">
|
||||||
<sha256 value="0f8a1b116e760b8fe6389c51b84e4b07a70fc11082d4f936e453b583dd50b43b" origin="Generated by Gradle"/>
|
<sha256 value="0f8a1b116e760b8fe6389c51b84e4b07a70fc11082d4f936e453b583dd50b43b" origin="Generated by Gradle"/>
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package haveno.network;
|
package haveno.network;
|
||||||
|
|
||||||
import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;
|
import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;
|
||||||
|
import haveno.common.util.SingleThreadExecutorUtils;
|
||||||
import haveno.common.util.Utilities;
|
import haveno.common.util.Utilities;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.bitcoinj.core.NetworkParameters;
|
import org.bitcoinj.core.NetworkParameters;
|
||||||
|
@ -32,7 +33,6 @@ import java.net.InetSocketAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,9 +83,9 @@ public class Socks5DnsDiscovery extends MultiplexingDiscovery {
|
||||||
// Attempted workaround for reported bugs on Linux in which gethostbyname does not appear to be properly
|
// Attempted workaround for reported bugs on Linux in which gethostbyname does not appear to be properly
|
||||||
// thread safe and can cause segfaults on some libc versions.
|
// thread safe and can cause segfaults on some libc versions.
|
||||||
if (Utilities.isLinux())
|
if (Utilities.isLinux())
|
||||||
return Executors.newSingleThreadExecutor(new ContextPropagatingThreadFactory("DNS seed lookups"));
|
return SingleThreadExecutorUtils.getSingleThreadExecutor(new ContextPropagatingThreadFactory("DNS seed lookups"));
|
||||||
else
|
else
|
||||||
return Executors.newFixedThreadPool(seeds.size(), new DaemonThreadFactory("DNS seed lookups"));
|
return Utilities.getFixedThreadPoolExecutor(seeds.size(), new DaemonThreadFactory("DNS seed lookups"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -40,11 +40,11 @@ public abstract class BootstrapListener implements P2PServiceListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDataReceived() {
|
public void onUpdatedDataReceived() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract void onUpdatedDataReceived();
|
public abstract void onDataReceived();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestCustomBridges() {
|
public void onRequestCustomBridges() {
|
||||||
|
|
|
@ -189,6 +189,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doShutDown() {
|
private void doShutDown() {
|
||||||
|
log.info("P2PService doShutDown started");
|
||||||
|
|
||||||
if (p2PDataStorage != null) {
|
if (p2PDataStorage != null) {
|
||||||
p2PDataStorage.shutDown();
|
p2PDataStorage.shutDown();
|
||||||
|
@ -298,7 +299,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onUpdatedDataReceived() {
|
||||||
applyIsBootstrapped(P2PServiceListener::onUpdatedDataReceived);
|
p2pServiceListeners.forEach(P2PServiceListener::onUpdatedDataReceived);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -313,7 +314,8 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDataReceived() {
|
public void onDataReceived() {
|
||||||
p2pServiceListeners.forEach(P2PServiceListener::onDataReceived);
|
applyIsBootstrapped(P2PServiceListener::onDataReceived);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyIsBootstrapped(Consumer<P2PServiceListener> listenerHandler) {
|
private void applyIsBootstrapped(Consumer<P2PServiceListener> listenerHandler) {
|
||||||
|
|
|
@ -44,7 +44,7 @@ public enum CloseConnectionReason {
|
||||||
|
|
||||||
// illegal requests
|
// illegal requests
|
||||||
RULE_VIOLATION(true, false),
|
RULE_VIOLATION(true, false),
|
||||||
PEER_BANNED(true, false),
|
PEER_BANNED(false, false),
|
||||||
INVALID_CLASS_RECEIVED(false, false),
|
INVALID_CLASS_RECEIVED(false, false),
|
||||||
MANDATORY_CAPABILITIES_NOT_SUPPORTED(false, false);
|
MANDATORY_CAPABILITIES_NOT_SUPPORTED(false, false);
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,16 @@ public class ConnectionState implements MessageListener {
|
||||||
@Setter
|
@Setter
|
||||||
private static int expectedRequests = 6;
|
private static int expectedRequests = 6;
|
||||||
|
|
||||||
|
// We have 2 GetDataResponses and 3 GetHashResponses. If node is a lite node it also has a GetBlocksResponse if
|
||||||
|
// blocks are missing.
|
||||||
|
private static final int MIN_EXPECTED_RESPONSES = 5;
|
||||||
|
private static int expectedInitialDataResponses = MIN_EXPECTED_RESPONSES;
|
||||||
|
|
||||||
|
// If app runs in LiteNode mode there is one more expected request for the getBlocks request, so we increment standard value.
|
||||||
|
public static void incrementExpectedInitialDataResponses() {
|
||||||
|
expectedInitialDataResponses += 1;
|
||||||
|
}
|
||||||
|
|
||||||
private final Connection connection;
|
private final Connection connection;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
@ -121,7 +131,7 @@ public class ConnectionState implements MessageListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void maybeResetInitialDataExchangeType() {
|
private void maybeResetInitialDataExchangeType() {
|
||||||
if (numInitialDataResponses >= expectedRequests) {
|
if (numInitialDataResponses >= expectedInitialDataResponses) {
|
||||||
// We have received the expected messages from initial data requests. We delay a bit the reset
|
// We have received the expected messages from initial data requests. We delay a bit the reset
|
||||||
// to give time for processing the response and more tolerance to edge cases where we expect more responses.
|
// to give time for processing the response and more tolerance to edge cases where we expect more responses.
|
||||||
// Reset to PEER does not mean disconnection as well, but just that this connection has lower priority and
|
// Reset to PEER does not mean disconnection as well, but just that this connection has lower priority and
|
||||||
|
@ -165,7 +175,7 @@ public class ConnectionState implements MessageListener {
|
||||||
",\n numInitialDataResponses=" + numInitialDataResponses +
|
",\n numInitialDataResponses=" + numInitialDataResponses +
|
||||||
",\n lastInitialDataMsgTimeStamp=" + lastInitialDataMsgTimeStamp +
|
",\n lastInitialDataMsgTimeStamp=" + lastInitialDataMsgTimeStamp +
|
||||||
",\n isSeedNode=" + isSeedNode +
|
",\n isSeedNode=" + isSeedNode +
|
||||||
",\n expectedRequests=" + expectedRequests +
|
",\n expectedInitialDataResponses=" + expectedInitialDataResponses +
|
||||||
"\n}";
|
"\n}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -361,6 +361,7 @@ public abstract class NetworkNode implements MessageListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shutDown(Runnable shutDownCompleteHandler) {
|
public void shutDown(Runnable shutDownCompleteHandler) {
|
||||||
|
log.info("NetworkNode shutdown started");
|
||||||
if (!shutDownInProgress) {
|
if (!shutDownInProgress) {
|
||||||
shutDownInProgress = true;
|
shutDownInProgress = true;
|
||||||
if (server != null) {
|
if (server != null) {
|
||||||
|
|
|
@ -18,12 +18,16 @@
|
||||||
package haveno.network.p2p.network;
|
package haveno.network.p2p.network;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.berndpruenster.netlayer.tor.ExternalTor;
|
import org.berndpruenster.netlayer.tor.ExternalTor;
|
||||||
import org.berndpruenster.netlayer.tor.Tor;
|
import org.berndpruenster.netlayer.tor.Tor;
|
||||||
import org.berndpruenster.netlayer.tor.TorCtlException;
|
import org.berndpruenster.netlayer.tor.TorCtlException;
|
||||||
|
|
||||||
|
import java.net.ConnectException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class creates a brand new instance of the Tor onion router.
|
* This class creates a brand new instance of the Tor onion router.
|
||||||
*
|
*
|
||||||
|
@ -61,24 +65,47 @@ public class RunningTor extends TorMode {
|
||||||
@Override
|
@Override
|
||||||
public Tor getTor() throws TorCtlException {
|
public Tor getTor() throws TorCtlException {
|
||||||
long ts1 = new Date().getTime();
|
long ts1 = new Date().getTime();
|
||||||
|
boolean retry = true;
|
||||||
|
long twoMinutesInMilli = 1000 * 60 * 2;
|
||||||
|
|
||||||
log.info("Connecting to running tor");
|
while (retry && ((new Date().getTime() - ts1) <= twoMinutesInMilli)) {
|
||||||
|
retry = false;
|
||||||
|
try {
|
||||||
|
log.info("Connecting to running tor");
|
||||||
|
|
||||||
Tor result;
|
Tor result;
|
||||||
if (!password.isEmpty())
|
if (!password.isEmpty())
|
||||||
result = new ExternalTor(controlHost, controlPort, password);
|
result = new ExternalTor(controlHost, controlPort, password);
|
||||||
else if (cookieFile != null && cookieFile.exists())
|
else if (cookieFile != null && cookieFile.exists())
|
||||||
result = new ExternalTor(controlHost, controlPort, cookieFile, useSafeCookieAuthentication);
|
result = new ExternalTor(controlHost, controlPort, cookieFile, useSafeCookieAuthentication);
|
||||||
else
|
else
|
||||||
result = new ExternalTor(controlHost, controlPort);
|
result = new ExternalTor(controlHost, controlPort);
|
||||||
|
|
||||||
log.info(
|
boolean isTorBootstrapped = result.control.waitUntilBootstrapped();
|
||||||
"\n################################################################\n"
|
if (!isTorBootstrapped) {
|
||||||
+ "Connecting to Tor successful after {} ms. Start publishing hidden service.\n"
|
log.error("Couldn't bootstrap Tor.");
|
||||||
+ "################################################################",
|
}
|
||||||
(new Date().getTime() - ts1)); // takes usually a few seconds
|
|
||||||
|
|
||||||
return result;
|
log.info(
|
||||||
|
"\n################################################################\n"
|
||||||
|
+ "Connecting to Tor successful after {} ms. Start publishing hidden service.\n"
|
||||||
|
+ "################################################################",
|
||||||
|
(new Date().getTime() - ts1)); // takes usually a few seconds
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// netlayer throws UnknownHostException when tor docker container is not ready yet.
|
||||||
|
// netlayer throws ConnectException before tor container bind to control port.
|
||||||
|
if (e instanceof UnknownHostException || e instanceof ConnectException) {
|
||||||
|
log.warn("Couldn't connect to Tor control port. Retrying...", e);
|
||||||
|
retry = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.error("Couldn't connect to Tor.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -70,7 +70,7 @@ public class Statistic {
|
||||||
totalReceivedBytesPerSec.set(((double) totalReceivedBytes.get()) / passed);
|
totalReceivedBytesPerSec.set(((double) totalReceivedBytes.get()) / passed);
|
||||||
}, 1);
|
}, 1);
|
||||||
|
|
||||||
// We log statistics every 5 minutes
|
// We log statistics every 60 minutes
|
||||||
UserThread.runPeriodically(() -> {
|
UserThread.runPeriodically(() -> {
|
||||||
String ls = System.lineSeparator();
|
String ls = System.lineSeparator();
|
||||||
log.info("Accumulated network statistics:" + ls +
|
log.info("Accumulated network statistics:" + ls +
|
||||||
|
@ -79,14 +79,14 @@ public class Statistic {
|
||||||
"Number of sent messages per sec: {};" + ls +
|
"Number of sent messages per sec: {};" + ls +
|
||||||
"Bytes received: {}" + ls +
|
"Bytes received: {}" + ls +
|
||||||
"Number of received messages/Received messages: {} / {};" + ls +
|
"Number of received messages/Received messages: {} / {};" + ls +
|
||||||
"Number of received messages per sec: {};" + ls,
|
"Number of received messages per sec: {}" + ls,
|
||||||
Utilities.readableFileSize(totalSentBytes.get()),
|
Utilities.readableFileSize(totalSentBytes.get()),
|
||||||
numTotalSentMessages.get(), totalSentMessages,
|
numTotalSentMessages.get(), totalSentMessages,
|
||||||
numTotalSentMessagesPerSec.get(),
|
numTotalSentMessagesPerSec.get(),
|
||||||
Utilities.readableFileSize(totalReceivedBytes.get()),
|
Utilities.readableFileSize(totalReceivedBytes.get()),
|
||||||
numTotalReceivedMessages.get(), totalReceivedMessages,
|
numTotalReceivedMessages.get(), totalReceivedMessages,
|
||||||
numTotalReceivedMessagesPerSec.get());
|
numTotalReceivedMessagesPerSec.get());
|
||||||
}, TimeUnit.MINUTES.toSeconds(5));
|
}, TimeUnit.MINUTES.toSeconds(60));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LongProperty totalSentBytesProperty() {
|
public static LongProperty totalSentBytesProperty() {
|
||||||
|
@ -236,6 +236,30 @@ public class Statistic {
|
||||||
return roundTripTime;
|
return roundTripTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long getTotalSentBytes() {
|
||||||
|
return totalSentBytes.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double getTotalSentBytesPerSec() {
|
||||||
|
return totalSentBytesPerSec.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getTotalReceivedBytes() {
|
||||||
|
return totalReceivedBytes.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double getTotalReceivedBytesPerSec() {
|
||||||
|
return totalReceivedBytesPerSec.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double numTotalReceivedMessagesPerSec() {
|
||||||
|
return numTotalReceivedMessagesPerSec.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double getNumTotalSentMessagesPerSec() {
|
||||||
|
return numTotalSentMessagesPerSec.get();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Statistic{" +
|
return "Statistic{" +
|
||||||
|
|
|
@ -74,6 +74,7 @@ public class BroadcastHandler implements PeerManager.Listener {
|
||||||
|
|
||||||
private final NetworkNode networkNode;
|
private final NetworkNode networkNode;
|
||||||
private final PeerManager peerManager;
|
private final PeerManager peerManager;
|
||||||
|
@Nullable
|
||||||
private final ResultHandler resultHandler;
|
private final ResultHandler resultHandler;
|
||||||
private final String uid;
|
private final String uid;
|
||||||
|
|
||||||
|
@ -276,6 +277,9 @@ public class BroadcastHandler implements PeerManager.Listener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(@NotNull Throwable throwable) {
|
public void onFailure(@NotNull Throwable throwable) {
|
||||||
|
log.warn("Broadcast to " + connection.getPeersNodeAddressOptional() + " failed. ", throwable);
|
||||||
|
numOfFailedBroadcasts.incrementAndGet();
|
||||||
|
|
||||||
if (stopped.get()) {
|
if (stopped.get()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import java.util.Set;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
@ -51,6 +52,7 @@ public class Broadcaster implements BroadcastHandler.ResultHandler {
|
||||||
private Runnable shutDownResultHandler;
|
private Runnable shutDownResultHandler;
|
||||||
private final ListeningExecutorService executor;
|
private final ListeningExecutorService executor;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -90,6 +92,7 @@ public class Broadcaster implements BroadcastHandler.ResultHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doShutDown() {
|
private void doShutDown() {
|
||||||
|
log.info("Broadcaster doShutDown started");
|
||||||
broadcastHandlers.forEach(BroadcastHandler::cancel);
|
broadcastHandlers.forEach(BroadcastHandler::cancel);
|
||||||
if (timer != null) {
|
if (timer != null) {
|
||||||
timer.stop();
|
timer.stop();
|
||||||
|
|
|
@ -77,6 +77,7 @@ public final class PeerManager implements ConnectionListener, PersistedDataHost
|
||||||
private static final boolean PRINT_REPORTED_PEERS_DETAILS = true;
|
private static final boolean PRINT_REPORTED_PEERS_DETAILS = true;
|
||||||
private Timer printStatisticsTimer;
|
private Timer printStatisticsTimer;
|
||||||
private boolean shutDownRequested;
|
private boolean shutDownRequested;
|
||||||
|
private int numOnConnections;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -167,7 +168,7 @@ public final class PeerManager implements ConnectionListener, PersistedDataHost
|
||||||
};
|
};
|
||||||
clockWatcher.addListener(clockWatcherListener);
|
clockWatcher.addListener(clockWatcherListener);
|
||||||
|
|
||||||
printStatisticsTimer = UserThread.runPeriodically(this::printStatistics, TimeUnit.MINUTES.toSeconds(5));
|
printStatisticsTimer = UserThread.runPeriodically(this::printStatistics, TimeUnit.MINUTES.toSeconds(60));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shutDown() {
|
public void shutDown() {
|
||||||
|
@ -209,6 +210,8 @@ public final class PeerManager implements ConnectionListener, PersistedDataHost
|
||||||
|
|
||||||
doHouseKeeping();
|
doHouseKeeping();
|
||||||
|
|
||||||
|
numOnConnections++;
|
||||||
|
|
||||||
if (lostAllConnections) {
|
if (lostAllConnections) {
|
||||||
lostAllConnections = false;
|
lostAllConnections = false;
|
||||||
stopped = false;
|
stopped = false;
|
||||||
|
@ -224,14 +227,15 @@ public final class PeerManager implements ConnectionListener, PersistedDataHost
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisconnect(CloseConnectionReason closeConnectionReason, Connection connection) {
|
public void onDisconnect(CloseConnectionReason closeConnectionReason, Connection connection) {
|
||||||
log.info("onDisconnect called: nodeAddress={}, closeConnectionReason={}",
|
log.debug("onDisconnect called: nodeAddress={}, closeConnectionReason={}",
|
||||||
connection.getPeersNodeAddressOptional(), closeConnectionReason);
|
connection.getPeersNodeAddressOptional(), closeConnectionReason);
|
||||||
handleConnectionFault(connection);
|
handleConnectionFault(connection);
|
||||||
|
|
||||||
boolean previousLostAllConnections = lostAllConnections;
|
boolean previousLostAllConnections = lostAllConnections;
|
||||||
lostAllConnections = networkNode.getAllConnections().isEmpty();
|
lostAllConnections = networkNode.getAllConnections().isEmpty();
|
||||||
|
|
||||||
if (lostAllConnections) {
|
// At start-up we ignore if we would lose a connection and would fall back to no connections
|
||||||
|
if (lostAllConnections && numOnConnections > 2) {
|
||||||
stopped = true;
|
stopped = true;
|
||||||
|
|
||||||
if (!shutDownRequested) {
|
if (!shutDownRequested) {
|
||||||
|
@ -553,7 +557,7 @@ public final class PeerManager implements ConnectionListener, PersistedDataHost
|
||||||
|
|
||||||
if (!candidates.isEmpty()) {
|
if (!candidates.isEmpty()) {
|
||||||
Connection connection = candidates.remove(0);
|
Connection connection = candidates.remove(0);
|
||||||
log.info("checkMaxConnections: Num candidates for shut down={}. We close oldest connection to peer {}",
|
log.info("checkMaxConnections: Num candidates (inbound/peer) for shut down={}. We close oldest connection to peer {}",
|
||||||
candidates.size(), connection.getPeersNodeAddressOptional());
|
candidates.size(), connection.getPeersNodeAddressOptional());
|
||||||
if (!connection.isStopped()) {
|
if (!connection.isStopped()) {
|
||||||
connection.shutDown(CloseConnectionReason.TOO_MANY_CONNECTIONS_OPEN,
|
connection.shutDown(CloseConnectionReason.TOO_MANY_CONNECTIONS_OPEN,
|
||||||
|
|
|
@ -37,16 +37,16 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class GetDataRequestHandler {
|
public class GetDataRequestHandler {
|
||||||
private static final long TIMEOUT = 180;
|
private static final long TIMEOUT = 240;
|
||||||
|
|
||||||
private static final int MAX_ENTRIES = 10000;
|
private static final int MAX_ENTRIES = 5000;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Listener
|
// Listener
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public interface Listener {
|
public interface Listener {
|
||||||
void onComplete();
|
void onComplete(int serializedSize);
|
||||||
|
|
||||||
void onFault(String errorMessage, Connection connection);
|
void onFault(String errorMessage, Connection connection);
|
||||||
}
|
}
|
||||||
|
@ -94,15 +94,11 @@ public class GetDataRequestHandler {
|
||||||
connection.getCapabilities());
|
connection.getCapabilities());
|
||||||
|
|
||||||
if (wasPersistableNetworkPayloadsTruncated.get()) {
|
if (wasPersistableNetworkPayloadsTruncated.get()) {
|
||||||
log.warn("The getData request from peer with {} caused too much PersistableNetworkPayload " +
|
log.info("The getDataResponse for peer {} got truncated.", connectionInfo);
|
||||||
"entries to get delivered. We limited the entries for the response to {} entries",
|
|
||||||
connectionInfo, MAX_ENTRIES);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wasProtectedStorageEntriesTruncated.get()) {
|
if (wasProtectedStorageEntriesTruncated.get()) {
|
||||||
log.warn("The getData request from peer with {} caused too much ProtectedStorageEntry " +
|
log.info("The getDataResponse for peer {} got truncated.", connectionInfo);
|
||||||
"entries to get delivered. We limited the entries for the response to {} entries",
|
|
||||||
connectionInfo, MAX_ENTRIES);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("The getDataResponse to peer with {} contains {} ProtectedStorageEntries and {} PersistableNetworkPayloads",
|
log.info("The getDataResponse to peer with {} contains {} ProtectedStorageEntries and {} PersistableNetworkPayloads",
|
||||||
|
@ -126,8 +122,8 @@ public class GetDataRequestHandler {
|
||||||
if (!stopped) {
|
if (!stopped) {
|
||||||
log.trace("Send DataResponse to {} succeeded. getDataResponse={}",
|
log.trace("Send DataResponse to {} succeeded. getDataResponse={}",
|
||||||
connection.getPeersNodeAddressOptional(), getDataResponse);
|
connection.getPeersNodeAddressOptional(), getDataResponse);
|
||||||
|
listener.onComplete(getDataResponse.toProtoNetworkEnvelope().getSerializedSize());
|
||||||
cleanup();
|
cleanup();
|
||||||
listener.onComplete();
|
|
||||||
} else {
|
} else {
|
||||||
log.trace("We have stopped already. We ignore that networkNode.sendMessage.onSuccess call.");
|
log.trace("We have stopped already. We ignore that networkNode.sendMessage.onSuccess call.");
|
||||||
}
|
}
|
||||||
|
@ -136,7 +132,7 @@ public class GetDataRequestHandler {
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(@NotNull Throwable throwable) {
|
public void onFailure(@NotNull Throwable throwable) {
|
||||||
if (!stopped) {
|
if (!stopped) {
|
||||||
String errorMessage = "Sending getDataRequest to " + connection +
|
String errorMessage = "Sending getDataResponse to " + connection +
|
||||||
" failed. That is expected if the peer is offline. getDataResponse=" + getDataResponse + "." +
|
" failed. That is expected if the peer is offline. getDataResponse=" + getDataResponse + "." +
|
||||||
"Exception: " + throwable.getMessage();
|
"Exception: " + throwable.getMessage();
|
||||||
handleFault(errorMessage, CloseConnectionReason.SEND_MSG_FAILURE, connection);
|
handleFault(errorMessage, CloseConnectionReason.SEND_MSG_FAILURE, connection);
|
||||||
|
|
|
@ -50,7 +50,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
class RequestDataHandler implements MessageListener {
|
class RequestDataHandler implements MessageListener {
|
||||||
private static final long TIMEOUT = 180;
|
private static final long TIMEOUT = 240;
|
||||||
|
|
||||||
private NodeAddress peersNodeAddress;
|
private NodeAddress peersNodeAddress;
|
||||||
private String getDataRequestType;
|
private String getDataRequestType;
|
||||||
|
@ -69,7 +69,7 @@ class RequestDataHandler implements MessageListener {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public interface Listener {
|
public interface Listener {
|
||||||
void onComplete();
|
void onComplete(boolean wasTruncated);
|
||||||
|
|
||||||
@SuppressWarnings("UnusedParameters")
|
@SuppressWarnings("UnusedParameters")
|
||||||
void onFault(String errorMessage, @SuppressWarnings("SameParameterValue") @Nullable Connection connection);
|
void onFault(String errorMessage, @SuppressWarnings("SameParameterValue") @Nullable Connection connection);
|
||||||
|
@ -138,7 +138,7 @@ class RequestDataHandler implements MessageListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
getDataRequestType = getDataRequest.getClass().getSimpleName();
|
getDataRequestType = getDataRequest.getClass().getSimpleName();
|
||||||
log.info("We send a {} to peer {}. ", getDataRequestType, nodeAddress);
|
log.info("\n\n>> We send a {} to peer {}\n", getDataRequestType, nodeAddress);
|
||||||
networkNode.addMessageListener(this);
|
networkNode.addMessageListener(this);
|
||||||
SettableFuture<Connection> future = networkNode.sendMessage(nodeAddress, getDataRequest);
|
SettableFuture<Connection> future = networkNode.sendMessage(nodeAddress, getDataRequest);
|
||||||
//noinspection UnstableApiUsage
|
//noinspection UnstableApiUsage
|
||||||
|
@ -197,8 +197,7 @@ class RequestDataHandler implements MessageListener {
|
||||||
connection.getPeersNodeAddressOptional().get());
|
connection.getPeersNodeAddressOptional().get());
|
||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
listener.onComplete();
|
listener.onComplete(getDataResponse.isWasTruncated());
|
||||||
// firstRequest = false;
|
|
||||||
} else {
|
} else {
|
||||||
log.warn("Nonce not matching. That can happen rarely if we get a response after a canceled " +
|
log.warn("Nonce not matching. That can happen rarely if we get a response after a canceled " +
|
||||||
"handshake (timeout causes connection close but peer might have sent a msg before " +
|
"handshake (timeout causes connection close but peer might have sent a msg before " +
|
||||||
|
@ -239,7 +238,7 @@ class RequestDataHandler implements MessageListener {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
String sep = System.lineSeparator();
|
String sep = System.lineSeparator();
|
||||||
sb.append(sep).append("#################################################################").append(sep);
|
sb.append(sep).append("#################################################################").append(sep);
|
||||||
sb.append("Connected to node: ").append(peersNodeAddress.getFullAddress()).append(sep);
|
sb.append("Data provided by node: ").append(peersNodeAddress.getFullAddress()).append(sep);
|
||||||
int items = dataSet.size() + persistableNetworkPayloadSet.size();
|
int items = dataSet.size() + persistableNetworkPayloadSet.size();
|
||||||
sb.append("Received ").append(items).append(" instances from a ")
|
sb.append("Received ").append(items).append(" instances from a ")
|
||||||
.append(getDataRequestType).append(sep);
|
.append(getDataRequestType).append(sep);
|
||||||
|
@ -249,7 +248,7 @@ class RequestDataHandler implements MessageListener {
|
||||||
.append(" / ")
|
.append(" / ")
|
||||||
.append(Utilities.readableFileSize(value.second.get()))
|
.append(Utilities.readableFileSize(value.second.get()))
|
||||||
.append(sep));
|
.append(sep));
|
||||||
sb.append("#################################################################");
|
sb.append("#################################################################\n");
|
||||||
log.info(sb.toString());
|
log.info(sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
@ -55,8 +56,10 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
|
||||||
private static int NUM_SEEDS_FOR_PRELIMINARY_REQUEST = 2;
|
private static int NUM_SEEDS_FOR_PRELIMINARY_REQUEST = 2;
|
||||||
// how many seeds additional to the first responding PreliminaryGetDataRequest seed we request the GetUpdatedDataRequest from
|
// how many seeds additional to the first responding PreliminaryGetDataRequest seed we request the GetUpdatedDataRequest from
|
||||||
private static int NUM_ADDITIONAL_SEEDS_FOR_UPDATE_REQUEST = 1;
|
private static int NUM_ADDITIONAL_SEEDS_FOR_UPDATE_REQUEST = 1;
|
||||||
|
private static int MAX_REPEATED_REQUESTS = 30;
|
||||||
private boolean isPreliminaryDataRequest = true;
|
private boolean isPreliminaryDataRequest = true;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Listener
|
// Listener
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -75,6 +78,12 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface ResponseListener {
|
||||||
|
void onSuccess(int serializedSize);
|
||||||
|
|
||||||
|
void onFault();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Class fields
|
// Class fields
|
||||||
|
@ -84,6 +93,7 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
|
||||||
private final P2PDataStorage dataStorage;
|
private final P2PDataStorage dataStorage;
|
||||||
private final PeerManager peerManager;
|
private final PeerManager peerManager;
|
||||||
private final List<NodeAddress> seedNodeAddresses;
|
private final List<NodeAddress> seedNodeAddresses;
|
||||||
|
private final List<ResponseListener> responseListeners = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
// As we use Guice injection we cannot set the listener in our constructor but the P2PService calls the setListener
|
// As we use Guice injection we cannot set the listener in our constructor but the P2PService calls the setListener
|
||||||
// in it's constructor so we can guarantee it is not null.
|
// in it's constructor so we can guarantee it is not null.
|
||||||
|
@ -94,8 +104,9 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
|
||||||
private Optional<NodeAddress> nodeAddressOfPreliminaryDataRequest = Optional.empty();
|
private Optional<NodeAddress> nodeAddressOfPreliminaryDataRequest = Optional.empty();
|
||||||
private Timer retryTimer;
|
private Timer retryTimer;
|
||||||
private boolean dataUpdateRequested;
|
private boolean dataUpdateRequested;
|
||||||
|
private boolean allDataReceived;
|
||||||
private boolean stopped;
|
private boolean stopped;
|
||||||
|
private int numRepeatedRequests = 0;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
|
@ -124,6 +135,7 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
|
||||||
if (seedNodeRepository.isSeedNode(myAddress)) {
|
if (seedNodeRepository.isSeedNode(myAddress)) {
|
||||||
NUM_SEEDS_FOR_PRELIMINARY_REQUEST = 3;
|
NUM_SEEDS_FOR_PRELIMINARY_REQUEST = 3;
|
||||||
NUM_ADDITIONAL_SEEDS_FOR_UPDATE_REQUEST = 2;
|
NUM_ADDITIONAL_SEEDS_FOR_UPDATE_REQUEST = 2;
|
||||||
|
MAX_REPEATED_REQUESTS = 100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -199,6 +211,10 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
|
||||||
return nodeAddressOfPreliminaryDataRequest;
|
return nodeAddressOfPreliminaryDataRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addResponseListener(ResponseListener responseListener) {
|
||||||
|
responseListeners.add(responseListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// ConnectionListener implementation
|
// ConnectionListener implementation
|
||||||
|
@ -266,9 +282,11 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
|
||||||
GetDataRequestHandler getDataRequestHandler = new GetDataRequestHandler(networkNode, dataStorage,
|
GetDataRequestHandler getDataRequestHandler = new GetDataRequestHandler(networkNode, dataStorage,
|
||||||
new GetDataRequestHandler.Listener() {
|
new GetDataRequestHandler.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onComplete() {
|
public void onComplete(int serializedSize) {
|
||||||
getDataRequestHandlers.remove(uid);
|
getDataRequestHandlers.remove(uid);
|
||||||
log.trace("requestDataHandshake completed.\n\tConnection={}", connection);
|
log.trace("requestDataHandshake completed.\n\tConnection={}", connection);
|
||||||
|
|
||||||
|
responseListeners.forEach(listener -> listener.onSuccess(serializedSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -278,6 +296,8 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
|
||||||
log.trace("GetDataRequestHandler failed.\n\tConnection={}\n\t" +
|
log.trace("GetDataRequestHandler failed.\n\tConnection={}\n\t" +
|
||||||
"ErrorMessage={}", connection, errorMessage);
|
"ErrorMessage={}", connection, errorMessage);
|
||||||
peerManager.handleConnectionFault(connection);
|
peerManager.handleConnectionFault(connection);
|
||||||
|
|
||||||
|
responseListeners.forEach(ResponseListener::onFault);
|
||||||
} else {
|
} else {
|
||||||
log.warn("We have stopped already. We ignore that getDataRequestHandler.handle.onFault call.");
|
log.warn("We have stopped already. We ignore that getDataRequestHandler.handle.onFault call.");
|
||||||
}
|
}
|
||||||
|
@ -313,7 +333,7 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
|
||||||
RequestDataHandler requestDataHandler = new RequestDataHandler(networkNode, dataStorage, peerManager,
|
RequestDataHandler requestDataHandler = new RequestDataHandler(networkNode, dataStorage, peerManager,
|
||||||
new RequestDataHandler.Listener() {
|
new RequestDataHandler.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onComplete() {
|
public void onComplete(boolean wasTruncated) {
|
||||||
log.trace("RequestDataHandshake of outbound connection complete. nodeAddress={}",
|
log.trace("RequestDataHandshake of outbound connection complete. nodeAddress={}",
|
||||||
nodeAddress);
|
nodeAddress);
|
||||||
stopRetryTimer();
|
stopRetryTimer();
|
||||||
|
@ -336,7 +356,27 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
|
||||||
checkNotNull(listener).onUpdatedDataReceived();
|
checkNotNull(listener).onUpdatedDataReceived();
|
||||||
}
|
}
|
||||||
|
|
||||||
checkNotNull(listener).onDataReceived();
|
if (wasTruncated) {
|
||||||
|
if (numRepeatedRequests < MAX_REPEATED_REQUESTS) {
|
||||||
|
// If we had allDataReceived already set to true but get a response with truncated flag,
|
||||||
|
// we still repeat the request to that node for higher redundancy. Otherwise, one seed node
|
||||||
|
// providing incomplete data would stop others to fill the gaps.
|
||||||
|
log.info("DataResponse did not contain all data, so we repeat request until we got all data");
|
||||||
|
UserThread.runAfter(() -> requestData(nodeAddress, remainingNodeAddresses), 2);
|
||||||
|
} else if (!allDataReceived) {
|
||||||
|
allDataReceived = true;
|
||||||
|
log.warn("\n#################################################################\n" +
|
||||||
|
"Loading initial data from {} did not complete after 20 repeated requests. \n" +
|
||||||
|
"#################################################################\n", nodeAddress);
|
||||||
|
checkNotNull(listener).onDataReceived();
|
||||||
|
}
|
||||||
|
} else if (!allDataReceived) {
|
||||||
|
allDataReceived = true;
|
||||||
|
log.info("\n\n#################################################################\n" +
|
||||||
|
"Loading initial data from {} completed\n" +
|
||||||
|
"#################################################################\n", nodeAddress);
|
||||||
|
checkNotNull(listener).onDataReceived();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -377,6 +417,7 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
handlerMap.put(nodeAddress, requestDataHandler);
|
handlerMap.put(nodeAddress, requestDataHandler);
|
||||||
|
numRepeatedRequests++;
|
||||||
requestDataHandler.requestData(nodeAddress, isPreliminaryDataRequest);
|
requestDataHandler.requestData(nodeAddress, isPreliminaryDataRequest);
|
||||||
} else {
|
} else {
|
||||||
log.warn("We have started already a requestDataHandshake to peer. nodeAddress=" + nodeAddress + "\n" +
|
log.warn("We have started already a requestDataHandshake to peer. nodeAddress=" + nodeAddress + "\n" +
|
||||||
|
|
|
@ -130,7 +130,7 @@ public class PeerExchangeManager implements MessageListener, ConnectionListener,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisconnect(CloseConnectionReason closeConnectionReason, Connection connection) {
|
public void onDisconnect(CloseConnectionReason closeConnectionReason, Connection connection) {
|
||||||
log.info("onDisconnect closeConnectionReason={}, nodeAddressOpt={}", closeConnectionReason, connection.getPeersNodeAddressOptional());
|
log.debug("onDisconnect closeConnectionReason={}, nodeAddressOpt={}", closeConnectionReason, connection.getPeersNodeAddressOptional());
|
||||||
closeHandler(connection);
|
closeHandler(connection);
|
||||||
|
|
||||||
if (retryTimer == null) {
|
if (retryTimer == null) {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import com.google.protobuf.ByteString;
|
||||||
import com.google.protobuf.Message;
|
import com.google.protobuf.Message;
|
||||||
import haveno.common.crypto.CryptoException;
|
import haveno.common.crypto.CryptoException;
|
||||||
import haveno.common.crypto.Sig;
|
import haveno.common.crypto.Sig;
|
||||||
|
import haveno.common.proto.network.GetDataResponsePriority;
|
||||||
import haveno.common.proto.network.NetworkPayload;
|
import haveno.common.proto.network.NetworkPayload;
|
||||||
import haveno.common.proto.network.NetworkProtoResolver;
|
import haveno.common.proto.network.NetworkProtoResolver;
|
||||||
import haveno.common.proto.persistable.PersistablePayload;
|
import haveno.common.proto.persistable.PersistablePayload;
|
||||||
|
@ -141,6 +142,10 @@ public class ProtectedStorageEntry implements NetworkPayload, PersistablePayload
|
||||||
(clock.millis() - creationTimeStamp) > ((ExpirablePayload) protectedStoragePayload).getTTL();
|
(clock.millis() - creationTimeStamp) > ((ExpirablePayload) protectedStoragePayload).getTTL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GetDataResponsePriority getGetDataResponsePriority() {
|
||||||
|
return protectedStoragePayload.getGetDataResponsePriority();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns true if the Entry is valid for an add operation. For non-mailbox Entrys, the entry owner must
|
* Returns true if the Entry is valid for an add operation. For non-mailbox Entrys, the entry owner must
|
||||||
* match the payload owner.
|
* match the payload owner.
|
||||||
|
|
|
@ -27,8 +27,10 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -79,7 +79,7 @@ public abstract class HistoricalDataStoreService<T extends PersistableNetworkPay
|
||||||
"As our historical store is a newer version we add the data to our result map." :
|
"As our historical store is a newer version we add the data to our result map." :
|
||||||
"As the requester version is not older as our historical store we do not " +
|
"As the requester version is not older as our historical store we do not " +
|
||||||
"add the data to the result map.";
|
"add the data to the result map.";
|
||||||
log.info("The requester had version {}. Our historical data store has version {}.\n{}",
|
log.trace("The requester had version {}. Our historical data store has version {}.\n{}",
|
||||||
requestersVersion, storeVersion, details);
|
requestersVersion, storeVersion, details);
|
||||||
return newVersion;
|
return newVersion;
|
||||||
})
|
})
|
||||||
|
@ -141,7 +141,7 @@ public abstract class HistoricalDataStoreService<T extends PersistableNetworkPay
|
||||||
@Override
|
@Override
|
||||||
protected void readFromResources(String postFix, Runnable completeHandler) {
|
protected void readFromResources(String postFix, Runnable completeHandler) {
|
||||||
readStore(persisted -> {
|
readStore(persisted -> {
|
||||||
log.info("We have created the {} store for the live data and filled it with {} entries from the persisted data.",
|
log.debug("We have created the {} store for the live data and filled it with {} entries from the persisted data.",
|
||||||
getFileName(), getMapOfLiveData().size());
|
getFileName(), getMapOfLiveData().size());
|
||||||
|
|
||||||
// Now we add our historical data stores.
|
// Now we add our historical data stores.
|
||||||
|
@ -181,7 +181,7 @@ public abstract class HistoricalDataStoreService<T extends PersistableNetworkPay
|
||||||
persistenceManager.readPersisted(fileName, persisted -> {
|
persistenceManager.readPersisted(fileName, persisted -> {
|
||||||
storesByVersion.put(version, persisted);
|
storesByVersion.put(version, persisted);
|
||||||
allHistoricalPayloads.putAll(persisted.getMap());
|
allHistoricalPayloads.putAll(persisted.getMap());
|
||||||
log.info("We have read from {} {} historical items.", fileName, persisted.getMap().size());
|
log.debug("We have read from {} {} historical items.", fileName, persisted.getMap().size());
|
||||||
pruneStore(persisted, version);
|
pruneStore(persisted, version);
|
||||||
completeHandler.run();
|
completeHandler.run();
|
||||||
},
|
},
|
||||||
|
@ -195,11 +195,11 @@ public abstract class HistoricalDataStoreService<T extends PersistableNetworkPay
|
||||||
mapOfLiveData.keySet().removeAll(historicalStore.getMap().keySet());
|
mapOfLiveData.keySet().removeAll(historicalStore.getMap().keySet());
|
||||||
int postLive = mapOfLiveData.size();
|
int postLive = mapOfLiveData.size();
|
||||||
if (preLive > postLive) {
|
if (preLive > postLive) {
|
||||||
log.info("We pruned data from our live data store which are already contained in the historical data store with version {}. " +
|
log.debug("We pruned data from our live data store which are already contained in the historical data store with version {}. " +
|
||||||
"The live map had {} entries before pruning and has {} entries afterwards.",
|
"The live map had {} entries before pruning and has {} entries afterwards.",
|
||||||
version, preLive, postLive);
|
version, preLive, postLive);
|
||||||
} else {
|
} else {
|
||||||
log.info("No pruning from historical data store with version {} was applied", version);
|
log.debug("No pruning from historical data store with version {} was applied", version);
|
||||||
}
|
}
|
||||||
requestPersistence();
|
requestPersistence();
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,18 +109,18 @@ public abstract class StoreService<T extends PersistableEnvelope> {
|
||||||
File destinationFile = new File(Paths.get(absolutePathOfStorageDir, fileName).toString());
|
File destinationFile = new File(Paths.get(absolutePathOfStorageDir, fileName).toString());
|
||||||
if (!destinationFile.exists()) {
|
if (!destinationFile.exists()) {
|
||||||
try {
|
try {
|
||||||
log.info("We copy resource to file: resourceFileName={}, destinationFile={}", resourceFileName, destinationFile);
|
log.debug("We copy resource to file: resourceFileName={}, destinationFile={}", resourceFileName, destinationFile);
|
||||||
FileUtil.resourceToFile(resourceFileName, destinationFile);
|
FileUtil.resourceToFile(resourceFileName, destinationFile);
|
||||||
return true;
|
return true;
|
||||||
} catch (ResourceNotFoundException e) {
|
} catch (ResourceNotFoundException e) {
|
||||||
log.info("Could not find resourceFile " + resourceFileName + ". That is expected if none is provided yet.");
|
log.debug("Could not find resourceFile " + resourceFileName + ". That is expected if none is provided yet.");
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
log.error("Could not copy resourceFile " + resourceFileName + " to " +
|
log.error("Could not copy resourceFile " + resourceFileName + " to " +
|
||||||
destinationFile.getAbsolutePath() + ".\n" + e.getMessage());
|
destinationFile.getAbsolutePath() + ".\n" + e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.info("No resource file was copied. {} exists already.", fileName);
|
log.debug("No resource file was copied. {} exists already.", fileName);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,10 +33,10 @@ import haveno.network.p2p.storage.payload.CapabilityRequiringPayload;
|
||||||
import haveno.network.p2p.storage.payload.PersistableNetworkPayload;
|
import haveno.network.p2p.storage.payload.PersistableNetworkPayload;
|
||||||
import haveno.network.p2p.storage.payload.ProtectedStorageEntry;
|
import haveno.network.p2p.storage.payload.ProtectedStorageEntry;
|
||||||
import haveno.network.p2p.storage.payload.ProtectedStoragePayload;
|
import haveno.network.p2p.storage.payload.ProtectedStoragePayload;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
|
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
@ -45,6 +45,10 @@ import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.mockito.junit.jupiter.MockitoSettings;
|
||||||
|
import org.mockito.quality.Strictness;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
@ -54,6 +58,8 @@ import static org.mockito.Mockito.when;
|
||||||
import static org.mockito.Mockito.withSettings;
|
import static org.mockito.Mockito.withSettings;
|
||||||
|
|
||||||
public class P2PDataStorageBuildGetDataResponseTest {
|
public class P2PDataStorageBuildGetDataResponseTest {
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
@MockitoSettings(strictness = Strictness.LENIENT) // there are unused stubs in TestState & elsewhere
|
||||||
abstract static class P2PDataStorageBuildGetDataResponseTestBase {
|
abstract static class P2PDataStorageBuildGetDataResponseTestBase {
|
||||||
// GIVEN null & non-null supportedCapabilities
|
// GIVEN null & non-null supportedCapabilities
|
||||||
private TestState testState;
|
private TestState testState;
|
||||||
|
@ -67,7 +73,6 @@ public class P2PDataStorageBuildGetDataResponseTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
this.testState = new TestState();
|
this.testState = new TestState();
|
||||||
|
|
||||||
this.localNodeAddress = new NodeAddress("localhost", 8080);
|
this.localNodeAddress = new NodeAddress("localhost", 8080);
|
||||||
|
|
|
@ -30,7 +30,6 @@ import java.util.Optional;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static haveno.network.p2p.storage.TestState.SavedTestState;
|
import static haveno.network.p2p.storage.TestState.SavedTestState;
|
||||||
import static haveno.network.p2p.storage.TestState.getTestNodeAddress;
|
|
||||||
import static java.util.stream.Stream.of;
|
import static java.util.stream.Stream.of;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
@ -67,8 +66,9 @@ public class P2PDataStoragePersistableNetworkPayloadTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setup() {
|
public void setup() {
|
||||||
persistableNetworkPayload = createInstance();
|
this.persistableNetworkPayload = this.createInstance();
|
||||||
testState = new TestState();
|
|
||||||
|
this.testState = new TestState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void assertAndDoAdd(PersistableNetworkPayload persistableNetworkPayload,
|
void assertAndDoAdd(PersistableNetworkPayload persistableNetworkPayload,
|
||||||
|
@ -82,14 +82,15 @@ public class P2PDataStoragePersistableNetworkPayloadTest {
|
||||||
|
|
||||||
if (testCase == TestCase.PUBLIC_API) {
|
if (testCase == TestCase.PUBLIC_API) {
|
||||||
assertEquals(expectedReturnValue,
|
assertEquals(expectedReturnValue,
|
||||||
testState.mockedStorage.addPersistableNetworkPayload(persistableNetworkPayload, getTestNodeAddress(), reBroadcast));
|
this.testState.mockedStorage.addPersistableNetworkPayload(persistableNetworkPayload, TestState.getTestNodeAddress(), reBroadcast));
|
||||||
} else { // onMessage
|
} else { // onMessage
|
||||||
Connection mockedConnection = mock();
|
Connection mockedConnection = mock(Connection.class);
|
||||||
when(mockedConnection.getPeersNodeAddressOptional()).thenReturn(Optional.of(getTestNodeAddress()));
|
when(mockedConnection.getPeersNodeAddressOptional()).thenReturn(Optional.of(TestState.getTestNodeAddress()));
|
||||||
|
|
||||||
testState.mockedStorage.onMessage(new AddPersistableNetworkPayloadMessage(persistableNetworkPayload), mockedConnection);
|
testState.mockedStorage.onMessage(new AddPersistableNetworkPayloadMessage(persistableNetworkPayload), mockedConnection);
|
||||||
}
|
}
|
||||||
testState.verifyPersistableAdd(beforeState, persistableNetworkPayload, expectedHashMapAndDataStoreUpdated, expectedListenersSignaled, expectedBroadcast);
|
|
||||||
|
this.testState.verifyPersistableAdd(beforeState, persistableNetworkPayload, expectedHashMapAndDataStoreUpdated, expectedListenersSignaled, expectedBroadcast);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Stream<Object[]> data() {
|
static Stream<Object[]> data() {
|
||||||
|
@ -103,16 +104,17 @@ public class P2PDataStoragePersistableNetworkPayloadTest {
|
||||||
@MethodSource("data")
|
@MethodSource("data")
|
||||||
@ParameterizedTest(name = "{index}: Test with TestCase={0} allowBroadcast={1} reBroadcast={2} checkDate={3}")
|
@ParameterizedTest(name = "{index}: Test with TestCase={0} allowBroadcast={1} reBroadcast={2} checkDate={3}")
|
||||||
public void addPersistableNetworkPayload(TestCase testCase, boolean reBroadcast) {
|
public void addPersistableNetworkPayload(TestCase testCase, boolean reBroadcast) {
|
||||||
assertAndDoAdd(persistableNetworkPayload, testCase, reBroadcast, true, true, true, true);
|
// First add should succeed regardless of parameters
|
||||||
|
assertAndDoAdd(this.persistableNetworkPayload, testCase, reBroadcast, true, true, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@MethodSource("data")
|
@MethodSource("data")
|
||||||
@ParameterizedTest(name = "{index}: Test with TestCase={0} allowBroadcast={1} reBroadcast={2} checkDate={3}")
|
@ParameterizedTest(name = "{index}: Test with TestCase={0} allowBroadcast={1} reBroadcast={2} checkDate={3}")
|
||||||
public void addPersistableNetworkPayloadDuplicate(TestCase testCase, boolean reBroadcast) {
|
public void addPersistableNetworkPayloadDuplicate(TestCase testCase, boolean reBroadcast) {
|
||||||
assertAndDoAdd(persistableNetworkPayload, testCase, reBroadcast, true, true, true, true);
|
assertAndDoAdd(this.persistableNetworkPayload, testCase, reBroadcast, true, true, true, true);
|
||||||
|
|
||||||
// We return true and broadcast if reBroadcast is set
|
// We return true and broadcast if reBroadcast is set
|
||||||
// assertAndDoAdd(persistableNetworkPayload, testCase, reBroadcast, reBroadcast, false, false, reBroadcast);
|
// assertAndDoAdd(this.persistableNetworkPayload, testCase, reBroadcast, reBroadcast, false, false, reBroadcast);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ import haveno.network.p2p.storage.payload.ProtectedStorageEntry;
|
||||||
import haveno.network.p2p.storage.payload.ProtectedStoragePayload;
|
import haveno.network.p2p.storage.payload.ProtectedStoragePayload;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
|
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
@ -47,7 +46,6 @@ public class P2PDataStorageProcessGetDataResponse {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
this.testState = new TestState();
|
this.testState = new TestState();
|
||||||
|
|
||||||
this.peerNodeAddress = new NodeAddress("peer", 8080);
|
this.peerNodeAddress = new NodeAddress("peer", 8080);
|
||||||
|
@ -108,7 +106,7 @@ public class P2PDataStorageProcessGetDataResponse {
|
||||||
// XXXBUGXXX: We signal listeners w/ non ProcessOncePersistableNetworkPayloads
|
// XXXBUGXXX: We signal listeners w/ non ProcessOncePersistableNetworkPayloads
|
||||||
@Test
|
@Test
|
||||||
public void processGetDataResponse_newPNPUpdatesState() {
|
public void processGetDataResponse_newPNPUpdatesState() {
|
||||||
PersistableNetworkPayload persistableNetworkPayload = new PersistableNetworkPayloadStub(new byte[] { 1 });
|
PersistableNetworkPayload persistableNetworkPayload = new PersistableNetworkPayloadStub(new byte[]{1});
|
||||||
|
|
||||||
GetDataResponse getDataResponse = buildGetDataResponse(persistableNetworkPayload);
|
GetDataResponse getDataResponse = buildGetDataResponse(persistableNetworkPayload);
|
||||||
|
|
||||||
|
@ -134,7 +132,7 @@ public class P2PDataStorageProcessGetDataResponse {
|
||||||
// TESTCASE: GetDataResponse w/ existing PNP changes no state
|
// TESTCASE: GetDataResponse w/ existing PNP changes no state
|
||||||
@Test
|
@Test
|
||||||
public void processGetDataResponse_duplicatePNPDoesNothing() {
|
public void processGetDataResponse_duplicatePNPDoesNothing() {
|
||||||
PersistableNetworkPayload persistableNetworkPayload = new PersistableNetworkPayloadStub(new byte[] { 1 });
|
PersistableNetworkPayload persistableNetworkPayload = new PersistableNetworkPayloadStub(new byte[]{1});
|
||||||
this.testState.mockedStorage.addPersistableNetworkPayload(persistableNetworkPayload,
|
this.testState.mockedStorage.addPersistableNetworkPayload(persistableNetworkPayload,
|
||||||
this.peerNodeAddress, false);
|
this.peerNodeAddress, false);
|
||||||
|
|
||||||
|
@ -149,7 +147,7 @@ public class P2PDataStorageProcessGetDataResponse {
|
||||||
// TESTCASE: GetDataResponse w/ missing PNP is added with no broadcast or listener signal (ProcessOncePersistableNetworkPayload)
|
// TESTCASE: GetDataResponse w/ missing PNP is added with no broadcast or listener signal (ProcessOncePersistableNetworkPayload)
|
||||||
@Test
|
@Test
|
||||||
public void processGetDataResponse_newPNPUpdatesState_LazyProcessed() {
|
public void processGetDataResponse_newPNPUpdatesState_LazyProcessed() {
|
||||||
PersistableNetworkPayload persistableNetworkPayload = new LazyPersistableNetworkPayloadStub(new byte[] { 1 });
|
PersistableNetworkPayload persistableNetworkPayload = new LazyPersistableNetworkPayloadStub(new byte[]{1});
|
||||||
|
|
||||||
GetDataResponse getDataResponse = buildGetDataResponse(persistableNetworkPayload);
|
GetDataResponse getDataResponse = buildGetDataResponse(persistableNetworkPayload);
|
||||||
|
|
||||||
|
@ -162,7 +160,7 @@ public class P2PDataStorageProcessGetDataResponse {
|
||||||
// TESTCASE: GetDataResponse w/ existing PNP changes no state (ProcessOncePersistableNetworkPayload)
|
// TESTCASE: GetDataResponse w/ existing PNP changes no state (ProcessOncePersistableNetworkPayload)
|
||||||
@Test
|
@Test
|
||||||
public void processGetDataResponse_duplicatePNPDoesNothing_LazyProcessed() {
|
public void processGetDataResponse_duplicatePNPDoesNothing_LazyProcessed() {
|
||||||
PersistableNetworkPayload persistableNetworkPayload = new LazyPersistableNetworkPayloadStub(new byte[] { 1 });
|
PersistableNetworkPayload persistableNetworkPayload = new LazyPersistableNetworkPayloadStub(new byte[]{1});
|
||||||
this.testState.mockedStorage.addPersistableNetworkPayload(persistableNetworkPayload,
|
this.testState.mockedStorage.addPersistableNetworkPayload(persistableNetworkPayload,
|
||||||
this.peerNodeAddress, false);
|
this.peerNodeAddress, false);
|
||||||
|
|
||||||
|
@ -177,7 +175,7 @@ public class P2PDataStorageProcessGetDataResponse {
|
||||||
// TESTCASE: Second call to processGetDataResponse adds PNP for non-ProcessOncePersistableNetworkPayloads
|
// TESTCASE: Second call to processGetDataResponse adds PNP for non-ProcessOncePersistableNetworkPayloads
|
||||||
@Test
|
@Test
|
||||||
public void processGetDataResponse_secondProcessNewPNPUpdatesState() {
|
public void processGetDataResponse_secondProcessNewPNPUpdatesState() {
|
||||||
PersistableNetworkPayload addFromFirstProcess = new PersistableNetworkPayloadStub(new byte[] { 1 });
|
PersistableNetworkPayload addFromFirstProcess = new PersistableNetworkPayloadStub(new byte[]{1});
|
||||||
GetDataResponse getDataResponse = buildGetDataResponse(addFromFirstProcess);
|
GetDataResponse getDataResponse = buildGetDataResponse(addFromFirstProcess);
|
||||||
|
|
||||||
TestState.SavedTestState beforeState = this.testState.saveTestState(addFromFirstProcess);
|
TestState.SavedTestState beforeState = this.testState.saveTestState(addFromFirstProcess);
|
||||||
|
@ -185,7 +183,7 @@ public class P2PDataStorageProcessGetDataResponse {
|
||||||
this.testState.verifyPersistableAdd(
|
this.testState.verifyPersistableAdd(
|
||||||
beforeState, addFromFirstProcess, true, true, false);
|
beforeState, addFromFirstProcess, true, true, false);
|
||||||
|
|
||||||
PersistableNetworkPayload addFromSecondProcess = new PersistableNetworkPayloadStub(new byte[] { 2 });
|
PersistableNetworkPayload addFromSecondProcess = new PersistableNetworkPayloadStub(new byte[]{2});
|
||||||
getDataResponse = buildGetDataResponse(addFromSecondProcess);
|
getDataResponse = buildGetDataResponse(addFromSecondProcess);
|
||||||
beforeState = this.testState.saveTestState(addFromSecondProcess);
|
beforeState = this.testState.saveTestState(addFromSecondProcess);
|
||||||
this.testState.mockedStorage.processGetDataResponse(getDataResponse, this.peerNodeAddress);
|
this.testState.mockedStorage.processGetDataResponse(getDataResponse, this.peerNodeAddress);
|
||||||
|
@ -196,7 +194,7 @@ public class P2PDataStorageProcessGetDataResponse {
|
||||||
// TESTCASE: Second call to processGetDataResponse does not add any PNP (LazyProcessed)
|
// TESTCASE: Second call to processGetDataResponse does not add any PNP (LazyProcessed)
|
||||||
@Test
|
@Test
|
||||||
public void processGetDataResponse_secondProcessNoPNPUpdates_LazyProcessed() {
|
public void processGetDataResponse_secondProcessNoPNPUpdates_LazyProcessed() {
|
||||||
PersistableNetworkPayload addFromFirstProcess = new LazyPersistableNetworkPayloadStub(new byte[] { 1 });
|
PersistableNetworkPayload addFromFirstProcess = new LazyPersistableNetworkPayloadStub(new byte[]{1});
|
||||||
GetDataResponse getDataResponse = buildGetDataResponse(addFromFirstProcess);
|
GetDataResponse getDataResponse = buildGetDataResponse(addFromFirstProcess);
|
||||||
|
|
||||||
TestState.SavedTestState beforeState = this.testState.saveTestState(addFromFirstProcess);
|
TestState.SavedTestState beforeState = this.testState.saveTestState(addFromFirstProcess);
|
||||||
|
@ -204,7 +202,7 @@ public class P2PDataStorageProcessGetDataResponse {
|
||||||
this.testState.verifyPersistableAdd(
|
this.testState.verifyPersistableAdd(
|
||||||
beforeState, addFromFirstProcess, true, false, false);
|
beforeState, addFromFirstProcess, true, false, false);
|
||||||
|
|
||||||
PersistableNetworkPayload addFromSecondProcess = new LazyPersistableNetworkPayloadStub(new byte[] { 2 });
|
PersistableNetworkPayload addFromSecondProcess = new LazyPersistableNetworkPayloadStub(new byte[]{2});
|
||||||
getDataResponse = buildGetDataResponse(addFromSecondProcess);
|
getDataResponse = buildGetDataResponse(addFromSecondProcess);
|
||||||
beforeState = this.testState.saveTestState(addFromSecondProcess);
|
beforeState = this.testState.saveTestState(addFromSecondProcess);
|
||||||
this.testState.mockedStorage.processGetDataResponse(getDataResponse, this.peerNodeAddress);
|
this.testState.mockedStorage.processGetDataResponse(getDataResponse, this.peerNodeAddress);
|
||||||
|
|
|
@ -30,7 +30,6 @@ import haveno.network.p2p.storage.payload.ProtectedStorageEntry;
|
||||||
import haveno.network.p2p.storage.payload.ProtectedStoragePayload;
|
import haveno.network.p2p.storage.payload.ProtectedStoragePayload;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
|
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
@ -49,7 +48,6 @@ public class P2PDataStorageRequestDataTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
this.testState = new TestState();
|
this.testState = new TestState();
|
||||||
|
|
||||||
this.localNodeAddress = new NodeAddress("localhost", 8080);
|
this.localNodeAddress = new NodeAddress("localhost", 8080);
|
||||||
|
@ -115,8 +113,8 @@ public class P2PDataStorageRequestDataTest {
|
||||||
// correct GetDataRequestMessage with both sets of keys.
|
// correct GetDataRequestMessage with both sets of keys.
|
||||||
@Test
|
@Test
|
||||||
public void buildPreliminaryGetDataRequest_FilledP2PDataStore() throws NoSuchAlgorithmException {
|
public void buildPreliminaryGetDataRequest_FilledP2PDataStore() throws NoSuchAlgorithmException {
|
||||||
PersistableNetworkPayload toAdd1 = new PersistableNetworkPayloadStub(new byte[] { 1 });
|
PersistableNetworkPayload toAdd1 = new PersistableNetworkPayloadStub(new byte[]{1});
|
||||||
PersistableNetworkPayload toAdd2 = new PersistableNetworkPayloadStub(new byte[] { 2 });
|
PersistableNetworkPayload toAdd2 = new PersistableNetworkPayloadStub(new byte[]{2});
|
||||||
ProtectedStorageEntry toAdd3 = getProtectedStorageEntryForAdd();
|
ProtectedStorageEntry toAdd3 = getProtectedStorageEntryForAdd();
|
||||||
ProtectedStorageEntry toAdd4 = getProtectedStorageEntryForAdd();
|
ProtectedStorageEntry toAdd4 = getProtectedStorageEntryForAdd();
|
||||||
|
|
||||||
|
@ -143,8 +141,8 @@ public class P2PDataStorageRequestDataTest {
|
||||||
// correct GetDataRequestMessage with both sets of keys.
|
// correct GetDataRequestMessage with both sets of keys.
|
||||||
@Test
|
@Test
|
||||||
public void requestData_FilledP2PDataStore_GetUpdatedDataRequest() throws NoSuchAlgorithmException {
|
public void requestData_FilledP2PDataStore_GetUpdatedDataRequest() throws NoSuchAlgorithmException {
|
||||||
PersistableNetworkPayload toAdd1 = new PersistableNetworkPayloadStub(new byte[] { 1 });
|
PersistableNetworkPayload toAdd1 = new PersistableNetworkPayloadStub(new byte[]{1});
|
||||||
PersistableNetworkPayload toAdd2 = new PersistableNetworkPayloadStub(new byte[] { 2 });
|
PersistableNetworkPayload toAdd2 = new PersistableNetworkPayloadStub(new byte[]{2});
|
||||||
ProtectedStorageEntry toAdd3 = getProtectedStorageEntryForAdd();
|
ProtectedStorageEntry toAdd3 = getProtectedStorageEntryForAdd();
|
||||||
ProtectedStorageEntry toAdd4 = getProtectedStorageEntryForAdd();
|
ProtectedStorageEntry toAdd4 = getProtectedStorageEntryForAdd();
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class Statistics {
|
||||||
priceFeedService.setCurrencyCode("USD");
|
priceFeedService.setCurrencyCode("USD");
|
||||||
p2pService.addP2PServiceListener(new BootstrapListener() {
|
p2pService.addP2PServiceListener(new BootstrapListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUpdatedDataReceived() {
|
public void onDataReceived() {
|
||||||
// we need to have tor ready
|
// we need to have tor ready
|
||||||
log.info("onBootstrapComplete: we start requestPriceFeed");
|
log.info("onBootstrapComplete: we start requestPriceFeed");
|
||||||
priceFeedService.startRequestingPrices(price -> log.info("requestPriceFeed. price=" + price),
|
priceFeedService.startRequestingPrices(price -> log.info("requestPriceFeed. price=" + price),
|
||||||
|
|
Loading…
Reference in a new issue