From 36a371ef340ef1fe9f21f1ed4dd3087bd8cfbb5a Mon Sep 17 00:00:00 2001 From: KewbitXMR Date: Mon, 9 Jun 2025 20:11:17 +0700 Subject: [PATCH] bumped to 1.1.2 --- Makefile | 12 ++ .../main/java/haveno/bot/app/HavenoBot.java | 64 ++++++ .../java/haveno/bot/app/HavenoBotMain.java | 187 ++++++++++++++++++ bot/src/main/resources/logback.xml | 19 ++ build.gradle | 68 ++++++- .../java/haveno/core/alert/AlertManager.java | 22 +-- .../alert/PrivateNotificationManager.java | 21 +- .../haveno/core/filter/FilterManager.java | 10 +- .../arbitrator/ArbitratorManager.java | 28 +-- settings.gradle | 1 + 10 files changed, 370 insertions(+), 62 deletions(-) create mode 100644 bot/src/main/java/haveno/bot/app/HavenoBot.java create mode 100644 bot/src/main/java/haveno/bot/app/HavenoBotMain.java create mode 100644 bot/src/main/resources/logback.xml diff --git a/Makefile b/Makefile index 7bca61db..cf2866e0 100644 --- a/Makefile +++ b/Makefile @@ -595,3 +595,15 @@ user3-desktop-mainnet: --apiPort=1204 \ --useNativeXmrWallet=false \ --ignoreLocalXmrNode=false \ + +parner1-bot-stagenet: + ./haveno-bot$(APP_EXT) \ + --baseCurrencyNetwork=XMR_STAGENET \ + --useLocalhostForP2P=false \ + --useDevPrivilegeKeys=false \ + --nodePort=9999 \ + --appName=haveno-XMR_STAGENET_user3 \ + --apiPassword=apitest \ + --apiPort=1204 \ + --useNativeXmrWallet=false \ + --ignoreLocalXmrNode=false \ \ No newline at end of file diff --git a/bot/src/main/java/haveno/bot/app/HavenoBot.java b/bot/src/main/java/haveno/bot/app/HavenoBot.java new file mode 100644 index 00000000..c5098f99 --- /dev/null +++ b/bot/src/main/java/haveno/bot/app/HavenoBot.java @@ -0,0 +1,64 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + + /* + * This file is part of Haveno Multi-Platform by Kewbit. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package haveno.bot.app; + +import com.google.inject.Injector; +import haveno.core.app.misc.AppSetup; +import haveno.core.app.misc.AppSetupWithP2P; +import haveno.core.network.p2p.inventory.GetInventoryRequestHandler; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class HavenoBot { + @Setter + private Injector injector; + private AppSetup appSetup; + private GetInventoryRequestHandler getInventoryRequestHandler; + + public HavenoBot() { + } + + public void startApplication() { + appSetup = injector.getInstance(AppSetupWithP2P.class); + appSetup.start(); + + getInventoryRequestHandler = injector.getInstance(GetInventoryRequestHandler.class); + } + + public void shutDown() { + getInventoryRequestHandler.shutDown(); + } +} \ No newline at end of file diff --git a/bot/src/main/java/haveno/bot/app/HavenoBotMain.java b/bot/src/main/java/haveno/bot/app/HavenoBotMain.java new file mode 100644 index 00000000..60b9868f --- /dev/null +++ b/bot/src/main/java/haveno/bot/app/HavenoBotMain.java @@ -0,0 +1,187 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package haveno.bot.app; + +import haveno.common.UserThread; +import haveno.common.app.AppModule; +import haveno.common.handlers.ResultHandler; +import lombok.extern.slf4j.Slf4j; + +import haveno.common.Timer; +import haveno.common.config.BaseCurrencyNetwork; +import haveno.common.config.Config; +import haveno.core.app.TorSetup; +import haveno.core.app.misc.ExecutableForAppWithP2p; +import haveno.core.app.misc.ModuleForAppWithP2p; +import haveno.core.user.Cookie; +import haveno.core.user.CookieKey; +import haveno.core.user.User; +import haveno.network.p2p.P2PService; +import haveno.network.p2p.P2PServiceListener; +import haveno.network.p2p.peers.PeerManager; + +@Slf4j +public class HavenoBotMain extends ExecutableForAppWithP2p { + + private static final long CHECK_CONNECTION_LOSS_SEC = 30; + private static final String VERSION = "1.1.2"; + private HavenoBot bot; + private Timer checkConnectionLossTime; + + public HavenoBotMain() { + super("Haveno Bot", "haveno-bot", "haveno_bot", VERSION); + } + + public static void main(String[] args) { + System.out.println("HavenoBot.VERSION: " + VERSION); + new HavenoBotMain().execute(args); + } + + @Override + protected int doExecute() { + super.doExecute(); + + checkMemory(config, this); + + return keepRunning(); + } + + @Override + protected void addCapabilities() { + } + + @Override + protected void launchApplication() { + UserThread.execute(() -> { + try { + bot = new HavenoBot(); + UserThread.execute(this::onApplicationLaunched); + } catch (Exception e) { + log.error("Error launching haveno bot: {}\n", e.toString(), e); + } + }); + } + + @Override + protected void onApplicationLaunched() { + super.onApplicationLaunched(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // We continue with a series of synchronous execution tasks + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected AppModule getModule() { + return new ModuleForAppWithP2p(config); + } + + @Override + protected void applyInjector() { + super.applyInjector(); + + bot.setInjector(injector); + + } + + @Override + protected void startApplication() { + Cookie cookie = injector.getInstance(User.class).getCookie(); + cookie.getAsOptionalBoolean(CookieKey.CLEAN_TOR_DIR_AT_RESTART).ifPresent(wasCleanTorDirSet -> { + if (wasCleanTorDirSet) { + injector.getInstance(TorSetup.class).cleanupTorFiles(() -> { + log.info("Tor directory reset"); + cookie.remove(CookieKey.CLEAN_TOR_DIR_AT_RESTART); + }, log::error); + } + }); + + bot.startApplication(); + + injector.getInstance(P2PService.class).addP2PServiceListener(new P2PServiceListener() { + @Override + public void onDataReceived() { + // Do nothing + } + + @Override + public void onNoSeedNodeAvailable() { + // Do nothing + } + + @Override + public void onNoPeersAvailable() { + // Do nothing + } + + @Override + public void onUpdatedDataReceived() { + // Do nothing + } + + @Override + public void onTorNodeReady() { + // Do nothing + } + + @Override + public void onHiddenServicePublished() { + UserThread.runAfter(() -> setupConnectionLossCheck(), 60); + } + + @Override + public void onSetupFailed(Throwable throwable) { + // Do nothing + } + + @Override + public void onRequestCustomBridges() { + // Do nothing + } + }); + } + + private void setupConnectionLossCheck() { + // For dev testing (usually on XMR_LOCAL) we don't want to get the seed shut + // down as it is normal that the seed is the only actively running node. + if (Config.baseCurrencyNetwork() != BaseCurrencyNetwork.XMR_MAINNET) { + return; + } + + if (checkConnectionLossTime != null) { + return; + } + + checkConnectionLossTime = UserThread.runPeriodically(() -> { + if (injector.getInstance(PeerManager.class).getNumAllConnectionsLostEvents() > 1) { + // We set a flag to clear tor cache files at re-start. We cannot clear it now as Tor is used and + // that can cause problems. + injector.getInstance(User.class).getCookie().putAsBoolean(CookieKey.CLEAN_TOR_DIR_AT_RESTART, true); + shutDown(this); + } + }, CHECK_CONNECTION_LOSS_SEC); + + } + + @Override + public void gracefulShutDown(ResultHandler resultHandler) { + bot.shutDown(); + super.gracefulShutDown(resultHandler); + } +} diff --git a/bot/src/main/resources/logback.xml b/bot/src/main/resources/logback.xml new file mode 100644 index 00000000..f838048e --- /dev/null +++ b/bot/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + + + + %hl2(%d{MMM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{40}: %msg %xEx%n) + + + + + + + + + + + diff --git a/build.gradle b/build.gradle index 295ccc3d..0f4e82ac 100644 --- a/build.gradle +++ b/build.gradle @@ -132,7 +132,8 @@ configure([project(':cli'), project(':seednode'), project(':statsnode'), project(':inventory'), - project(':apitest')]) { + project(':apitest'), + project(':bot')]) { apply plugin: 'application' @@ -735,6 +736,71 @@ configure(project(':daemon')) { } } +configure(project(':bot')) { + apply plugin: 'com.github.johnrengelman.shadow' + apply plugin: 'application' + + application { + mainClass = 'haveno.bot.app.HavenoBotMain' + } + + dependencies { + implementation project(':proto') + implementation project(':common') + implementation project(':p2p') + implementation project(':core') + annotationProcessor "org.projectlombok:lombok:$lombokVersion" + compileOnly "javax.annotation:javax.annotation-api:$javaxAnnotationVersion" + compileOnly "org.projectlombok:lombok:$lombokVersion" + implementation "ch.qos.logback:logback-classic:$logbackVersion" + implementation "ch.qos.logback:logback-core:$logbackVersion" + implementation "com.google.code.gson:gson:$gsonVersion" + implementation "com.google.guava:guava:$guavaVersion" + implementation "com.google.protobuf:protobuf-java:$protobufVersion" + implementation "org.apache.commons:commons-lang3:$langVersion" + implementation "org.jetbrains:annotations:$jetbrainsAnnotationsVersion" + implementation "org.slf4j:slf4j-api:$slf4jVersion" + implementation("com.github.bisq-network:bitcoinj:$bitcoinjVersion") { + exclude(module: 'bcprov-jdk15on') + exclude(module: 'guava') + exclude(module: 'jsr305') + exclude(module: 'okhttp') + exclude(module: 'okio') + exclude(module: 'protobuf-java') + exclude(module: 'slf4j-api') + } + implementation("com.google.inject:guice:$guiceVersion") { + exclude(module: 'guava') + } + implementation("io.grpc:grpc-protobuf:$grpcVersion") { + exclude(module: 'animal-sniffer-annotations') + exclude(module: 'guava') + } + implementation("io.grpc:grpc-stub:$grpcVersion") { + exclude(module: 'animal-sniffer-annotations') + exclude(module: 'guava') + } + runtimeOnly("io.grpc:grpc-netty-shaded:$grpcVersion") { + exclude(module: 'animal-sniffer-annotations') + exclude(module: 'guava') + } + testAnnotationProcessor "org.projectlombok:lombok:$lombokVersion" + testCompileOnly "org.projectlombok:lombok:$lombokVersion" + testImplementation "org.junit.jupiter:junit-jupiter-api:$jupiterVersion" + testImplementation "org.junit.jupiter:junit-jupiter-params:$jupiterVersion" + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$jupiterVersion") + + implementation("io.github.woodser:monero-java:$moneroJavaVersion") { + exclude(module: 'jackson-core') + exclude(module: 'jackson-annotations') + exclude(module: 'jackson-databind') + exclude(module: 'bcprov-jdk15on') + exclude(group: 'org.slf4j', module: 'slf4j-simple') + } + implementation "org.openjfx:javafx-base:$javafxVersion:$os" + implementation "org.openjfx:javafx-graphics:$javafxVersion:$os" + } +} configure(project(':inventory')) { apply plugin: 'com.github.johnrengelman.shadow' diff --git a/core/src/main/java/haveno/core/alert/AlertManager.java b/core/src/main/java/haveno/core/alert/AlertManager.java index a54f45c4..cf60e545 100644 --- a/core/src/main/java/haveno/core/alert/AlertManager.java +++ b/core/src/main/java/haveno/core/alert/AlertManager.java @@ -97,25 +97,13 @@ public class AlertManager { } protected List getPubKeyList() { - if (useDevPrivilegeKeys) return List.of(DevEnv.DEV_PRIVILEGE_PUB_KEY); - switch (Config.baseCurrencyNetwork()) { - case XMR_LOCAL: - return List.of( - "027a381b5333a56e1cc3d90d3a7d07f26509adf7029ed06fc997c656621f8da1ee", - "024baabdba90e7cc0dc4626ef73ea9d722ea7085d1104491da8c76f28187513492"); - case XMR_STAGENET: - return List.of( - "036d8a1dfcb406886037d2381da006358722823e1940acc2598c844bbc0fd1026f", - "026c581ad773d987e6bd10785ac7f7e0e64864aedeb8bce5af37046de812a37854", - "025b058c9f2c60d839669dbfa5578cf5a8117d60e6b70e2f0946f8a691273c6a36"); - case XMR_MAINNET: - return List.of(); - default: - throw new RuntimeException("Unhandled base currency network: " + Config.baseCurrencyNetwork()); - } + return List.of( + "0326b14f3a55d02575dceed5202b8b125f458cbe0fdceeee294b443bf1a8d8cf78", + "03d62d14438adbe7aea688ade1f73933c6f0a705f238c02c5b54b83dd1e4fca225", + "023c8fdea9ff2d03daef54337907e70a7b0e20084a75fcc3ad2f0c28d8b691dea1" + ); } - /////////////////////////////////////////////////////////////////////////////////////////// // API /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/core/src/main/java/haveno/core/alert/PrivateNotificationManager.java b/core/src/main/java/haveno/core/alert/PrivateNotificationManager.java index fd6abac5..5aa84c86 100644 --- a/core/src/main/java/haveno/core/alert/PrivateNotificationManager.java +++ b/core/src/main/java/haveno/core/alert/PrivateNotificationManager.java @@ -96,22 +96,11 @@ public class PrivateNotificationManager implements MessageListener { } protected List getPubKeyList() { - if (useDevPrivilegeKeys) return List.of(DevEnv.DEV_PRIVILEGE_PUB_KEY); - switch (Config.baseCurrencyNetwork()) { - case XMR_LOCAL: - return List.of( - "027a381b5333a56e1cc3d90d3a7d07f26509adf7029ed06fc997c656621f8da1ee", - "024baabdba90e7cc0dc4626ef73ea9d722ea7085d1104491da8c76f28187513492"); - case XMR_STAGENET: - return List.of( - "02ba7c5de295adfe57b60029f3637a2c6b1d0e969a8aaefb9e0ddc3a7963f26925", - "026c581ad773d987e6bd10785ac7f7e0e64864aedeb8bce5af37046de812a37854", - "025b058c9f2c60d839669dbfa5578cf5a8117d60e6b70e2f0946f8a691273c6a36"); - case XMR_MAINNET: - return List.of(); - default: - throw new RuntimeException("Unhandled base currency network: " + Config.baseCurrencyNetwork()); - } + return List.of( + "0326b14f3a55d02575dceed5202b8b125f458cbe0fdceeee294b443bf1a8d8cf78", + "03d62d14438adbe7aea688ade1f73933c6f0a705f238c02c5b54b83dd1e4fca225", + "023c8fdea9ff2d03daef54337907e70a7b0e20084a75fcc3ad2f0c28d8b691dea1" + ); } private void handleMessage(DecryptedMessageWithPubKey decryptedMessageWithPubKey, NodeAddress senderNodeAddress) { diff --git a/core/src/main/java/haveno/core/filter/FilterManager.java b/core/src/main/java/haveno/core/filter/FilterManager.java index 2cebb66f..37f8eca9 100644 --- a/core/src/main/java/haveno/core/filter/FilterManager.java +++ b/core/src/main/java/haveno/core/filter/FilterManager.java @@ -114,11 +114,11 @@ public class FilterManager { this.providersRepository = providersRepository; this.ignoreDevMsg = ignoreDevMsg; - publicKeys = useDevPrivilegeKeys ? - Collections.singletonList(DevEnv.DEV_PRIVILEGE_PUB_KEY) : - List.of("0358d47858acdc41910325fce266571540681ef83a0d6fedce312bef9810793a27", - "029340c3e7d4bb0f9e651b5f590b434fecb6175aeaa57145c7804ff05d210e534f", - "034dc7530bf66ffd9580aa98031ea9a18ac2d269f7c56c0e71eca06105b9ed69f9"); + publicKeys = List.of( + "0326b14f3a55d02575dceed5202b8b125f458cbe0fdceeee294b443bf1a8d8cf78", + "03d62d14438adbe7aea688ade1f73933c6f0a705f238c02c5b54b83dd1e4fca225", + "023c8fdea9ff2d03daef54337907e70a7b0e20084a75fcc3ad2f0c28d8b691dea1" + ); banFilter.setBannedNodePredicate(this::isNodeAddressBannedFromNetwork); } diff --git a/core/src/main/java/haveno/core/support/dispute/arbitration/arbitrator/ArbitratorManager.java b/core/src/main/java/haveno/core/support/dispute/arbitration/arbitrator/ArbitratorManager.java index 30fe0be1..781ae7a4 100644 --- a/core/src/main/java/haveno/core/support/dispute/arbitration/arbitrator/ArbitratorManager.java +++ b/core/src/main/java/haveno/core/support/dispute/arbitration/arbitrator/ArbitratorManager.java @@ -59,29 +59,11 @@ public class ArbitratorManager extends DisputeAgentManager { @Override protected List getPubKeyList() { - switch (Config.baseCurrencyNetwork()) { - case XMR_LOCAL: - return List.of( - "027a381b5333a56e1cc3d90d3a7d07f26509adf7029ed06fc997c656621f8da1ee", - "024baabdba90e7cc0dc4626ef73ea9d722ea7085d1104491da8c76f28187513492", - "026eeec3c119dd6d537249d74e5752a642dd2c3cc5b6a9b44588eb58344f29b519"); - case XMR_STAGENET: - return List.of( - "03bb559ce207a4deb51d4c705076c95b85ad8581d35936b2a422dcb504eaf7cdb0", - "026c581ad773d987e6bd10785ac7f7e0e64864aedeb8bce5af37046de812a37854", - "025b058c9f2c60d839669dbfa5578cf5a8117d60e6b70e2f0946f8a691273c6a36", - "036c7d3f4bf05ef39b9d1b0a5d453a18210de36220c3d83cd16e59bd6132b037ad", - "030f7122a10ff73cd73808bddace95be77a94189c8a0eb24586265e125ce5ce6b9", - "03aa23e062afa0dda465f46986f8aa8d0374ad3e3f256141b05681dcb1e39c3859", - "02d3beb1293ca2ca14e6d42ca8bd18089a62aac62fd6bb23923ee6ead46ac60fba", - "03fa0f38f27bdd324db6f933f7e57851dadf3b911e4db6b19dd0950492c4525a31", - "02a1a458df5acf4ab08fdca748e28f33a955a30854c8c1a831ee733dca7f0d2fcd", - "0374dd70f3fa6e47ec5ab97932e1cec6233e98e6ae3129036b17118650c44fd3de"); - case XMR_MAINNET: - return List.of(); - default: - throw new RuntimeException("Unhandled base currency network: " + Config.baseCurrencyNetwork()); - } + return List.of( + "0326b14f3a55d02575dceed5202b8b125f458cbe0fdceeee294b443bf1a8d8cf78", + "03d62d14438adbe7aea688ade1f73933c6f0a705f238c02c5b54b83dd1e4fca225", + "023c8fdea9ff2d03daef54337907e70a7b0e20084a75fcc3ad2f0c28d8b691dea1" + ); } @Override diff --git a/settings.gradle b/settings.gradle index 2d96ad24..1f9f7a9f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -12,5 +12,6 @@ include 'seednode' include 'statsnode' include 'inventory' include 'apitest' +include 'bot' rootProject.name = 'haveno'