Compare commits
9 Commits
mainnet_pl
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
5c36b00d07 | ||
|
9c0af85ed8 | ||
|
216260da85 | ||
|
4a57b26469 | ||
|
8d7bb250c5 | ||
|
82eb081089 | ||
|
697828d773 | ||
|
5ad099a33c | ||
|
77d3879013 |
@ -17,19 +17,20 @@
|
||||
|
||||
package haveno.asset.coins;
|
||||
|
||||
import haveno.asset.Base58AddressValidator;
|
||||
import haveno.asset.BitcoinAddressValidator;
|
||||
import haveno.asset.Coin;
|
||||
import haveno.asset.NetworkParametersAdapter;
|
||||
|
||||
public class Litecoin extends Coin {
|
||||
public Litecoin() {
|
||||
super("Litecoin", "LTC", new Base58AddressValidator(new LitecoinMainNetParams()), Network.MAINNET);
|
||||
super("Litecoin", "LTC", new BitcoinAddressValidator(new LitecoinMainNetParams()), Network.MAINNET);
|
||||
}
|
||||
|
||||
public static class LitecoinMainNetParams extends NetworkParametersAdapter {
|
||||
public LitecoinMainNetParams() {
|
||||
this.addressHeader = 48;
|
||||
this.p2shHeader = 5;
|
||||
this.p2shHeader = 50;
|
||||
this.segwitAddressHrp = "ltc";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -31,6 +31,17 @@ public class LitecoinTest extends AbstractAssetTest {
|
||||
assertValidAddress("Lg3PX8wRWmApFCoCMAsPF5P9dPHYQHEWKW");
|
||||
assertValidAddress("LTuoeY6RBHV3n3cfhXVVTbJbxzxnXs9ofm");
|
||||
assertValidAddress("LgfapHEPhZbRF9pMd5WPT35hFXcZS1USrW");
|
||||
assertValidAddress("M8T1B2Z97gVdvmfkQcAtYbEepune1tzGua");
|
||||
assertValidAddress("ltc1qr07zu594qf63xm7l7x6pu3a2v39m2z6hh5pp4t");
|
||||
assertValidAddress("ltc1qzvcgmntglcuv4smv3lzj6k8szcvsrmvk0phrr9wfq8w493r096ssm2fgsw");
|
||||
assertValidAddress("MESruSiB2uC9i7tMU6VMUVom91ohM7Rnbd");
|
||||
assertValidAddress("ltc1q2a0laq2jg2gntzhfs43qptajd325kkx7hrq9cs");
|
||||
assertValidAddress("ltc1qd6d54mt8xxcg0xg3l0vh6fymdfvd2tv0vnwyrv");
|
||||
assertValidAddress("ltc1gmay6ht028aurcm680f8e8wxdup07y2tq46f6z2d4v8rutewqmmcqk29jtm");
|
||||
assertValidAddress("MTf4tP1TCNBn8dNkyxeBVoPrFCcVzxJvvh");
|
||||
assertValidAddress("LaRoRBC6utQtY3U2FbHwhmhhDPyxodDeKA");
|
||||
assertValidAddress("MDMFP9Dx84tyaxiYksjvkG1jymBdqCuHGA");
|
||||
//assertValidAddress("3MSvaVbVFFLML86rt5eqgA9SvW23upaXdY"); // deprecated
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -38,5 +49,14 @@ public class LitecoinTest extends AbstractAssetTest {
|
||||
assertInvalidAddress("1LgfapHEPhZbRF9pMd5WPT35hFXcZS1USrW");
|
||||
assertInvalidAddress("LgfapHEPhZbdRF9pMd5WPT35hFXcZS1USrW");
|
||||
assertInvalidAddress("LgfapHEPhZbRF9pMd5WPT35hFXcZS1USrW#");
|
||||
assertInvalidAddress("3MSvaVbVFFLML86rt5eqgl9SvW23upaXdY"); // contains lowercase l
|
||||
assertInvalidAddress("LURw7hYhREXjWHyiXhQNsKInWtPezwNe98"); // contains uppercase I
|
||||
assertInvalidAddress("LM4ch8ZtAowdiGLSnf92MrMOC9dVmve2hr"); // contains uppercase O
|
||||
assertInvalidAddress("MArsfeyS7P0HzsqLpAFGC9pFdhuqHgdL2R"); // contains number 0
|
||||
assertInvalidAddress("ltc1qr6quwn3v2gxpadd0cu040r9385gayk5vdcyl5"); // too short
|
||||
assertInvalidAddress("ltc1q5det08ke2gpet06wczcdfs2v3hgfqllxw28uln8vxxx82qlue6uswceljma"); // too long
|
||||
assertInvalidAddress("MADpfTtabZ6pDjms4pMd3ZmnrgyhTCo4N8?time=1708476729&exp=86400"); // additional information
|
||||
assertInvalidAddress("ltc1q8tk47lvgqu55h4pfast39r3t9360gmll5z9m6z?time=1708476604&exp=600"); // additional information
|
||||
assertInvalidAddress("ltc1q026xyextkwhmveh7rpf6v6mp5p88vwc25aynxr?time=1708476626"); // additional information
|
||||
}
|
||||
}
|
||||
|
19
build.gradle
19
build.gradle
@ -49,7 +49,7 @@ configure(subprojects) {
|
||||
gsonVersion = '2.8.5'
|
||||
guavaVersion = '32.1.1-jre'
|
||||
guiceVersion = '7.0.0'
|
||||
moneroJavaVersion = '0.8.10'
|
||||
moneroJavaVersion = '0.8.11'
|
||||
httpclient5Version = '5.0'
|
||||
hamcrestVersion = '2.2'
|
||||
httpclientVersion = '4.5.12'
|
||||
@ -436,16 +436,21 @@ configure(project(':core')) {
|
||||
systemProperty 'jdk.attach.allowAttachSelf', true
|
||||
}
|
||||
|
||||
task generateKeypairs(type: JavaExec) {
|
||||
mainClass = 'haveno.core.util.GenerateKeyPairs'
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
}
|
||||
|
||||
task havenoDeps {
|
||||
doLast {
|
||||
// get monero binaries download url
|
||||
Map moneroBinaries = [
|
||||
'linux' : 'https://github.com/haveno-dex/monero/releases/download/release1/monero-bins-haveno-linux.tar.gz',
|
||||
'linux-sha256' : '4020274ef546410f218c3c3a3c2a8c2c2cda3f653f8cc6fe8e3cd74334500489',
|
||||
'mac' : 'https://github.com/haveno-dex/monero/releases/download/release1/monero-bins-haveno-mac.tar.gz',
|
||||
'mac-sha256' : '72514caac499c4900c5cb6e957e5e3aaabba48968ae798c419f4559a51e5fc79',
|
||||
'windows' : 'https://github.com/haveno-dex/monero/releases/download/release1/monero-bins-haveno-windows.zip',
|
||||
'windows-sha256': '27d8315d5da876e57fd12ed1c1d60a622763de99f0cc2521ce7f31c7fa4ab0ee'
|
||||
'linux' : 'https://github.com/haveno-dex/monero/releases/download/release2/monero-bins-haveno-linux.tar.gz',
|
||||
'linux-sha256' : '3537fe2006997a1065748d27e9513ac3e0c942ab56a97a6e43065ddfd1820394',
|
||||
'mac' : 'https://github.com/haveno-dex/monero/releases/download/release2/monero-bins-haveno-mac.tar.gz',
|
||||
'mac-sha256' : 'c7cafe1000a5839f02d02ed2edce5b1df3a06b5c77f4d91eaba106d948347730',
|
||||
'windows' : 'https://github.com/haveno-dex/monero/releases/download/release2/monero-bins-haveno-windows.zip',
|
||||
'windows-sha256': '9b900faefa75f354870646989484978d1fb11add392ffd05eb5abe7e514e395a'
|
||||
]
|
||||
|
||||
String osKey
|
||||
|
@ -22,7 +22,6 @@ import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
@ -41,10 +40,10 @@ public class ThreadUtils {
|
||||
* @param command the command to execute
|
||||
* @param threadId the thread id
|
||||
*/
|
||||
public static void execute(Runnable command, String threadId) {
|
||||
public static Future<?> execute(Runnable command, String threadId) {
|
||||
synchronized (EXECUTORS) {
|
||||
if (!EXECUTORS.containsKey(threadId)) EXECUTORS.put(threadId, Executors.newFixedThreadPool(1));
|
||||
EXECUTORS.get(threadId).execute(() -> {
|
||||
return EXECUTORS.get(threadId).submit(() -> {
|
||||
synchronized (THREADS) {
|
||||
THREADS.put(threadId, Thread.currentThread());
|
||||
}
|
||||
@ -60,24 +59,10 @@ public class ThreadUtils {
|
||||
* @param threadId the thread id
|
||||
*/
|
||||
public static void await(Runnable command, String threadId) {
|
||||
if (isCurrentThread(Thread.currentThread(), threadId)) {
|
||||
command.run();
|
||||
} else {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
execute(() -> {
|
||||
try {
|
||||
command.run();
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
} finally {
|
||||
latch.countDown();
|
||||
}
|
||||
}, threadId);
|
||||
try {
|
||||
latch.await();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
try {
|
||||
execute(command, threadId).get();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,16 +19,6 @@ package haveno.common.crypto;
|
||||
|
||||
import haveno.common.util.Hex;
|
||||
import haveno.common.util.Utilities;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.OAEPParameterSpec;
|
||||
import javax.crypto.spec.PSource;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidKeyException;
|
||||
@ -43,10 +33,17 @@ import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.MGF1ParameterSpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.OAEPParameterSpec;
|
||||
import javax.crypto.spec.PSource;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class Encryption {
|
||||
private static final Logger log = LoggerFactory.getLogger(Encryption.class);
|
||||
|
||||
public static final String ASYM_KEY_ALGO = "RSA";
|
||||
private static final String ASYM_CIPHER = "RSA/ECB/OAEPWithSHA-256AndMGF1PADDING";
|
||||
|
||||
|
@ -95,7 +95,7 @@ public class AlertManager {
|
||||
}
|
||||
pubKeyAsHex = useDevPrivilegeKeys ?
|
||||
DevEnv.DEV_PRIVILEGE_PUB_KEY :
|
||||
"036d8a1dfcb406886037d2381da006358722823e1940acc2598c844bbc0fd1026f"; // TODO: replace with mainnet pub key for alerts
|
||||
"036d8a1dfcb406886037d2381da006358722823e1940acc2598c844bbc0fd1026f";
|
||||
}
|
||||
|
||||
|
||||
|
@ -95,7 +95,7 @@ public class PrivateNotificationManager implements MessageListener {
|
||||
}
|
||||
pubKeyAsHex = useDevPrivilegeKeys ?
|
||||
DevEnv.DEV_PRIVILEGE_PUB_KEY :
|
||||
"02ba7c5de295adfe57b60029f3637a2c6b1d0e969a8aaefb9e0ddc3a7963f26925"; // TODO: replace with mainnet dev pub key for private messages
|
||||
"02ba7c5de295adfe57b60029f3637a2c6b1d0e969a8aaefb9e0ddc3a7963f26925";
|
||||
}
|
||||
|
||||
private void handleMessage(DecryptedMessageWithPubKey decryptedMessageWithPubKey, NodeAddress senderNodeAddress) {
|
||||
|
@ -458,8 +458,8 @@ public class CoreApi {
|
||||
paymentAccount);
|
||||
}
|
||||
|
||||
public void cancelOffer(String id) {
|
||||
coreOffersService.cancelOffer(id);
|
||||
public void cancelOffer(String id, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
|
||||
coreOffersService.cancelOffer(id, resultHandler, errorMessageHandler);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -38,6 +38,7 @@ import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import haveno.common.crypto.KeyRing;
|
||||
import haveno.common.handlers.ErrorMessageHandler;
|
||||
import haveno.common.handlers.ResultHandler;
|
||||
import static haveno.common.util.MathUtils.exactMultiply;
|
||||
import static haveno.common.util.MathUtils.roundDoubleToLong;
|
||||
import static haveno.common.util.MathUtils.scaleUpByPowerOf10;
|
||||
@ -236,14 +237,9 @@ public class CoreOffersService {
|
||||
paymentAccount);
|
||||
}
|
||||
|
||||
void cancelOffer(String id) {
|
||||
void cancelOffer(String id, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
|
||||
Offer offer = getMyOffer(id).getOffer();
|
||||
openOfferManager.removeOffer(offer,
|
||||
() -> {
|
||||
},
|
||||
errorMessage -> {
|
||||
throw new IllegalStateException(errorMessage);
|
||||
});
|
||||
openOfferManager.removeOffer(offer, resultHandler, errorMessageHandler);
|
||||
}
|
||||
|
||||
// -------------------------- PRIVATE HELPERS -----------------------------
|
||||
|
@ -133,7 +133,6 @@ class CoreWalletsService {
|
||||
verifyWalletCurrencyCodeIsValid(currencyCode);
|
||||
verifyWalletsAreAvailable();
|
||||
verifyEncryptedWalletIsUnlocked();
|
||||
if (balances.getAvailableBalance().get() == null) throw new IllegalStateException("balance is not yet available");
|
||||
|
||||
switch (currencyCode.trim().toUpperCase()) {
|
||||
case "":
|
||||
@ -418,28 +417,8 @@ class CoreWalletsService {
|
||||
private XmrBalanceInfo getXmrBalances() {
|
||||
verifyWalletsAreAvailable();
|
||||
verifyEncryptedWalletIsUnlocked();
|
||||
|
||||
var availableBalance = balances.getAvailableBalance().get();
|
||||
if (availableBalance == null)
|
||||
throw new IllegalStateException("available balance is not yet available");
|
||||
|
||||
var pendingBalance = balances.getPendingBalance().get();
|
||||
if (pendingBalance == null)
|
||||
throw new IllegalStateException("locked balance is not yet available");
|
||||
|
||||
var reservedOfferBalance = balances.getReservedOfferBalance().get();
|
||||
if (reservedOfferBalance == null)
|
||||
throw new IllegalStateException("reserved offer balance is not yet available");
|
||||
|
||||
var reservedTradeBalance = balances.getReservedTradeBalance().get();
|
||||
if (reservedTradeBalance == null)
|
||||
throw new IllegalStateException("reserved trade balance is not yet available");
|
||||
|
||||
return new XmrBalanceInfo(availableBalance.longValue() + pendingBalance.longValue(),
|
||||
availableBalance.longValue(),
|
||||
pendingBalance.longValue(),
|
||||
reservedOfferBalance.longValue(),
|
||||
reservedTradeBalance.longValue());
|
||||
if (balances.getAvailableBalance() == null) throw new IllegalStateException("Balances are not yet available");
|
||||
return balances.getBalances();
|
||||
}
|
||||
|
||||
// Returns a Coin for the transfer amount string, or a RuntimeException if invalid.
|
||||
|
@ -1,10 +1,10 @@
|
||||
package haveno.core.api.model;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import haveno.common.Payload;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class XmrBalanceInfo implements Payload {
|
||||
|
||||
public static final XmrBalanceInfo EMPTY = new XmrBalanceInfo(-1,
|
||||
@ -19,17 +19,19 @@ public class XmrBalanceInfo implements Payload {
|
||||
private final long pendingBalance;
|
||||
private final long reservedOfferBalance;
|
||||
private final long reservedTradeBalance;
|
||||
private final long reservedBalance;
|
||||
|
||||
public XmrBalanceInfo(long balance,
|
||||
long unlockedBalance,
|
||||
long lockedBalance,
|
||||
long pendingBalance,
|
||||
long reservedOfferBalance,
|
||||
long reservedTradeBalance) {
|
||||
this.balance = balance;
|
||||
this.availableBalance = unlockedBalance;
|
||||
this.pendingBalance = lockedBalance;
|
||||
this.pendingBalance = pendingBalance;
|
||||
this.reservedOfferBalance = reservedOfferBalance;
|
||||
this.reservedTradeBalance = reservedTradeBalance;
|
||||
this.reservedBalance = reservedOfferBalance + reservedTradeBalance;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@ -45,6 +47,30 @@ public class XmrBalanceInfo implements Payload {
|
||||
reservedTradeBalance);
|
||||
}
|
||||
|
||||
public BigInteger getBalance() {
|
||||
return BigInteger.valueOf(balance);
|
||||
}
|
||||
|
||||
public BigInteger getAvailableBalance() {
|
||||
return BigInteger.valueOf(availableBalance);
|
||||
}
|
||||
|
||||
public BigInteger getPendingBalance() {
|
||||
return BigInteger.valueOf(pendingBalance);
|
||||
}
|
||||
|
||||
public BigInteger getReservedOfferBalance() {
|
||||
return BigInteger.valueOf(reservedOfferBalance);
|
||||
}
|
||||
|
||||
public BigInteger getReservedTradeBalance() {
|
||||
return BigInteger.valueOf(reservedTradeBalance);
|
||||
}
|
||||
|
||||
public BigInteger getReservedBalance() {
|
||||
return BigInteger.valueOf(reservedBalance);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PROTO BUFFER
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -116,7 +116,7 @@ public class FilterManager {
|
||||
|
||||
publicKeys = useDevPrivilegeKeys ?
|
||||
Collections.singletonList(DevEnv.DEV_PRIVILEGE_PUB_KEY) :
|
||||
List.of("0358d47858acdc41910325fce266571540681ef83a0d6fedce312bef9810793a27", // TODO: replace with mainnet dev pub keys
|
||||
List.of("0358d47858acdc41910325fce266571540681ef83a0d6fedce312bef9810793a27",
|
||||
"029340c3e7d4bb0f9e651b5f590b434fecb6175aeaa57145c7804ff05d210e534f",
|
||||
"034dc7530bf66ffd9580aa98031ea9a18ac2d269f7c56c0e71eca06105b9ed69f9");
|
||||
|
||||
|
@ -620,9 +620,13 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||
if (!offersToBeEdited.containsKey(openOffer.getId())) {
|
||||
if (openOffer.isDeactivated()) {
|
||||
onCancelled(openOffer);
|
||||
resultHandler.handleResult();
|
||||
} else {
|
||||
offerBookService.removeOffer(openOffer.getOffer().getOfferPayload(),
|
||||
() -> onCancelled(openOffer),
|
||||
() -> {
|
||||
onCancelled(openOffer);
|
||||
resultHandler.handleResult();
|
||||
},
|
||||
errorMessageHandler);
|
||||
}
|
||||
} else {
|
||||
|
@ -19,6 +19,7 @@ package haveno.core.presentation;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import haveno.common.UserThread;
|
||||
import haveno.core.api.model.XmrBalanceInfo;
|
||||
import haveno.core.trade.HavenoUtils;
|
||||
import haveno.core.xmr.Balances;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
@ -38,14 +39,13 @@ public class BalancePresentation {
|
||||
|
||||
@Inject
|
||||
public BalancePresentation(Balances balances) {
|
||||
balances.getAvailableBalance().addListener((observable, oldValue, newValue) -> {
|
||||
UserThread.execute(() -> availableBalance.set(HavenoUtils.formatXmr(newValue, true)));
|
||||
});
|
||||
balances.getPendingBalance().addListener((observable, oldValue, newValue) -> {
|
||||
UserThread.execute(() -> pendingBalance.set(HavenoUtils.formatXmr(newValue, true)));
|
||||
});
|
||||
balances.getReservedBalance().addListener((observable, oldValue, newValue) -> {
|
||||
UserThread.execute(() -> reservedBalance.set(HavenoUtils.formatXmr(newValue, true)));
|
||||
balances.getUpdateCounter().addListener((observable, oldValue, newValue) -> {
|
||||
XmrBalanceInfo info = balances.getBalances();
|
||||
UserThread.execute(() -> {
|
||||
availableBalance.set(HavenoUtils.formatXmr(info.getAvailableBalance(), true));
|
||||
pendingBalance.set(HavenoUtils.formatXmr(info.getPendingBalance(), true));
|
||||
reservedBalance.set(HavenoUtils.formatXmr(info.getReservedBalance(), true));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ public class ArbitratorManager extends DisputeAgentManager<Arbitrator> {
|
||||
"02a1a458df5acf4ab08fdca748e28f33a955a30854c8c1a831ee733dca7f0d2fcd",
|
||||
"0374dd70f3fa6e47ec5ab97932e1cec6233e98e6ae3129036b17118650c44fd3de");
|
||||
case XMR_MAINNET:
|
||||
return new ArrayList<String>(); // TODO: add mainnet arbitrator pubkeys
|
||||
return new ArrayList<String>();
|
||||
default:
|
||||
throw new RuntimeException("Unhandled base currency network: " + Config.baseCurrencyNetwork());
|
||||
}
|
||||
|
@ -63,7 +63,6 @@ import org.bitcoinj.core.Coin;
|
||||
public class HavenoUtils {
|
||||
|
||||
// configurable
|
||||
// TODO: adjust for mainnet release
|
||||
private static final String RELEASE_DATE = "01-03-2024 00:00:00"; // optionally set to release date of the network in format dd-mm-yyyy to impose temporary limits, etc. e.g. "01-03-2024 00:00:00"
|
||||
public static final int RELEASE_LIMIT_DAYS = 60; // number of days to limit sell offers to max buy limit for new accounts
|
||||
public static final int WARN_ON_OFFER_EXCEEDS_UNSIGNED_BUY_LIMIT_DAYS = 182; // number of days to warn if sell offer exceeds unsigned buy limit
|
||||
@ -454,7 +453,7 @@ public class HavenoUtils {
|
||||
case XMR_STAGENET:
|
||||
return "5B11hTJdG2XDNwjdKGLRxwSLwDhkbGg7C7UEAZBxjE6FbCeRMjudrpNACmDNtWPiSnNfjDQf39QRjdtdgoL69txv81qc2Mc";
|
||||
case XMR_MAINNET:
|
||||
throw new RuntimeException("Mainnet fee address not implemented"); // TODO: replace with mainnet trade fee address
|
||||
throw new RuntimeException("Mainnet fee address not implemented");
|
||||
default:
|
||||
throw new RuntimeException("Unhandled base currency network: " + Config.baseCurrencyNetwork());
|
||||
}
|
||||
|
@ -12,29 +12,29 @@ import org.bitcoinj.core.Utils;
|
||||
import haveno.common.crypto.Encryption;
|
||||
|
||||
/**
|
||||
* This utility generates and prints public/private keypairs
|
||||
* This utility generates and prints public/private key-pairs
|
||||
* which can be used to register arbitrators on the network.
|
||||
*/
|
||||
public class GenerateKeypairs {
|
||||
|
||||
public class GenerateKeyPairs {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// generate public/private keypairs
|
||||
List<SecretKey> secretKeys = new ArrayList<SecretKey>();
|
||||
|
||||
// generate public/private key-pairs
|
||||
List<SecretKey> secretKeys = new ArrayList<>();
|
||||
for (int i = 0; i < 20; i++) {
|
||||
secretKeys.add(Encryption.generateSecretKey(256));
|
||||
}
|
||||
|
||||
// print keypairs
|
||||
// print key-pairs
|
||||
System.out.println("Private keys:");
|
||||
for (SecretKey sk : secretKeys) {
|
||||
String privKey = Utils.HEX.encode(sk.getEncoded());
|
||||
System.out.println(privKey);
|
||||
String privateKey = Utils.HEX.encode(sk.getEncoded());
|
||||
System.out.println(privateKey);
|
||||
}
|
||||
System.out.println("Corresponding public keys:");
|
||||
for (SecretKey sk : secretKeys) {
|
||||
String privKey = Utils.HEX.encode(sk.getEncoded());
|
||||
ECKey ecKey = ECKey.fromPrivate(new BigInteger(1, Utils.HEX.decode(privKey)));
|
||||
String privateKey = Utils.HEX.encode(sk.getEncoded());
|
||||
ECKey ecKey = ECKey.fromPrivate(new BigInteger(1, Utils.HEX.decode(privateKey)));
|
||||
String pubKey = Utils.HEX.encode(ecKey.getPubKey());
|
||||
System.out.println(pubKey);
|
||||
}
|
@ -37,6 +37,7 @@ package haveno.core.xmr;
|
||||
import com.google.inject.Inject;
|
||||
import haveno.common.ThreadUtils;
|
||||
import haveno.common.UserThread;
|
||||
import haveno.core.api.model.XmrBalanceInfo;
|
||||
import haveno.core.offer.OpenOffer;
|
||||
import haveno.core.offer.OpenOfferManager;
|
||||
import haveno.core.support.dispute.Dispute;
|
||||
@ -51,8 +52,8 @@ import haveno.core.xmr.wallet.XmrWalletService;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -67,15 +68,18 @@ public class Balances {
|
||||
private final RefundManager refundManager;
|
||||
|
||||
@Getter
|
||||
private final ObjectProperty<BigInteger> availableBalance = new SimpleObjectProperty<>();
|
||||
private BigInteger availableBalance;
|
||||
@Getter
|
||||
private final ObjectProperty<BigInteger> pendingBalance = new SimpleObjectProperty<>();
|
||||
private BigInteger pendingBalance;
|
||||
@Getter
|
||||
private final ObjectProperty<BigInteger> reservedOfferBalance = new SimpleObjectProperty<>();
|
||||
private BigInteger reservedOfferBalance;
|
||||
@Getter
|
||||
private final ObjectProperty<BigInteger> reservedTradeBalance = new SimpleObjectProperty<>();
|
||||
private BigInteger reservedTradeBalance;
|
||||
@Getter
|
||||
private final ObjectProperty<BigInteger> reservedBalance = new SimpleObjectProperty<>(); // TODO (woodser): this balance is sum of reserved funds for offers and trade multisigs; remove?
|
||||
private BigInteger reservedBalance; // TODO (woodser): this balance is sum of reserved funds for offers and trade multisigs; remove?
|
||||
|
||||
@Getter
|
||||
private final IntegerProperty updateCounter = new SimpleIntegerProperty(0);
|
||||
|
||||
@Inject
|
||||
public Balances(TradeManager tradeManager,
|
||||
@ -103,52 +107,57 @@ public class Balances {
|
||||
updateBalances();
|
||||
}
|
||||
|
||||
public XmrBalanceInfo getBalances() {
|
||||
synchronized (this) {
|
||||
return new XmrBalanceInfo(availableBalance.longValue() + pendingBalance.longValue(),
|
||||
availableBalance.longValue(),
|
||||
pendingBalance.longValue(),
|
||||
reservedOfferBalance.longValue(),
|
||||
reservedTradeBalance.longValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBalances() {
|
||||
ThreadUtils.submitToPool(() -> doUpdateBalances());
|
||||
}
|
||||
|
||||
private void doUpdateBalances() {
|
||||
synchronized (this) {
|
||||
|
||||
// get wallet balances
|
||||
BigInteger balance = xmrWalletService.getWallet() == null ? BigInteger.ZERO : xmrWalletService.getBalance();
|
||||
availableBalance = xmrWalletService.getWallet() == null ? BigInteger.ZERO : xmrWalletService.getAvailableBalance();
|
||||
|
||||
// get wallet balances
|
||||
BigInteger balance = xmrWalletService.getWallet() == null ? BigInteger.ZERO : xmrWalletService.getWallet().getBalance(0);
|
||||
BigInteger unlockedBalance = xmrWalletService.getWallet() == null ? BigInteger.ZERO : xmrWalletService.getWallet().getUnlockedBalance(0);
|
||||
// calculate pending balance by adding frozen trade balances - reserved amounts
|
||||
pendingBalance = balance.subtract(availableBalance);
|
||||
List<Trade> trades = tradeManager.getTradesStreamWithFundsLockedIn().collect(Collectors.toList());
|
||||
for (Trade trade : trades) {
|
||||
if (trade.getFrozenAmount().equals(new BigInteger("0"))) continue;
|
||||
BigInteger tradeFee = trade instanceof MakerTrade ? trade.getMakerFee() : trade.getTakerFee();
|
||||
pendingBalance = pendingBalance.add(trade.getFrozenAmount()).subtract(trade.getReservedAmount()).subtract(tradeFee).subtract(trade.getSelf().getDepositTxFee());
|
||||
}
|
||||
|
||||
// calculate pending balance by adding frozen trade balances - reserved amounts
|
||||
BigInteger pendingBalance = balance.subtract(unlockedBalance);
|
||||
List<Trade> trades = tradeManager.getTradesStreamWithFundsLockedIn().collect(Collectors.toList());
|
||||
for (Trade trade : trades) {
|
||||
if (trade.getFrozenAmount().equals(new BigInteger("0"))) continue;
|
||||
BigInteger tradeFee = trade instanceof MakerTrade ? trade.getMakerFee() : trade.getTakerFee();
|
||||
pendingBalance = pendingBalance.add(trade.getFrozenAmount()).subtract(trade.getReservedAmount()).subtract(tradeFee).subtract(trade.getSelf().getDepositTxFee());
|
||||
// calculate reserved offer balance
|
||||
reservedOfferBalance = BigInteger.ZERO;
|
||||
if (xmrWalletService.getWallet() != null) {
|
||||
List<MoneroOutputWallet> frozenOutputs = xmrWalletService.getWallet().getOutputs(new MoneroOutputQuery().setIsFrozen(true).setIsSpent(false));
|
||||
for (MoneroOutputWallet frozenOutput : frozenOutputs) reservedOfferBalance = reservedOfferBalance.add(frozenOutput.getAmount());
|
||||
}
|
||||
for (Trade trade : trades) {
|
||||
reservedOfferBalance = reservedOfferBalance.subtract(trade.getFrozenAmount()); // subtract frozen trade balances
|
||||
}
|
||||
|
||||
// calculate reserved trade balance
|
||||
reservedTradeBalance = BigInteger.ZERO;
|
||||
for (Trade trade : trades) {
|
||||
reservedTradeBalance = reservedTradeBalance.add(trade.getReservedAmount());
|
||||
}
|
||||
|
||||
// calculate reserved balance
|
||||
reservedBalance = reservedOfferBalance.add(reservedTradeBalance);
|
||||
|
||||
// notify balance update
|
||||
UserThread.execute(() -> updateCounter.set(updateCounter.get() + 1));
|
||||
}
|
||||
|
||||
// calculate reserved offer balance
|
||||
BigInteger reservedOfferBalance = BigInteger.ZERO;
|
||||
if (xmrWalletService.getWallet() != null) {
|
||||
List<MoneroOutputWallet> frozenOutputs = xmrWalletService.getWallet().getOutputs(new MoneroOutputQuery().setIsFrozen(true).setIsSpent(false));
|
||||
for (MoneroOutputWallet frozenOutput : frozenOutputs) reservedOfferBalance = reservedOfferBalance.add(frozenOutput.getAmount());
|
||||
}
|
||||
for (Trade trade : trades) {
|
||||
reservedOfferBalance = reservedOfferBalance.subtract(trade.getFrozenAmount()); // subtract frozen trade balances
|
||||
}
|
||||
|
||||
// calculate reserved trade balance
|
||||
BigInteger reservedTradeBalance = BigInteger.ZERO;
|
||||
for (Trade trade : trades) {
|
||||
reservedTradeBalance = reservedTradeBalance.add(trade.getReservedAmount());
|
||||
}
|
||||
|
||||
// set balances
|
||||
setBalances(balance, unlockedBalance, pendingBalance, reservedOfferBalance, reservedTradeBalance);
|
||||
}
|
||||
|
||||
private void setBalances(BigInteger balance, BigInteger unlockedBalance, BigInteger pendingBalance, BigInteger reservedOfferBalance, BigInteger reservedTradeBalance) {
|
||||
UserThread.execute(() -> {
|
||||
this.availableBalance.set(unlockedBalance);
|
||||
this.pendingBalance.set(pendingBalance);
|
||||
this.reservedOfferBalance.set(reservedOfferBalance);
|
||||
this.reservedTradeBalance.set(reservedTradeBalance);
|
||||
this.reservedBalance.set(reservedOfferBalance.add(reservedTradeBalance));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -333,7 +333,9 @@ public class XmrWalletService {
|
||||
Callable<MoneroSyncResult> task = () -> wallet.sync();
|
||||
Future<MoneroSyncResult> future = syncWalletThreadPool.submit(task);
|
||||
try {
|
||||
return future.get();
|
||||
MoneroSyncResult result = future.get();
|
||||
wallet.getTxs(); // TODO: this is necessary to sync from pool, otherwise balance can be incorrect
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
throw new MoneroError(e.getMessage());
|
||||
}
|
||||
@ -893,7 +895,7 @@ public class XmrWalletService {
|
||||
}
|
||||
|
||||
// register internal listener to notify external listeners
|
||||
wallet.addListener(new XmrWalletListener());
|
||||
wallet.addListener(new XmrWalletListener()); // TODO: initial snapshot calls getTxs() which updates balance after returning but will not announce change
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
# nodeaddress.onion:port [(@owner,@backup)] (add mainnet seed addresses)
|
||||
# nodeaddress.onion:port [(@owner,@backup)]
|
||||
placeholder.onion:8000 (@placeholder)
|
@ -140,11 +140,7 @@ class GrpcOffersService extends OffersImplBase {
|
||||
@Override
|
||||
public void postOffer(PostOfferRequest req,
|
||||
StreamObserver<PostOfferReply> responseObserver) {
|
||||
GrpcErrorMessageHandler errorMessageHandler =
|
||||
new GrpcErrorMessageHandler(getPostOfferMethod().getFullMethodName(),
|
||||
responseObserver,
|
||||
exceptionHandler,
|
||||
log);
|
||||
GrpcErrorMessageHandler errorMessageHandler = new GrpcErrorMessageHandler(getPostOfferMethod().getFullMethodName(), responseObserver, exceptionHandler, log);
|
||||
try {
|
||||
coreApi.postOffer(
|
||||
req.getCurrencyCode(),
|
||||
@ -170,8 +166,7 @@ class GrpcOffersService extends OffersImplBase {
|
||||
responseObserver.onCompleted();
|
||||
},
|
||||
errorMessage -> {
|
||||
if (!errorMessageHandler.isErrorHandled())
|
||||
errorMessageHandler.handleErrorMessage(errorMessage);
|
||||
if (!errorMessageHandler.isErrorHandled()) errorMessageHandler.handleErrorMessage(errorMessage);
|
||||
});
|
||||
} catch (Throwable cause) {
|
||||
exceptionHandler.handleException(log, cause, responseObserver);
|
||||
@ -181,11 +176,15 @@ class GrpcOffersService extends OffersImplBase {
|
||||
@Override
|
||||
public void cancelOffer(CancelOfferRequest req,
|
||||
StreamObserver<CancelOfferReply> responseObserver) {
|
||||
GrpcErrorMessageHandler errorMessageHandler = new GrpcErrorMessageHandler(getCancelOfferMethod().getFullMethodName(), responseObserver, exceptionHandler, log);
|
||||
try {
|
||||
coreApi.cancelOffer(req.getId());
|
||||
var reply = CancelOfferReply.newBuilder().build();
|
||||
responseObserver.onNext(reply);
|
||||
responseObserver.onCompleted();
|
||||
coreApi.cancelOffer(req.getId(), () -> {
|
||||
var reply = CancelOfferReply.newBuilder().build();
|
||||
responseObserver.onNext(reply);
|
||||
responseObserver.onCompleted();
|
||||
}, errorMessage -> {
|
||||
if (!errorMessageHandler.isErrorHandled()) errorMessageHandler.handleErrorMessage(errorMessage);
|
||||
});
|
||||
} catch (Throwable cause) {
|
||||
exceptionHandler.handleException(log, cause, responseObserver);
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ Follow [instructions](https://github.com/haveno-dex/haveno-ts#run-tests) to run
|
||||
|
||||
Based on these instructions: https://github.com/monero-project/monero#cross-compiling
|
||||
|
||||
1. Install Ubuntu 20.04.
|
||||
1. Install Ubuntu 20.04 on x86_64.
|
||||
2. `sudo apt-get update && sudo apt-get upgrade`
|
||||
3. Install monero dependencies: `sudo apt update && sudo apt install build-essential cmake pkg-config libssl-dev libzmq3-dev libsodium-dev libunwind8-dev liblzma-dev libreadline6-dev libpgm-dev qttools5-dev-tools libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler libudev-dev libboost-chrono-dev libboost-date-time-dev libboost-filesystem-dev libboost-locale-dev libboost-program-options-dev libboost-regex-dev libboost-serialization-dev libboost-system-dev libboost-thread-dev python3 ccache`
|
||||
4. `sudo apt install cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev libtinfo5 autoconf libtool libtool-bin gperf git curl`
|
||||
|
@ -31,7 +31,7 @@ If it's the first time you are building Haveno, run the following commands to do
|
||||
```
|
||||
git clone https://github.com/haveno-dex/haveno.git
|
||||
cd haveno
|
||||
git checkout v0.0.18
|
||||
git checkout v0.0.19
|
||||
make
|
||||
```
|
||||
|
||||
@ -40,7 +40,7 @@ make
|
||||
If you are updating from a previous version, run from the root of the repository:
|
||||
|
||||
```
|
||||
git checkout v0.0.18
|
||||
git checkout v0.0.19
|
||||
git pull
|
||||
make clean && make
|
||||
```
|
||||
|
@ -846,9 +846,9 @@
|
||||
<sha256 value="c92e2ca40a3f2474d61e56831aeb379cf8ae3dddeea61b4a828cee2d99f71f38" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.github.woodser" name="monero-java" version="0.8.10">
|
||||
<artifact name="monero-java-0.8.10.jar">
|
||||
<sha256 value="3ea921cb8122e9be4401479e7040055063b2132e8210f7129117b8b10472f773" origin="Generated by Gradle"/>
|
||||
<component group="io.github.woodser" name="monero-java" version="0.8.11">
|
||||
<artifact name="monero-java-0.8.11.jar">
|
||||
<sha256 value="37c125a31463c44e43452bc3e18e74a05b65d1fbebb11adc5131521b29b48a6b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.grpc" name="grpc-api" version="1.42.1">
|
||||
|
@ -1,7 +1,7 @@
|
||||
# docker run -it -p 9050 -p 2002 --restart-policy unless-stopped --name haveno-seednode haveno-seednode
|
||||
# TODO: image very heavy, but it's hard to significantly reduce the size without bins
|
||||
|
||||
FROM openjdk:11
|
||||
FROM openjdk:21-jdk-bullseye
|
||||
|
||||
RUN set -ex && \
|
||||
apt update && \
|
||||
|
@ -1,11 +1,11 @@
|
||||
# configuration for haveno service
|
||||
# install in /etc/default/haveno.env
|
||||
|
||||
# java home, set to openjdk 10
|
||||
JAVA_HOME=/usr/lib/jvm/openjdk-10.0.2
|
||||
# java home, set to latest openjdk 21 from os repository
|
||||
JAVA_HOME=/usr/lib/jvm/openjdk-21
|
||||
|
||||
# java memory and remote management options
|
||||
JAVA_OPTS="-Xms4096M -Xmx4096M"
|
||||
JAVA_OPTS="-Xms4096M -Xmx4096M" -XX:+ExitOnOutOfMemoryError"
|
||||
|
||||
# use external tor (change to -1 for internal tor binary)
|
||||
HAVENO_EXTERNAL_TOR_PORT=9051
|
||||
@ -28,7 +28,7 @@ BITCOIN_RPC_BLOCKNOTIFY_PORT=5120
|
||||
HAVENO_HOME=__HAVENO_HOME__
|
||||
HAVENO_APP_NAME=haveno-seednode
|
||||
HAVENO_ENTRYPOINT=haveno-seednode
|
||||
HAVENO_BASE_CURRENCY=btc_mainnet
|
||||
HAVENO_BASE_CURRENCY=xmr_mainnet
|
||||
|
||||
# haveno node settings
|
||||
HAVENO_NODE_PORT=8000
|
||||
|
@ -7,22 +7,21 @@ echo "[*] Haveno Seednode installation script"
|
||||
|
||||
ROOT_USER=root
|
||||
ROOT_GROUP=root
|
||||
ROOT_PKG="build-essential libtool autotools-dev automake pkg-config bsdmainutils python3 git vim screen ufw"
|
||||
ROOT_PKG="build-essential libtool autotools-dev automake pkg-config bsdmainutils python3 git vim screen ufw openjdk-21-jdk"
|
||||
ROOT_HOME=/root
|
||||
|
||||
SYSTEMD_SERVICE_HOME=/etc/systemd/system
|
||||
SYSTEMD_ENV_HOME=/etc/default
|
||||
|
||||
HAVENO_REPO_URL=https://github.com/bisq-network/bisq
|
||||
HAVENO_REPO_URL=https://github.com/haveno-dex/haveno
|
||||
HAVENO_REPO_NAME=haveno
|
||||
HAVENO_REPO_TAG=master
|
||||
HAVENO_LATEST_RELEASE=$(curl -s https://api.github.com/repos/bisq-network/bisq/releases/latest|grep tag_name|head -1|cut -d '"' -f4)
|
||||
HAVENO_LATEST_RELEASE=$(curl -s https://api.github.com/repos/haveno-dex/haveno/releases/latest|grep tag_name|head -1|cut -d '"' -f4)
|
||||
HAVENO_HOME=/haveno
|
||||
HAVENO_USER=haveno
|
||||
|
||||
# by default, this script will build and setup bitcoin fullnode
|
||||
# if you want to use an existing bitcoin fullnode, see next section
|
||||
BITCOIN_INSTALL=true
|
||||
# by default, this script will not build and setup bitcoin full-node
|
||||
BITCOIN_INSTALL=false
|
||||
BITCOIN_REPO_URL=https://github.com/bitcoin/bitcoin
|
||||
BITCOIN_REPO_NAME=bitcoin
|
||||
BITCOIN_REPO_TAG=$(curl -s https://api.github.com/repos/bitcoin/bitcoin/releases/latest|grep tag_name|head -1|cut -d '"' -f4)
|
||||
@ -60,19 +59,13 @@ sudo -H -i -u "${ROOT_USER}" DEBIAN_FRONTEND=noninteractive apt-get upgrade -qq
|
||||
echo "[*] Installing base packages"
|
||||
sudo -H -i -u "${ROOT_USER}" DEBIAN_FRONTEND=noninteractive apt-get install -qq -y ${ROOT_PKG}
|
||||
|
||||
echo "[*] Installing Git LFS"
|
||||
sudo -H -i -u "${ROOT_USER}" apt-get install git-lfs
|
||||
sudo -H -i -u "${ROOT_USER}" git lfs install
|
||||
|
||||
echo "[*] Cloning Haveno repo"
|
||||
sudo -H -i -u "${ROOT_USER}" git config --global advice.detachedHead false
|
||||
sudo -H -i -u "${ROOT_USER}" git clone --branch "${HAVENO_REPO_TAG}" "${HAVENO_REPO_URL}" "${ROOT_HOME}/${HAVENO_REPO_NAME}"
|
||||
|
||||
echo "[*] Installing Tor"
|
||||
sudo -H -i -u "${ROOT_USER}" wget -qO- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gp
|
||||
g --dearmor | tee /usr/share/keyrings/tor-archive-keyring.gpg >/dev/null
|
||||
sudo -H -i -u "${ROOT_USER}" echo "deb [arch=amd64 signed-by=/usr/share/keyrings/tor-archive-keyring.gpg] https://deb.torproject.o
|
||||
rg/torproject.org focal main" > /etc/apt/sources.list.d/tor.list
|
||||
sudo -H -i -u "${ROOT_USER}" wget -qO- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | sudo gpg --dearmor | sudo tee /usr/share/keyrings/tor-archive-keyring.gpg >/dev/null
|
||||
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/tor-archive-keyring.gpg] https://deb.torproject.org/torproject.org focal main" | sudo -H -i -u "${ROOT_USER}" tee /etc/apt/sources.list.d/tor.list
|
||||
sudo -H -i -u "${ROOT_USER}" DEBIAN_FRONTEND=noninteractive apt-get update -q
|
||||
sudo -H -i -u "${ROOT_USER}" DEBIAN_FRONTEND=noninteractive apt-get install -qq -y ${TOR_PKG}
|
||||
|
||||
@ -128,17 +121,14 @@ echo "[*] Moving Haveno repo"
|
||||
sudo -H -i -u "${ROOT_USER}" mv "${ROOT_HOME}/${HAVENO_REPO_NAME}" "${HAVENO_HOME}/${HAVENO_REPO_NAME}"
|
||||
sudo -H -i -u "${ROOT_USER}" chown -R "${HAVENO_USER}:${HAVENO_GROUP}" "${HAVENO_HOME}/${HAVENO_REPO_NAME}"
|
||||
|
||||
echo "[*] Installing OpenJDK 10.0.2 from Haveno repo"
|
||||
sudo -H -i -u "${ROOT_USER}" "${HAVENO_HOME}/${HAVENO_REPO_NAME}/scripts/install_java.sh"
|
||||
|
||||
echo "[*] Installing Haveno init script"
|
||||
sudo -H -i -u "${ROOT_USER}" install -c -o "${ROOT_USER}" -g "${ROOT_GROUP}" -m 644 "${HAVENO_HOME}/${HAVENO_REPO_NAME}/seednode/haveno.service" "${SYSTEMD_SERVICE_HOME}/haveno.service"
|
||||
sudo -H -i -u "${ROOT_USER}" install -c -o "${ROOT_USER}" -g "${ROOT_GROUP}" -m 644 "${HAVENO_HOME}/${HAVENO_REPO_NAME}/seednode/haveno-seednode.service" "${SYSTEMD_SERVICE_HOME}/haveno-seednode.service"
|
||||
if [ "${BITCOIN_INSTALL}" = true ];then
|
||||
sudo sed -i -e "s/#Requires=bitcoin.service/Requires=bitcoin.service/" "${SYSTEMD_SERVICE_HOME}/haveno.service"
|
||||
sudo sed -i -e "s/#BindsTo=bitcoin.service/BindsTo=bitcoin.service/" "${SYSTEMD_SERVICE_HOME}/haveno.service"
|
||||
sudo sed -i -e "s/#Requires=bitcoin.service/Requires=bitcoin.service/" "${SYSTEMD_SERVICE_HOME}/haveno-seednode.service"
|
||||
sudo sed -i -e "s/#BindsTo=bitcoin.service/BindsTo=bitcoin.service/" "${SYSTEMD_SERVICE_HOME}/haveno-seednode.service"
|
||||
fi
|
||||
sudo sed -i -e "s/__HAVENO_REPO_NAME__/${HAVENO_REPO_NAME}/" "${SYSTEMD_SERVICE_HOME}/haveno.service"
|
||||
sudo sed -i -e "s!__HAVENO_HOME__!${HAVENO_HOME}!" "${SYSTEMD_SERVICE_HOME}/haveno.service"
|
||||
sudo sed -i -e "s/__HAVENO_REPO_NAME__/${HAVENO_REPO_NAME}/" "${SYSTEMD_SERVICE_HOME}/haveno-seednode.service"
|
||||
sudo sed -i -e "s!__HAVENO_HOME__!${HAVENO_HOME}!" "${SYSTEMD_SERVICE_HOME}/haveno-seednode.service"
|
||||
|
||||
echo "[*] Installing Haveno environment file with Bitcoin RPC credentials"
|
||||
sudo -H -i -u "${ROOT_USER}" install -c -o "${ROOT_USER}" -g "${ROOT_GROUP}" -m 644 "${HAVENO_HOME}/${HAVENO_REPO_NAME}/seednode/haveno.env" "${SYSTEMD_ENV_HOME}/haveno.env"
|
||||
@ -154,16 +144,13 @@ sudo sed -i -e "s!__HAVENO_HOME__!${HAVENO_HOME}!" "${SYSTEMD_ENV_HOME}/haveno.e
|
||||
echo "[*] Checking out Haveno ${HAVENO_LATEST_RELEASE}"
|
||||
sudo -H -i -u "${HAVENO_USER}" sh -c "cd ${HAVENO_HOME}/${HAVENO_REPO_NAME} && git checkout ${HAVENO_LATEST_RELEASE}"
|
||||
|
||||
echo "[*] Performing Git LFS pull"
|
||||
sudo -H -i -u "${HAVENO_USER}" sh -c "cd ${HAVENO_HOME}/${HAVENO_REPO_NAME} && git lfs pull"
|
||||
|
||||
echo "[*] Building Haveno from source"
|
||||
sudo -H -i -u "${HAVENO_USER}" sh -c "cd ${HAVENO_HOME}/${HAVENO_REPO_NAME} && ./gradlew build -x test < /dev/null" # redirect from /dev/null is necessary to workaround gradlew non-interactive shell hanging issue
|
||||
|
||||
echo "[*] Updating systemd daemon configuration"
|
||||
sudo -H -i -u "${ROOT_USER}" systemctl daemon-reload
|
||||
sudo -H -i -u "${ROOT_USER}" systemctl enable tor.service
|
||||
sudo -H -i -u "${ROOT_USER}" systemctl enable haveno.service
|
||||
sudo -H -i -u "${ROOT_USER}" systemctl enable haveno-seednode.service
|
||||
if [ "${BITCOIN_INSTALL}" = true ];then
|
||||
sudo -H -i -u "${ROOT_USER}" systemctl enable bitcoin.service
|
||||
fi
|
||||
@ -185,13 +172,13 @@ fi
|
||||
echo "[*] Adding notes to motd"
|
||||
sudo -H -i -u "${ROOT_USER}" sh -c 'echo " " >> /etc/motd'
|
||||
sudo -H -i -u "${ROOT_USER}" sh -c 'echo "Haveno Seednode instructions:" >> /etc/motd'
|
||||
sudo -H -i -u "${ROOT_USER}" sh -c 'echo "https://github.com/bisq-network/bisq/tree/master/seednode" >> /etc/motd'
|
||||
sudo -H -i -u "${ROOT_USER}" sh -c 'echo "https://github.com/haveno-dex/haveno/tree/master/seednode" >> /etc/motd'
|
||||
sudo -H -i -u "${ROOT_USER}" sh -c 'echo " " >> /etc/motd'
|
||||
sudo -H -i -u "${ROOT_USER}" sh -c 'echo "How to check logs for Haveno-Seednode service:" >> /etc/motd'
|
||||
sudo -H -i -u "${ROOT_USER}" sh -c 'echo "sudo journalctl --no-pager --unit haveno" >> /etc/motd'
|
||||
sudo -H -i -u "${ROOT_USER}" sh -c 'echo "sudo journalctl --no-pager --unit haveno-seednode" >> /etc/motd'
|
||||
sudo -H -i -u "${ROOT_USER}" sh -c 'echo " " >> /etc/motd'
|
||||
sudo -H -i -u "${ROOT_USER}" sh -c 'echo "How to restart Haveno-Seednode service:" >> /etc/motd'
|
||||
sudo -H -i -u "${ROOT_USER}" sh -c 'echo "sudo service haveno restart" >> /etc/motd'
|
||||
sudo -H -i -u "${ROOT_USER}" sh -c 'echo "sudo service haveno-seednode restart" >> /etc/motd'
|
||||
|
||||
echo '[*] Done!'
|
||||
|
||||
|
@ -3,9 +3,9 @@ echo "[*] Uninstalling Bitcoin and Haveno, will delete all data!!"
|
||||
sleep 10
|
||||
sudo rm -rf /root/haveno
|
||||
sudo systemctl stop bitcoin
|
||||
sudo systemctl stop haveno
|
||||
sudo systemctl stop haveno-seednode
|
||||
sudo systemctl disable bitcoin
|
||||
sudo systemctl disable haveno
|
||||
sudo systemctl disable haveno-seednode
|
||||
sudo userdel -f -r haveno
|
||||
sudo userdel -f -r bitcoin
|
||||
echo "[*] Done!"
|
||||
|
Loading…
Reference in New Issue
Block a user