bumped to 1.1.2

This commit is contained in:
Kewbit 2025-06-09 20:11:17 +07:00
parent 13b201b020
commit 36a371ef34
10 changed files with 370 additions and 62 deletions

View file

@ -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 \

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
/*
* 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 <http://www.gnu.org/licenses/>.
*/
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();
}
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<conversionRule conversionWord="hl2" converterClass="haveno.common.app.LogHighlighter" />
<appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%hl2(%d{MMM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{40}: %msg %xEx%n)</pattern>
</encoder>
</appender>
<root level="TRACE">
<appender-ref ref="CONSOLE_APPENDER"/>
</root>
<logger name="io.grpc.netty" level="WARN"/>
<logger name="org.apache" level="WARN" />
</configuration>

View file

@ -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'

View file

@ -97,25 +97,13 @@ public class AlertManager {
}
protected List<String> 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
///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -96,22 +96,11 @@ public class PrivateNotificationManager implements MessageListener {
}
protected List<String> 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) {

View file

@ -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);
}

View file

@ -59,29 +59,11 @@ public class ArbitratorManager extends DisputeAgentManager<Arbitrator> {
@Override
protected List<String> 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

View file

@ -12,5 +12,6 @@ include 'seednode'
include 'statsnode'
include 'inventory'
include 'apitest'
include 'bot'
rootProject.name = 'haveno'