DECODED_CHUNK_LENGTH = Map.of( 2, 1,
+ 3, 2,
+ 5, 3,
+ 6, 4,
+ 7, 5,
+ 9, 6,
+ 10, 7,
+ 11, 8);
+
+ private static void decodeChunk(String input,
+ int inputOffset,
+ int inputLength,
+ byte[] decoded,
+ int decodedOffset,
+ int decodedLength) throws Exception {
+
+ BigInteger result = BigInteger.ZERO;
+
+ BigInteger order = BigInteger.ONE;
+ for (int index = inputOffset + inputLength; index != inputOffset; order = order.multiply(ALPHABET_SIZE)) {
+ char character = input.charAt(--index);
+ int digit = ALPHABET.indexOf(character);
+ if (digit == -1) {
+ throw new Exception("invalid character " + character);
+ }
+ result = result.add(order.multiply(BigInteger.valueOf(digit)));
+ if (result.compareTo(UINT64_MAX) > 0) {
+ throw new Exception("64-bit unsigned integer overflow " + result.toString());
+ }
+ }
+
+ BigInteger maxCapacity = BigInteger.ONE.shiftLeft(8 * decodedLength);
+ if (result.compareTo(maxCapacity) >= 0) {
+ throw new Exception("capacity overflow " + result.toString());
+ }
+
+ for (int index = decodedOffset + decodedLength; index != decodedOffset; result = result.shiftRight(8)) {
+ decoded[--index] = result.byteValue();
+ }
+ }
+
+ private static byte[] decode(String input) throws Exception {
+ if (input.length() == 0) {
+ return new byte[0];
+ }
+
+ int chunks = input.length() / FULL_ENCODED_BLOCK_SIZE;
+ int lastEncodedSize = input.length() % FULL_ENCODED_BLOCK_SIZE;
+ int lastChunkSize = lastEncodedSize > 0 ? DECODED_CHUNK_LENGTH.get(lastEncodedSize) : 0;
+
+ byte[] result = new byte[chunks * FULL_DECODED_BLOCK_SIZE + lastChunkSize];
+ int inputOffset = 0;
+ int resultOffset = 0;
+ for (int chunk = 0; chunk < chunks; ++chunk,
+ inputOffset += FULL_ENCODED_BLOCK_SIZE,
+ resultOffset += FULL_DECODED_BLOCK_SIZE) {
+ decodeChunk(input, inputOffset, FULL_ENCODED_BLOCK_SIZE, result, resultOffset, FULL_DECODED_BLOCK_SIZE);
+ }
+ if (lastChunkSize > 0) {
+ decodeChunk(input, inputOffset, lastEncodedSize, result, resultOffset, lastChunkSize);
+ }
+
+ return result;
+ }
+
+ private static long readVarInt(ByteBuffer buffer) {
+ long result = 0;
+ for (int shift = 0; ; shift += 7) {
+ byte current = buffer.get();
+ result += (current & 0x7fL) << shift;
+ if ((current & 0x80L) == 0) {
+ break;
+ }
+ }
+ return result;
+ }
+
+ public static long decodeAddress(String address, boolean validateChecksum) throws Exception {
+ byte[] decoded = decode(address);
+
+ int checksumSize = 4;
+ if (decoded.length < checksumSize) {
+ throw new Exception("invalid length");
+ }
+
+ ByteBuffer decodedAddress = ByteBuffer.wrap(decoded, 0, decoded.length - checksumSize);
+
+ long prefix = readVarInt(decodedAddress.slice());
+ if (!validateChecksum) {
+ return prefix;
+ }
+
+ ByteBuffer fastHash = Keccak.keccak1600(decodedAddress.slice());
+ int checksum = fastHash.getInt();
+ int expected = ByteBuffer.wrap(decoded, decoded.length - checksumSize, checksumSize).getInt();
+ if (checksum != expected) {
+ throw new Exception(String.format("invalid checksum %08X, expected %08X", checksum, expected));
+ }
+
+ return prefix;
+ }
+}
diff --git a/assets/src/main/java/bisq/asset/CryptonoteAddressValidator.java b/assets/src/main/java/bisq/asset/CryptonoteAddressValidator.java
deleted file mode 100644
index 47a6883154e..00000000000
--- a/assets/src/main/java/bisq/asset/CryptonoteAddressValidator.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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 bisq.asset;
-
-/**
- * {@link AddressValidator} for Base58-encoded Cryptonote addresses.
- *
- * @author Chris Beams
- * @since 0.7.0
- */
-public class CryptonoteAddressValidator implements AddressValidator {
-
- private final String prefix;
- private final String subAddressPrefix;
- private final String validCharactersRegex = "^[1-9A-HJ-NP-Za-km-z]+$";
-
- public CryptonoteAddressValidator(String prefix, String subAddressPrefix) {
- this.prefix = prefix;
- this.subAddressPrefix = subAddressPrefix;
- }
-
- @Override
- public AddressValidationResult validate(String address) {
- if (!address.matches(validCharactersRegex)) {
- // Invalid characters
- return AddressValidationResult.invalidStructure();
- }
- if (address.startsWith(prefix)) {
- if (prefix.length() == 1 && address.length() == 94 + prefix.length()) {
- // XMR-type Standard address
- return AddressValidationResult.validAddress();
- }
- else if (prefix.length() == 2 && address.length() == 95 + prefix.length()) {
- //Aeon & Blur-type addresses
- return AddressValidationResult.validAddress();
- }
- else if (prefix.length() == 4 && address.length() == 94 + prefix.length()) {
- // FourtyTwo-type address
- return AddressValidationResult.validAddress();
- }
- else {
- //Non-supported prefix
- return AddressValidationResult.invalidStructure();
- }
- }
- if (address.startsWith(subAddressPrefix)) {
- if (subAddressPrefix.length() == 1 && address.length() == 94 + subAddressPrefix.length()) {
- // XMR-type subaddress
- return AddressValidationResult.validAddress();
- }
- else if (subAddressPrefix.length() == 2 && address.length() == 95 + subAddressPrefix.length()) {
- // Aeon, Mask & Blur-type subaddress
- return AddressValidationResult.validAddress();
- }
- if (subAddressPrefix.length() == 5 && address.length() == 96 + subAddressPrefix.length()) {
- // FourtyTwo-type subaddress
- return AddressValidationResult.validAddress();
- }
- else {
- // Non-supported subAddress
- return AddressValidationResult.invalidStructure();
- }
- }
- else {
- //Integrated? Invalid? Doesn't matter
- return AddressValidationResult.invalidStructure();
- }
- }
-}
-
-
diff --git a/assets/src/main/java/bisq/asset/GrinAddressValidator.java b/assets/src/main/java/bisq/asset/GrinAddressValidator.java
index 71c8ec36f95..f397bca0bae 100644
--- a/assets/src/main/java/bisq/asset/GrinAddressValidator.java
+++ b/assets/src/main/java/bisq/asset/GrinAddressValidator.java
@@ -18,7 +18,8 @@
package bisq.asset;
/**
- * The supported "address" (better wallet URL) format is IP:port or the grinbox format.
+ * We only support the grinbox format as it is currently the only tool which offers a validation options of sender.
+ * Beside that is the IP:port format very insecure with MITM attacks.
*
* Here is the information from a conversation with the Grinbox developer regarding the Grinbox address format.
*
@@ -53,7 +54,6 @@ public class GrinAddressValidator implements AddressValidator {
// Regex for IP validation borrowed from https://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses
- private static final String IPV4 = "((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])";
private static final String PORT = "((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4}))$";
private static final String DOMAIN = "[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\\.[a-zA-Z]{2,}$";
private static final String KEY = "[a-km-zA-HJ-NP-Z1-9]{52}$";
@@ -64,13 +64,9 @@ public GrinAddressValidator() {
@Override
public AddressValidationResult validate(String address) {
if (address == null || address.length() == 0)
- return AddressValidationResult.invalidAddress("Address may not be empty");
+ return AddressValidationResult.invalidAddress("Address may not be empty (only Grinbox format is supported)");
- if (address.matches("^" + IPV4 + ":" + PORT))
- return AddressValidationResult.validAddress();
-
-
- // We might have a grinbox address
+ // We only support grinbox address
String key;
String domain = null;
String port = null;
@@ -92,13 +88,13 @@ public AddressValidationResult validate(String address) {
}
if (!key.matches("^" + KEY))
- return AddressValidationResult.invalidAddress("Invalid key");
+ return AddressValidationResult.invalidAddress("Invalid key (only Grinbox format is supported)");
if (domain != null && !domain.matches("^" + DOMAIN))
- return AddressValidationResult.invalidAddress("Invalid domain");
+ return AddressValidationResult.invalidAddress("Invalid domain (only Grinbox format is supported)");
if (port != null && !port.matches("^" + PORT))
- return AddressValidationResult.invalidAddress("Invalid port");
+ return AddressValidationResult.invalidAddress("Invalid port (only Grinbox format is supported)");
return AddressValidationResult.validAddress();
diff --git a/assets/src/main/java/bisq/asset/coins/Adeptio.java b/assets/src/main/java/bisq/asset/coins/Adeptio.java
new file mode 100644
index 00000000000..ecfd4b34113
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/Adeptio.java
@@ -0,0 +1,56 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AddressValidationResult;
+import bisq.asset.Base58BitcoinAddressValidator;
+import bisq.asset.Coin;
+import bisq.asset.NetworkParametersAdapter;
+
+public class Adeptio extends Coin {
+
+ public Adeptio() {
+ super("Adeptio", "ADE", new AdeptioAddressValidator());
+ }
+
+
+ public static class AdeptioAddressValidator extends Base58BitcoinAddressValidator {
+
+ public AdeptioAddressValidator() {
+ super(new AdeptioParams());
+ }
+
+ @Override
+ public AddressValidationResult validate(String address) {
+ if (!address.matches("^[A][a-km-zA-HJ-NP-Z1-9]{24,33}$"))
+ return AddressValidationResult.invalidStructure();
+
+ return super.validate(address);
+ }
+ }
+
+
+ public static class AdeptioParams extends NetworkParametersAdapter {
+
+ public AdeptioParams() {
+ addressHeader = 23;
+ p2shHeader = 16;
+ acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
+ }
+ }
+}
diff --git a/assets/src/main/java/bisq/asset/coins/Aeon.java b/assets/src/main/java/bisq/asset/coins/Aeon.java
index a1ded133e6d..1af6aa838d2 100644
--- a/assets/src/main/java/bisq/asset/coins/Aeon.java
+++ b/assets/src/main/java/bisq/asset/coins/Aeon.java
@@ -18,11 +18,11 @@
package bisq.asset.coins;
import bisq.asset.Coin;
-import bisq.asset.CryptonoteAddressValidator;
+import bisq.asset.CryptoNoteAddressValidator;
public class Aeon extends Coin {
public Aeon() {
- super("Aeon", "AEON", new CryptonoteAddressValidator("Wm", "Xn"));
+ super("Aeon", "AEON", new CryptoNoteAddressValidator(0xB2, 0x06B8));
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Amitycoin.java b/assets/src/main/java/bisq/asset/coins/Amitycoin.java
new file mode 100644
index 00000000000..8265df5d981
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/Amitycoin.java
@@ -0,0 +1,28 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.Coin;
+import bisq.asset.RegexAddressValidator;
+
+public class Amitycoin extends Coin {
+
+ public Amitycoin() {
+ super("Amitycoin", "AMIT", new RegexAddressValidator("^amit[1-9A-Za-z^OIl]{94}"));
+ }
+}
diff --git a/desktop/src/main/java/bisq/desktop/util/validation/VenmoValidator.java b/assets/src/main/java/bisq/asset/coins/Arqma.java
similarity index 67%
rename from desktop/src/main/java/bisq/desktop/util/validation/VenmoValidator.java
rename to assets/src/main/java/bisq/asset/coins/Arqma.java
index 6906ffc0256..472db1c0b65 100644
--- a/desktop/src/main/java/bisq/desktop/util/validation/VenmoValidator.java
+++ b/assets/src/main/java/bisq/asset/coins/Arqma.java
@@ -15,17 +15,16 @@
* along with Bisq. If not, see .
*/
-package bisq.desktop.util.validation;
+package bisq.asset.coins;
-import bisq.core.util.validation.InputValidator;
+import bisq.asset.AltCoinAccountDisclaimer;
+import bisq.asset.Coin;
+import bisq.asset.CryptoNoteAddressValidator;
-// Removed due too high chargeback risk
-@Deprecated
-public final class VenmoValidator extends InputValidator {
+@AltCoinAccountDisclaimer("account.altcoin.popup.arq.msg")
+public class Arqma extends Coin {
- @Override
- public ValidationResult validate(String input) {
- // TODO
- return super.validate(input);
+ public Arqma() {
+ super("Arqma", "ARQ", new CryptoNoteAddressValidator(0x2cca, 0x6847));
}
}
diff --git a/assets/src/test/java/bisq/asset/coins/GridcoinTest.java b/assets/src/main/java/bisq/asset/coins/Askcoin.java
similarity index 77%
rename from assets/src/test/java/bisq/asset/coins/GridcoinTest.java
rename to assets/src/main/java/bisq/asset/coins/Askcoin.java
index 62b1241db51..39d4ddf4c41 100644
--- a/assets/src/test/java/bisq/asset/coins/GridcoinTest.java
+++ b/assets/src/main/java/bisq/asset/coins/Askcoin.java
@@ -17,11 +17,12 @@
package bisq.asset.coins;
-import bisq.asset.AbstractAssetWithDefaultValidatorTest;
+import bisq.asset.Coin;
+import bisq.asset.RegexAddressValidator;
-public class GridcoinTest extends AbstractAssetWithDefaultValidatorTest {
+public class Askcoin extends Coin {
- public GridcoinTest() {
- super(new Gridcoin());
+ public Askcoin() {
+ super("Askcoin", "ASK", new RegexAddressValidator("^[1-9][0-9]{0,11}"));
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Beam.java b/assets/src/main/java/bisq/asset/coins/Beam.java
index ae233aad841..99fa273e02a 100644
--- a/assets/src/main/java/bisq/asset/coins/Beam.java
+++ b/assets/src/main/java/bisq/asset/coins/Beam.java
@@ -17,6 +17,7 @@
package bisq.asset.coins;
+import bisq.asset.AltCoinAccountDisclaimer;
import bisq.asset.Coin;
import bisq.asset.RegexAddressValidator;
@@ -30,6 +31,7 @@
* but it's a more complex test, requiring cryptographic code.
*
*/
+@AltCoinAccountDisclaimer("account.altcoin.popup.beam.msg")
public class Beam extends Coin {
public Beam() {
super("Beam", "BEAM", new RegexAddressValidator("^([0-9a-f]{1,80})$"));
diff --git a/assets/src/main/java/bisq/asset/coins/BitDaric.java b/assets/src/main/java/bisq/asset/coins/BitDaric.java
new file mode 100644
index 00000000000..7871fbbbe82
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/BitDaric.java
@@ -0,0 +1,29 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.Coin;
+import bisq.asset.RegexAddressValidator;
+
+public class BitDaric extends Coin {
+
+ public BitDaric() {
+ super("BitDaric", "DARX", new RegexAddressValidator("^[R][a-km-zA-HJ-NP-Z1-9]{25,34}$"));
+ }
+}
+
diff --git a/assets/src/main/java/bisq/asset/coins/Bitzec.java b/assets/src/main/java/bisq/asset/coins/Bitzec.java
new file mode 100644
index 00000000000..df1207315d5
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/Bitzec.java
@@ -0,0 +1,29 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.Coin;
+import bisq.asset.RegexAddressValidator;
+
+public class Bitzec extends Coin {
+
+ public Bitzec() {
+ super("Bitzec", "BZC", new RegexAddressValidator("^t.*", "validation.altcoin.zAddressesNotSupported"));
+ }
+
+}
diff --git a/assets/src/main/java/bisq/asset/coins/Blur.java b/assets/src/main/java/bisq/asset/coins/Blur.java
index 90eea565751..99fb0422af2 100644
--- a/assets/src/main/java/bisq/asset/coins/Blur.java
+++ b/assets/src/main/java/bisq/asset/coins/Blur.java
@@ -19,12 +19,12 @@
import bisq.asset.AltCoinAccountDisclaimer;
import bisq.asset.Coin;
-import bisq.asset.CryptonoteAddressValidator;
+import bisq.asset.CryptoNoteAddressValidator;
@AltCoinAccountDisclaimer("account.altcoin.popup.blur.msg")
public class Blur extends Coin {
public Blur() {
- super("Blur", "BLUR", new CryptonoteAddressValidator("bL", "Ry"));
+ super("Blur", "BLUR", new CryptoNoteAddressValidator(0x1e4d, 0x2195));
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/BurntBlackCoin.java b/assets/src/main/java/bisq/asset/coins/BurntBlackCoin.java
new file mode 100644
index 00000000000..c825d9fd824
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/BurntBlackCoin.java
@@ -0,0 +1,33 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AltCoinAccountDisclaimer;
+import bisq.asset.Coin;
+import bisq.asset.RegexAddressValidator;
+
+@AltCoinAccountDisclaimer("account.altcoin.popup.blk-burnt.msg")
+public class BurntBlackCoin extends Coin {
+ public static final short PAYLOAD_LIMIT = 15000;
+
+ public BurntBlackCoin() {
+ super("Burnt BlackCoin",
+ "BLK-BURNT",
+ new RegexAddressValidator(String.format("(?:[0-9a-z]{2}?){1,%d}+", 2 * PAYLOAD_LIMIT)));
+ }
+}
diff --git a/assets/src/main/java/bisq/asset/coins/CRowdCLassic.java b/assets/src/main/java/bisq/asset/coins/CRowdCLassic.java
new file mode 100644
index 00000000000..db156cabefb
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/CRowdCLassic.java
@@ -0,0 +1,29 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.Coin;
+import bisq.asset.RegexAddressValidator;
+
+public class CRowdCLassic extends Coin {
+
+ public CRowdCLassic() {
+ super("CRowdCLassic", "CRCL", new RegexAddressValidator("^[C][a-zA-Z0-9]{33}$"));
+ }
+}
+
\ No newline at end of file
diff --git a/desktop/src/main/java/bisq/desktop/util/validation/CashAppValidator.java b/assets/src/main/java/bisq/asset/coins/Cash2.java
similarity index 67%
rename from desktop/src/main/java/bisq/desktop/util/validation/CashAppValidator.java
rename to assets/src/main/java/bisq/asset/coins/Cash2.java
index 4a861938495..3c7ad2718f7 100644
--- a/desktop/src/main/java/bisq/desktop/util/validation/CashAppValidator.java
+++ b/assets/src/main/java/bisq/asset/coins/Cash2.java
@@ -15,18 +15,16 @@
* along with Bisq. If not, see .
*/
-package bisq.desktop.util.validation;
+package bisq.asset.coins;
+import bisq.asset.AltCoinAccountDisclaimer;
+import bisq.asset.Coin;
+import bisq.asset.CryptoNoteAddressValidator;
-import bisq.core.util.validation.InputValidator;
+@AltCoinAccountDisclaimer("account.altcoin.popup.cash2.msg")
+public class Cash2 extends Coin {
-// Removed due too high chargeback risk
-@Deprecated
-public final class CashAppValidator extends InputValidator {
-
- @Override
- public ValidationResult validate(String input) {
- // TODO
- return super.validate(input);
+ public Cash2() {
+ super("Cash2", "CASH2", new CryptoNoteAddressValidator(false, 0x6));
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/CloakCoin.java b/assets/src/main/java/bisq/asset/coins/CloakCoin.java
new file mode 100644
index 00000000000..19b5d7727ed
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/CloakCoin.java
@@ -0,0 +1,28 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.Coin;
+import bisq.asset.RegexAddressValidator;
+
+public class CloakCoin extends Coin {
+
+ public CloakCoin() {
+ super("CloakCoin", "CLOAK", new RegexAddressValidator("^[B|C][a-km-zA-HJ-NP-Z1-9]{33}|^smY[a-km-zA-HJ-NP-Z1-9]{99}$"));
+ }
+}
diff --git a/assets/src/main/java/bisq/asset/coins/Credits.java b/assets/src/main/java/bisq/asset/coins/Credits.java
new file mode 100644
index 00000000000..1a64f4a391e
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/Credits.java
@@ -0,0 +1,56 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AddressValidationResult;
+import bisq.asset.Base58BitcoinAddressValidator;
+import bisq.asset.Coin;
+import bisq.asset.NetworkParametersAdapter;
+
+public class Credits extends Coin {
+
+ public Credits() {
+ super("Credits", "CRDS", new CreditsAddressValidator());
+ }
+
+
+ public static class CreditsAddressValidator extends Base58BitcoinAddressValidator {
+
+ public CreditsAddressValidator() {
+ super(new CreditsParams());
+ }
+
+ @Override
+ public AddressValidationResult validate(String address) {
+ if (!address.matches("^[C][a-km-zA-HJ-NP-Z1-9]{25,34}$"))
+ return AddressValidationResult.invalidStructure();
+
+ return super.validate(address);
+ }
+ }
+
+
+ public static class CreditsParams extends NetworkParametersAdapter {
+
+ public CreditsParams() {
+ addressHeader = 28;
+ p2shHeader = 5;
+ acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
+ }
+ }
+}
\ No newline at end of file
diff --git a/assets/src/main/java/bisq/asset/coins/DSTRA.java b/assets/src/main/java/bisq/asset/coins/DSTRA.java
new file mode 100644
index 00000000000..e7ec0e2ca3d
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/DSTRA.java
@@ -0,0 +1,56 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AddressValidationResult;
+import bisq.asset.Base58BitcoinAddressValidator;
+import bisq.asset.Coin;
+import bisq.asset.NetworkParametersAdapter;
+
+public class DSTRA extends Coin {
+
+ public DSTRA() {
+ super("DSTRA", "DST", new DSTRAAddressValidator());
+ }
+
+
+ public static class DSTRAAddressValidator extends Base58BitcoinAddressValidator {
+
+ public DSTRAAddressValidator() {
+ super(new DSTRAParams());
+ }
+
+ @Override
+ public AddressValidationResult validate(String address) {
+ if (!address.matches("^[D][a-km-zA-HJ-NP-Z1-9]{33}$"))
+ return AddressValidationResult.invalidStructure();
+
+ return super.validate(address);
+ }
+ }
+
+
+ public static class DSTRAParams extends NetworkParametersAdapter {
+
+ public DSTRAParams() {
+ addressHeader = 30;
+ p2shHeader = 33;
+ acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
+ }
+ }
+}
diff --git a/assets/src/main/java/bisq/asset/coins/Dash.java b/assets/src/main/java/bisq/asset/coins/Dash.java
index 28ca118afc3..754c8528b58 100644
--- a/assets/src/main/java/bisq/asset/coins/Dash.java
+++ b/assets/src/main/java/bisq/asset/coins/Dash.java
@@ -19,11 +19,18 @@
import bisq.asset.Base58BitcoinAddressValidator;
import bisq.asset.Coin;
-
-import org.libdohj.params.DashMainNetParams;
+import bisq.asset.NetworkParametersAdapter;
public class Dash extends Coin {
public Dash() {
- super("Dash", "DASH", new Base58BitcoinAddressValidator(DashMainNetParams.get()), Network.MAINNET);
+ super("Dash", "DASH", new Base58BitcoinAddressValidator(new DashMainNetParams()), Network.MAINNET);
+ }
+
+ public static class DashMainNetParams extends NetworkParametersAdapter {
+ public DashMainNetParams() {
+ this.addressHeader = 76;
+ this.p2shHeader = 16;
+ this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
+ }
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/DeepOnion.java b/assets/src/main/java/bisq/asset/coins/DeepOnion.java
index ed5ba25e88b..716d1b96dae 100644
--- a/assets/src/main/java/bisq/asset/coins/DeepOnion.java
+++ b/assets/src/main/java/bisq/asset/coins/DeepOnion.java
@@ -22,8 +22,6 @@
import bisq.asset.Coin;
import bisq.asset.NetworkParametersAdapter;
-import org.libdohj.params.DashMainNetParams;
-
public class DeepOnion extends Coin {
public DeepOnion() {
super("DeepOnion", "ONION", new DeepOnionAddressValidator());
diff --git a/assets/src/main/java/bisq/asset/coins/Dogecoin.java b/assets/src/main/java/bisq/asset/coins/Dogecoin.java
index 159803e1e0a..40a500ea529 100644
--- a/assets/src/main/java/bisq/asset/coins/Dogecoin.java
+++ b/assets/src/main/java/bisq/asset/coins/Dogecoin.java
@@ -19,12 +19,19 @@
import bisq.asset.Base58BitcoinAddressValidator;
import bisq.asset.Coin;
-
-import org.libdohj.params.DogecoinMainNetParams;
+import bisq.asset.NetworkParametersAdapter;
public class Dogecoin extends Coin {
public Dogecoin() {
- super("Dogecoin", "DOGE", new Base58BitcoinAddressValidator(DogecoinMainNetParams.get()));
+ super("Dogecoin", "DOGE", new Base58BitcoinAddressValidator(new DogecoinMainNetParams()), Network.MAINNET);
+ }
+
+ public static class DogecoinMainNetParams extends NetworkParametersAdapter {
+ public DogecoinMainNetParams() {
+ this.addressHeader = 30;
+ this.p2shHeader = 22;
+ this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
+ }
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Doichain.java b/assets/src/main/java/bisq/asset/coins/Doichain.java
new file mode 100644
index 00000000000..9bf904cc713
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/Doichain.java
@@ -0,0 +1,37 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.Base58BitcoinAddressValidator;
+import bisq.asset.Coin;
+import bisq.asset.NetworkParametersAdapter;
+
+public class Doichain extends Coin {
+
+ public Doichain() {
+ super("Doichain", "DOI", new Base58BitcoinAddressValidator(new DoichainParams()));
+ }
+
+ public static class DoichainParams extends NetworkParametersAdapter {
+ public DoichainParams() {
+ addressHeader = 52;
+ p2shHeader = 13;
+ acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
+ }
+ }
+}
diff --git a/assets/src/main/java/bisq/asset/coins/FourtyTwo.java b/assets/src/main/java/bisq/asset/coins/FourtyTwo.java
index fb21882df4e..4e3c16d6a0a 100644
--- a/assets/src/main/java/bisq/asset/coins/FourtyTwo.java
+++ b/assets/src/main/java/bisq/asset/coins/FourtyTwo.java
@@ -18,11 +18,11 @@
package bisq.asset.coins;
import bisq.asset.Coin;
-import bisq.asset.CryptonoteAddressValidator;
+import bisq.asset.CryptoNoteAddressValidator;
public class FourtyTwo extends Coin {
public FourtyTwo() {
- super("FourtyTwo", "FRTY", new CryptonoteAddressValidator("foUr", "SNake"));
+ super("FourtyTwo", "FRTY", new CryptoNoteAddressValidator(0x1cbd67, 0x13271817));
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Galilel.java b/assets/src/main/java/bisq/asset/coins/Galilel.java
new file mode 100644
index 00000000000..138e965330d
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/Galilel.java
@@ -0,0 +1,36 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.Base58BitcoinAddressValidator;
+import bisq.asset.Coin;
+import bisq.asset.NetworkParametersAdapter;
+
+public class Galilel extends Coin {
+ public Galilel() {
+ super("Galilel", "GALI", new Base58BitcoinAddressValidator(new GalilelMainNetParams()));
+ }
+
+ public static class GalilelMainNetParams extends NetworkParametersAdapter {
+ public GalilelMainNetParams() {
+ this.addressHeader = 68;
+ this.p2shHeader = 16;
+ this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
+ }
+ }
+}
diff --git a/assets/src/main/java/bisq/asset/coins/Grin.java b/assets/src/main/java/bisq/asset/coins/Grin.java
index b934077801a..7812aacc294 100644
--- a/assets/src/main/java/bisq/asset/coins/Grin.java
+++ b/assets/src/main/java/bisq/asset/coins/Grin.java
@@ -17,9 +17,11 @@
package bisq.asset.coins;
+import bisq.asset.AltCoinAccountDisclaimer;
import bisq.asset.Coin;
import bisq.asset.GrinAddressValidator;
+@AltCoinAccountDisclaimer("account.altcoin.popup.grin.msg")
public class Grin extends Coin {
public Grin() {
diff --git a/assets/src/main/java/bisq/asset/coins/Hatch.java b/assets/src/main/java/bisq/asset/coins/Hatch.java
new file mode 100644
index 00000000000..bbff61765bf
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/Hatch.java
@@ -0,0 +1,36 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.Base58BitcoinAddressValidator;
+import bisq.asset.Coin;
+import bisq.asset.NetworkParametersAdapter;
+
+public class Hatch extends Coin {
+ public Hatch() {
+ super("Hatch", "HATCH", new Base58BitcoinAddressValidator(new HatchMainNetParams()), Network.MAINNET);
+ }
+
+ public static class HatchMainNetParams extends NetworkParametersAdapter {
+ public HatchMainNetParams() {
+ this.addressHeader = 76;
+ this.p2shHeader = 16;
+ this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
+ }
+ }
+}
diff --git a/assets/src/main/java/bisq/asset/coins/ZeroOneCoin.java b/assets/src/main/java/bisq/asset/coins/Helium.java
similarity index 72%
rename from assets/src/main/java/bisq/asset/coins/ZeroOneCoin.java
rename to assets/src/main/java/bisq/asset/coins/Helium.java
index 0fc6b3849cd..cec17a9f7ba 100644
--- a/assets/src/main/java/bisq/asset/coins/ZeroOneCoin.java
+++ b/assets/src/main/java/bisq/asset/coins/Helium.java
@@ -17,22 +17,22 @@
package bisq.asset.coins;
+import bisq.asset.AddressValidationResult;
import bisq.asset.Base58BitcoinAddressValidator;
import bisq.asset.Coin;
import bisq.asset.NetworkParametersAdapter;
-public class ZeroOneCoin extends Coin {
+public class Helium extends Coin {
- public ZeroOneCoin() {
- super("01coin", "ZOC", new Base58BitcoinAddressValidator(new ZeroOneCoinAddressParams()));
+ public Helium() {
+ super("Helium", "HLM", new Base58BitcoinAddressValidator(new HeliumParams()));
}
+ public static class HeliumParams extends NetworkParametersAdapter {
- public static class ZeroOneCoinAddressParams extends NetworkParametersAdapter {
-
- public ZeroOneCoinAddressParams() {
- addressHeader = 80;
- p2shHeader = 10;
+ public HeliumParams() {
+ addressHeader = 63;
+ p2shHeader = 5;
acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Litecoin.java b/assets/src/main/java/bisq/asset/coins/Litecoin.java
index 6c2463205d7..57b61a3cb50 100644
--- a/assets/src/main/java/bisq/asset/coins/Litecoin.java
+++ b/assets/src/main/java/bisq/asset/coins/Litecoin.java
@@ -19,11 +19,18 @@
import bisq.asset.Base58BitcoinAddressValidator;
import bisq.asset.Coin;
-
-import org.libdohj.params.LitecoinMainNetParams;
+import bisq.asset.NetworkParametersAdapter;
public class Litecoin extends Coin {
public Litecoin() {
- super("Litecoin", "LTC", new Base58BitcoinAddressValidator(LitecoinMainNetParams.get()), Network.MAINNET);
+ super("Litecoin", "LTC", new Base58BitcoinAddressValidator(new LitecoinMainNetParams()), Network.MAINNET);
+ }
+
+ public static class LitecoinMainNetParams extends NetworkParametersAdapter {
+ public LitecoinMainNetParams() {
+ this.addressHeader = 48;
+ this.p2shHeader = 5;
+ this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
+ }
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/LitecoinPlus.java b/assets/src/main/java/bisq/asset/coins/LitecoinPlus.java
new file mode 100644
index 00000000000..aaf8d669b96
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/LitecoinPlus.java
@@ -0,0 +1,38 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.Base58BitcoinAddressValidator;
+import bisq.asset.Coin;
+import bisq.asset.NetworkParametersAdapter;
+
+public class LitecoinPlus extends Coin {
+
+ public LitecoinPlus() {
+ super("LitecoinPlus", "LCP", new Base58BitcoinAddressValidator(new LitecoinPlusMainNetParams()));
+ }
+
+ public static class LitecoinPlusMainNetParams extends NetworkParametersAdapter {
+ public LitecoinPlusMainNetParams() {
+ this.addressHeader = 75;
+ this.p2shHeader = 8;
+ this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
+ }
+ }
+}
+
diff --git a/assets/src/main/java/bisq/asset/coins/LitecoinZ.java b/assets/src/main/java/bisq/asset/coins/LitecoinZ.java
new file mode 100644
index 00000000000..2d6bc0a28ed
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/LitecoinZ.java
@@ -0,0 +1,29 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.Coin;
+import bisq.asset.RegexAddressValidator;
+
+public class LitecoinZ extends Coin {
+
+ public LitecoinZ() {
+ super("LitecoinZ", "LTZ", new RegexAddressValidator("^L.*", "validation.altcoin.ltz.zAddressesNotSupported"));
+ }
+
+}
diff --git a/assets/src/main/java/bisq/asset/coins/Lytix.java b/assets/src/main/java/bisq/asset/coins/Lytix.java
new file mode 100644
index 00000000000..d9a0de079b0
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/Lytix.java
@@ -0,0 +1,39 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AddressValidationResult;
+import bisq.asset.Base58BitcoinAddressValidator;
+import bisq.asset.Coin;
+import bisq.asset.NetworkParametersAdapter;
+
+public class Lytix extends Coin {
+
+ public Lytix() {
+ super("Lytix", "LYTX", new Base58BitcoinAddressValidator(new LytixParams()));
+ }
+
+ public static class LytixParams extends NetworkParametersAdapter {
+
+ public LytixParams() {
+ addressHeader = 19;
+ p2shHeader = 11;
+ acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
+ }
+ }
+}
diff --git a/assets/src/main/java/bisq/asset/coins/Mask.java b/assets/src/main/java/bisq/asset/coins/Mask.java
index 99217222152..1ab50ba4b31 100644
--- a/assets/src/main/java/bisq/asset/coins/Mask.java
+++ b/assets/src/main/java/bisq/asset/coins/Mask.java
@@ -18,10 +18,10 @@
package bisq.asset.coins;
import bisq.asset.Coin;
-import bisq.asset.CryptonoteAddressValidator;
+import bisq.asset.CryptoNoteAddressValidator;
public class Mask extends Coin {
public Mask() {
- super("Mask", "MASK", new CryptonoteAddressValidator("M", "bT"));
+ super("Mask", "MASK", new CryptoNoteAddressValidator(123, 206));
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/MirQuiX.java b/assets/src/main/java/bisq/asset/coins/MirQuiX.java
new file mode 100644
index 00000000000..142daa46ca5
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/MirQuiX.java
@@ -0,0 +1,28 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.Coin;
+import bisq.asset.RegexAddressValidator;
+
+public class MirQuiX extends Coin {
+
+ public MirQuiX() {
+ super("MirQuiX", "MQX", new RegexAddressValidator("^[M][a-km-zA-HJ-NP-Z1-9]{33}$"));
+ }
+}
diff --git a/assets/src/main/java/bisq/asset/coins/Monero.java b/assets/src/main/java/bisq/asset/coins/Monero.java
index 898ff326ad3..68c2c774f68 100644
--- a/assets/src/main/java/bisq/asset/coins/Monero.java
+++ b/assets/src/main/java/bisq/asset/coins/Monero.java
@@ -19,12 +19,12 @@
import bisq.asset.AltCoinAccountDisclaimer;
import bisq.asset.Coin;
-import bisq.asset.CryptonoteAddressValidator;
+import bisq.asset.CryptoNoteAddressValidator;
@AltCoinAccountDisclaimer("account.altcoin.popup.xmr.msg")
public class Monero extends Coin {
public Monero() {
- super("Monero", "XMR", new CryptonoteAddressValidator("4", "8"));
+ super("Monero", "XMR", new CryptoNoteAddressValidator(18, 42));
}
}
diff --git a/pricenode/src/main/java/bisq/price/mining/providers/FixedFeeRateProvider.java b/assets/src/main/java/bisq/asset/coins/Navcoin.java
similarity index 55%
rename from pricenode/src/main/java/bisq/price/mining/providers/FixedFeeRateProvider.java
rename to assets/src/main/java/bisq/asset/coins/Navcoin.java
index 23661001798..31c07866573 100644
--- a/pricenode/src/main/java/bisq/price/mining/providers/FixedFeeRateProvider.java
+++ b/assets/src/main/java/bisq/asset/coins/Navcoin.java
@@ -15,26 +15,22 @@
* along with Bisq. If not, see .
*/
-package bisq.price.mining.providers;
+package bisq.asset.coins;
-import bisq.price.mining.FeeRate;
-import bisq.price.mining.FeeRateProvider;
+import bisq.asset.Base58BitcoinAddressValidator;
+import bisq.asset.Coin;
+import bisq.asset.NetworkParametersAdapter;
-import java.time.Duration;
-import java.time.Instant;
-
-abstract class FixedFeeRateProvider extends FeeRateProvider {
-
- private final String currency;
- private final long price;
-
- public FixedFeeRateProvider(String currency, long price) {
- super(Duration.ofDays(1));
- this.currency = currency;
- this.price = price;
+public class Navcoin extends Coin {
+ public Navcoin() {
+ super("Navcoin", "NAV", new Base58BitcoinAddressValidator(new NavcoinParams()));
}
- protected final FeeRate doGet() {
- return new FeeRate(currency, price, Instant.now().getEpochSecond());
+ public static class NavcoinParams extends NetworkParametersAdapter {
+ public NavcoinParams() {
+ this.addressHeader = 53;
+ this.p2shHeader = 85;
+ this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
+ }
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/ParsiCoin.java b/assets/src/main/java/bisq/asset/coins/ParsiCoin.java
new file mode 100644
index 00000000000..cceee9f2002
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/ParsiCoin.java
@@ -0,0 +1,30 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AltCoinAccountDisclaimer;
+import bisq.asset.Coin;
+import bisq.asset.CryptoNoteAddressValidator;
+
+@AltCoinAccountDisclaimer("account.altcoin.popup.pars.msg")
+public class ParsiCoin extends Coin {
+
+ public ParsiCoin() {
+ super("ParsiCoin", "PARS", new CryptoNoteAddressValidator(false, 0x90004));
+ }
+}
\ No newline at end of file
diff --git a/assets/src/main/java/bisq/asset/coins/Plenteum.java b/assets/src/main/java/bisq/asset/coins/Plenteum.java
new file mode 100644
index 00000000000..4e99108383d
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/Plenteum.java
@@ -0,0 +1,28 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.Coin;
+import bisq.asset.RegexAddressValidator;
+
+public class Plenteum extends Coin {
+
+ public Plenteum() {
+ super("Plenteum", "PLE", new RegexAddressValidator("^PLe[1-9A-Za-z^OIl]{95}"));
+ }
+}
diff --git a/assets/src/main/java/bisq/asset/coins/Qwertycoin.java b/assets/src/main/java/bisq/asset/coins/Qwertycoin.java
new file mode 100644
index 00000000000..58d0849f294
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/Qwertycoin.java
@@ -0,0 +1,30 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AltCoinAccountDisclaimer;
+import bisq.asset.Coin;
+import bisq.asset.CryptoNoteAddressValidator;
+
+@AltCoinAccountDisclaimer("account.altcoin.popup.qwertycoin.msg")
+public class Qwertycoin extends Coin {
+
+ public Qwertycoin() {
+ super("Qwertycoin", "QWC", new CryptoNoteAddressValidator(false, 0x14820c));
+ }
+}
diff --git a/pricenode/src/main/java/bisq/price/mining/providers/DogecoinFeeRateProvider.java b/assets/src/main/java/bisq/asset/coins/TEO.java
similarity index 74%
rename from pricenode/src/main/java/bisq/price/mining/providers/DogecoinFeeRateProvider.java
rename to assets/src/main/java/bisq/asset/coins/TEO.java
index 5edcf3c091d..e36581e2da3 100644
--- a/pricenode/src/main/java/bisq/price/mining/providers/DogecoinFeeRateProvider.java
+++ b/assets/src/main/java/bisq/asset/coins/TEO.java
@@ -15,14 +15,14 @@
* along with Bisq. If not, see .
*/
-package bisq.price.mining.providers;
+package bisq.asset.coins;
-import org.springframework.stereotype.Component;
+import bisq.asset.Coin;
+import bisq.asset.RegexAddressValidator;
-@Component
-class DogecoinFeeRateProvider extends FixedFeeRateProvider {
+public class TEO extends Coin {
- public DogecoinFeeRateProvider() {
- super("DOGE", 5_000_000);
+ public TEO() {
+ super("Trust Ether reOrigin", "TEO", new RegexAddressValidator("^0x[0-9a-fA-F]{40}$"));
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Veil.java b/assets/src/main/java/bisq/asset/coins/Veil.java
new file mode 100644
index 00000000000..792cba487ab
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/Veil.java
@@ -0,0 +1,57 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.*;
+import org.bitcoinj.core.Address;
+import org.bitcoinj.core.AddressFormatException;
+
+public class Veil extends Coin {
+
+ public Veil() {
+ super("Veil", "VEIL", new VeilAddressValidator());
+ }
+
+ public static class VeilAddressValidator extends Base58BitcoinAddressValidator {
+
+ public VeilAddressValidator() {
+ super(new VeilParams());
+ }
+
+ @Override
+ public AddressValidationResult validate(String address) {
+ if (address.startsWith("V")) {
+ return super.validate(address);
+ }else if (address.startsWith("bv")){
+ // TODO: Add bech32 support
+ return AddressValidationResult.invalidAddress("Bech32 addresses not supported on bisq");
+ }
+ return AddressValidationResult.invalidStructure();
+ }
+ }
+
+ public static class VeilParams extends NetworkParametersAdapter {
+
+ public VeilParams() {
+ addressHeader = 70;
+ p2shHeader = 5;
+ acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
+ }
+ }
+}
+
diff --git a/assets/src/main/java/bisq/asset/coins/Gridcoin.java b/assets/src/main/java/bisq/asset/coins/XDR.java
similarity index 81%
rename from assets/src/main/java/bisq/asset/coins/Gridcoin.java
rename to assets/src/main/java/bisq/asset/coins/XDR.java
index 717573613c3..ea236b29e21 100644
--- a/assets/src/main/java/bisq/asset/coins/Gridcoin.java
+++ b/assets/src/main/java/bisq/asset/coins/XDR.java
@@ -18,11 +18,11 @@
package bisq.asset.coins;
import bisq.asset.Coin;
-import bisq.asset.DefaultAddressValidator;
-public class Gridcoin extends Coin {
+public class XDR extends Coin {
- public Gridcoin() {
- super("Gridcoin", "GRC", new DefaultAddressValidator());
+ public XDR() {
+ super("XDR", "XDR0", new Mile.MileAddressValidator());
}
+
}
diff --git a/assets/src/main/java/bisq/asset/coins/ZeroClassic.java b/assets/src/main/java/bisq/asset/coins/ZeroClassic.java
new file mode 100644
index 00000000000..a593b9bc704
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/coins/ZeroClassic.java
@@ -0,0 +1,29 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.Coin;
+import bisq.asset.RegexAddressValidator;
+
+public class ZeroClassic extends Coin {
+
+ public ZeroClassic() {
+ super("ZeroClassic", "ZERC", new RegexAddressValidator("^t.*", "validation.altcoin.zAddressesNotSupported"));
+ }
+
+}
diff --git a/pricenode/src/main/java/bisq/price/mining/providers/DashFeeRateProvider.java b/assets/src/main/java/bisq/asset/tokens/AugmintEuro.java
similarity index 76%
rename from pricenode/src/main/java/bisq/price/mining/providers/DashFeeRateProvider.java
rename to assets/src/main/java/bisq/asset/tokens/AugmintEuro.java
index abedc627e23..32ac1d581e2 100644
--- a/pricenode/src/main/java/bisq/price/mining/providers/DashFeeRateProvider.java
+++ b/assets/src/main/java/bisq/asset/tokens/AugmintEuro.java
@@ -15,14 +15,13 @@
* along with Bisq. If not, see .
*/
-package bisq.price.mining.providers;
+package bisq.asset.tokens;
-import org.springframework.stereotype.Component;
+import bisq.asset.Erc20Token;
-@Component
-class DashFeeRateProvider extends FixedFeeRateProvider {
+public class AugmintEuro extends Erc20Token {
- public DashFeeRateProvider() {
- super("DASH", 50);
+ public AugmintEuro() {
+ super("Augmint Euro", "AEUR");
}
}
diff --git a/pricenode/src/main/java/bisq/price/mining/providers/LitecoinFeeRateProvider.java b/assets/src/main/java/bisq/asset/tokens/DaiStablecoin.java
similarity index 75%
rename from pricenode/src/main/java/bisq/price/mining/providers/LitecoinFeeRateProvider.java
rename to assets/src/main/java/bisq/asset/tokens/DaiStablecoin.java
index b6681d9a812..f0f673c527d 100644
--- a/pricenode/src/main/java/bisq/price/mining/providers/LitecoinFeeRateProvider.java
+++ b/assets/src/main/java/bisq/asset/tokens/DaiStablecoin.java
@@ -15,14 +15,13 @@
* along with Bisq. If not, see .
*/
-package bisq.price.mining.providers;
+package bisq.asset.tokens;
-import org.springframework.stereotype.Component;
+import bisq.asset.Erc20Token;
-@Component
-class LitecoinFeeRateProvider extends FixedFeeRateProvider {
+public class DaiStablecoin extends Erc20Token {
- public LitecoinFeeRateProvider() {
- super("LTC", 500);
+ public DaiStablecoin() {
+ super("Dai Stablecoin", "DAI");
}
}
diff --git a/assets/src/main/java/bisq/asset/tokens/TrueUSD.java b/assets/src/main/java/bisq/asset/tokens/TrueUSD.java
new file mode 100644
index 00000000000..0ca465fe8a2
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/tokens/TrueUSD.java
@@ -0,0 +1,27 @@
+/*
+ * 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 bisq.asset.tokens;
+
+import bisq.asset.Erc20Token;
+
+public class TrueUSD extends Erc20Token {
+
+ public TrueUSD() {
+ super("TrueUSD", "TUSD");
+ }
+}
diff --git a/assets/src/main/java/bisq/asset/tokens/USDCoin.java b/assets/src/main/java/bisq/asset/tokens/USDCoin.java
new file mode 100644
index 00000000000..91d5a926e31
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/tokens/USDCoin.java
@@ -0,0 +1,27 @@
+/*
+ * 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 bisq.asset.tokens;
+
+import bisq.asset.Erc20Token;
+
+public class USDCoin extends Erc20Token {
+
+ public USDCoin() {
+ super("USD Coin", "USDC");
+ }
+}
diff --git a/assets/src/main/java/bisq/asset/tokens/VectorspaceAI.java b/assets/src/main/java/bisq/asset/tokens/VectorspaceAI.java
new file mode 100644
index 00000000000..c080f848c6e
--- /dev/null
+++ b/assets/src/main/java/bisq/asset/tokens/VectorspaceAI.java
@@ -0,0 +1,27 @@
+/*
+ * 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 bisq.asset.tokens;
+
+import bisq.asset.Erc20Token;
+
+public class VectorspaceAI extends Erc20Token {
+
+ public VectorspaceAI() {
+ super("VectorspaceAI", "VXV");
+ }
+}
diff --git a/assets/src/main/resources/META-INF/services/bisq.asset.Asset b/assets/src/main/resources/META-INF/services/bisq.asset.Asset
index aacd6ed9118..2a6cf1a7d54 100644
--- a/assets/src/main/resources/META-INF/services/bisq.asset.Asset
+++ b/assets/src/main/resources/META-INF/services/bisq.asset.Asset
@@ -3,55 +3,78 @@
# See bisq.asset.Asset and bisq.asset.AssetRegistry for further details.
# See https://bisq.network/list-asset for complete instructions.
bisq.asset.coins.Actinium
+bisq.asset.coins.Adeptio
bisq.asset.coins.Aeon
+bisq.asset.coins.Amitycoin
+bisq.asset.coins.Arqma
+bisq.asset.coins.Askcoin
bisq.asset.coins.Australiacash
bisq.asset.coins.Beam
bisq.asset.coins.Bitcoin$Mainnet
bisq.asset.coins.Bitcoin$Regtest
bisq.asset.coins.BitcoinRhodium
bisq.asset.coins.Bitcoin$Testnet
+bisq.asset.coins.BitDaric
bisq.asset.coins.Bitmark
+bisq.asset.coins.Bitzec
bisq.asset.coins.Blur
bisq.asset.coins.BSQ$Mainnet
bisq.asset.coins.BSQ$Regtest
bisq.asset.coins.BSQ$Testnet
+bisq.asset.coins.BurntBlackCoin
bisq.asset.coins.Byteball
+bisq.asset.coins.Cash2
bisq.asset.coins.Chaucha
+bisq.asset.coins.CloakCoin
bisq.asset.coins.Counterparty
+bisq.asset.coins.Credits
bisq.asset.coins.Croat
+bisq.asset.coins.CRowdCLassic
bisq.asset.coins.Dash
bisq.asset.coins.Decred
bisq.asset.coins.DeepOnion
bisq.asset.coins.Dextro
bisq.asset.coins.Dogecoin
+bisq.asset.coins.Doichain
bisq.asset.coins.Dragonglass
+bisq.asset.coins.DSTRA
bisq.asset.coins.Ether
bisq.asset.coins.EtherClassic
bisq.asset.coins.FourtyTwo
bisq.asset.coins.Fujicoin
+bisq.asset.coins.Galilel
bisq.asset.coins.GambleCoin
-bisq.asset.coins.Gridcoin
bisq.asset.coins.Grin
+bisq.asset.coins.Hatch
+bisq.asset.coins.Helium
bisq.asset.coins.Horizen
bisq.asset.coins.IdaPay
bisq.asset.coins.Iridium
bisq.asset.coins.Kekcoin
bisq.asset.coins.Litecoin
+bisq.asset.coins.LitecoinPlus
+bisq.asset.coins.LitecoinZ
+bisq.asset.coins.Lytix
bisq.asset.coins.Mask
bisq.asset.coins.Mile
+bisq.asset.coins.MirQuiX
bisq.asset.coins.MobitGlobal
bisq.asset.coins.Monero
bisq.asset.coins.MonetaryUnit
bisq.asset.coins.MoX
bisq.asset.coins.Namecoin
+bisq.asset.coins.Navcoin
bisq.asset.coins.Neos
bisq.asset.coins.Noir
+bisq.asset.coins.ParsiCoin
bisq.asset.coins.Persona
bisq.asset.coins.Pinkcoin
bisq.asset.coins.PIVX
+bisq.asset.coins.Plenteum
bisq.asset.coins.PZDC
bisq.asset.coins.Qbase
bisq.asset.coins.QMCoin
+bisq.asset.coins.Qwertycoin
bisq.asset.coins.Radium
bisq.asset.coins.Remix
bisq.asset.coins.Ryo
@@ -61,14 +84,22 @@ bisq.asset.coins.SpaceCash
bisq.asset.coins.Spectrecoin
bisq.asset.coins.Starwels
bisq.asset.coins.SUB1X
+bisq.asset.coins.TEO
bisq.asset.coins.TurtleCoin
bisq.asset.coins.UnitedCommunityCoin
bisq.asset.coins.Unobtanium
+bisq.asset.coins.Veil
bisq.asset.coins.Webchain
bisq.asset.coins.WrkzCoin
+bisq.asset.coins.XDR
bisq.asset.coins.Zcash
bisq.asset.coins.Zcoin
bisq.asset.coins.ZelCash
bisq.asset.coins.Zero
-bisq.asset.coins.ZeroOneCoin
+bisq.asset.coins.ZeroClassic
+bisq.asset.tokens.AugmintEuro
+bisq.asset.tokens.DaiStablecoin
bisq.asset.tokens.EtherStone
+bisq.asset.tokens.TrueUSD
+bisq.asset.tokens.USDCoin
+bisq.asset.tokens.VectorspaceAI
diff --git a/assets/src/test/java/bisq/asset/coins/AdeptioTest.java b/assets/src/test/java/bisq/asset/coins/AdeptioTest.java
new file mode 100644
index 00000000000..4efa16b6ee3
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/AdeptioTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class AdeptioTest extends AbstractAssetTest {
+
+ public AdeptioTest() {
+ super(new Adeptio());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("AP7rSyQMZRek9HGy9QB1bpung69xViesN7");
+ assertValidAddress("AWVXtnMo4pS2vBSNrBPLVvMgYvJGD6gSXk");
+ assertValidAddress("AHq8sM8DEeFoZXeDkaimfCLtnMuuSWXFE7");
+ assertValidAddress("ANG52tPNJuVknLQiLUdzVFoZ3vyo8UzkDL");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("aP7rSyQMZRek9HGy9QB1bpung69xViesN7");
+ assertInvalidAddress("DAeiBSH4nudXgoxS4kY6uhTPobc7AlrWDA");
+ assertInvalidAddress("BGhVYBXk511m8TPvQA6YokzxdpdhRE3sG6");
+ assertInvalidAddress("AZt2Kuy9cWFbTc888HNphppkuCTNyqu5PY");
+ assertInvalidAddress("AbosH98t3TRKzyNb8pPQV9boupVcBAX6of");
+ assertInvalidAddress("DTPAqTryNRCE2FgsxzohTtJXfCBIDnG6Rc");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/AmitycoinTest.java b/assets/src/test/java/bisq/asset/coins/AmitycoinTest.java
new file mode 100644
index 00000000000..ae9135b981a
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/AmitycoinTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class AmitycoinTest extends AbstractAssetTest {
+
+ public AmitycoinTest() {
+ super(new Amitycoin());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("amitMgDfvfUZ2CP1g1SEJQSN4n7qK4d45hqXSDtiFMwE5uo7DnSihknJzcEG9WtFc26fnhDHK6ydjBDKe6wjCoGt4RiP18a5Zb");
+ assertValidAddress("amitUnFFwApLG9btiPWRgTjRCQUj9kZjQJ8kH3ZraSsCU4yzX4AzgaoP8jkgXhp5c5jQT3idFJChAPYzA2EydJ5A4bShqrEixa");
+ assertValidAddress("amitAcVJTUZKJtYYsosMXJBQeEbt3ZV9qSvoQ1EqkvA45MRUaYWECYNKyRZ82BvLM9MPD2Gpud3DbGzGsStKnZ9x5yKVPVGJUa");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("amitAcVJTUZKJtYYsosMXJBQeEbt3ZV9qSvoQ1EqkvA45MRUaYWECYNKyRZ82BvLM9MPD2Gpud3DbGzGsStKnZ9");
+ assertInvalidAddress("amitAcVJTUZKJtYYsosMXJBQeEbt3ZV9qSvoQ1EqkvA45MRUaYWECYNKyRZ82BvLM9MPD2Gpud3DbGzGsStKnZ9x5yKVPVGJUaljashfeafh");
+ assertInvalidAddress("");
+ assertInvalidAddress("amitAcVJTUZKJtYYsosMXJBQeEbt3ZV9qSvoQ1EqkvA45MRUaYWECY#RoPOWRwpsx1F");
+ assertInvalidAddress("amitAcVJTUZKJtYYsosMXJByRZ82BvLM9MPD2Gpud3DbGzGsStKnZ9x5yKVPVGJUaJbc2q4C4fWN$C4fWNLoDLDvADvpjNYdt3sdRB434UidKXimQQn");
+ assertInvalidAddress("dsfkjasd56yaSDdguaw");
+ assertInvalidAddress("KEKlulzlksadfwe");
+ assertInvalidAddress("HOleeSheetdsdjqwqwpoo3");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/ArqmaTest.java b/assets/src/test/java/bisq/asset/coins/ArqmaTest.java
new file mode 100644
index 00000000000..3c5a5a9842b
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/ArqmaTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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 bisq.asset.coins;
+
+ import bisq.asset.AbstractAssetTest;
+ import org.junit.Test;
+
+ public class ArqmaTest extends AbstractAssetTest {
+
+ public ArqmaTest() {
+ super(new Arqma());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("ar3ZLUTSac5DhxhyLJB11gcXWLYPKJchg7c8hoaKmqchC9TtHEdXzxGgt2vzCLUYwtSvkJQTXNCjzCR7KZiFUySV138PEopVC");
+ assertValidAddress("aRS3V2hXuVAGAb5XWcDvN7McsSyqrEZ3XWyfMdEDCqioWNmVUuoKyNxDo7rwPCg55Ugb6KHXLN7hLZEGcnZzbm8M7uJ9YdVpeN");
+ assertValidAddress("ar3mXR6SQeC3P9Dmq2LGsAeq5eDvjiNnYaywtqdNzixe6xLr38DiNVaaRKMkAQkR3NV3TuVAwAwEGH3QDgXJF3th1RwxABa9a");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("");
+ assertInvalidAddress("ar3ZLUTSac5DhxhyLJB11gcXWLYPKJchg7c8hoaKmqchC9TtHEdXzxGgt2vzCLUYwtSvkJQTXNCjzCR7KZiFUySV138PEopV");
+ assertInvalidAddress("aRS3V2hXuVAGAb5XWcDvN7McsSyqrEZ3XWyfMdEDCqioWNmVUuoKyNxDo7rwPCg55Ugb6KHXLN7hLZEGcnZzbm8M7uJ9YdVpeNZz");
+ assertInvalidAddress("aRV3V2hXuVAGAb5XWcDvN7McsSyqrEZ3XWyfMdEDCqioWNmVUuoKyNxDo7rwPCg55Ugb6KHXLN7hLZEGcnZzbm8M7uJ9YdVpeN");
+ assertInvalidAddress("ar3mXR6SQeC3P9Dmq2LGsAeq5eDvjiNnYaywtqdNzi#exLr38DiNVaaRKMkAQkR3NV3TuVAwAwEGH3QDgXJF3th1RwxABa9a");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/AskcoinTest.java b/assets/src/test/java/bisq/asset/coins/AskcoinTest.java
new file mode 100644
index 00000000000..f1f5b587cc3
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/AskcoinTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class AskcoinTest extends AbstractAssetTest {
+
+ public AskcoinTest() {
+ super(new Askcoin());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("1");
+ assertValidAddress("123");
+ assertValidAddress("876982302333");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("0");
+ assertInvalidAddress("038292");
+ assertInvalidAddress("");
+ assertInvalidAddress("000232320382");
+ assertInvalidAddress("1298934567890");
+ assertInvalidAddress("123abc5ab");
+ assertInvalidAddress("null");
+ assertInvalidAddress("xidjfwi23ii0");
+ }
+}
\ No newline at end of file
diff --git a/assets/src/test/java/bisq/asset/coins/BitDaricTest.java b/assets/src/test/java/bisq/asset/coins/BitDaricTest.java
new file mode 100644
index 00000000000..a21f1d8afcd
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/BitDaricTest.java
@@ -0,0 +1,36 @@
+/*
+ * 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 bisq.asset.coins;
+import bisq.asset.AbstractAssetTest;
+import org.junit.Test;
+public class BitDaricTest extends AbstractAssetTest {
+ public BitDaricTest() {
+ super(new BitDaric());
+ }
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("RKWuQUtmV3em1MyB7QKdshgDEAwKQXuifa");
+ assertValidAddress("RG9YuDw7fa21a8h4E3Z2z2tgHrFNN27NnG");
+ }
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem");
+ assertInvalidAddress("38NwrYsD1HxQW5zfLT0QcUUXGMPvQgzTSn");
+ assertInvalidAddress("8tP9rh3SH6n9cSLmV22vnSNNw56LKGpLrB");
+ assertInvalidAddress("8Zbvjr");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/BitzecTest.java b/assets/src/test/java/bisq/asset/coins/BitzecTest.java
new file mode 100644
index 00000000000..dcc3ac36c75
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/BitzecTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class BitzecTest extends AbstractAssetTest {
+
+ public BitzecTest() {
+ super(new Bitzec());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("t1K6LGT7z2uNTLxag6eK6XwGNpdkHbncBaK");
+ assertValidAddress("t1ZjdqCGEkqL9nZ8fk9R6KA7bqNvXaVLUpF");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem");
+ assertInvalidAddress("38NwrYsD1HxQW5zfLT0QcUUXGMPvQgzTSn");
+ assertInvalidAddress("8tP9rh3SH6n9cSLmV22vnSNNw56LKGpLrB");
+ assertInvalidAddress("8Zbvjr");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/BurntBlackCoinTest.java b/assets/src/test/java/bisq/asset/coins/BurntBlackCoinTest.java
new file mode 100644
index 00000000000..941ea5f5851
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/BurntBlackCoinTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+import java.util.Collections;
+import org.junit.Test;
+
+public class BurntBlackCoinTest extends AbstractAssetTest {
+
+ public BurntBlackCoinTest() {
+ super(new BurntBlackCoin());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("4b");
+ assertValidAddress("536865206d616b657320796f75206275726e207769746820612077617665206f66206865722068616e64");
+ String longAddress = String.join("", Collections.nCopies(2 * BurntBlackCoin.PAYLOAD_LIMIT, "af"));
+ assertValidAddress(longAddress);
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("AF");
+ assertInvalidAddress("afa");
+ assertInvalidAddress("B4Wa1C8zFgkSY4daLg8jWnxuKpw7UmWFoo");
+ String tooLongAddress = String.join("", Collections.nCopies(2 * BurntBlackCoin.PAYLOAD_LIMIT + 1, "af"));
+ assertInvalidAddress(tooLongAddress);
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/CRowdCLassicTest.java b/assets/src/test/java/bisq/asset/coins/CRowdCLassicTest.java
new file mode 100644
index 00000000000..ca834002ff6
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/CRowdCLassicTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class CRowdCLassicTest extends AbstractAssetTest {
+
+ public CRowdCLassicTest() {
+ super(new CRowdCLassic());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("CfvddKQHdd975N5XQgmpVGTuK9mumvDBQo");
+ assertValidAddress("CU7pAhQjw2mjgQEAkxpsvAmeLU4Gs7ogQb");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("0xmnuL9poRmnuLd55bzKe7t48xtYv2bRES");
+ assertInvalidAddress("cvaAgcLKrno2AC7kYhHVDC");
+ assertInvalidAddress("19p49poRmnuLdnu55bzKe7t48xtYv2bRES");
+ assertInvalidAddress("csabbfjqwr12fbdf2gvffbdb12vdssdcaa");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/Cash2Test.java b/assets/src/test/java/bisq/asset/coins/Cash2Test.java
new file mode 100644
index 00000000000..2cbfd40373a
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/Cash2Test.java
@@ -0,0 +1,108 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+import org.junit.Test;
+
+public class Cash2Test extends AbstractAssetTest {
+
+ public Cash2Test() {
+ super(new Cash2());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("21mCcygjJivUzYW4TMTeHbEfv3Fq9NnMGEeChYcVNa3cUcRrVvy3K6mD6oMZ99fv6DQq53hbWB8Td36oVbipR7Yk6bovyL7");
+ assertValidAddress("22nnHUyz7DScf3QLL27NsuAxFiuVnfDWUaDF38a35aa3CEPp2zDgcEGLfBkCdu2ohzKt7mVNfNa2NDNZHSoFWa5j3kY9os6");
+ assertValidAddress("232Vo5FGYWRHhKmJ3Vz8CRCTy25RJyLJQ8wQo8mUDtZJiGLqQqPgzPJSivKR1ux9GNizSSRh6ACMR74i4qREuQrRK6KF3XH");
+ assertValidAddress("247r4orbN2jcXtnSSEBxxdJgRNxexjHZRUiE3aPU7ZL4AoRF6eVh9eY3GQTi2rNuw4PSbZzttoaJPWfJnbUnJ4ZSL8tYppR");
+ assertValidAddress("25vJ3RnYBveVqavx1eZshSYc5Rn9YaFWcJ2q2WouT17DMouujdDiAT3MnE7C49hdmF84zbv1TG8mTNcchuTx6L2sBXkjFgw");
+ assertValidAddress("26UfQDRNs5X7FFoTrfZXFv5Phze2aotTkGPB5iwDpaM3iXQrhX87e5eUGRbiSzVbb53yuA1jpHG5xiieVkYkrhnSBCJCWHU");
+ assertValidAddress("27yDdygjMcLHPRh6iiEQDqZcb6dXYWDpiRhUYZbo3ztGTtEKG72FH7mUtRevHn4rdCX51MHLJMc2afycbSrouoXoGJkA8KE");
+ assertValidAddress("28t4qvTKmt34kscL3raEx9EBFjBF9t4JadFpL7vq4GsTj4PSt1mEXW36ENBZgJfW3FRJoBGP47yhj7S9CRSCXEPdVrTBG4m");
+ assertValidAddress("295wF4wHgFMGsP67t3te2e2ihruA1V5Bu9KBtrVrMRky9Wwt1mZhwFANpUTCiwuxHAV7cnWhx4y9bMN4esfZXAFJ59YrG9U");
+ assertValidAddress("2AZqafQ7tXmgui7ReiGdqsCqKnWVPC4uJ4RDag7pspk5jCA5dQ7ysoNeMGTQss8D4jQhp2ySvvD7XZ8JeNNgHTgULErC5BA");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("");
+ assertInvalidAddress("09s5NiYva6XS9bhhVc6jKYgXsH9wuHhZhWsqyAoPoWPUEiwEo9AZCDNbksvknyvZk73zwhHWSiXdgcDGLyhk5teEM7yxTgk");
+ assertInvalidAddress("15a2NPZy7Xe2WZt3nKMZBsBpgNdevnKfy6PLk99eCjYw5fWQ5nu4uM6LerRBvVKTJpdGp2acZ25X3QDPHc7ocTxz1WfN2Za");
+ assertInvalidAddress("34B8imA1UH29uR6PHiGpcz9MYdnL3rku27gGeLosn5XuSedFC7jPBmzaB9DoxmDA5VUZa5hPv6PSe3tJH2MJhBktMEJXaZ8");
+ assertInvalidAddress("45Ghz2JRTTrLh8Z4bm6QhzZxVbq7LPiKbgjjhHPNDvVXZAJLop91zRu9A7wJMjyrU89uF7QpZB5kHhniuGZ88MJv7jRZXNi");
+ assertInvalidAddress("58FFmFEGcS52mTWmhAskaKSSiX1BnHo8YcDjuhPdYBpWT9Q6ZCDz54k6cs3jPF2nk6desb1T6vRfHLfthiNf561qPct2SY1");
+ assertInvalidAddress("67rMF5ve4nt2wTHYJ1pZ6j3o2YP5KDBnE7GDxnr6bpem9WcqeHzw9yKWXvtxYdpDXCBbLiX9nm97r4aEtnXq8YNb9WPn15f");
+ assertInvalidAddress("798Qr9sWTprQ2sH2y5PGpfV3RAnFxUsJYY2a2VA9GjZ3MiyScD8VEh8ifWk4toYRCcbLZmRJw2dSsJBJAJ1Ava8WBzW7J12");
+ assertInvalidAddress("85CQSLDNNKR4HGHwhtsxhm8jheYEvk6ngf44AhqCRWDV2XsaTHr6ittDuyfCjinAP1SzBqnVJfqNhYGDJLzxq4Y7FBVofXV");
+ assertInvalidAddress("9AeKW87bkao59oadmTXGf8Jv7sMYByPrKahRbnmZEmGzRgoxGRbWqmmXuPDW6jPJSUAdpZRZn6E5B9935LtWD5gHAPpZQAh");
+ assertInvalidAddress("AATHHjFhvpWXksjxJri6yaRkjTAGML2wQ7B2srLFSFXCfQy4C4UdLx5gMLBaxtfvjLe54ZfdSyRDyH94gH9Z17WpSeoBnG6");
+ assertInvalidAddress("B1NiHMasw7bQsTyGLYGWh3RyUtvfJtzPyKj7NoGxMr9nJwZ4Un7vzM69EV2xpduUYEf3YMFPF58QvBmttLrUoJYDJzdVWXY");
+ assertInvalidAddress("C4ak4b51DGLhGm9sPCXzHe88r9J6bWbJo5LzG4jBVjfBKhqmiQseAUcPkeSwNeNZWtVxSHuTNAk8tRZCbpZcY1rZGvGrEqZ");
+ assertInvalidAddress("D8NnxEjgt5LcKLHEydcB7eUhQ1RUMSaHwN6f4w7rYcNH35ti897AAbtAk5Yon72oUee5t45ByaM651ytVVYhDtAFGfuhPBL");
+ assertInvalidAddress("E3LDMVt5dzdW9NfnUT7cmUBWjeTuKiYD6Uuq6LB1ETVaJLFwrEZekxLAtLhbcSwPQg2kPeTYG4gZJMK5qmSqTUoDKUvaR7N");
+ assertInvalidAddress("F3Jj7vhhZSrWRJirVT3tVSQroPzFdFxB2ChN5276kXEP93We6KJ532ZMQAj136yrrG4exJYtcYVfNZQNGNnV2rkh2bwetrP");
+ assertInvalidAddress("G4Lo9KzkK9LUpKL1n6StdrYG2oBKuTqaUEyHekA9jxy7T3VZj4og91CKtfBbuiPVgzYYhL7vpDsk4fDFpyrQ8k18LovPrw7");
+ assertInvalidAddress("H1Sv8KX7bnxEXmo6fh4x2y9pfiftbxnsx1QM6bhBjWgwaEqNBeyPdqi1mQKB6JSZqU1u4oEQcsUFY8yyTeP9Jh3s2jZ6qVc");
+ assertInvalidAddress("I5wP79cd9oz4Pw2Gdj5Youi5J2Jft1QRwBdtRdx7bFe782Gxacw9hCpQ3jbyqs5U18EWiuzpJaAgiGrwD3aC17He7vWRxQM");
+ assertInvalidAddress("J7icdECeckdDAofi9aBLwMZDvLnABZiT6XHFTu115E2pe3GqqBkFPL9dtbRUMrL5ZicQ6JMs2VamZNYyCWNt9jkEJvE4Fir");
+ assertInvalidAddress("K7vZECGxgqcgtLTcbyVH9d4z68Z3SYgJFD3jiyrimiiR87qqVQUXdoTciVr6JQCMSY3qNxk1SDqVFAmv7dFbhWA6AJBtQq1");
+ assertInvalidAddress("L5zCC9MAJVqXEogZ8YZFAHFN3Pp9J47vi3bXKV3tvP69FoSNzpsCgBHATYpJY7Aho958RyvbwxMDYFNqK5UiFe6WKy8xxQC");
+ assertInvalidAddress("M6kpYUXiyT7TBraQqtbxuZRtAzb9Px8vz7FWtBtM2UwqP68jYGoKENeDs8u6SGK7msXevM97AaB3ZYM9pk55uXSf9dbu8BD");
+ assertInvalidAddress("N8FMot8AeSzBNeNGzAwXb8eN3rNmb8neUWWL7epoVE6mSJdQ87p1byWcs6NTLQkJUkgUx7t51WhfKSQcJFrZq9EBPcWsQmP");
+ assertInvalidAddress("O4c4hCkAWf7RbVXsiZu4v9S9BQ5KdWZWreykUpHdMAFxYerg4xsg4KPCoR5bq9z9ahMKb3sHuHW627zCdcBRPLe8Ft2qvDp");
+ assertInvalidAddress("P6PhpdMqmcgAwV8iRjcoboFprEHgrPgYEYLzjaeU5HvRJAXu1yzWM1Q3D9zxvju6bwEv54Sccdp2S33HPx1s86uGSsZ9K8Q");
+ assertInvalidAddress("Q8DP7okc13sjL7Hens8obs3mgpKyXzteccUHpuRhDyRsfxyFx8KNeBdGUNHYxWcc4pVk4gdUQq9hiZhw5K8m4pxC5rtRXo1");
+ assertInvalidAddress("R9xFn1dKj6Rdsp6ZwCkpfDC2n98HHLa6M7DmV47qkYhm9vbeer1bbPoJopG4DYhspgNmTpbwe2nco3o7AsaMrT4D6MQaVxg");
+ assertInvalidAddress("S89QzLjkGJiFaYdb83wrQEEtMNBizmaiz3kHYUmwZURm5mbDcGLEnBpGrqSuJVxQjHE4cpiqFF1A6Gk2ZB2uwDUb1nms8Dg");
+ assertInvalidAddress("T7iiGq9NExdRwgUV6WcT58DPWA8SL8VyDdBEqY6vG8mwHedpWzU1e1Z7k5wc8DL7nyWfCYFsZKn2KcP5DXwYcvwRB9Xy4zG");
+ assertInvalidAddress("U2Ec4PmgrMuVahrYGAkS5jhisb1w8b63ra33t5eoY2e5V9syeyhqU8xUqSLe22WrxMYk4gve6isGb7EpU7RLrRGzANDVUtz");
+ assertInvalidAddress("V4U3d86FzU3bKvgjNNs4fuGDNRYQFoLx3XAKKtq4SiwbPLwmTpo9P2jMbwvby4YZmPCkTu6RgAdv1XispG1qtnT64Vbkn6W");
+ assertInvalidAddress("W1JeT4tzGAw4b9EiLsH1pC3dWLzTSGGaaVAGux1z8PuqCH8ziEmEMDZeEhcnxgjz8n27bS7oUvb1UcUYbYTHt5jaKwicC1x");
+ assertInvalidAddress("X5EAA2wJRhC3QomYEgu6NMg7AW77LfjcxhhK7YHT94XnRwGsEWmNW71Ct3UiNLbs3ab1xiWVfu4ymF3enZ19hgfM93Xp2dz");
+ assertInvalidAddress("Y3YWhEp25gw1gpVtdWxdyd9Fgj5quPGuy6hC9h8knpC58YPtB4TxpZEfhb9cRgXezxCXnq1GTmQ49TCQ3CsJ8gFW3q4WN95");
+ assertInvalidAddress("Z6q1WzvdPpZhiCEqzugGSPM5b39S6cdn64DtF6FcvtFg4d9hNaxXevvbkEYM8GwEH4ihW98pd6SVkR8meDu21oDbPgncEz9");
+ assertInvalidAddress("a6GQ2ZBomH5WojBELhHSmQXmgNDecv65ebzhhMMkmxZVhiJxRixh29ZJ7oQK4Yg8FF4qjYMv1ykA4JA7n6KoWy18DJPaUVs");
+ assertInvalidAddress("b4jmgQskiHLW8PtdX3X662eMLN2hnAnTzJsu4PLbggomVuhVFuGaUWEDntQSzpcKXgReLZAeYGEaYWPpFsTgmwEpLhEfN4m");
+ assertInvalidAddress("c9Nc2eUQXBnR2PpcRrKqbA2A4DSEeLDt7LhYy4aKmvCr6JCRGtXZxrePTJpbMC83MyR8W2KCCfVwfhygpLa437DBC2NQpYH");
+ assertInvalidAddress("dA5bw23DkMoXpYXbX8aPncW8ZgHKyPLngJkJS7tGPegjZycvquRKktFFf46n3VFxfrLT2UnrCkBE4LrqbWnDfRUW6Nfut6g");
+ assertInvalidAddress("e49CqpKzaDG8yV6rNRuQ2VVrZi8FCTVJ4b2C5AsVkqNtGFGKCBAjTeDFhWkGJvLfFTNDUkxsgQ9bP41Uhx5G3gdCB4k6oVJ");
+ assertInvalidAddress("f6x8ajQFtUReSoNYvCc7RjXpzZRngNaUU6xTAc6YvFsw8uTzwL4WDuM71cuBAW5oNAQrBjmPQmBZV8DYav6bAEVQQR7mLh2");
+ assertInvalidAddress("g1Pdnp4qJ4qYPu11EEBeUhTU7Bb3b7k1Rg8hAxAqJf2XDncBqrePPrNGsgqaLeRdpBFfsZRCHTabpHvQWMzUsiLNJGFvGnR");
+ assertInvalidAddress("h3DzqGR97GwWe7G3YC7D4mgCA7b68zMQmAq4r559JtcAjbG1GeXvjedTnHys9aS9vL9iG8djvVeZMdVi4S8Kc6oX2Zovt8r");
+ assertInvalidAddress("iALCRLmNc8WSzbyjri4dgw9iaL6a2Uf3QYsUwsXseJfb7FCQnUgGja2ATbYpLREQTxc5VLvExQpwqFsmvhdvpx5VEVAgmyJ");
+ assertInvalidAddress("j3bKBtupDeZcauKPMvzBLWHnHFn5q6ZVxDCZdvmvXJ7sgT5cQKQ8iJgARzJQ1SpzSKLwb6Kx8EVebbv4d9Y4o8AcKSQgWyx");
+ assertInvalidAddress("k1u7EQDv25yGG67XtWkCSDYsbSpHFwTKESVpAxM8XSPqFrYDWPQV8KWReVmPR4piLtByikCpTgvWW5tXaxrfSuRXKo8DwWh");
+ assertInvalidAddress("l6kW6xriMLxTTJBHdErywLZHQp6HchZwmZLXM4GyTfV3GFsZ7rF9JzrLx7ykNe75bqjii4b3kVX7SU98AEZmfyExNQFnZTm");
+ assertInvalidAddress("m5hY6yRHGDKbjYbZiveah4DntcKbGAaqnLR5QWnF8hFP7NDouKXcFPKfWX7q8jaXdKKTJsi3Aec36Lbz4rapaxB7PKtM4mw");
+ assertInvalidAddress("n9kXzy9NJhS5txFKQzh88XFFx7vi8XoLGc1UMXp7uFdK5NoaABPvemWRGm4zb6VNqgh786Q9ch1muayCQnszr8YzRYrxwWE");
+ assertInvalidAddress("o7bZkG5wPryY1Ld3TPhcjECcDFeP63neFD5cA1iXC8ZPJtBsAwXFFsdbyR9eV7oKp8bB26TKWyjU86ibaJVg9RtoR5Hr18N");
+ assertInvalidAddress("p37iEL6AWJaZm357fSqgQPQLzFigpuzTT9wTmUaGM7VfEzf9qmcZjP76y8bnN51bjqBKsMYPF7XLxA87vMhGAiAe5jdBhtX");
+ assertInvalidAddress("q6TkiMru8ELSdXeX1DWquJ9WH7yxjFC3QdGovpUZYG7v2nCDhCxyDdz8CcqpRaqzf55xg8suNHbVAgNaUVCeCv1yETsaFJq");
+ assertInvalidAddress("r9HCvadnFDSjDUAqhzorvaZmPeRqKgGG5GUnr3ph2zQteQ3TgGEvq6oiK2H967UUoUJKCH9yXmfuX3oDiyHNm2xaP7ZcPqa");
+ assertInvalidAddress("s7XmwW4Q2hdN4VqEcES8KnXGTaE7Dq2w4gsjzDfBAQKWZ3S45DGBSpwb32o7Y1STZvQDtxPKVXtgbScjWizvpbC8SNYcabo");
+ assertInvalidAddress("t5ZmMnkKCU8h44srsPYr5JVkvDhHBZG44QQYE2gEbUhTN4orqDgiKnMTyQYPj3XC1M5bST42rNUfR9LuWpGvkJmoCZaFvYJ");
+ assertInvalidAddress("uARGu2zWWtu9k9pb1TK6zmS1ASnNVX1Kj9H3nRq6MGGhLcNshUHML4gid6grswb3aaVq47t5qqre41isaExKFDGRD9LCUHG");
+ assertInvalidAddress("v1tYtfLchdzUrJow8RqMbGcH1ZAtWzSUmJHaQnrG1EypRkktGDo3tqXdk5yby64rgJjBgmMjJJ6NkRWsukHi9RTQ3XQBbqB");
+ assertInvalidAddress("w4Q6hafxurmZWPSHpmp8R2GSxYiAw5DJQ3fcS9irCF3zKRnYarXLxfQPd5t24rEyYRCDAUSV1DL7CTY5guRE6dk4FgXrw5H");
+ assertInvalidAddress("x7o5bwgPr1JMLMZQX8RoDT6JYfD7GwFanQa3QcMsUNbaj3siUp5i5okZxF237s5MhjWmWxWyVDxNvTq1c9MXSnQJHpNKq4d");
+ assertInvalidAddress("yAENYbDcrf49FUHHDdSbtCF4EEG6LxxjvE7CsusYoi6bQUoUCfqH9yqjbuTP8i8e5vPYzWqLj1VpdMSZ4DQdhhUB8MtdvcL");
+ assertInvalidAddress("z2kefw5QxZ9CmzdPCnFD766oaJ1yU1NXr5WwD2xZTpTFAGL8HRjzUzmXkdo2fqiiZyiTVAYMfxMtfJvo5QLEkHUnJEPmps4");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/CloakCoinTest.java b/assets/src/test/java/bisq/asset/coins/CloakCoinTest.java
new file mode 100644
index 00000000000..4f6b3f7cf34
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/CloakCoinTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class CloakCoinTest extends AbstractAssetTest {
+
+ public CloakCoinTest() {
+ super(new CloakCoin());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("C3MwbThsvquwA4Yg6recThXpAhR2hvRKws");
+ assertValidAddress("B6MwbThsvquwA4Yg6recThXpAhR2hvKRsz");
+ assertValidAddress("BCA31xPpijxiCuTQeYMpMTQsTH1m2jTg5t");
+ assertValidAddress("smYmLVV33zExmaFyVp3AUjU3fJMK5E93kwzDfMnPLnEBQ7BoHZkSQhCP92hZz7Hm24yavCceNeQm8RHekqdvrhFe8gX7EdXNwnhQgQ");
+
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("1sA31xPpijxiCuTQeYMpMTQsTH1m2jTgtS");
+ assertInvalidAddress("BsA31xPpijxiCuTQeYMpMTQsTH1m2jTgtSd");
+ assertInvalidAddress("bech3ThsvquwA4Yg6recThXpAhR2hvRKws");
+ assertInvalidAddress("smYmLYcVVzExmaFyVp3AUjU3fJMK5E93kwzDfMnPLnEBQ7BoHZkSQhCP92hZz7Hm24yavCceNeQm8RHekqdv");
+ assertInvalidAddress("C3MwbThsvquwA4Yg6recThXpAhR2hvRKw");
+ assertInvalidAddress(" B6MwbThsvquwA4Yg6recThXpAhR2hvKRsz");
+ assertInvalidAddress("B6MwbThsvquwA4Yg6recThXpAhR2hvKRsz ");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/CreditsTest.java b/assets/src/test/java/bisq/asset/coins/CreditsTest.java
new file mode 100644
index 00000000000..7a699999787
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/CreditsTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class CreditsTest extends AbstractAssetTest {
+
+ public CreditsTest() {
+ super(new Credits());
+ }
+
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("CfXBhPhSxx1wqxGQCryfgn6iU1M1XFUuCo");
+ assertValidAddress("CMde7YERCFWkCL2W5i8uyJmnpCVj8Chhww");
+ assertValidAddress("CcbqU3MLZuGAED2CuhUkquyJxKaSJqv6Vb");
+ assertValidAddress("CKaig5pznaUgiLqe6WkoCNGagNMhNLtqhK");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("1fXBhPhSxx1wqxGQCryfgn6iU1M1XFUuCo32");
+ assertInvalidAddress("CMde7YERCFWkCL2W5i8uyJmnpCVj8Chh");
+ assertInvalidAddress("CcbqU3MLZuGAED2CuhUkquyJxKaSJqv6V6#");
+ assertInvalidAddress("bKaig5pznaUgiLqe6WkoCNGagNMhNLtqhKkggg");
+ }
+}
\ No newline at end of file
diff --git a/assets/src/test/java/bisq/asset/coins/ZeroOneCoinTest.java b/assets/src/test/java/bisq/asset/coins/DSTRATest.java
similarity index 58%
rename from assets/src/test/java/bisq/asset/coins/ZeroOneCoinTest.java
rename to assets/src/test/java/bisq/asset/coins/DSTRATest.java
index 0dfdac67d1e..d371044cfa4 100644
--- a/assets/src/test/java/bisq/asset/coins/ZeroOneCoinTest.java
+++ b/assets/src/test/java/bisq/asset/coins/DSTRATest.java
@@ -21,26 +21,24 @@
import org.junit.Test;
-public class ZeroOneCoinTest extends AbstractAssetTest {
+public class DSTRATest extends AbstractAssetTest {
- public ZeroOneCoinTest() {
- super(new ZeroOneCoin());
+ public DSTRATest() {
+ super(new DSTRA());
}
@Test
public void testValidAddresses() {
- assertValidAddress("ZN17ww22Kg1cqM2VykoDwZW4fCTCvxGQMb");
- assertValidAddress("ZZJG1oqJ9VWHAy5AuE7bAugqoYvcGtPJcH");
- assertValidAddress("ZaUSzTWurWuaBw4zr8E4oEN25DzJK9vwbR");
- assertValidAddress("5AchYc7iQS7ynce7hNZ6Ya8djsbm5N9JBS");
+ assertValidAddress("DGiwGS8n3tJZuKxUdWF6MyTYvv6xgDcyd7");
+ assertValidAddress("DQcAKx5bFoeRwAEHE4EHQykyq8u2M1pwFa");
}
@Test
public void testInvalidAddresses() {
- assertInvalidAddress("ZaUSzTWurWuaBw4zr8E4oEN25DzJK9vqqe");
- assertInvalidAddress("ZN17ww22Kg1cqM2VykoDwZW4fCTCvxGQM");
- assertInvalidAddress("ZaUSzTWurWuaBw4zr8E4oEN25DzJK9vwbb");
- assertInvalidAddress("Zb17ww22Kg1cqM2VykoDwZW4fCTCvxGQMb");
+ assertInvalidAddress("DGiwGS8n3tJZuKxUdWF6MyTYvv6xgDcyd77");
+ assertInvalidAddress("DGiwGS8n3tJZuKxUdWF6MyTYvv6xgDcyd");
+ assertInvalidAddress("dGiwGS8n3tJZuKxUdWF6MyTYvv6xgDcyd7");
+ assertInvalidAddress("FGiwGS8n3tJZuKxUdWF6MyTYvv6xgDcyd7");
+ assertInvalidAddress("fGiwGS8n3tJZuKxUdWF6MyTYvv6xgDcyd7");
}
-
-}
\ No newline at end of file
+}
diff --git a/assets/src/test/java/bisq/asset/coins/DoichainTest.java b/assets/src/test/java/bisq/asset/coins/DoichainTest.java
new file mode 100644
index 00000000000..5465a3415c7
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/DoichainTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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 bisq.asset.coins;
+
+import org.junit.Test;
+import bisq.asset.AbstractAssetTest;
+
+public class DoichainTest extends AbstractAssetTest {
+
+ public DoichainTest() {
+ super(new Doichain());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("NGHV9LstnZfrkGx5QJmYhEepbzc66W7LN5");
+ assertValidAddress("N4jeY9YhU49qHN5wUv7HBxeVZrFg32XFy7");
+ assertValidAddress("6a6xk7Ff6XbgrNWhSwn7nM394KZJNt7JuV");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("NGHV9LstnZfrkGx5QJmYhEepbzc66W7LN5x");
+ assertInvalidAddress("16iWWt1uoG8Dct56Cq6eKHFxvGSDha46Lo");
+ assertInvalidAddress("38BFQkc9CdyJUxQK8PhebnDcA1tRRwLDW4");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/GalilelTest.java b/assets/src/test/java/bisq/asset/coins/GalilelTest.java
new file mode 100644
index 00000000000..70726fcf7cb
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/GalilelTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class GalilelTest extends AbstractAssetTest {
+
+ public GalilelTest() {
+ super(new Galilel());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("UVwXGh5B1NZbYdgWThqf2cLdkEupVXEVNi");
+ assertValidAddress("UbNJbC1hZgBH5tQ4HyrrQMEPswKxwwfziw");
+ assertValidAddress("UgqDDV8aekEXFP7BWLmTNpSQfk7uVk1jCF");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("1UgqDDV8aekEXFP7BWLmTNpSQfk7uVk1jCF");
+ assertInvalidAddress("UgqDDV8aekEXFP7BWLmTNpSQfk7uVk1jCFd");
+ assertInvalidAddress("UgqDDV8aekEXFP7BWLmTNpSQfk7uVk1jCF#");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/GrinTest.java b/assets/src/test/java/bisq/asset/coins/GrinTest.java
index 22851f78bb6..83b602607a8 100644
--- a/assets/src/test/java/bisq/asset/coins/GrinTest.java
+++ b/assets/src/test/java/bisq/asset/coins/GrinTest.java
@@ -29,16 +29,6 @@ public GrinTest() {
@Test
public void testValidAddresses() {
- assertValidAddress("0.0.0.0:8080");
- assertValidAddress("173.194.34.134:8080");
- assertValidAddress("127.0.0.1:8080");
- assertValidAddress("192.168.0.1:8080");
- assertValidAddress("18.101.25.153:8080");
- assertValidAddress("173.194.34.134:1");
- assertValidAddress("173.194.34.134:11");
- assertValidAddress("173.194.34.134:1111");
- assertValidAddress("173.194.34.134:65535");
-
// grinbox
assertValidAddress("gVvk7rLBg3r3qoWYL3VsREnBbooT7nynxx5HtDvUWCJUaNCnddvY");
assertValidAddress("grinbox://gVtWzX5NTLCBkyNV19QVdnLXue13heAVRD36sfkGD6xpqy7k7e4a");
@@ -50,6 +40,18 @@ public void testValidAddresses() {
@Test
public void testInvalidAddresses() {
+ // valid IP:port addresses but not supported in Bisq
+ assertInvalidAddress("0.0.0.0:8080");
+ assertInvalidAddress("173.194.34.134:8080");
+ assertInvalidAddress("127.0.0.1:8080");
+ assertInvalidAddress("192.168.0.1:8080");
+ assertInvalidAddress("18.101.25.153:8080");
+ assertInvalidAddress("173.194.34.134:1");
+ assertInvalidAddress("173.194.34.134:11");
+ assertInvalidAddress("173.194.34.134:1111");
+ assertInvalidAddress("173.194.34.134:65535");
+
+ // invalid IP:port addresses
assertInvalidAddress("google.com");
assertInvalidAddress("100.100.100.100");
assertInvalidAddress(".100.100.100.100:1222");
@@ -71,6 +73,5 @@ public void testInvalidAddresses() {
assertInvalidAddress("gVw9TWimGFXRjoDXWhWxeNQbu84ZpLkvnenkKvA5aJeDo31eM5tC@somerelay.com:1220a");
assertInvalidAddress("grinbox://gVwjSsYW5vvHpK4AunJ5piKhhQTV6V3Jb818Uqs6PdC3SsB36AsAsomerelay.com");
assertInvalidAddress("grinbox://gVwjSsYW5vvHpK4AunJ5piKhhQTV6V3Jb818Uqs6PdC3SsB36AsA@somerelay.com1220");
-
}
}
diff --git a/assets/src/test/java/bisq/asset/coins/HatchTest.java b/assets/src/test/java/bisq/asset/coins/HatchTest.java
new file mode 100644
index 00000000000..634bae0e02e
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/HatchTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class HatchTest extends AbstractAssetTest {
+
+ public HatchTest() {
+ super(new Hatch());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("XgUfhrcfKWTVprA1GGhTggAA3VVQy1xqNp");
+ assertValidAddress("Xo88XjP8RD2w3k7Fd16UT62y3oNcjbv4bz");
+ assertValidAddress("XrA7ZGDLQkiLwUsfKT6y6tLrYjsvRLrZQG");
+
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("1XrA7ZGDLQkiLwUsfKT6y6tLrYjsvRLrZQG");
+ assertInvalidAddress("XrA7ZGDLQkiLwUsfKT6y6tLrYjsvRLrZQGd");
+ assertInvalidAddress("XrA7ZGDLQkiLwUsfKT6y6tLrYjsvRLrZQG#");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/HeliumTest.java b/assets/src/test/java/bisq/asset/coins/HeliumTest.java
new file mode 100644
index 00000000000..0fa127d382d
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/HeliumTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class HeliumTest extends AbstractAssetTest {
+
+ public HeliumTest() {
+ super(new Helium());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("SPSXRJSwzGKxSiYXePf1vnkk4v9WKVLhZp");
+ assertValidAddress("SbzXDLmMfWDJZ1wEikUVAMbAzM2UnaSt4g");
+ assertValidAddress("Sd14293Zhxxur2Pim7NkjxPGVaJTjGR5qY");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("1PSXRJSwzGKxSiYXePf1vnkk4v9WKVLhZp");
+ assertInvalidAddress("SPSXRJSwzGKxSiYXePf1vnkk4v9WKVLhZpp");
+ assertInvalidAddress("SPSSPSSPSGKxSiYXePf1vnkk4v9WKVLhZp");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/LitecoinPlusTest.java b/assets/src/test/java/bisq/asset/coins/LitecoinPlusTest.java
new file mode 100644
index 00000000000..c3a8b169d4d
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/LitecoinPlusTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class LitecoinPlusTest extends AbstractAssetTest {
+
+ public LitecoinPlusTest() {
+ super(new LitecoinPlus());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("XGnikpGiuDTaxq9vPfDF9m9VfTpv4SnNN5");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("1LgfapHEPhZbRF9pMd5WPT35hFXcZS1USrW");
+ assertInvalidAddress("LgfapHEPhZbdRF9pMd5WPT35hFXcZS1USrW");
+ assertInvalidAddress("LgfapHEPhZbRF9pMd5WPT35hFXcZS1USrW#");
+ }
+}
+
diff --git a/assets/src/test/java/bisq/asset/coins/LitecoinZTest.java b/assets/src/test/java/bisq/asset/coins/LitecoinZTest.java
new file mode 100644
index 00000000000..e8f2e63ed0b
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/LitecoinZTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class LitecoinZTest extends AbstractAssetTest {
+
+ public LitecoinZTest() {
+ super(new LitecoinZ());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("L17opZaVcRK4h9MV4KhkCmzUBa56BxSRb8A");
+ assertValidAddress("L1EjNbAPVtg8jE9EyvbsA7epibZ9j8bdYmV");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem");
+ assertInvalidAddress("38NwrYsD1HxQW5zfLT0QcUUXGMPvQgzTSn");
+ assertInvalidAddress("8tP9rh3SH6n9cSLmV22vnSNNw56LKGpLrB");
+ assertInvalidAddress("8Zbvjr");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/LytixTest.java b/assets/src/test/java/bisq/asset/coins/LytixTest.java
new file mode 100644
index 00000000000..12747938021
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/LytixTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class LytixTest extends AbstractAssetTest {
+
+ public LytixTest() {
+ super(new Lytix());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("8hTBZgtuexiUVMxCPcrPgMem7jurB2YJds");
+ assertValidAddress("8hqgpDE5uSuyRrDMXo1w3y59SCxfv8sSsf");
+ assertValidAddress("8wtCT2JHu4wd4JqCwxnWFQXhmggnwdjpSn");
+ assertValidAddress("8pYVReruVqYdp6LRhsy63nuVgsg9Rx7FJT");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("6pYVReruVqYdp6LRhsy63nuVgsg9Rx7FJT");
+ assertInvalidAddress("8mgfRRiHVxf4JZH3pvffuY6NrKhffh13Q");
+ assertInvalidAddress("8j75cPWABNXdZ62u6ZfF4tDQ1tVdvJx2oh7");
+ assertInvalidAddress("FryiHzNPFatNV15hTurq9iFWeHTrQhUhG6");
+ assertInvalidAddress("8ryiHzNPFatNV15hTurq9iFWefffQhUhG6");
+ assertInvalidAddress("8ryigz2PFatNV15hTurq9iFWeHTrQhUhG1");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/MirQuiXTest.java b/assets/src/test/java/bisq/asset/coins/MirQuiXTest.java
new file mode 100644
index 00000000000..cf86ad6ee56
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/MirQuiXTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class MirQuiXTest extends AbstractAssetTest {
+
+ public MirQuiXTest() {
+ super(new MirQuiX());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("MCfFP5bFtN9riJiRRnH2QRkqCDqgNVC3FX");
+ assertValidAddress("MEoLjNvFbNv63NtBW6eyYHUAGgLsJrpJbG");
+ assertValidAddress("M84gmHb7mg4PMNBpVt3BeeAWVuKBmH6vtd");
+ assertValidAddress("MNurUTgTSgg5ckmCcbjPrkgp7fekouLYgh");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("MCfFP5bFtN9riJiRRnH2QRkqCDqgNVC3FX2");
+ assertInvalidAddress("MmEoLjNvFbNv63NtBW6eyYHUAGgLsJrpJbG");
+ assertInvalidAddress("M84gmHb7mg4PMNBpVt3BeeAWVuKBmH63vtd");
+ assertInvalidAddress("MNurUTgTSgg5ckmCcbjPrkgp7fekouLYfgh");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/NavcoinTest.java b/assets/src/test/java/bisq/asset/coins/NavcoinTest.java
new file mode 100644
index 00000000000..55a1182d8c3
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/NavcoinTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class NavcoinTest extends AbstractAssetTest {
+
+ public NavcoinTest() {
+ super(new Navcoin());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("NNR93HzmuhYKZ4Tnc9TGoD2DK6TVzXG9P7");
+ assertValidAddress("NSm5NyCe5BFRuV3gFY5VcfhxWx7GTu9U9F");
+ assertValidAddress("NaSdzJ64o8DQo5DMPexVrL4PYFCBZqcmsW");
+
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("NNR93HzmuhYKZ4Tnc9TGoD2DK6TVzXG9P");
+ assertInvalidAddress("NNR93HzmuhYKZ4TnO9TGoD2DK6TVzXG9P8");
+ assertInvalidAddress("NNR93HzmuhYKZ4Tnc9TGoD2DK6TVzXG9P71");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/ParsiCoinTest.java b/assets/src/test/java/bisq/asset/coins/ParsiCoinTest.java
new file mode 100644
index 00000000000..3840990d15f
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/ParsiCoinTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class ParsiCoinTest extends AbstractAssetTest {
+
+ public ParsiCoinTest() {
+ super(new ParsiCoin());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("PARSGnjdcRG4gY9g4rMTFAEHZLGU7uK8YMiFY3Do1uzoMz4LMA6PqmdPp7ZxDu25b56RyhCevkWjbAMng532iFFj8L5RaPyT4s");
+ assertValidAddress("PARSftfY5pwJaUFtaxThVgKY9Sepd4mG44WpyncbtAxTddwTvJ84GCgGfoxYjzG53kLhRm21ENWp3fx5bneArq1D815ZoWNVqA");
+ assertValidAddress("PARSju1hCQ5GmXSRbca8weGYDn2pqCypgLyTrENqL4XU3mdEx1mZ2vR7osrVA2hHNGRJRA5pRENF2Q8Pee8BscHoABVrcfkWnx");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("");
+ assertInvalidAddress("1GfqxEuuFmwwHTFkch3Aq3frEBbdpYfWPP");
+ assertInvalidAddress("PARsaUEu1c9HWPQx6WpCcjZNmpS3vMhN4Jws12KrccLhH9vzUw4racG3g7St2FKDYngjcnkNF3N2sKQJ5jv1NYqD2buCpmVKE");
+ assertInvalidAddress("PArSeoCiQL2Rjyo9GR39boeLCTM6ou3zGiv8AuFFblGHfNasy5iKfvG6JgnksNby26J6i5sEorRcmG8gF2AxC8bYiHyDGEfD6hp8T9KfwjQxVa");
+ assertInvalidAddress("PaRSaUEu1c9HWPQx6WpCcjZNmpS3vMhN4Jws12rccLhH9vzUw4racG3g7St2#FKDYngjcnkNF3N2sKQJ5jv1NYqD2buCpmVKE");
+ assertInvalidAddress("pARSeoCiQL2Rjyo9GR39boeLCTM6ou3zGiv8AuFFby5iKfvG6JNby26J6i5s$&*orRcmG8gF2AxC8bYiHyDGEfD6hp8T9KfwjQxVa");
+ assertInvalidAddress("hyrjMmPhaznQkJD6C9dcmbBH9y6r9vYAg2aTG9CHSzL1R89xrFi7wj1azmkXyLPiWDBeTCsKGMmr6JzygbP2ZGSN2JqWs1WcK");
+ assertInvalidAddress("parsGnjdcRG4gY9g4rMTFAEHZLGU7uK8YMiFY3Do1uzoMz4LMA6PqmdPp7ZxDu25b56RyhCevkWjbAMng532iFFj8L5RaPyT");
+ }
+}
\ No newline at end of file
diff --git a/assets/src/test/java/bisq/asset/coins/PlenteumTest.java b/assets/src/test/java/bisq/asset/coins/PlenteumTest.java
new file mode 100644
index 00000000000..ce36a0f819c
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/PlenteumTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class PlenteumTest extends AbstractAssetTest {
+
+ public PlenteumTest() {
+ super(new Plenteum());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("PLeah9bvqxEDUWbRFqgNcYDeoL772WH9mcCQu9p29MC23NeCUkbVdUEfwDAtF8SgV81kf2hwCdpxqAJmC9k3nJsA7W4UThrufj");
+ assertValidAddress("PLeavHTKHz9UcTCSCmd8eihuLxbsK9a7wSpfcYXPYY87JMpvYwwTH6Df32fRLc1r4rQMKoDLpTvywXx4FUVTggCR4jh9PEhvXb");
+ assertValidAddress("PLeazd7iQEoFWJttR6353BMvs1cJfMqDmEUk2Z2XSoDdZigY5CbNLvrFUr7duvnEFdSKRdCQYTDkrcySYD1zaFtT9YMubRjHL2");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("PLev23ymatPTWgN1jncG33hMdJxZBLrBcCWQBGGGC14CFMUCq1nvxiV8d5cW92mmavzw542bpyjYXd8");
+ assertInvalidAddress("PLeuxauCnCH7XZrSZSZw7XEEbkgrnZcaE1MK8wLtTYkF3g1J7nciYiaZDsTNYm2oDLTAM2JPq4rrlhVN5cXWpTPYh8P5wKbXNdoh");
+ assertInvalidAddress("");
+ assertInvalidAddress("PLev3xxpAFfXKwF5ond4sWDX3ATpZngT88KpPCCJKcuRjGktgp5HHTK2yV7NTo8687u5jwMigLmHaoFKho0OhVmF8WP9pVZhBL9kC#RoPOWRwpsx1F");
+ assertInvalidAddress("PLeuwafXHTPzj1d2wc7c9X69r3qG1277ecnLnUaZ61M1YV5d3GYAs1Jbc2q4C4fWN$C4fWNLoDLDvADvpjNYdt3sdRB434UidKXimQQn");
+ assertInvalidAddress("1jRo3rcp9fjdfjdSGpx");
+ assertInvalidAddress("GDARp92UtmTWDjZatG8sduRockSteadyWasHere3atrHSXr9vJzjHq2TfPrjateDz9Wc8ZJKuDayqJ$%");
+ assertInvalidAddress("F3xQ8Gv6xnvDhUrM57z71bfFvu9HeofXtXpZRLnrCN2s2cKvkQowrWjJTGz4676ymKvU4NzYT5Aadgsdhsdfhg4gfJwL2yhhkJ7");
+ }
+}
\ No newline at end of file
diff --git a/assets/src/test/java/bisq/asset/coins/QwertycoinTest.java b/assets/src/test/java/bisq/asset/coins/QwertycoinTest.java
new file mode 100644
index 00000000000..ed39da44b71
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/QwertycoinTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+import org.junit.Test;
+
+public class QwertycoinTest extends AbstractAssetTest {
+
+ public QwertycoinTest() {
+ super(new Qwertycoin());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("QWC1NStUeRB9hZiYH8sG5RAWEt7YycyB44YZnpZQBpgq4CLwmLw4vAk9tU3h7Td21NL9aMbLHxseDGKdEv3gRexo2QCodNEZWa");
+ assertValidAddress("QWC1anUNJRo2HePBmenLFkGu8rnug4odGLCjHaCqAwMxboiZZS3Gv9ACLfn2zvcsGVcCc51eqZXB8Dot9X5qAt3F53F8BxjDrG");
+ assertValidAddress("QWC1hgpbsxsPrpxH9H3wL771p4KdgS7vA369PQTiznHiCC3NjZxKJSmBtJPVCJBBUKE346FcPTsQ18W6fgiDzj762BHNgo2sir");
+ assertValidAddress("QWC1YAvWpYBVs8XT2eSt2JV5iAJSdm8CwbQhDruuBeTzRNKSdtdK8Mn3WjaXQrFvjMMWWTf24x89p31mWppJN2Br9uiA5zdYQu");
+ assertValidAddress("QWC1YzR91Zmcj7fpf1HRZhSfz6cgXbxqAVTjQTtrUV6Bfv1ysEzb78qgVojE7FuQWSRnVqSb3LyxP9nH2q4vWyo82Fonutfkzr");
+ assertValidAddress("QWC1KYAwX6sRXK94HabKLCFNMjfC12KFC74cRjTgFtsD79VUBydTtMd3G2z4xLg2e1LKaXsTt3zkYibH3pBrAMjd5z5ConjRXn");
+ assertValidAddress("QWC1ZgSyFwS3tUbmCRPGDBi224ynMZXgXCHxvQ5pEmtuZSCrmid4z1de1DWRjhZKRZXe4E5LYhtP6e7FmpN8R2MM2SHGFvg12z");
+ assertValidAddress("QWC1W7223e83cBdseddQp461j49bhr7y4VHh8FTPs7qWArhpqBzNvrYR5QXyFtc3eRaoASo3QVhuT6ogAa6AHhgt4bVMUNpZGh");
+ assertValidAddress("QWC1NgBcSwvXghUkEqGttNPSSmPEgEdknXELNLyTG444Fx3cKkV2oJ9iCwzySbps7y9BqqkWAKbkvdkA8FTspfdm29ScDzASK1");
+ assertValidAddress("QWC1FVgbYqkafwnpW8KU2gKXLTKoraMXuEJ2c1yG6PNdesh6BA3Wq8d1mgRYqfsbCn53g5VLHuxyLT8CXnGRLxN64wHssuSa9D");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("");
+ assertInvalidAddress("QW009s5NiYva6XS9bhhVc6jKYgXsH9wuHhZhWsqyAoPoWPUEiwEo9AZCDNbksvknyvZk73zwhHWSiXdgcDGLyhk5teEM7yxTgk");
+ assertInvalidAddress("WC115a2NPZy7Xe2WZt3nKMZBsBpgNdevnKfy6PLk99eCjYw5fWQ5nu4uM6LerRBvVKTJpdGp2acZ25X3QDPHc7ocTxz1WfN2Za");
+ assertInvalidAddress("34BQWC8imA1UH29uR6PHiGpcz9MYdnL3rku27gGeLosn5XuSedFC7jPBmzaB9DoxmDA5VUZa5hPv6PSe3tJH2MJhBktMEJXaZ8");
+ assertInvalidAddress("KWC45Ghz2JRTTrLh8Z4bm6QhzZxVbq7LPiKbgjjhHPNDvVXZAJLop91zRu9A7wJMjyrU89uF7QpZB5kHhniuGZ88MJv7jRZXNi");
+ assertInvalidAddress("ABc58FFmFEGcS52mTWmhAskQaKSSiX1BnHo8YcDjuhPdYBpWT9Q6ZCDz54k6cs3jPF2nk6desb1T6vRfHLfthiNf561qPct2SY");
+ assertInvalidAddress("2K267rMF5ve4nt2wTHYJ1pZ6j3o2YP5KDBnE7GDxnr6bpem9WcqeHzw9yKWXvtxYdpDXCBbLiX9nm97r4aEtnXq8YNb9WPn15f");
+ assertInvalidAddress("798Qr9sWTprQ2sH2y5PGpfV3RAnFxUsJYY2a2VQWCA9GjZ3MiyScD8VEh8ifWk4toYRCcbLZmRJw2dSsJBJAJ1Ava8WBzW7J12");
+ assertInvalidAddress("A2o85CQSLDNNKR4HGHwhtsxhm8jheYEvk6ngf44AhqCRWDV2XsaTHr6ittDuyfCjinAP1SzBqnVJfqNhYGDJLzxq4Y7FBVofXV");
+ assertInvalidAddress("QW9AeKW87bkao59oadmTXGf8Jv7sMYByPrKahRbnmZEmGzRgoxGRbWqmmXuPDW6jPJSUAdpZRZn6E5B9935LtWD5gHAPpZQA");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/TEOTest.java b/assets/src/test/java/bisq/asset/coins/TEOTest.java
new file mode 100644
index 00000000000..66f67b605ff
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/TEOTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class TEOTest extends AbstractAssetTest {
+
+ public TEOTest() {
+ super(new TEO());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("0x8d1ba0497c3e3db17143604ab7f5e93a3cbac68b");
+ assertValidAddress("0x23c9c5ae8c854e9634a610af82924a5366a360a3");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("");
+ assertInvalidAddress("8d1ba0497c3e3db17143604ab7f5e93a3cbac68b");
+ assertInvalidAddress("0x8d1ba0497c3e3db17143604ab7f5e93a3cbac68");
+ assertInvalidAddress("0x8d1ba0497c3e3db17143604ab7f5e93a3cbac68k");
+ assertInvalidAddress("098d1ba0497c3e3db17143604ab7f5e93a3cbac68b");
+ assertInvalidAddress("098d1ba0497c3e3db17143604ab7f5e93a3cbac68b");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/VeilTest.java b/assets/src/test/java/bisq/asset/coins/VeilTest.java
new file mode 100644
index 00000000000..68e9ca856a3
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/VeilTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+import org.junit.Test;
+
+public class VeilTest extends AbstractAssetTest {
+
+ public VeilTest() {
+ super(new Veil());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("VS2oF2pouKoLPJCjY8D7E1dStmUtitACu7");
+ assertValidAddress("VV8VtpWTsYFBnhnvgQVnTvqoTx7XRRevte");
+ assertValidAddress("VRZF4Am891FS224uuNirsrEugqMyg3VxjJ");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhemqq");
+ assertInvalidAddress("3EktnHQD7RiAE6uzMj2ZifT9YgRrkSgzQX");
+ assertInvalidAddress("DRbnCYbuMXdKU4y8dya9EnocL47gFjErWeg");
+ assertInvalidAddress("DTPAqTryNRCE2FgsxzohTtJXfCBODnG6Rc");
+ assertInvalidAddress("DTPAqTryNRCE2FgsxzohTtJXfCB0DnG6Rc");
+ assertInvalidAddress("DTPAqTryNRCE2FgsxzohTtJXfCBIDnG6Rc");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/XDRTest.java b/assets/src/test/java/bisq/asset/coins/XDRTest.java
new file mode 100644
index 00000000000..dcf61c808fc
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/XDRTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class XDRTest extends AbstractAssetTest {
+
+ public XDRTest() {
+ super(new XDR());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("2WeY8JpRJgrvWQxbSPuyhsBMjtZMMN7cADEomPHh2bCkdZ7xQW");
+ assertValidAddress("NTvSfK1Gr5Jg97UvJo2wvi7BTZo8KqJzgSL2FCGucF6nUH7yq");
+ assertValidAddress("ztNdPsuyfDWt1ufCbDqaCDQH3FXvucXNZqVrdzsWvzDHPrkSh");
+ assertValidAddress("jkvx3z98rJmuVKqMSktDpKTSBrsqJEtTBW1CBSWJEtchDGkDX");
+ assertValidAddress("is2YXBxk91d4Lw4Pet7RoP8KAxCKFHUC6iQyaNgmac5ies6ko");
+ assertValidAddress("2NNEr5YLniGxWajoeXiiAZPR68hJXncnhEmC4GWAaV5kwaLRcP");
+ assertValidAddress("wGmjgRu8hgjgRsRV8k6h2puis1K9UQCTKWZEPa4yS8mrmJUpU");
+ assertValidAddress("i8rc9oMunRtVbSxA4VBESxbYzHnfhP39aM5M1srtxVZ8oBiKD");
+ assertValidAddress("vP4w8khXHFQ7cJ2BJNyPbJiV5kFfBHPVivHxKf5nyd8cEgB9U");
+ assertValidAddress("QQQZZa46QJ3499RL8CatuqaUx4haKQGUuZ4ZE5SeL13Awkf6m");
+ assertValidAddress("qqqfpHD3VbbyZXTHgCW2VX8jvoERcxanzQkCqVyHB8fRBszMn");
+ assertValidAddress("BiSQkPqCCET4UovJASnnU1Hk5bnqBxBVi5bjA5wLZpN9HCA6A");
+ assertValidAddress("bisqFm6Zbf6ULcpJqQ2ibn2adkL2E9iivQFTAP15Q18daQxnS");
+ assertValidAddress("miLEgbhGv4ARoPG2kAhTCy8UGqBcFbsY6rr5tXq63nH8RyqcE");
+
+
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("1WeY8JpRJgrvWQxbSPuyhsBMjtZMMN7cADEomPHh2bCkdZ7xQW");
+ assertInvalidAddress("2WeY8JpRJgrvWQxbSPuyhsBMjtZMMN3cADEomPHh2bCkdZ7xQW");
+ assertInvalidAddress("2WeY8JpRJgrvWQxbSPuyhsBMjtZMMN7cADEomPHh2bCkdZ7xQ1");
+ assertInvalidAddress("2WeY8JpRJgrvWQxbSPuyhsBMjtZMMN7cADEomPHh2bCkdZ7xQ");
+ assertInvalidAddress("WeY8JpRJgrvWQxbSPuyhsBMjtZMMN7cADEomPHh2bCkdZ7xQW");
+ assertInvalidAddress("2WeY8JpRJgrvWQx");
+ assertInvalidAddress("2WeY8JpRJgrvWQxbSPuyhsBMjtZMMN7cADEomPHh2bCkdZ7xQW1");
+ assertInvalidAddress("milEgbhGv4ARoPG2kAhTCy8UGqBcFbsY6rr5tXq63nH8RyqcE");
+ assertInvalidAddress("miLegbhGv4ARoPG2kAhTCy8UGqBcFbsY6rr5tXq63nH8RyqcE");
+ assertInvalidAddress("1111111");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/coins/ZeroClassicTest.java b/assets/src/test/java/bisq/asset/coins/ZeroClassicTest.java
new file mode 100644
index 00000000000..d175790f77d
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/coins/ZeroClassicTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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 bisq.asset.coins;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class ZeroClassicTest extends AbstractAssetTest {
+
+ public ZeroClassicTest() {
+ super(new ZeroClassic());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("t1PLfc14vCYaRz6Nv1zxpKXhn5W5h9vUdUE");
+ assertValidAddress("t1MjXvaqL5X2CquP8hLmvyxCiJqCBzuMofS");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem");
+ assertInvalidAddress("38NwrYsD1HxQW5zfLT0QcUUXGMPvQgzTSn");
+ assertInvalidAddress("8tP9rh3SH6n9cSLmV22vnSNNw56LKGpLrB");
+ assertInvalidAddress("8Zbvjr");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/tokens/AugmintEuroTest.java b/assets/src/test/java/bisq/asset/tokens/AugmintEuroTest.java
new file mode 100644
index 00000000000..0a7013da8b7
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/tokens/AugmintEuroTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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 bisq.asset.tokens;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class AugmintEuroTest extends AbstractAssetTest {
+
+ public AugmintEuroTest() {
+ super(new AugmintEuro());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("0x0d81d9e21bd7c5bb095535624dcb0759e64b3899");
+ assertValidAddress("0d81d9e21bd7c5bb095535624dcb0759e64b3899");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("0x65767ec6d4d3d18a200842352485cdc37cbf3a216");
+ assertInvalidAddress("0x65767ec6d4d3d18a200842352485cdc37cbf3a2g");
+ assertInvalidAddress("65767ec6d4d3d18a200842352485cdc37cbf3a2g");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/tokens/DaiStablecoinTest.java b/assets/src/test/java/bisq/asset/tokens/DaiStablecoinTest.java
new file mode 100644
index 00000000000..d567cce57da
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/tokens/DaiStablecoinTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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 bisq.asset.tokens;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class DaiStablecoinTest extends AbstractAssetTest {
+
+ public DaiStablecoinTest() {
+ super(new DaiStablecoin());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("0x2a65Aca4D5fC5B5C859090a6c34d164135398226");
+ assertValidAddress("2a65Aca4D5fC5B5C859090a6c34d164135398226");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("0x2a65Aca4D5fC5B5C859090a6c34d1641353982266");
+ assertInvalidAddress("0x2a65Aca4D5fC5B5C859090a6c34d16413539822g");
+ assertInvalidAddress("2a65Aca4D5fC5B5C859090a6c34d16413539822g");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/tokens/TrueUSDTest.java b/assets/src/test/java/bisq/asset/tokens/TrueUSDTest.java
new file mode 100644
index 00000000000..e86612cdda8
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/tokens/TrueUSDTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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 bisq.asset.tokens;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class TrueUSDTest extends AbstractAssetTest {
+
+ public TrueUSDTest() {
+ super(new TrueUSD());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("0xa23579c2f7b462e5fb2e92f8cf02971fe4de4f82");
+ assertValidAddress("0xdb59b63738e27e6d689c9d72c92c7a12f22161bb");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("0x2a65Aca4D5fC5B5C859090a6c34d1641353982266");
+ assertInvalidAddress("0x2a65Aca4D5fC5B5C859090a6c34d16413539822g");
+ assertInvalidAddress("2a65Aca4D5fC5B5C859090a6c34d16413539822g");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/tokens/USDCoinTest.java b/assets/src/test/java/bisq/asset/tokens/USDCoinTest.java
new file mode 100644
index 00000000000..dd76c40e908
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/tokens/USDCoinTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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 bisq.asset.tokens;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class USDCoinTest extends AbstractAssetTest {
+
+ public USDCoinTest() {
+ super(new USDCoin());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("0xb86bb5fc804768db34f1a37da8b719e19af9dffd");
+ assertValidAddress("0xea82afd93ebfc4f6564f3e5bd823cdef710f75dd");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("0x2a65Aca4D5fC5B5C859090a6c34d1641353982266");
+ assertInvalidAddress("0x2a65Aca4D5fC5B5C859090a6c34d16413539822g");
+ assertInvalidAddress("2a65Aca4D5fC5B5C859090a6c34d16413539822g");
+ }
+}
diff --git a/assets/src/test/java/bisq/asset/tokens/VectorspaceAITest.java b/assets/src/test/java/bisq/asset/tokens/VectorspaceAITest.java
new file mode 100644
index 00000000000..4e4e5e4cc42
--- /dev/null
+++ b/assets/src/test/java/bisq/asset/tokens/VectorspaceAITest.java
@@ -0,0 +1,42 @@
+/*
+ * 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 bisq.asset.tokens;
+
+import bisq.asset.AbstractAssetTest;
+
+import org.junit.Test;
+
+public class VectorspaceAITest extends AbstractAssetTest {
+
+ public VectorspaceAITest () {
+ super(new VectorspaceAI());
+ }
+
+ @Test
+ public void testValidAddresses() {
+ assertValidAddress("0xdd88dbdde30b684798881d4f3d9a3752d6c1dd71");
+ assertValidAddress("dd88dbdde30b684798881d4f3d9a3752d6c1dd71");
+ }
+
+ @Test
+ public void testInvalidAddresses() {
+ assertInvalidAddress("0x2ecf455d8a2e6baf8d1039204c4f97efeddf27a82");
+ assertInvalidAddress("0xh8wheG1jdka0c8b8263758chanbmshj2937zgab");
+ assertInvalidAddress("h8wheG1jdka0c8b8263758chanbmshj2937zgab");
+ }
+}
diff --git a/build.gradle b/build.gradle
index 92e2892da56..92316e488df 100644
--- a/build.gradle
+++ b/build.gradle
@@ -33,8 +33,7 @@ configure(subprojects) {
jmockitVersion = '1.42'
joptVersion = '5.0.3'
langVersion = '3.4'
- libdohjVersion = '7be803fa'
- bitcoinjVersion = 'cd30ad5b'
+ bitcoinjVersion = 'a88d36d'
logbackVersion = '1.1.10'
lombokVersion = '1.18.2'
mockitoVersion = '2.21.0'
@@ -66,7 +65,8 @@ configure([project(':desktop'),
project(':monitor'),
project(':relay'),
project(':seednode'),
- project(':statsnode')]) {
+ project(':statsnode'),
+ project(':pricenode')]) {
apply plugin: 'application'
@@ -132,13 +132,14 @@ configure([project(':desktop'),
configure(project(':assets')) {
dependencies {
- compile("network.bisq.libdohj:libdohj-core:$libdohjVersion") {
- exclude(module: 'protobuf-java')
- exclude(module: 'bitcoinj-core')
- }
compile("com.github.bisq-network.bitcoinj:bitcoinj-core:$bitcoinjVersion") {
+ exclude(module: 'jsr305')
+ exclude(module: 'slf4j-api')
+ exclude(module: 'guava')
exclude(module: 'protobuf-java')
}
+ compile 'com.google.guava:guava:20.0'
+ compile "org.slf4j:slf4j-api:$slf4jVersion"
compile "commons-codec:commons-codec:$codecVersion"
compile "org.apache.commons:commons-lang3:$langVersion"
compile "org.bouncycastle:bcpg-jdk15on:$bcVersion"
@@ -174,11 +175,6 @@ configure(project(':common')) {
compile('com.google.inject:guice:4.1.0') {
exclude(module: 'guava')
}
- compile("network.bisq.libdohj:libdohj-core:$libdohjVersion") {
- exclude(module: 'slf4j-api')
- exclude(module: 'protobuf-java')
- exclude(module: 'bitcoinj-core')
- }
compile("com.github.bisq-network.bitcoinj:bitcoinj-core:$bitcoinjVersion") {
exclude(module: 'jsr305')
exclude(module: 'slf4j-api')
@@ -199,10 +195,10 @@ configure(project(':common')) {
configure(project(':p2p')) {
dependencies {
compile project(':common')
- compile('com.github.JesusMcCloud.netlayer:tor.native:0.6.3') {
+ compile('com.github.JesusMcCloud.netlayer:tor.native:0.6.5') {
exclude(module: 'slf4j-api')
}
- compile('com.github.JesusMcCloud.netlayer:tor.external:0.6.3') {
+ compile('com.github.JesusMcCloud.netlayer:tor.external:0.6.5') {
exclude(module: 'slf4j-api')
}
compile('org.apache.httpcomponents:httpclient:4.5.3') {
@@ -276,7 +272,7 @@ configure(project(':desktop')) {
apply plugin: 'witness'
apply from: '../gradle/witness/gradle-witness.gradle'
- version = '0.9.3-SNAPSHOT'
+ version = '1.1.2-SNAPSHOT'
mainClassName = 'bisq.desktop.app.BisqAppMain'
@@ -339,6 +335,7 @@ configure(project(':monitor')) {
}
dependencies {
+ compile project(':core')
compile "org.slf4j:slf4j-api:$slf4jVersion"
compile "ch.qos.logback:logback-core:$logbackVersion"
compile "ch.qos.logback:logback-classic:$logbackVersion"
@@ -347,10 +344,6 @@ configure(project(':monitor')) {
compileOnly "org.projectlombok:lombok:$lombokVersion"
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
- compile('com.github.JesusMcCloud.netlayer:tor.native:0.6.2') {
- exclude(module: 'slf4j-api')
- }
-
testCompile 'org.junit.jupiter:junit-jupiter-api:5.3.2'
testCompile 'org.junit.jupiter:junit-jupiter-params:5.3.2'
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
diff --git a/common/src/main/java/bisq/common/Clock.java b/common/src/main/java/bisq/common/Clock.java
index 43f990011e9..3383b8eba51 100644
--- a/common/src/main/java/bisq/common/Clock.java
+++ b/common/src/main/java/bisq/common/Clock.java
@@ -21,22 +21,24 @@
import java.util.List;
import java.util.concurrent.TimeUnit;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import lombok.extern.slf4j.Slf4j;
// Helps configure listener objects that are run by the `UserThread` each second
// and can do per second, per minute and delayed second actions.
+@Slf4j
public class Clock {
- private static final Logger log = LoggerFactory.getLogger(Clock.class);
-
- public static final int IDLE_TOLERANCE = 20000;
+ public static final int IDLE_TOLERANCE_MS = 20000;
public interface Listener {
void onSecondTick();
void onMinuteTick();
- void onMissedSecondTick(long missed);
+ default void onMissedSecondTick(long missedMs) {
+ }
+
+ default void onAwakeFromStandby(long missedMs) {
+ }
}
private Timer timer;
@@ -51,18 +53,24 @@ public void start() {
if (timer == null) {
lastSecondTick = System.currentTimeMillis();
timer = UserThread.runPeriodically(() -> {
- listeners.stream().forEach(Listener::onSecondTick);
+ listeners.forEach(Listener::onSecondTick);
counter++;
if (counter >= 60) {
counter = 0;
- listeners.stream().forEach(Listener::onMinuteTick);
+ listeners.forEach(Listener::onMinuteTick);
}
long currentTimeMillis = System.currentTimeMillis();
long diff = currentTimeMillis - lastSecondTick;
- if (diff > 1000)
- listeners.stream().forEach(listener -> listener.onMissedSecondTick(diff - 1000));
-
+ if (diff > 1000) {
+ long missedMs = diff - 1000;
+ listeners.forEach(listener -> listener.onMissedSecondTick(missedMs));
+
+ if (missedMs > Clock.IDLE_TOLERANCE_MS) {
+ log.info("We have been in standby mode for {} sec", missedMs / 1000);
+ listeners.forEach(listener -> listener.onAwakeFromStandby(missedMs));
+ }
+ }
lastSecondTick = currentTimeMillis;
}, 1, TimeUnit.SECONDS);
}
diff --git a/common/src/main/java/bisq/common/Envelope.java b/common/src/main/java/bisq/common/Envelope.java
index 40fc91b8966..c713e8a26c6 100644
--- a/common/src/main/java/bisq/common/Envelope.java
+++ b/common/src/main/java/bisq/common/Envelope.java
@@ -18,7 +18,7 @@
package bisq.common;
/**
- * Interface for the outside envelope object sent over the network or persisted to disc.
+ * Interface for the outside envelope object sent over the network or persisted to disk.
*/
public interface Envelope extends Proto {
}
diff --git a/common/src/main/java/bisq/common/UserThread.java b/common/src/main/java/bisq/common/UserThread.java
index c46b576d22d..d7b994eeda5 100644
--- a/common/src/main/java/bisq/common/UserThread.java
+++ b/common/src/main/java/bisq/common/UserThread.java
@@ -37,7 +37,7 @@
* For JavaFX it is usually the Platform::RunLater executor, for a headless application it is any single threaded
* executor.
* Additionally sets a timer class so JavaFX and headless applications can set different timers (UITimer for JavaFX
- * otherwise we use teh default FrameRateTimer).
+ * otherwise we use the default FrameRateTimer).
*
* Provides also methods for delayed and periodic executions.
*/
diff --git a/common/src/main/java/bisq/common/app/Capabilities.java b/common/src/main/java/bisq/common/app/Capabilities.java
index 015a98c74f8..841b9d1c494 100644
--- a/common/src/main/java/bisq/common/app/Capabilities.java
+++ b/common/src/main/java/bisq/common/app/Capabilities.java
@@ -17,55 +17,106 @@
package bisq.common.app;
-import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.stream.Collectors;
-import lombok.Getter;
-import lombok.Setter;
+import lombok.EqualsAndHashCode;
+/**
+ * hold a set of capabilities and offers appropriate comparison methods.
+ *
+ * @author Florian Reimair
+ */
+@EqualsAndHashCode
public class Capabilities {
- // We can define here special features the client is supporting.
- // Useful for updates to new versions where a new data type would break backwards compatibility or to
- // limit a node to certain behaviour and roles like the seed nodes.
- // We don't use the Enum in any serialized data, as changes in the enum would break backwards compatibility. We use the ordinal integer instead.
- // Sequence in the enum must not be changed (append only).
- public enum Capability {
- TRADE_STATISTICS,
- TRADE_STATISTICS_2,
- ACCOUNT_AGE_WITNESS,
- SEED_NODE,
- DAO_FULL_NODE,
- PROPOSAL,
- BLIND_VOTE,
- ACK_MSG,
- BSQ_BLOCK
+
+ /**
+ * The global set of capabilities, i.e. the capabilities if the local app.
+ */
+ public static final Capabilities app = new Capabilities();
+
+ protected final Set capabilities = new HashSet<>();
+
+ public Capabilities(Capability... capabilities) {
+ this(Arrays.asList(capabilities));
+ }
+
+ public Capabilities(Capabilities capabilities) {
+ this(capabilities.capabilities);
+ }
+
+ public Capabilities(Collection capabilities) {
+ this.capabilities.addAll(capabilities);
+ }
+
+ public void set(Capability... capabilities) {
+ set(Arrays.asList(capabilities));
+ }
+
+ public void set(Capabilities capabilities) {
+ set(capabilities.capabilities);
+ }
+
+ public void set(Collection capabilities) {
+ this.capabilities.clear();
+ this.capabilities.addAll(capabilities);
}
- // Application need to set supported capabilities at startup
- @Getter
- @Setter
- private static List supportedCapabilities = new ArrayList<>();
+ public void addAll(Capability... capabilities) {
+ this.capabilities.addAll(Arrays.asList(capabilities));
+ }
+
+ public void addAll(Capabilities capabilities) {
+ if(capabilities != null)
+ this.capabilities.addAll(capabilities.capabilities);
+ }
+
+ public boolean containsAll(final Set requiredItems) {
+ return capabilities.containsAll(requiredItems);
+ }
+
+ public boolean containsAll(final Capabilities capabilities) {
+ return containsAll(capabilities.capabilities);
+ }
+
+ public boolean isEmpty() {
+ return capabilities.isEmpty();
+ }
+
+
+ /**
+ * helper for protobuffer stuff
+ *
+ * @param capabilities
+ * @return int list of Capability ordinals
+ */
+ public static List toIntList(Capabilities capabilities) {
+ return capabilities.capabilities.stream().map(capability -> capability.ordinal()).sorted().collect(Collectors.toList());
+ }
+
+ /**
+ * helper for protobuffer stuff
+ *
+ * @param capabilities a list of Capability ordinals
+ * @return a {@link Capabilities} object
+ */
+ public static Capabilities fromIntList(List capabilities) {
+ return new Capabilities(capabilities.stream()
+ .filter(integer -> integer < Capability.values().length)
+ .map(integer -> Capability.values()[integer])
+ .collect(Collectors.toSet()));
+ }
- public static void addCapability(int capability) {
- supportedCapabilities.add(capability);
+ @Override
+ public String toString() {
+ return Arrays.toString(Capabilities.toIntList(this).toArray());
}
- public static boolean isCapabilitySupported(final List requiredItems, final List supportedItems) {
- if (requiredItems != null && !requiredItems.isEmpty()) {
- if (supportedItems != null && !supportedItems.isEmpty()) {
- List matches = new ArrayList<>();
- for (int requiredItem : requiredItems) {
- matches.addAll(supportedItems.stream()
- .filter(supportedItem -> requiredItem == supportedItem)
- .collect(Collectors.toList()));
- }
- return matches.size() == requiredItems.size();
- } else {
- return false;
- }
- } else {
- return true;
- }
+ public int size() {
+ return capabilities.size();
}
}
diff --git a/common/src/main/java/bisq/common/app/Capability.java b/common/src/main/java/bisq/common/app/Capability.java
new file mode 100644
index 00000000000..83e4d0f1136
--- /dev/null
+++ b/common/src/main/java/bisq/common/app/Capability.java
@@ -0,0 +1,36 @@
+/*
+ * 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 bisq.common.app;
+
+// We can define here special features the client is supporting.
+// Useful for updates to new versions where a new data type would break backwards compatibility or to
+// limit a node to certain behaviour and roles like the seed nodes.
+// We don't use the Enum in any serialized data, as changes in the enum would break backwards compatibility. We use the ordinal integer instead.
+// Sequence in the enum must not be changed (append only).
+public enum Capability {
+ TRADE_STATISTICS,
+ TRADE_STATISTICS_2,
+ ACCOUNT_AGE_WITNESS,
+ SEED_NODE,
+ DAO_FULL_NODE,
+ PROPOSAL,
+ BLIND_VOTE,
+ ACK_MSG,
+ BSQ_BLOCK,
+ DAO_STATE
+}
diff --git a/common/src/main/java/bisq/common/app/DevEnv.java b/common/src/main/java/bisq/common/app/DevEnv.java
index d1ed2579dc7..14429b7a3bb 100644
--- a/common/src/main/java/bisq/common/app/DevEnv.java
+++ b/common/src/main/java/bisq/common/app/DevEnv.java
@@ -52,10 +52,7 @@ public static void setDevMode(boolean devMode) {
DevEnv.devMode = devMode;
}
- private static final boolean DAO_PHASE2_ACTIVATED = false;
- private static final boolean DAO_TRADING_ACTIVATED = false;
-
- private static boolean daoActivated = false;
+ private static boolean daoActivated = true;
public static boolean isDaoActivated() {
return daoActivated;
@@ -71,11 +68,7 @@ public static void logErrorAndThrowIfDevMode(String msg) {
throw new RuntimeException(msg);
}
- public static boolean isDaoPhase2Activated() {
- return DAO_PHASE2_ACTIVATED || daoActivated;
- }
-
public static boolean isDaoTradingActivated() {
- return DAO_TRADING_ACTIVATED || daoActivated;
+ return true;
}
}
diff --git a/common/src/main/java/bisq/common/app/HasCapabilities.java b/common/src/main/java/bisq/common/app/HasCapabilities.java
new file mode 100644
index 00000000000..9652f8825cc
--- /dev/null
+++ b/common/src/main/java/bisq/common/app/HasCapabilities.java
@@ -0,0 +1,28 @@
+/*
+ * 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 bisq.common.app;
+
+/**
+ * Holds a set of {@link Capabilities}.
+ *
+ * @author Florian Reimair
+ */
+public interface HasCapabilities {
+
+ Capabilities getCapabilities();
+}
diff --git a/common/src/main/java/bisq/common/app/Log.java b/common/src/main/java/bisq/common/app/Log.java
index 45eae96b494..bb2268a70d6 100644
--- a/common/src/main/java/bisq/common/app/Log.java
+++ b/common/src/main/java/bisq/common/app/Log.java
@@ -91,26 +91,4 @@ public static void setup(String fileName) {
public static void setCustomLogLevel(String pattern, Level logLevel) {
((Logger) LoggerFactory.getLogger(pattern)).setLevel(logLevel);
}
-
- public static void traceCall() {
- if (LoggerFactory.getLogger(Log.class).isTraceEnabled()) {
- StackTraceElement stackTraceElement = new Throwable().getStackTrace()[1];
- String methodName = stackTraceElement.getMethodName();
- if (methodName.equals(""))
- methodName = "Constructor ";
- String className = stackTraceElement.getClassName();
- LoggerFactory.getLogger(className).trace("Called: {}", methodName);
- }
- }
-
- public static void traceCall(String message) {
- if (LoggerFactory.getLogger(Log.class).isTraceEnabled()) {
- StackTraceElement stackTraceElement = new Throwable().getStackTrace()[1];
- String methodName = stackTraceElement.getMethodName();
- if (methodName.equals(""))
- methodName = "Constructor ";
- String className = stackTraceElement.getClassName();
- LoggerFactory.getLogger(className).trace("Called: {} [{}]", methodName, message);
- }
- }
}
diff --git a/common/src/main/java/bisq/common/app/Version.java b/common/src/main/java/bisq/common/app/Version.java
index 02a3bbab3cc..f0ba73988d3 100644
--- a/common/src/main/java/bisq/common/app/Version.java
+++ b/common/src/main/java/bisq/common/app/Version.java
@@ -27,7 +27,7 @@ public class Version {
// VERSION = 0.5.0 introduces proto buffer for the P2P network and local DB and is a not backward compatible update
// Therefore all sub versions start again with 1
// We use semantic versioning with major, minor and patch
- public static final String VERSION = "0.9.3";
+ public static final String VERSION = "1.1.2";
public static int getMajorVersion(String version) {
return getSubVersion(version, 0);
@@ -82,6 +82,7 @@ private static int getSubVersion(String version, int index) {
// The version no. of the current protocol. The offer holds that version.
// A taker will check the version of the offers to see if his version is compatible.
+ // Offers created with the old version will become invalid and have to be canceled.
// VERSION = 0.5.0 -> TRADE_PROTOCOL_VERSION = 1
public static final int TRADE_PROTOCOL_VERSION = 1;
private static int p2pMessageVersion;
diff --git a/common/src/main/java/bisq/common/crypto/PGP.java b/common/src/main/java/bisq/common/crypto/PGP.java
index 46b87b6f204..efccbc222bd 100644
--- a/common/src/main/java/bisq/common/crypto/PGP.java
+++ b/common/src/main/java/bisq/common/crypto/PGP.java
@@ -17,6 +17,8 @@
package bisq.common.crypto;
+import com.google.common.base.Charsets;
+
import org.bouncycastle.bcpg.BCPGKey;
import org.bouncycastle.bcpg.RSAPublicBCPGKey;
import org.bouncycastle.openpgp.PGPException;
@@ -54,7 +56,7 @@ public class PGP {
@Nullable
public static PGPPublicKey getPubKeyFromPem(@Nullable String pem) {
if (pem != null) {
- InputStream inputStream = new ByteArrayInputStream(pem.getBytes());
+ InputStream inputStream = new ByteArrayInputStream(pem.getBytes(Charsets.UTF_8));
try {
inputStream = PGPUtil.getDecoderStream(inputStream);
try {
diff --git a/common/src/main/java/bisq/common/proto/ProtoUtil.java b/common/src/main/java/bisq/common/proto/ProtoUtil.java
index de2c566eb33..2cb80250bd9 100644
--- a/common/src/main/java/bisq/common/proto/ProtoUtil.java
+++ b/common/src/main/java/bisq/common/proto/ProtoUtil.java
@@ -69,9 +69,10 @@ public static > E enumFromProto(Class enumType, String name
E result = Enums.getIfPresent(enumType, name).orNull();
if (result == null) {
log.error("Invalid value for enum " + enumType.getSimpleName() + ": " + name);
- // TODO returning null here can cause problems in caller. Maybe we should throw an exception? Or maybe
- // better to ensure that enums have always a default value with represents an undefined state and we fall
- // back to that.
+ result = Enums.getIfPresent(enumType, "UNDEFINED").orNull();
+ log.error("We try to lookup for an enum entry with name 'UNDEFINED' and use that if available, " +
+ "otherwise the enum is null. enum={}", result);
+ return result;
}
return result;
}
diff --git a/common/src/main/java/bisq/common/proto/persistable/PersistableEnvelope.java b/common/src/main/java/bisq/common/proto/persistable/PersistableEnvelope.java
index 32357d3fea2..dfab4f0b4dd 100644
--- a/common/src/main/java/bisq/common/proto/persistable/PersistableEnvelope.java
+++ b/common/src/main/java/bisq/common/proto/persistable/PersistableEnvelope.java
@@ -20,7 +20,7 @@
import bisq.common.Envelope;
/**
- * Interface for the outside envelope object persisted to disc.
+ * Interface for the outside envelope object persisted to disk.
*/
public interface PersistableEnvelope extends Envelope {
}
diff --git a/common/src/main/java/bisq/common/storage/FileManager.java b/common/src/main/java/bisq/common/storage/FileManager.java
index 7291fb9cae5..a0f907cc9cf 100644
--- a/common/src/main/java/bisq/common/storage/FileManager.java
+++ b/common/src/main/java/bisq/common/storage/FileManager.java
@@ -133,7 +133,6 @@ public synchronized T read(File file) {
}
public synchronized void removeFile(String fileName) {
- log.debug("removeFile" + fileName);
File file = new File(dir, fileName);
boolean result = file.delete();
if (!result)
@@ -163,16 +162,21 @@ void shutDown() {
}
}
- public synchronized void removeAndBackupFile(String fileName) throws IOException {
- File corruptedBackupDir = new File(Paths.get(dir.getAbsolutePath(), "backup_of_corrupted_data").toString());
+ public static void removeAndBackupFile(File dbDir, File storageFile, String fileName, String backupFolderName)
+ throws IOException {
+ File corruptedBackupDir = new File(Paths.get(dbDir.getAbsolutePath(), backupFolderName).toString());
if (!corruptedBackupDir.exists())
if (!corruptedBackupDir.mkdir())
log.warn("make dir failed");
- File corruptedFile = new File(Paths.get(dir.getAbsolutePath(), "backup_of_corrupted_data", fileName).toString());
+ File corruptedFile = new File(Paths.get(dbDir.getAbsolutePath(), backupFolderName, fileName).toString());
FileUtil.renameFile(storageFile, corruptedFile);
}
+ public synchronized void removeAndBackupFile(String fileName) throws IOException {
+ removeAndBackupFile(dir, storageFile, fileName, "backup_of_corrupted_data");
+ }
+
public synchronized void backupFile(String fileName, int numMaxBackupFiles) {
FileUtil.rollingBackup(dir, fileName, numMaxBackupFiles);
}
diff --git a/common/src/main/java/bisq/common/storage/JsonFileManager.java b/common/src/main/java/bisq/common/storage/JsonFileManager.java
index d3070eea258..05532148fd9 100644
--- a/common/src/main/java/bisq/common/storage/JsonFileManager.java
+++ b/common/src/main/java/bisq/common/storage/JsonFileManager.java
@@ -79,6 +79,13 @@ public void writeToDisc(String json, String fileName) {
printWriter = new PrintWriter(tempFile);
printWriter.println(json);
+ // This close call and comment is borrowed from FileManager. Not 100% sure it that is really needed but
+ // seems that had fixed in the past and we got reported issues on Windows so that fix might be still
+ // required.
+ // Close resources before replacing file with temp file because otherwise it causes problems on windows
+ // when rename temp file
+ printWriter.close();
+
FileUtil.renameFile(tempFile, jsonFile);
} catch (Throwable t) {
log.error("storageFile " + jsonFile.toString());
diff --git a/common/src/main/java/bisq/common/storage/Storage.java b/common/src/main/java/bisq/common/storage/Storage.java
index 199f26615ba..21e5a89fb76 100644
--- a/common/src/main/java/bisq/common/storage/Storage.java
+++ b/common/src/main/java/bisq/common/storage/Storage.java
@@ -114,7 +114,6 @@ public void setNumMaxBackupFiles(int numMaxBackupFiles) {
// Save delayed and on a background thread
public void queueUpForSave(T persistable) {
if (persistable != null) {
- log.trace("save " + fileName);
checkNotNull(storageFile, "storageFile = null. Call setupFileStorage before using read/write.");
fileManager.saveLater(persistable);
@@ -125,7 +124,6 @@ public void queueUpForSave(T persistable) {
public void queueUpForSave(T persistable, long delayInMilli) {
if (persistable != null) {
- log.trace("save " + fileName);
checkNotNull(storageFile, "storageFile = null. Call setupFileStorage before using read/write.");
fileManager.saveLater(persistable, delayInMilli);
diff --git a/common/src/main/java/bisq/common/taskrunner/TaskRunner.java b/common/src/main/java/bisq/common/taskrunner/TaskRunner.java
index ce0eaab15ac..f6f6d12d2bb 100644
--- a/common/src/main/java/bisq/common/taskrunner/TaskRunner.java
+++ b/common/src/main/java/bisq/common/taskrunner/TaskRunner.java
@@ -82,7 +82,6 @@ public void cancel() {
}
void handleComplete() {
- log.trace("Task completed: " + currentTask.getSimpleName());
sharedModel.persist();
next();
}
diff --git a/common/src/main/java/bisq/common/util/ExtraDataMapValidator.java b/common/src/main/java/bisq/common/util/ExtraDataMapValidator.java
new file mode 100644
index 00000000000..df158557165
--- /dev/null
+++ b/common/src/main/java/bisq/common/util/ExtraDataMapValidator.java
@@ -0,0 +1,83 @@
+/*
+ * 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 bisq.common.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import lombok.extern.slf4j.Slf4j;
+
+import javax.annotation.Nullable;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Validator for extraDataMap fields used in network payloads.
+ * Ensures that we don't get the network attacked by huge data inserted there.
+ */
+@Slf4j
+public class ExtraDataMapValidator {
+ // ExtraDataMap is only used for exceptional cases to not break backward compatibility.
+ // We don't expect many entries there.
+ public final static int MAX_SIZE = 10;
+ public final static int MAX_KEY_LENGTH = 100;
+ public final static int MAX_VALUE_LENGTH = 100000; // 100 kb
+
+ public static Map getValidatedExtraDataMap(@Nullable Map extraDataMap) {
+ return getValidatedExtraDataMap(extraDataMap, MAX_SIZE, MAX_KEY_LENGTH, MAX_VALUE_LENGTH);
+ }
+
+ public static Map getValidatedExtraDataMap(@Nullable Map extraDataMap, int maxSize,
+ int maxKeyLength, int maxValueLength) {
+ if (extraDataMap == null)
+ return null;
+
+ try {
+ checkArgument(extraDataMap.entrySet().size() <= maxSize,
+ "Size of map must not exceed " + maxSize);
+ extraDataMap.forEach((key, value) -> {
+ checkArgument(key.length() <= maxKeyLength,
+ "Length of key must not exceed " + maxKeyLength);
+ checkArgument(value.length() <= maxValueLength,
+ "Length of value must not exceed " + maxValueLength);
+ });
+ return extraDataMap;
+ } catch (Throwable t) {
+ return new HashMap<>();
+ }
+ }
+
+ public static void validate(@Nullable Map extraDataMap) {
+ validate(extraDataMap, MAX_SIZE, MAX_KEY_LENGTH, MAX_VALUE_LENGTH);
+ }
+
+ public static void validate(@Nullable Map extraDataMap, int maxSize, int maxKeyLength,
+ int maxValueLength) {
+ if (extraDataMap == null)
+ return;
+
+ checkArgument(extraDataMap.entrySet().size() <= maxSize,
+ "Size of map must not exceed " + maxSize);
+ extraDataMap.forEach((key, value) -> {
+ checkArgument(key.length() <= maxKeyLength,
+ "Length of key must not exceed " + maxKeyLength);
+ checkArgument(value.length() <= maxValueLength,
+ "Length of value must not exceed " + maxValueLength);
+ });
+ }
+}
diff --git a/common/src/main/java/bisq/common/util/PermutationUtil.java b/common/src/main/java/bisq/common/util/PermutationUtil.java
new file mode 100644
index 00000000000..0a84e478179
--- /dev/null
+++ b/common/src/main/java/bisq/common/util/PermutationUtil.java
@@ -0,0 +1,109 @@
+/*
+ * 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 bisq.common.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class PermutationUtil {
+
+ /**
+ * @param list Original list
+ * @param indicesToRemove List of indices to remove
+ * @param Type of List items
+ * @return Partial list where items at indices of indicesToRemove have been removed
+ */
+ public static List getPartialList(List list, List indicesToRemove) {
+ List altered = new ArrayList<>(list);
+
+ // Eliminate duplicates
+ indicesToRemove = new ArrayList<>(new HashSet<>(indicesToRemove));
+
+ // Sort
+ Collections.sort(indicesToRemove);
+
+ // Reverse list.
+ // We need to remove from highest index downwards to not change order of remaining indices
+ Collections.reverse(indicesToRemove);
+
+ indicesToRemove.forEach(index -> {
+ if (altered.size() > index && index >= 0)
+ altered.remove((int) index);
+ });
+ return altered;
+ }
+
+ //TODO optimize algorithm so that it starts from all objects and goes down instead starting with from the bottom.
+ // That should help that we are not hitting the iteration limit so easily.
+ /**
+ * Returns a list of all possible permutations of a give sorted list ignoring duplicates.
+ * E.g. List [A,B,C] results in this list of permutations: [[A], [B], [A,B], [C], [A,C], [B,C], [A,B,C]]
+ * Number of variations and iterations grows with 2^n - 1 where n is the number of items in the list.
+ * With 20 items we reach about 1 million iterations and it takes about 0.5 sec.
+ * To avoid performance issues we added the maxIterations parameter to stop once the number of iterations has
+ * reached the maxIterations and return in such a case the list of permutations we have been able to create.
+ * Depending on the type of object which is stored in the list the memory usage should be considered as well for
+ * choosing the right maxIterations value.
+ *
+ * @param list List from which we create permutations
+ * @param maxIterations Max. number of iterations including inner iterations
+ * @param Type of list items
+ * @return List of possible permutations of the original list
+ */
+ public static List> findAllPermutations(List list, int maxIterations) {
+ List> result = new ArrayList<>();
+ int counter = 0;
+ long ts = System.currentTimeMillis();
+ for (T item : list) {
+ counter++;
+ if (counter > maxIterations) {
+ log.warn("We reached maxIterations of our allowed iterations and return current state of the result. " +
+ "counter={}", counter);
+ return result;
+ }
+
+ List> subLists = new ArrayList<>();
+ for (int n = 0; n < result.size(); n++) {
+ counter++;
+ if (counter > maxIterations) {
+ log.warn("We reached maxIterations of our allowed iterations and return current state of the result. " +
+ "counter={}", counter);
+ return result;
+ }
+ List subList = new ArrayList<>(result.get(n));
+ subList.add(item);
+ subLists.add(subList);
+ }
+
+ // add single item
+ result.add(new ArrayList<>(Collections.singletonList(item)));
+
+ // add subLists
+ result.addAll(subLists);
+ }
+
+ log.info("findAllPermutations took {} ms for {} items and {} iterations. Heap size used: {} MB",
+ (System.currentTimeMillis() - ts), list.size(), counter, Profiler.getUsedMemoryInMB());
+ return result;
+ }
+}
diff --git a/common/src/main/java/bisq/common/util/Utilities.java b/common/src/main/java/bisq/common/util/Utilities.java
index 4c8f5e81903..11c72ac8a84 100644
--- a/common/src/main/java/bisq/common/util/Utilities.java
+++ b/common/src/main/java/bisq/common/util/Utilities.java
@@ -155,6 +155,21 @@ public static ScheduledThreadPoolExecutor getScheduledThreadPoolExecutor(String
return executor;
}
+ /**
+ * @return true if defaults read -g AppleInterfaceStyle
has an exit status of 0
(i.e. _not_ returning "key not found").
+ */
+ public static boolean isMacMenuBarDarkMode() {
+ try {
+ // check for exit status only. Once there are more modes than "dark" and "default", we might need to analyze string contents..
+ Process process = Runtime.getRuntime().exec(new String[]{"defaults", "read", "-g", "AppleInterfaceStyle"});
+ process.waitFor(100, TimeUnit.MILLISECONDS);
+ return process.exitValue() == 0;
+ } catch (IOException | InterruptedException | IllegalThreadStateException ex) {
+ // IllegalThreadStateException thrown by proc.exitValue(), if process didn't terminate
+ return false;
+ }
+ }
+
public static boolean isUnix() {
return isOSX() || isLinux() || getOSName().contains("freebsd");
}
@@ -171,6 +186,14 @@ public static boolean isLinux() {
return getOSName().contains("linux");
}
+ public static boolean isDebianLinux() {
+ return isLinux() && new File("/etc/debian_version").isFile();
+ }
+
+ public static boolean isRedHatLinux() {
+ return isLinux() && new File("/etc/redhat-release").isFile();
+ }
+
private static String getOSName() {
return System.getProperty("os.name").toLowerCase(Locale.US);
}
@@ -489,15 +512,29 @@ public static void checkCryptoPolicySetup() throws NoSuchAlgorithmException, Lim
throw new LimitedKeyStrengthException();
}
+ public static String toTruncatedString(Object message) {
+ return toTruncatedString(message, 200, true);
+ }
+
public static String toTruncatedString(Object message, int maxLength) {
- if (message != null) {
- return StringUtils.abbreviate(message.toString(), maxLength).replace("\n", "");
- }
- return "null";
+ return toTruncatedString(message, maxLength, true);
}
- public static String toTruncatedString(Object message) {
- return toTruncatedString(message, 200);
+ public static String toTruncatedString(Object message, boolean removeLinebreaks) {
+ return toTruncatedString(message, 200, removeLinebreaks);
+ }
+
+ public static String toTruncatedString(Object message, int maxLength, boolean removeLinebreaks) {
+ if (message == null)
+ return "null";
+
+
+ String result = StringUtils.abbreviate(message.toString(), maxLength);
+ if (removeLinebreaks)
+ return result.replace("\n", "");
+
+ return result;
+
}
public static String getRandomPrefix(int minLength, int maxLength) {
diff --git a/common/src/main/proto/pb.proto b/common/src/main/proto/pb.proto
index 6653b665363..aba03e79d81 100644
--- a/common/src/main/proto/pb.proto
+++ b/common/src/main/proto/pb.proto
@@ -57,6 +57,15 @@ message NetworkEnvelope {
AddPersistableNetworkPayloadMessage add_persistable_network_payload_message = 31;
AckMessage ack_message = 32;
RepublishGovernanceDataRequest republish_governance_data_request = 33;
+ NewDaoStateHashMessage new_dao_state_hash_message = 34;
+ GetDaoStateHashesRequest get_dao_state_hashes_request = 35;
+ GetDaoStateHashesResponse get_dao_state_hashes_response = 36;
+ NewProposalStateHashMessage new_proposal_state_hash_message = 37;
+ GetProposalStateHashesRequest get_proposal_state_hashes_request = 38;
+ GetProposalStateHashesResponse get_proposal_state_hashes_response = 39;
+ NewBlindVoteStateHashMessage new_blind_vote_state_hash_message = 40;
+ GetBlindVoteStateHashesRequest get_blind_vote_state_hashes_request = 41;
+ GetBlindVoteStateHashesResponse get_blind_vote_state_hashes_response = 42;
}
}
@@ -308,6 +317,8 @@ message PrivateNotificationMessage {
message GetBlocksRequest {
int32 from_block_height = 1;
int32 nonce = 2;
+ NodeAddress sender_node_address = 3;
+ repeated int32 supported_capabilities = 4;
}
message GetBlocksResponse {
@@ -324,6 +335,48 @@ message NewBlockBroadcastMessage {
message RepublishGovernanceDataRequest {
}
+message NewDaoStateHashMessage {
+ DaoStateHash state_hash = 1;
+}
+
+message NewProposalStateHashMessage {
+ ProposalStateHash state_hash = 1;
+}
+
+message NewBlindVoteStateHashMessage {
+ BlindVoteStateHash state_hash = 1;
+}
+
+message GetDaoStateHashesRequest {
+ int32 height = 1;
+ int32 nonce = 2;
+}
+
+message GetProposalStateHashesRequest {
+ int32 height = 1;
+ int32 nonce = 2;
+}
+
+message GetBlindVoteStateHashesRequest {
+ int32 height = 1;
+ int32 nonce = 2;
+}
+
+message GetDaoStateHashesResponse {
+ repeated DaoStateHash state_hashes = 1;
+ int32 request_nonce = 2;
+}
+
+message GetProposalStateHashesResponse {
+ repeated ProposalStateHash state_hashes = 1;
+ int32 request_nonce = 2;
+}
+
+message GetBlindVoteStateHashesResponse {
+ repeated BlindVoteStateHash state_hashes = 1;
+ int32 request_nonce = 2;
+}
+
///////////////////////////////////////////////////////////////////////////////////////////
// Payload
///////////////////////////////////////////////////////////////////////////////////////////
@@ -476,6 +529,9 @@ message Filter {
repeated string price_relay_nodes = 11;
bool prevent_public_btc_network = 12;
repeated string btc_nodes = 13;
+ bool disable_dao = 14;
+ string disable_dao_below_version = 15;
+ string disable_trade_below_version = 16;
}
// not used anymore from v0.6 on. But leave it for receiving TradeStatistics objects from older
@@ -709,14 +765,14 @@ message PaymentAccountPayload {
CryptoCurrencyAccountPayload crypto_currency_account_payload = 8;
FasterPaymentsAccountPayload faster_payments_account_payload = 9;
InteracETransferAccountPayload interac_e_transfer_account_payload = 10;
- OKPayAccountPayload o_k_pay_account_payload = 11;
+ OKPayAccountPayload o_k_pay_account_payload = 11; // Deprecated, not used anymore
PerfectMoneyAccountPayload perfect_money_account_payload = 12;
SwishAccountPayload swish_account_payload = 13;
USPostalMoneyOrderAccountPayload u_s_postal_money_order_account_payload = 14;
UpholdAccountPayload uphold_account_payload = 16;
- CashAppAccountPayload cash_app_account_payload = 17;
+ CashAppAccountPayload cash_app_account_payload = 17; // Deprecated, not used anymore
MoneyBeamAccountPayload money_beam_account_payload = 18;
- VenmoAccountPayload venmo_account_payload = 19;
+ VenmoAccountPayload venmo_account_payload = 19; // Deprecated, not used anymore
PopmoneyAccountPayload popmoney_account_payload = 20;
RevolutAccountPayload revolut_account_payload = 21;
WeChatPayAccountPayload we_chat_pay_account_payload = 22;
@@ -724,6 +780,7 @@ message PaymentAccountPayload {
HalCashAccountPayload hal_cash_account_payload = 24;
PromptPayAccountPayload prompt_pay_account_payload = 25;
AdvancedCashAccountPayload advanced_cash_account_payload = 26;
+ InstantCryptoCurrencyAccountPayload instant_crypto_currency_account_payload = 27;
}
map exclude_from_json_data = 15;
}
@@ -835,6 +892,10 @@ message CryptoCurrencyAccountPayload {
string address = 1;
}
+message InstantCryptoCurrencyAccountPayload {
+ string address = 1;
+}
+
message FasterPaymentsAccountPayload {
string sort_code = 1;
string account_nr = 2;
@@ -848,6 +909,7 @@ message InteracETransferAccountPayload {
string answer = 4;
}
+// Deprecated, not used anymore
message OKPayAccountPayload {
string account_nr = 1;
}
@@ -856,6 +918,7 @@ message UpholdAccountPayload {
string account_id = 1;
}
+// Deprecated, not used anymore
message CashAppAccountPayload {
string cash_tag = 1;
}
@@ -864,6 +927,7 @@ message MoneyBeamAccountPayload {
string account_id = 1;
}
+// Deprecated, not used anymore
message VenmoAccountPayload {
string venmo_user_name = 1;
string holder_name = 2;
@@ -906,7 +970,6 @@ message AdvancedCashAccountPayload {
string account_nr = 1;
}
-
///////////////////////////////////////////////////////////////////////////////////////////
// PersistableEnvelope
///////////////////////////////////////////////////////////////////////////////////////////
@@ -950,6 +1013,7 @@ message PersistableEnvelope {
DaoStateStore dao_state_store = 24;
MyReputationList my_reputation_list = 25;
MyProofOfBurnList my_proof_of_burn_list = 26;
+ UnconfirmedBsqChangeOutputList unconfirmed_bsq_change_output_list = 27;
}
}
@@ -1268,7 +1332,7 @@ message PreferencesPayload {
string bitcoin_nodes = 27;
repeated string ignore_traders_list = 28;
string directory_chooser_path = 29;
- int64 buyer_security_deposit_as_long = 30;
+ int64 buyer_security_deposit_as_long = 30; // Deprectated: Superseded by buyerSecurityDepositAsPercent
bool use_animations = 31;
PaymentAccount selectedPayment_account_for_createOffer = 32;
bool pay_fee_in_Btc = 33;
@@ -1288,6 +1352,10 @@ message PreferencesPayload {
string rpc_user = 47;
string rpc_pw = 48;
string take_offer_selected_payment_account_id = 49;
+ double buyer_security_deposit_as_percent = 50;
+ int32 ignore_dust_threshold = 51;
+ double buyer_security_deposit_as_percent_for_crypto = 52;
+ int32 block_notify_port = 53;
}
///////////////////////////////////////////////////////////////////////////////////////////
@@ -1359,7 +1427,7 @@ message Tx {
// Because of the way how PB implements inheritence we need to use the super class as type
repeated BaseTxOutput tx_outputs = 1;
TxType txType = 2;
- int64 burnt_fee = 3;
+ int64 burnt_bsq = 3;
}
enum TxType {
@@ -1379,6 +1447,7 @@ enum TxType {
UNLOCK = 13;
ASSET_LISTING_FEE = 14;
PROOF_OF_BURN = 15;
+ IRREGULAR = 16;
}
message TxInput {
@@ -1401,6 +1470,12 @@ message BaseTxOutput {
}
}
+message UnconfirmedTxOutput {
+ int32 index = 1;
+ int64 value = 2;
+ string tx_id = 3;
+}
+
message RawTxOutput {
}
@@ -1471,20 +1546,19 @@ message Cycle {
repeated DaoPhase dao_phase = 2;
}
-message BsqState {
+message DaoState {
int32 chain_height = 1;
// Because of the way how PB implements inheritence we need to use the super class as type
repeated BaseBlock blocks = 2;
repeated Cycle cycles = 3;
// Because of the way how PB implements inheritence we need to use the super class as type
map unspent_tx_output_map = 4;
- map non_bsq_tx_output_map = 5;
- map issuance_map = 6;
- repeated string confiscated_lockup_tx_list = 7;
- map spent_info_map = 8;
- repeated ParamChange param_change_list = 9;
- repeated EvaluatedProposal evaluated_proposal_list = 10;
- repeated DecryptedBallotsWithMerits decrypted_ballots_with_merits_list = 11;
+ map issuance_map = 5;
+ repeated string confiscated_lockup_tx_list = 6;
+ map spent_info_map = 7;
+ repeated ParamChange param_change_list = 8;
+ repeated EvaluatedProposal evaluated_proposal_list = 9;
+ repeated DecryptedBallotsWithMerits decrypted_ballots_with_merits_list = 10;
}
message Issuance {
@@ -1510,6 +1584,8 @@ message Proposal {
GenericProposal generic_proposal = 11;
RemoveAssetProposal remove_asset_proposal = 12;
}
+ // We leave some index space here in case we add more subclasses
+ map extra_data = 20;
}
message CompensationProposal {
@@ -1529,6 +1605,8 @@ message ChangeParamProposal {
message RoleProposal {
Role role = 1;
+ int64 required_bond_unit = 2;
+ int32 unlock_time = 3;
}
message ConfiscateBondProposal {
@@ -1567,6 +1645,10 @@ message MyProofOfBurnList {
repeated MyProofOfBurn my_proof_of_burn = 1;
}
+message UnconfirmedBsqChangeOutputList {
+ repeated UnconfirmedTxOutput unconfirmed_tx_output = 1;
+}
+
message TempProposalPayload {
Proposal proposal = 1;
bytes owner_pub_key_encoded = 2;
@@ -1636,6 +1718,8 @@ message BlindVote {
string tx_id = 2;
int64 stake = 3;
bytes encrypted_merit_list = 4;
+ int64 date = 5;
+ map extra_data = 6;
}
message MyBlindVoteList {
@@ -1648,8 +1732,7 @@ message BlindVoteStore {
message BlindVotePayload {
BlindVote blind_vote = 1;
- int64 date = 2;
- bytes hash = 3;
+ bytes hash = 2;
}
message Vote {
@@ -1677,8 +1760,6 @@ message ProposalVoteResult {
message EvaluatedProposal {
bool is_accepted = 1;
ProposalVoteResult proposal_vote_result = 2;
- int64 required_quorum = 3;
- int64 required_threshold = 4;
}
message DecryptedBallotsWithMerits {
@@ -1691,7 +1772,28 @@ message DecryptedBallotsWithMerits {
}
message DaoStateStore {
- BsqState bsq_state = 1;
+ DaoState dao_state = 1;
+ repeated DaoStateHash dao_state_hash = 2;
+}
+
+message DaoStateHash {
+ int32 height = 1;
+ bytes hash = 2;
+ bytes prev_hash = 3;
+}
+
+message ProposalStateHash {
+ int32 height = 1;
+ bytes hash = 2;
+ bytes prev_hash = 3;
+ int32 num_proposals = 4;
+}
+
+message BlindVoteStateHash {
+ int32 height = 1;
+ bytes hash = 2;
+ bytes prev_hash = 3;
+ int32 num_blind_votes = 4;
}
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/common/src/test/java/bisq/common/app/CapabilitiesTest.java b/common/src/test/java/bisq/common/app/CapabilitiesTest.java
index 23e7ef83387..d0166e130c6 100644
--- a/common/src/test/java/bisq/common/app/CapabilitiesTest.java
+++ b/common/src/test/java/bisq/common/app/CapabilitiesTest.java
@@ -17,39 +17,47 @@
package bisq.common.app;
-import java.util.Arrays;
+import java.util.HashSet;
import org.junit.Test;
+import static bisq.common.app.Capability.*;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class CapabilitiesTest {
@Test
- public void testVersionNumber() {
- // if required are null or empty its true
- assertTrue(Capabilities.isCapabilitySupported(null, null));
- assertTrue(Capabilities.isCapabilitySupported(null, Arrays.asList()));
- assertTrue(Capabilities.isCapabilitySupported(null, Arrays.asList(0)));
- assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(), null));
- assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(), Arrays.asList()));
- assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(), Arrays.asList(0)));
-
- // required are not null and not empty but supported is null or empty its false
- assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(0), null));
- assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(0), Arrays.asList()));
+ public void testNoCapabilitiesAvailable() {
+ Capabilities DUT = new Capabilities();
+
+ assertTrue(DUT.containsAll(new HashSet<>()));
+ assertFalse(DUT.containsAll(new Capabilities(SEED_NODE)));
+ }
+
+ @Test
+ public void testO() {
+ Capabilities DUT = new Capabilities(TRADE_STATISTICS);
+
+ assertTrue(DUT.containsAll(new HashSet<>()));
+ }
+
+ @Test
+ public void testSingleMatch() {
+ Capabilities DUT = new Capabilities(TRADE_STATISTICS);
// single match
- assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(0), Arrays.asList(0)));
- assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(1), Arrays.asList(0)));
- assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(0), Arrays.asList(1)));
-
- // multi match
- assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(0), Arrays.asList(0, 1)));
- assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(0), Arrays.asList(1, 2)));
- assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(0, 1), Arrays.asList(0, 1)));
- assertTrue(Capabilities.isCapabilitySupported(Arrays.asList(0, 1), Arrays.asList(1, 0)));
- assertFalse(Capabilities.isCapabilitySupported(Arrays.asList(0, 1), Arrays.asList(0)));
+ assertTrue(DUT.containsAll(new Capabilities(TRADE_STATISTICS)));
+ assertFalse(DUT.containsAll(new Capabilities(SEED_NODE)));
+ }
+
+ @Test
+ public void testMultiMatch() {
+ Capabilities DUT = new Capabilities(TRADE_STATISTICS, TRADE_STATISTICS_2);
+
+ assertTrue(DUT.containsAll(new Capabilities(TRADE_STATISTICS)));
+ assertFalse(DUT.containsAll(new Capabilities(SEED_NODE)));
+ assertTrue(DUT.containsAll(new Capabilities(TRADE_STATISTICS, TRADE_STATISTICS_2)));
+ assertFalse(DUT.containsAll(new Capabilities(SEED_NODE, TRADE_STATISTICS_2)));
}
}
diff --git a/common/src/test/java/bisq/common/util/PermutationTest.java b/common/src/test/java/bisq/common/util/PermutationTest.java
new file mode 100644
index 00000000000..149cf9c971a
--- /dev/null
+++ b/common/src/test/java/bisq/common/util/PermutationTest.java
@@ -0,0 +1,432 @@
+/*
+ * 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 bisq.common.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class PermutationTest {
+
+
+ @Test
+ public void testGetPartialList() {
+ String blindVote0 = "blindVote0";
+ String blindVote1 = "blindVote1";
+ String blindVote2 = "blindVote2";
+ String blindVote3 = "blindVote3";
+ String blindVote4 = "blindVote4";
+ String blindVote5 = "blindVote5";
+
+ List list = new ArrayList<>(Arrays.asList(blindVote0, blindVote1, blindVote2, blindVote3, blindVote4, blindVote5));
+ List indicesToRemove = Arrays.asList(0, 3);
+ List expected = new ArrayList<>(Arrays.asList(blindVote1, blindVote2, blindVote4, blindVote5));
+ List result = PermutationUtil.getPartialList(list, indicesToRemove);
+ assertTrue(expected.toString().equals(result.toString()));
+
+ // remove nothing
+ indicesToRemove = new ArrayList<>();
+ expected = new ArrayList<>(list);
+ result = PermutationUtil.getPartialList(list, indicesToRemove);
+ assertTrue(expected.toString().equals(result.toString()));
+
+ // remove first
+ indicesToRemove = Collections.singletonList(0);
+ expected = new ArrayList<>(list);
+ expected.remove(0);
+ result = PermutationUtil.getPartialList(list, indicesToRemove);
+ assertTrue(expected.toString().equals(result.toString()));
+
+ // remove last
+ indicesToRemove = Collections.singletonList(5);
+ expected = new ArrayList<>(list);
+ expected.remove(5);
+ result = PermutationUtil.getPartialList(list, indicesToRemove);
+ assertTrue(expected.toString().equals(result.toString()));
+
+ // remove all
+ indicesToRemove = Arrays.asList(0, 1, 2, 3, 4, 5);
+ expected = new ArrayList<>();
+ result = PermutationUtil.getPartialList(list, indicesToRemove);
+ assertTrue(expected.toString().equals(result.toString()));
+
+ // wrong sorting of indices
+ indicesToRemove = Arrays.asList(4, 0, 1);
+ expected = expected = new ArrayList<>(Arrays.asList(blindVote2, blindVote3, blindVote5));
+ result = PermutationUtil.getPartialList(list, indicesToRemove);
+ assertTrue(expected.toString().equals(result.toString()));
+
+ // wrong sorting of indices
+ indicesToRemove = Arrays.asList(0, 0);
+ expected = new ArrayList<>(Arrays.asList(blindVote1, blindVote2, blindVote3, blindVote4, blindVote5));
+ result = PermutationUtil.getPartialList(list, indicesToRemove);
+ assertTrue(expected.toString().equals(result.toString()));
+
+ // don't remove as invalid index
+ indicesToRemove = Collections.singletonList(9);
+ expected = new ArrayList<>(list);
+ result = PermutationUtil.getPartialList(list, indicesToRemove);
+ assertTrue(expected.toString().equals(result.toString()));
+
+ // don't remove as invalid index
+ indicesToRemove = Collections.singletonList(-2);
+ expected = new ArrayList<>(list);
+ result = PermutationUtil.getPartialList(list, indicesToRemove);
+ assertTrue(expected.toString().equals(result.toString()));
+ }
+
+ @Test
+ public void testFindAllPermutations() {
+ String blindVote0 = "blindVote0";
+ String blindVote1 = "blindVote1";
+ String blindVote2 = "blindVote2";
+ String blindVote3 = "blindVote3";
+ String blindVote4 = "blindVote4";
+
+ // Up to about 1M iterations performance is acceptable (0.5 sec)
+ // findAllPermutations took 580 ms for 20 items and 1048575 iterations
+ // findAllPermutations took 10 ms for 15 items and 32767 iterations
+ // findAllPermutations took 0 ms for 10 items and 1023 iterations
+ int limit = 1048575;
+ List list;
+ List> expected;
+ List> result;
+ List subList;
+
+
+ /* list = new ArrayList<>();
+ for (int i = 0; i < 20; i++) {
+ list.add("blindVote"+i);
+ }
+ PermutationUtil.findAllPermutations(list, limit);*/
+
+
+ list = new ArrayList<>();
+ expected = new ArrayList<>();
+ result = PermutationUtil.findAllPermutations(list, limit);
+ assertTrue(expected.toString().equals(result.toString()));
+
+ list = new ArrayList<>(Arrays.asList(blindVote0));
+ expected = new ArrayList<>();
+ expected.add(list);
+ result = PermutationUtil.findAllPermutations(list, limit);
+ assertTrue(expected.toString().equals(result.toString()));
+
+ // 2 items -> 3 variations
+ list = new ArrayList<>(Arrays.asList(blindVote0, blindVote1));
+ expected = new ArrayList<>();
+ expected.add(Arrays.asList(list.get(0)));
+
+ expected.add(Arrays.asList(list.get(1)));
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(1));
+ expected.add(subList);
+
+ result = PermutationUtil.findAllPermutations(list, limit);
+ assertTrue(expected.toString().equals(result.toString()));
+
+ // 3 items -> 7 variations
+ list = new ArrayList<>(Arrays.asList(blindVote0, blindVote1, blindVote2));
+ expected = new ArrayList<>();
+ expected.add(Arrays.asList(list.get(0)));
+
+ expected.add(Arrays.asList(list.get(1)));
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(1));
+ expected.add(subList);
+
+ expected.add(Arrays.asList(list.get(2)));
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(2));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(1));
+ subList.add(list.get(2));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(1));
+ subList.add(list.get(2));
+ expected.add(subList);
+
+ result = PermutationUtil.findAllPermutations(list, limit);
+ assertTrue(expected.toString().equals(result.toString()));
+
+ // 4 items -> 15 variations
+ list = new ArrayList<>(Arrays.asList(blindVote0, blindVote1, blindVote2, blindVote3));
+ expected = new ArrayList<>();
+ expected.add(Arrays.asList(list.get(0)));
+
+ expected.add(Arrays.asList(list.get(1)));
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(1));
+ expected.add(subList);
+
+ expected.add(Arrays.asList(list.get(2)));
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(2));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(1));
+ subList.add(list.get(2));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(1));
+ subList.add(list.get(2));
+ expected.add(subList);
+
+ expected.add(Arrays.asList(list.get(3)));
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(3));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(1));
+ subList.add(list.get(3));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(1));
+ subList.add(list.get(3));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(2));
+ subList.add(list.get(3));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(2));
+ subList.add(list.get(3));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(1));
+ subList.add(list.get(2));
+ subList.add(list.get(3));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(1));
+ subList.add(list.get(2));
+ subList.add(list.get(3));
+ expected.add(subList);
+
+ result = PermutationUtil.findAllPermutations(list, limit);
+ assertTrue(expected.toString().equals(result.toString()));
+
+
+ // 5 items -> 31 variations
+ list = new ArrayList<>(Arrays.asList(blindVote0, blindVote1, blindVote2, blindVote3, blindVote4));
+ expected = new ArrayList<>();
+ expected.add(Arrays.asList(list.get(0)));
+
+ expected.add(Arrays.asList(list.get(1)));
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(1));
+ expected.add(subList);
+
+ expected.add(Arrays.asList(list.get(2)));
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(2));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(1));
+ subList.add(list.get(2));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(1));
+ subList.add(list.get(2));
+ expected.add(subList);
+
+ expected.add(Arrays.asList(list.get(3)));
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(3));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(1));
+ subList.add(list.get(3));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(1));
+ subList.add(list.get(3));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(2));
+ subList.add(list.get(3));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(2));
+ subList.add(list.get(3));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(1));
+ subList.add(list.get(2));
+ subList.add(list.get(3));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(1));
+ subList.add(list.get(2));
+ subList.add(list.get(3));
+ expected.add(subList);
+
+ expected.add(Arrays.asList(list.get(4)));
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(4));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(1));
+ subList.add(list.get(4));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(1));
+ subList.add(list.get(4));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(2));
+ subList.add(list.get(4));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(2));
+ subList.add(list.get(4));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(1));
+ subList.add(list.get(2));
+ subList.add(list.get(4));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(1));
+ subList.add(list.get(2));
+ subList.add(list.get(4));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(3));
+ subList.add(list.get(4));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(3));
+ subList.add(list.get(4));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(1));
+ subList.add(list.get(3));
+ subList.add(list.get(4));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(1));
+ subList.add(list.get(3));
+ subList.add(list.get(4));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(2));
+ subList.add(list.get(3));
+ subList.add(list.get(4));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(2));
+ subList.add(list.get(3));
+ subList.add(list.get(4));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(1));
+ subList.add(list.get(2));
+ subList.add(list.get(3));
+ subList.add(list.get(4));
+ expected.add(subList);
+
+ subList = new ArrayList<>();
+ subList.add(list.get(0));
+ subList.add(list.get(1));
+ subList.add(list.get(2));
+ subList.add(list.get(3));
+ subList.add(list.get(4));
+ expected.add(subList);
+
+ result = PermutationUtil.findAllPermutations(list, limit);
+ assertTrue(expected.toString().equals(result.toString()));
+
+
+ }
+
+
+}
diff --git a/core/src/main/java/bisq/core/CoreModule.java b/core/src/main/java/bisq/core/CoreModule.java
index db41abc2211..e22d44406ab 100644
--- a/core/src/main/java/bisq/core/CoreModule.java
+++ b/core/src/main/java/bisq/core/CoreModule.java
@@ -23,13 +23,13 @@
import bisq.core.app.BisqEnvironment;
import bisq.core.app.BisqSetup;
import bisq.core.app.P2PNetworkSetup;
+import bisq.core.app.TorSetup;
import bisq.core.app.WalletAppSetup;
import bisq.core.arbitration.ArbitratorModule;
import bisq.core.btc.BitcoinModule;
import bisq.core.dao.DaoModule;
import bisq.core.filter.FilterModule;
import bisq.core.network.p2p.seed.DefaultSeedNodeRepository;
-import bisq.core.network.p2p.seed.SeedNodeAddressLookup;
import bisq.core.notifications.MobileMessageEncryption;
import bisq.core.notifications.MobileModel;
import bisq.core.notifications.MobileNotificationService;
@@ -40,6 +40,7 @@
import bisq.core.notifications.alerts.market.MarketAlerts;
import bisq.core.notifications.alerts.price.PriceAlert;
import bisq.core.offer.OfferModule;
+import bisq.core.payment.TradeLimits;
import bisq.core.presentation.CorePresentationModule;
import bisq.core.proto.network.CoreNetworkProtoResolver;
import bisq.core.proto.persistable.CorePersistenceProtoResolver;
@@ -80,11 +81,14 @@ public CoreModule(Environment environment) {
@Override
protected void configure() {
bind(BisqSetup.class).in(Singleton.class);
+ bind(TorSetup.class).in(Singleton.class);
bind(P2PNetworkSetup.class).in(Singleton.class);
bind(WalletAppSetup.class).in(Singleton.class);
bind(BisqEnvironment.class).toInstance((BisqEnvironment) environment);
+ bind(TradeLimits.class).in(Singleton.class);
+
bind(KeyStorage.class).in(Singleton.class);
bind(KeyRing.class).in(Singleton.class);
bind(User.class).in(Singleton.class);
@@ -94,7 +98,6 @@ protected void configure() {
bind(CorruptedDatabaseFilesHandler.class).in(Singleton.class);
bind(AvoidStandbyModeService.class).in(Singleton.class);
- bind(SeedNodeAddressLookup.class).in(Singleton.class);
bind(SeedNodeRepository.class).to(DefaultSeedNodeRepository.class).in(Singleton.class);
File storageDir = new File(environment.getRequiredProperty(Storage.STORAGE_DIR));
diff --git a/core/src/main/java/bisq/core/alert/Alert.java b/core/src/main/java/bisq/core/alert/Alert.java
index cb2569f3901..4081b231f26 100644
--- a/core/src/main/java/bisq/core/alert/Alert.java
+++ b/core/src/main/java/bisq/core/alert/Alert.java
@@ -22,6 +22,7 @@
import bisq.common.app.Version;
import bisq.common.crypto.Sig;
+import bisq.common.util.ExtraDataMapValidator;
import io.bisq.generated.protobuffer.PB;
@@ -91,7 +92,7 @@ public Alert(String message,
this.version = version;
this.ownerPubKeyBytes = ownerPubKeyBytes;
this.signatureAsBase64 = signatureAsBase64;
- this.extraDataMap = extraDataMap;
+ this.extraDataMap = ExtraDataMapValidator.getValidatedExtraDataMap(extraDataMap);
ownerPubKey = Sig.getPublicKeyFromBytes(ownerPubKeyBytes);
}
diff --git a/core/src/main/java/bisq/core/alert/AlertManager.java b/core/src/main/java/bisq/core/alert/AlertManager.java
index 1473fc4ae2d..05a3872a7ff 100644
--- a/core/src/main/java/bisq/core/alert/AlertManager.java
+++ b/core/src/main/java/bisq/core/alert/AlertManager.java
@@ -34,6 +34,8 @@
import com.google.inject.Inject;
import com.google.inject.name.Named;
+import com.google.common.base.Charsets;
+
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
@@ -121,7 +123,7 @@ public boolean addAlertMessageIfKeyIsValid(Alert alert, String privKeyString) {
user.setDevelopersAlert(alert);
boolean result = p2PService.addProtectedStorageEntry(alert, true);
if (result) {
- log.trace("Add alertMessage to network was successful. AlertMessage = " + alert);
+ log.trace("Add alertMessage to network was successful. AlertMessage={}", alert);
}
}
@@ -132,7 +134,7 @@ public boolean removeAlertMessageIfKeyIsValid(String privKeyString) {
Alert alert = user.getDevelopersAlert();
if (isKeyValid(privKeyString) && alert != null) {
if (p2PService.removeData(alert, true))
- log.trace("Remove alertMessage from network was successful. AlertMessage = " + alert);
+ log.trace("Remove alertMessage from network was successful. AlertMessage={}", alert);
user.setDevelopersAlert(null);
return true;
@@ -151,13 +153,13 @@ private boolean isKeyValid(String privKeyString) {
}
private void signAndAddSignatureToAlertMessage(Alert alert) {
- String alertMessageAsHex = Utils.HEX.encode(alert.getMessage().getBytes());
+ String alertMessageAsHex = Utils.HEX.encode(alert.getMessage().getBytes(Charsets.UTF_8));
String signatureAsBase64 = alertSigningKey.signMessage(alertMessageAsHex);
alert.setSigAndPubKey(signatureAsBase64, keyRing.getSignatureKeyPair().getPublic());
}
private boolean verifySignature(Alert alert) {
- String alertMessageAsHex = Utils.HEX.encode(alert.getMessage().getBytes());
+ String alertMessageAsHex = Utils.HEX.encode(alert.getMessage().getBytes(Charsets.UTF_8));
try {
ECKey.fromPublicOnly(HEX.decode(pubKeyAsHex)).verifyMessage(alertMessageAsHex, alert.getSignatureAsBase64());
return true;
diff --git a/core/src/main/java/bisq/core/alert/PrivateNotificationManager.java b/core/src/main/java/bisq/core/alert/PrivateNotificationManager.java
index a10a275f56d..529f4b7ed55 100644
--- a/core/src/main/java/bisq/core/alert/PrivateNotificationManager.java
+++ b/core/src/main/java/bisq/core/alert/PrivateNotificationManager.java
@@ -35,6 +35,8 @@
import com.google.inject.Inject;
import com.google.inject.name.Named;
+import com.google.common.base.Charsets;
+
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
@@ -145,13 +147,13 @@ private boolean isKeyValid(String privKeyString) {
}
private void signAndAddSignatureToPrivateNotificationMessage(PrivateNotificationPayload privateNotification) {
- String privateNotificationMessageAsHex = Utils.HEX.encode(privateNotification.getMessage().getBytes());
+ String privateNotificationMessageAsHex = Utils.HEX.encode(privateNotification.getMessage().getBytes(Charsets.UTF_8));
String signatureAsBase64 = privateNotificationSigningKey.signMessage(privateNotificationMessageAsHex);
privateNotification.setSigAndPubKey(signatureAsBase64, keyRing.getSignatureKeyPair().getPublic());
}
private boolean verifySignature(PrivateNotificationPayload privateNotification) {
- String privateNotificationMessageAsHex = Utils.HEX.encode(privateNotification.getMessage().getBytes());
+ String privateNotificationMessageAsHex = Utils.HEX.encode(privateNotification.getMessage().getBytes(Charsets.UTF_8));
try {
ECKey.fromPublicOnly(HEX.decode(pubKeyAsHex)).verifyMessage(privateNotificationMessageAsHex, privateNotification.getSignatureAsBase64());
return true;
diff --git a/core/src/main/java/bisq/core/app/BisqEnvironment.java b/core/src/main/java/bisq/core/app/BisqEnvironment.java
index d40e3bcc232..4c7afa5d49d 100644
--- a/core/src/main/java/bisq/core/app/BisqEnvironment.java
+++ b/core/src/main/java/bisq/core/app/BisqEnvironment.java
@@ -25,9 +25,9 @@
import bisq.core.filter.FilterManager;
import bisq.network.NetworkOptionKeys;
+import bisq.network.p2p.network.ConnectionConfig;
import bisq.common.CommonOptionKeys;
-import bisq.common.app.DevEnv;
import bisq.common.app.Version;
import bisq.common.crypto.KeyStorage;
import bisq.common.storage.Storage;
@@ -58,6 +58,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
@@ -109,15 +110,6 @@ public static BaseCurrencyNetwork getDefaultBaseCurrencyNetwork() {
protected static BaseCurrencyNetwork baseCurrencyNetwork = getDefaultBaseCurrencyNetwork();
- public static boolean isDAOActivatedAndBaseCurrencySupportingBsq() {
- //noinspection ConstantConditions,PointlessBooleanExpression
- return DevEnv.isDaoActivated() && isBaseCurrencySupportingBsq();
- }
-
- public static boolean isBaseCurrencySupportingBsq() {
- return getBaseCurrencyNetwork().getCurrencyCode().equals("BTC");
- }
-
public static NetworkParameters getParameters() {
return getBaseCurrencyNetwork().getParameters();
}
@@ -174,10 +166,9 @@ private static String appDataDir(String userDataDir, String appName) {
// Util to set isDaoActivated to true if either set as program argument or we run testnet or regtest.
// Can be removed once DAO is live.
public static boolean isDaoActivated(Environment environment) {
- Boolean daoActivatedFromOptions = environment.getProperty(DaoOptionKeys.DAO_ACTIVATED, Boolean.class, false);
+ Boolean daoActivatedFromOptions = environment.getProperty(DaoOptionKeys.DAO_ACTIVATED, Boolean.class, true);
BaseCurrencyNetwork baseCurrencyNetwork = BisqEnvironment.getBaseCurrencyNetwork();
- boolean isRegTestOrTestNet = (baseCurrencyNetwork.isTestnet() || baseCurrencyNetwork.isRegtest());
- return daoActivatedFromOptions || isRegTestOrTestNet;
+ return daoActivatedFromOptions || !baseCurrencyNetwork.isMainnet();
}
@@ -202,9 +193,10 @@ public static boolean isDaoActivated(Environment environment) {
protected final String btcNodes, seedNodes, ignoreDevMsg, useDevPrivilegeKeys, useDevMode, useTorForBtc, rpcUser, rpcPassword,
rpcPort, rpcBlockNotificationPort, dumpBlockchainData, fullDaoNode,
- myAddress, banList, dumpStatistics, maxMemory, socks5ProxyBtcAddress,
+ banList, dumpStatistics, maxMemory, socks5ProxyBtcAddress,
torRcFile, torRcOptions, externalTorControlPort, externalTorPassword, externalTorCookieFile,
- socks5ProxyHttpAddress, useAllProvidedNodes, numConnectionForBtc, genesisTxId, genesisBlockHeight, referralId, daoActivated;
+ socks5ProxyHttpAddress, useAllProvidedNodes, numConnectionForBtc, genesisTxId, genesisBlockHeight, genesisTotalSupply,
+ referralId, daoActivated, msgThrottlePerSec, msgThrottlePer10Sec, sendMsgThrottleTrigger, sendMsgThrottleSleep;
protected final boolean externalTorUseSafeCookieAuthentication, torStreamIsolation;
@@ -267,9 +259,6 @@ public BisqEnvironment(PropertySource commandLineProperties) {
(String) commandLineProperties.getProperty(NetworkOptionKeys.SEED_NODES_KEY) :
"";
- myAddress = commandLineProperties.containsProperty(NetworkOptionKeys.MY_ADDRESS) ?
- (String) commandLineProperties.getProperty(NetworkOptionKeys.MY_ADDRESS) :
- "";
banList = commandLineProperties.containsProperty(NetworkOptionKeys.BAN_LIST) ?
(String) commandLineProperties.getProperty(NetworkOptionKeys.BAN_LIST) :
"";
@@ -294,12 +283,20 @@ public BisqEnvironment(PropertySource commandLineProperties) {
externalTorCookieFile = commandLineProperties.containsProperty(NetworkOptionKeys.EXTERNAL_TOR_COOKIE_FILE) ?
(String) commandLineProperties.getProperty(NetworkOptionKeys.EXTERNAL_TOR_COOKIE_FILE) :
"";
- externalTorUseSafeCookieAuthentication = commandLineProperties.containsProperty(NetworkOptionKeys.EXTERNAL_TOR_USE_SAFECOOKIE) ?
- true :
- false;
- torStreamIsolation = commandLineProperties.containsProperty(NetworkOptionKeys.TOR_STREAM_ISOLATION) ?
- true :
- false;
+ externalTorUseSafeCookieAuthentication = commandLineProperties.containsProperty(NetworkOptionKeys.EXTERNAL_TOR_USE_SAFECOOKIE);
+ torStreamIsolation = commandLineProperties.containsProperty(NetworkOptionKeys.TOR_STREAM_ISOLATION);
+ msgThrottlePerSec = commandLineProperties.containsProperty(NetworkOptionKeys.MSG_THROTTLE_PER_SEC) ?
+ (String) commandLineProperties.getProperty(NetworkOptionKeys.MSG_THROTTLE_PER_SEC) :
+ String.valueOf(ConnectionConfig.MSG_THROTTLE_PER_SEC);
+ msgThrottlePer10Sec = commandLineProperties.containsProperty(NetworkOptionKeys.MSG_THROTTLE_PER_10_SEC) ?
+ (String) commandLineProperties.getProperty(NetworkOptionKeys.MSG_THROTTLE_PER_10_SEC) :
+ String.valueOf(ConnectionConfig.MSG_THROTTLE_PER_10_SEC);
+ sendMsgThrottleTrigger = commandLineProperties.containsProperty(NetworkOptionKeys.SEND_MSG_THROTTLE_TRIGGER) ?
+ (String) commandLineProperties.getProperty(NetworkOptionKeys.SEND_MSG_THROTTLE_TRIGGER) :
+ String.valueOf(ConnectionConfig.SEND_MSG_THROTTLE_TRIGGER);
+ sendMsgThrottleSleep = commandLineProperties.containsProperty(NetworkOptionKeys.SEND_MSG_THROTTLE_SLEEP) ?
+ (String) commandLineProperties.getProperty(NetworkOptionKeys.SEND_MSG_THROTTLE_SLEEP) :
+ String.valueOf(ConnectionConfig.SEND_MSG_THROTTLE_SLEEP);
//RpcOptionKeys
rpcUser = commandLineProperties.containsProperty(DaoOptionKeys.RPC_USER) ?
@@ -326,9 +323,12 @@ public BisqEnvironment(PropertySource commandLineProperties) {
genesisBlockHeight = commandLineProperties.containsProperty(DaoOptionKeys.GENESIS_BLOCK_HEIGHT) ?
(String) commandLineProperties.getProperty(DaoOptionKeys.GENESIS_BLOCK_HEIGHT) :
"-1";
+ genesisTotalSupply = commandLineProperties.containsProperty(DaoOptionKeys.GENESIS_TOTAL_SUPPLY) ?
+ (String) commandLineProperties.getProperty(DaoOptionKeys.GENESIS_TOTAL_SUPPLY) :
+ "-1";
daoActivated = commandLineProperties.containsProperty(DaoOptionKeys.DAO_ACTIVATED) ?
(String) commandLineProperties.getProperty(DaoOptionKeys.DAO_ACTIVATED) :
- "";
+ "true";
btcNodes = commandLineProperties.containsProperty(BtcOptionKeys.BTC_NODES) ?
(String) commandLineProperties.getProperty(BtcOptionKeys.BTC_NODES) :
@@ -356,7 +356,7 @@ public BisqEnvironment(PropertySource commandLineProperties) {
bannedPriceRelayNodes = !bannedPriceRelayNodesAsString.isEmpty() ? Arrays.asList(StringUtils.deleteWhitespace(bannedPriceRelayNodesAsString).split(",")) : null;
final String bannedSeedNodesAsString = getProperty(FilterManager.BANNED_SEED_NODES, "");
- bannedSeedNodes = !bannedSeedNodesAsString.isEmpty() ? Arrays.asList(StringUtils.deleteWhitespace(bannedSeedNodesAsString).split(",")) : null;
+ bannedSeedNodes = !bannedSeedNodesAsString.isEmpty() ? Arrays.asList(StringUtils.deleteWhitespace(bannedSeedNodesAsString).split(",")) : new ArrayList<>();
final String bannedBtcNodesAsString = getProperty(FilterManager.BANNED_BTC_NODES, "");
bannedBtcNodes = !bannedBtcNodesAsString.isEmpty() ? Arrays.asList(StringUtils.deleteWhitespace(bannedBtcNodesAsString).split(",")) : null;
@@ -462,7 +462,6 @@ private PropertySource> defaultProperties() {
setProperty(CommonOptionKeys.USE_DEV_MODE, useDevMode);
setProperty(NetworkOptionKeys.SEED_NODES_KEY, seedNodes);
- setProperty(NetworkOptionKeys.MY_ADDRESS, myAddress);
setProperty(NetworkOptionKeys.BAN_LIST, banList);
setProperty(NetworkOptionKeys.TOR_DIR, Paths.get(btcNetworkDir, "tor").toString());
setProperty(NetworkOptionKeys.NETWORK_ID, String.valueOf(baseCurrencyNetwork.ordinal()));
@@ -478,6 +477,11 @@ private PropertySource> defaultProperties() {
if (torStreamIsolation)
setProperty(NetworkOptionKeys.TOR_STREAM_ISOLATION, "true");
+ setProperty(NetworkOptionKeys.MSG_THROTTLE_PER_SEC, msgThrottlePerSec);
+ setProperty(NetworkOptionKeys.MSG_THROTTLE_PER_10_SEC, msgThrottlePer10Sec);
+ setProperty(NetworkOptionKeys.SEND_MSG_THROTTLE_TRIGGER, sendMsgThrottleTrigger);
+ setProperty(NetworkOptionKeys.SEND_MSG_THROTTLE_SLEEP, sendMsgThrottleSleep);
+
setProperty(AppOptionKeys.APP_DATA_DIR_KEY, appDataDir);
setProperty(AppOptionKeys.DESKTOP_WITH_HTTP_API, desktopWithHttpApi);
setProperty(AppOptionKeys.DESKTOP_WITH_GRPC_API, desktopWithGrpcApi);
@@ -498,6 +502,7 @@ private PropertySource> defaultProperties() {
setProperty(DaoOptionKeys.FULL_DAO_NODE, fullDaoNode);
setProperty(DaoOptionKeys.GENESIS_TX_ID, genesisTxId);
setProperty(DaoOptionKeys.GENESIS_BLOCK_HEIGHT, genesisBlockHeight);
+ setProperty(DaoOptionKeys.GENESIS_TOTAL_SUPPLY, genesisTotalSupply);
setProperty(DaoOptionKeys.DAO_ACTIVATED, daoActivated);
setProperty(BtcOptionKeys.BTC_NODES, btcNodes);
diff --git a/core/src/main/java/bisq/core/app/BisqExecutable.java b/core/src/main/java/bisq/core/app/BisqExecutable.java
index 9050763edaa..b2a8ee122e7 100644
--- a/core/src/main/java/bisq/core/app/BisqExecutable.java
+++ b/core/src/main/java/bisq/core/app/BisqExecutable.java
@@ -33,6 +33,7 @@
import bisq.network.NetworkOptionKeys;
import bisq.network.p2p.P2PService;
+import bisq.network.p2p.network.ConnectionConfig;
import bisq.common.CommonOptionKeys;
import bisq.common.UserThread;
@@ -68,9 +69,7 @@
import static bisq.core.app.BisqEnvironment.DEFAULT_APP_NAME;
import static bisq.core.app.BisqEnvironment.DEFAULT_USER_DATA_DIR;
-import static bisq.core.btc.BaseCurrencyNetwork.BTC_MAINNET;
-import static bisq.core.btc.BaseCurrencyNetwork.BTC_REGTEST;
-import static bisq.core.btc.BaseCurrencyNetwork.BTC_TESTNET;
+import static bisq.core.btc.BaseCurrencyNetwork.*;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.String.format;
@@ -256,7 +255,7 @@ protected void setupPersistedDataHosts(Injector injector) {
// We need to delay it as the stage is not created yet and so popups would not be shown.
if (DevEnv.isDevMode())
UserThread.runAfter(() -> {
- log.error("Error at PersistedDataHost.apply: " + t.toString());
+ log.error("Error at PersistedDataHost.apply: {}", t.toString());
throw t;
}, 2);
}
@@ -339,11 +338,6 @@ protected void customizeOptionParsing(OptionParser parser) {
.withRequiredArg()
.describedAs("host:port[,...]");
- parser.accepts(NetworkOptionKeys.MY_ADDRESS,
- "My own onion address (used for bootstrap nodes to exclude itself)")
- .withRequiredArg()
- .describedAs("host:port");
-
parser.accepts(NetworkOptionKeys.BAN_LIST,
"Nodes to exclude from network connections.")
.withRequiredArg()
@@ -415,6 +409,27 @@ protected void customizeOptionParsing(OptionParser parser) {
parser.accepts(NetworkOptionKeys.TOR_STREAM_ISOLATION,
"Use stream isolation for Tor [experimental!].");
+ parser.accepts(NetworkOptionKeys.MSG_THROTTLE_PER_SEC,
+ format("Message throttle per sec for connection class (default: %s)",
+ String.valueOf(ConnectionConfig.MSG_THROTTLE_PER_SEC)))
+ .withRequiredArg()
+ .ofType(int.class);
+ parser.accepts(NetworkOptionKeys.MSG_THROTTLE_PER_10_SEC,
+ format("Message throttle per 10 sec for connection class (default: %s)",
+ String.valueOf(ConnectionConfig.MSG_THROTTLE_PER_10_SEC)))
+ .withRequiredArg()
+ .ofType(int.class);
+ parser.accepts(NetworkOptionKeys.SEND_MSG_THROTTLE_TRIGGER,
+ format("Time in ms when we trigger a sleep if 2 messages are sent (default: %s)",
+ String.valueOf(ConnectionConfig.SEND_MSG_THROTTLE_TRIGGER)))
+ .withRequiredArg()
+ .ofType(int.class);
+ parser.accepts(NetworkOptionKeys.SEND_MSG_THROTTLE_SLEEP,
+ format("Pause in ms to sleep if we get too many messages to send (default: %s)",
+ String.valueOf(ConnectionConfig.SEND_MSG_THROTTLE_SLEEP)))
+ .withRequiredArg()
+ .ofType(int.class);
+
//AppOptionKeys
parser.accepts(AppOptionKeys.USER_DATA_DIR_KEY,
format("User data directory (default: %s)", BisqEnvironment.DEFAULT_USER_DATA_DIR))
@@ -479,7 +494,7 @@ protected void customizeOptionParsing(OptionParser parser) {
format("Base currency network (default: %s)", BisqEnvironment.getDefaultBaseCurrencyNetwork().name()))
.withRequiredArg()
.ofType(String.class)
- .describedAs(format("%s|%s|%s", BTC_MAINNET, BTC_TESTNET, BTC_REGTEST));
+ .describedAs(format("%s|%s|%s|%s", BTC_MAINNET, BTC_TESTNET, BTC_REGTEST, BTC_DAO_TESTNET, BTC_DAO_BETANET, BTC_DAO_REGTEST));
parser.accepts(BtcOptionKeys.REG_TEST_HOST,
format("Bitcoin regtest host when using BTC_REGTEST network (default: %s)", RegTestHost.DEFAULT_HOST))
@@ -550,8 +565,12 @@ protected void customizeOptionParsing(OptionParser parser) {
format("Genesis transaction block height when not using the hard coded one (default: %s)", "-1"))
.withRequiredArg();
+ parser.accepts(DaoOptionKeys.GENESIS_TOTAL_SUPPLY,
+ format("Genesis total supply when not using the hard coded one (default: %s)", "-1"))
+ .withRequiredArg();
+
parser.accepts(DaoOptionKeys.DAO_ACTIVATED,
- format("Developer flag. If true it enables dao phase 2 features. (default: %s)", "false"))
+ format("Developer flag. If true it enables dao phase 2 features. (default: %s)", "true"))
.withRequiredArg()
.ofType(boolean.class);
}
diff --git a/core/src/main/java/bisq/core/app/BisqHeadlessApp.java b/core/src/main/java/bisq/core/app/BisqHeadlessApp.java
index 3bb23f40f2b..f7ece906fb7 100644
--- a/core/src/main/java/bisq/core/app/BisqHeadlessApp.java
+++ b/core/src/main/java/bisq/core/app/BisqHeadlessApp.java
@@ -78,26 +78,26 @@ protected void setupHandlers() {
log.info("onDisplayTacHandler: We accept the tacs automatically in headless mode");
acceptedHandler.run();
});
- bisqSetup.setCryptoSetupFailedHandler(msg -> log.info("onCryptoSetupFailedHandler: msg={}", msg));
+ bisqSetup.setCryptoSetupFailedHandler(msg -> log.error("onCryptoSetupFailedHandler: msg={}", msg));
bisqSetup.setDisplayTorNetworkSettingsHandler(show -> log.info("onDisplayTorNetworkSettingsHandler: show={}", show));
- bisqSetup.setSpvFileCorruptedHandler(msg -> log.info("onSpvFileCorruptedHandler: msg={}", msg));
- bisqSetup.setChainFileLockedExceptionHandler(msg -> log.info("onChainFileLockedExceptionHandler: msg={}", msg));
+ bisqSetup.setSpvFileCorruptedHandler(msg -> log.error("onSpvFileCorruptedHandler: msg={}", msg));
+ bisqSetup.setChainFileLockedExceptionHandler(msg -> log.error("onChainFileLockedExceptionHandler: msg={}", msg));
bisqSetup.setLockedUpFundsHandler(msg -> log.info("onLockedUpFundsHandler: msg={}", msg));
bisqSetup.setShowFirstPopupIfResyncSPVRequestedHandler(() -> log.info("onShowFirstPopupIfResyncSPVRequestedHandler"));
bisqSetup.setRequestWalletPasswordHandler(aesKeyHandler -> log.info("onRequestWalletPasswordHandler"));
bisqSetup.setDisplayUpdateHandler((alert, key) -> log.info("onDisplayUpdateHandler"));
bisqSetup.setDisplayAlertHandler(alert -> log.info("onDisplayAlertHandler. alert={}", alert));
bisqSetup.setDisplayPrivateNotificationHandler(privateNotification -> log.info("onDisplayPrivateNotificationHandler. privateNotification={}", privateNotification));
- bisqSetup.setDaoErrorMessageHandler(errorMessage -> log.info("onDaoErrorMessageHandler. errorMessage={}", errorMessage));
- bisqSetup.setDaoWarnMessageHandler(warnMessage -> log.info("onDaoWarnMessageHandler. warnMessage={}", warnMessage));
+ bisqSetup.setDaoErrorMessageHandler(errorMessage -> log.error("onDaoErrorMessageHandler. errorMessage={}", errorMessage));
+ bisqSetup.setDaoWarnMessageHandler(warnMessage -> log.warn("onDaoWarnMessageHandler. warnMessage={}", warnMessage));
bisqSetup.setDisplaySecurityRecommendationHandler(key -> log.info("onDisplaySecurityRecommendationHandler"));
bisqSetup.setDisplayLocalhostHandler(key -> log.info("onDisplayLocalhostHandler"));
- bisqSetup.setWrongOSArchitectureHandler(msg -> log.info("onWrongOSArchitectureHandler. msg={}", msg));
- bisqSetup.setVoteResultExceptionHandler(voteResultException -> log.info("voteResultException={}", voteResultException));
+ bisqSetup.setWrongOSArchitectureHandler(msg -> log.error("onWrongOSArchitectureHandler. msg={}", msg));
+ bisqSetup.setVoteResultExceptionHandler(voteResultException -> log.warn("voteResultException={}", voteResultException));
//TODO move to bisqSetup
- corruptedDatabaseFilesHandler.getCorruptedDatabaseFiles().ifPresent(files -> log.info("getCorruptedDatabaseFiles. files={}", files));
- tradeManager.setTakeOfferRequestErrorMessageHandler(errorMessage -> log.info("onTakeOfferRequestErrorMessageHandler"));
+ corruptedDatabaseFilesHandler.getCorruptedDatabaseFiles().ifPresent(files -> log.warn("getCorruptedDatabaseFiles. files={}", files));
+ tradeManager.setTakeOfferRequestErrorMessageHandler(errorMessage -> log.error("onTakeOfferRequestErrorMessageHandler"));
}
public void stop() {
diff --git a/core/src/main/java/bisq/core/app/BisqSetup.java b/core/src/main/java/bisq/core/app/BisqSetup.java
index cb8e6aa997e..26cc912e6c7 100644
--- a/core/src/main/java/bisq/core/app/BisqSetup.java
+++ b/core/src/main/java/bisq/core/app/BisqSetup.java
@@ -43,7 +43,7 @@
import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.PaymentAccount;
-import bisq.core.payment.payload.PaymentMethod;
+import bisq.core.payment.TradeLimits;
import bisq.core.provider.fee.FeeService;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.trade.TradeManager;
@@ -150,6 +150,8 @@ public interface BisqSetupCompleteListener {
private final VoteResultService voteResultService;
private final AssetTradeActivityCheck tradeActivityCheck;
private final AssetService assetService;
+ private final TorSetup torSetup;
+ private final TradeLimits tradeLimits;
private final BSFormatter formatter;
@Setter
@Nullable
@@ -226,6 +228,8 @@ public BisqSetup(P2PNetworkSetup p2PNetworkSetup,
VoteResultService voteResultService,
AssetTradeActivityCheck tradeActivityCheck,
AssetService assetService,
+ TorSetup torSetup,
+ TradeLimits tradeLimits,
BSFormatter formatter) {
@@ -264,6 +268,8 @@ public BisqSetup(P2PNetworkSetup p2PNetworkSetup,
this.voteResultService = voteResultService;
this.tradeActivityCheck = tradeActivityCheck;
this.assetService = assetService;
+ this.torSetup = torSetup;
+ this.tradeLimits = tradeLimits;
this.formatter = formatter;
}
@@ -286,6 +292,7 @@ private void step2() {
}
private void step3() {
+ torSetup.cleanupTorFiles();
readMapsFromResources();
checkCryptoSetup();
checkForCorrectOSArchitecture();
@@ -351,6 +358,10 @@ public StringProperty getBtcSplashSyncIconId() {
return walletAppSetup.getBtcSplashSyncIconId();
}
+ public BooleanProperty getUseTorForBTC() {
+ return walletAppSetup.getUseTorForBTC();
+ }
+
// P2P
public StringProperty getP2PNetworkInfo() {
return p2PNetworkSetup.getP2PNetworkInfo();
@@ -406,30 +417,35 @@ private void maybeShowTac() {
}
private void checkIfLocalHostNodeIsRunning() {
- Thread checkIfLocalHostNodeIsRunningThread = new Thread(() -> {
- Thread.currentThread().setName("checkIfLocalHostNodeIsRunningThread");
- Socket socket = null;
- try {
- socket = new Socket();
- socket.connect(new InetSocketAddress(InetAddresses.forString("127.0.0.1"),
- BisqEnvironment.getBaseCurrencyNetwork().getParameters().getPort()), 5000);
- log.info("Localhost Bitcoin node detected.");
- UserThread.execute(() -> {
- bisqEnvironment.setBitcoinLocalhostNodeRunning(true);
- step3();
- });
- } catch (Throwable e) {
- UserThread.execute(BisqSetup.this::step3);
- } finally {
- if (socket != null) {
- try {
- socket.close();
- } catch (IOException ignore) {
+ // For DAO testnet we ignore local btc node
+ if (BisqEnvironment.getBaseCurrencyNetwork().isDaoRegTest() || BisqEnvironment.getBaseCurrencyNetwork().isDaoTestNet()) {
+ step3();
+ } else {
+ Thread checkIfLocalHostNodeIsRunningThread = new Thread(() -> {
+ Thread.currentThread().setName("checkIfLocalHostNodeIsRunningThread");
+ Socket socket = null;
+ try {
+ socket = new Socket();
+ socket.connect(new InetSocketAddress(InetAddresses.forString("127.0.0.1"),
+ BisqEnvironment.getBaseCurrencyNetwork().getParameters().getPort()), 5000);
+ log.info("Localhost Bitcoin node detected.");
+ UserThread.execute(() -> {
+ bisqEnvironment.setBitcoinLocalhostNodeRunning(true);
+ step3();
+ });
+ } catch (Throwable e) {
+ UserThread.execute(BisqSetup.this::step3);
+ } finally {
+ if (socket != null) {
+ try {
+ socket.close();
+ } catch (IOException ignore) {
+ }
}
}
- }
- });
- checkIfLocalHostNodeIsRunningThread.start();
+ });
+ checkIfLocalHostNodeIsRunningThread.start();
+ }
}
private void readMapsFromResources() {
@@ -448,7 +464,6 @@ private void checkCryptoSetup() {
Thread checkCryptoThread = new Thread(() -> {
try {
Thread.currentThread().setName("checkCryptoThread");
- log.trace("Run crypto test");
// just use any simple dummy msg
Ping payload = new Ping(1, 1);
SealedAndSigned sealedAndSigned = EncryptionService.encryptHybridWithSignature(payload,
@@ -480,6 +495,11 @@ private void startP2pNetworkAndWallet() {
};
Timer startupTimeout = UserThread.runAfter(() -> {
+ if (p2PNetworkSetup.p2pNetworkFailed.get()) {
+ // Skip this timeout action if the p2p network setup failed
+ // since a p2p network error prompt will be shown containing the error message
+ return;
+ }
log.warn("startupTimeout called");
if (walletsManager.areWalletsEncrypted())
walletInitialized.addListener(walletInitializedListener);
@@ -579,7 +599,7 @@ private void initDomainServices() {
clock.start();
- PaymentMethod.onAllServicesInitialized();
+ tradeLimits.onAllServicesInitialized();
disputeManager.onAllServicesInitialized();
@@ -629,11 +649,28 @@ private void initDomainServices() {
filterManager.onAllServicesInitialized();
filterManager.addListener(filter -> {
if (filter != null && filterWarningHandler != null) {
- if (filter.getSeedNodes() != null && !filter.getSeedNodes().isEmpty())
- filterWarningHandler.accept(Res.get("popup.warning.nodeBanned", Res.get("popup.warning.seed")));
+ if (filter.getSeedNodes() != null && !filter.getSeedNodes().isEmpty()) {
+ log.warn(Res.get("popup.warning.nodeBanned", Res.get("popup.warning.seed")));
+ // Lets keep that more silent. Might be used in case a node is unstable and we don't want to confuse users.
+ // filterWarningHandler.accept(Res.get("popup.warning.nodeBanned", Res.get("popup.warning.seed")));
+ }
+
+ if (filter.getPriceRelayNodes() != null && !filter.getPriceRelayNodes().isEmpty()) {
+ log.warn(Res.get("popup.warning.nodeBanned", Res.get("popup.warning.priceRelay")));
+ // Lets keep that more silent. Might be used in case a node is unstable and we don't want to confuse users.
+ // filterWarningHandler.accept(Res.get("popup.warning.nodeBanned", Res.get("popup.warning.priceRelay")));
+ }
- if (filter.getPriceRelayNodes() != null && !filter.getPriceRelayNodes().isEmpty())
- filterWarningHandler.accept(Res.get("popup.warning.nodeBanned", Res.get("popup.warning.priceRelay")));
+ if (filterManager.requireUpdateToNewVersionForTrading()) {
+ filterWarningHandler.accept(Res.get("popup.warning.mandatoryUpdate.trading"));
+ }
+
+ if (filterManager.requireUpdateToNewVersionForDAO()) {
+ filterWarningHandler.accept(Res.get("popup.warning.mandatoryUpdate.dao"));
+ }
+ if (filter.isDisableDao()) {
+ filterWarningHandler.accept(Res.get("popup.warning.disable.dao"));
+ }
}
});
diff --git a/core/src/main/java/bisq/core/app/P2PNetworkSetup.java b/core/src/main/java/bisq/core/app/P2PNetworkSetup.java
index 8d70bf8bdca..cbcda4bb3af 100644
--- a/core/src/main/java/bisq/core/app/P2PNetworkSetup.java
+++ b/core/src/main/java/bisq/core/app/P2PNetworkSetup.java
@@ -65,6 +65,8 @@ public class P2PNetworkSetup {
final StringProperty p2pNetworkWarnMsg = new SimpleStringProperty();
@Getter
final BooleanProperty updatedDataReceived = new SimpleBooleanProperty();
+ @Getter
+ final BooleanProperty p2pNetworkFailed = new SimpleBooleanProperty();
@Inject
public P2PNetworkSetup(PriceFeedService priceFeedService,
@@ -85,6 +87,7 @@ BooleanProperty init(Runnable initWalletServiceHandler, @Nullable Consumer {
String result;
+ String daoFullNode = preferences.isDaoFullNode() ? Res.get("mainView.footer.daoFullNode") + " / " : "";
int peers = (int) numPeers;
if (warning != null && peers == 0) {
result = warning;
@@ -97,7 +100,7 @@ BooleanProperty init(Runnable initWalletServiceHandler, @Nullable Consumer {
p2PNetworkInfo.set(newValue);
@@ -194,11 +197,12 @@ public void onUpdatedDataReceived() {
@Override
public void onSetupFailed(Throwable throwable) {
- log.warn("onSetupFailed");
+ log.error("onSetupFailed");
p2pNetworkWarnMsg.set(Res.get("mainView.p2pNetworkWarnMsg.connectionToP2PFailed", throwable.getMessage()));
splashP2PNetworkAnimationVisible.set(false);
bootstrapWarning.set(Res.get("mainView.bootstrapWarning.bootstrappingToP2PFailed"));
p2pNetworkLabelId.set("splash-error-state-msg");
+ p2pNetworkFailed.set(true);
}
@Override
diff --git a/core/src/main/java/bisq/core/app/SetupUtils.java b/core/src/main/java/bisq/core/app/SetupUtils.java
index c7cf8cafa3c..f3bfcd9fccd 100644
--- a/core/src/main/java/bisq/core/app/SetupUtils.java
+++ b/core/src/main/java/bisq/core/app/SetupUtils.java
@@ -54,7 +54,6 @@ public static void checkCryptoSetup(KeyRing keyRing, EncryptionService encryptio
public void run() {
try {
Thread.currentThread().setName("checkCryptoThread");
- log.trace("Run crypto test");
// just use any simple dummy msg
Ping payload = new Ping(1, 1);
SealedAndSigned sealedAndSigned = EncryptionService.encryptHybridWithSignature(payload,
@@ -86,8 +85,7 @@ public static BooleanProperty readFromResources(P2PDataStorage p2PDataStorage) {
Thread.currentThread().setName("readFromResourcesThread");
// Used to load different files per base currency (EntryMap_BTC_MAINNET, EntryMap_LTC,...)
final BaseCurrencyNetwork baseCurrencyNetwork = BisqEnvironment.getBaseCurrencyNetwork();
- final String postFix = "_" + baseCurrencyNetwork.getCurrencyCode() + "_"
- + baseCurrencyNetwork.getNetwork();
+ final String postFix = "_" + baseCurrencyNetwork.name();
long ts = new Date().getTime();
p2PDataStorage.readFromResources(postFix);
log.info("readFromResources took {} ms", (new Date().getTime() - ts));
diff --git a/core/src/main/java/bisq/core/app/TorSetup.java b/core/src/main/java/bisq/core/app/TorSetup.java
new file mode 100644
index 00000000000..238e23e97a4
--- /dev/null
+++ b/core/src/main/java/bisq/core/app/TorSetup.java
@@ -0,0 +1,69 @@
+/*
+ * 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 bisq.core.app;
+
+import bisq.network.NetworkOptionKeys;
+
+import bisq.common.handlers.ErrorMessageHandler;
+import bisq.common.storage.FileUtil;
+
+import com.google.inject.name.Named;
+
+import javax.inject.Inject;
+
+import java.nio.file.Paths;
+
+import java.io.File;
+import java.io.IOException;
+
+import lombok.extern.slf4j.Slf4j;
+
+import javax.annotation.Nullable;
+
+@Slf4j
+public class TorSetup {
+ private File torDir;
+
+ @Inject
+ public TorSetup(@Named(NetworkOptionKeys.TOR_DIR) File torDir) {
+ this.torDir = torDir;
+ }
+
+ public void cleanupTorFiles() {
+ cleanupTorFiles(null, null);
+ }
+
+ // We get sometimes Tor startup problems which is related to some tor files in the tor directory. It happens
+ // more often if the application got killed (not graceful shutdown).
+ // Creating all tor files newly takes about 3-4 sec. longer and it does not benefit from cache files.
+ // TODO: We should fix those startup problems in the netlayer library, once fixed there we can remove that call at the
+ // Bisq startup again.
+ public void cleanupTorFiles(@Nullable Runnable resultHandler, @Nullable ErrorMessageHandler errorMessageHandler) {
+ File hiddenservice = new File(Paths.get(torDir.getAbsolutePath(), "hiddenservice").toString());
+ try {
+ FileUtil.deleteDirectory(torDir, hiddenservice, true);
+ if (resultHandler != null)
+ resultHandler.run();
+ } catch (IOException e) {
+ e.printStackTrace();
+ log.error(e.toString());
+ if (errorMessageHandler != null)
+ errorMessageHandler.handleErrorMessage(e.toString());
+ }
+ }
+}
diff --git a/core/src/main/java/bisq/core/app/WalletAppSetup.java b/core/src/main/java/bisq/core/app/WalletAppSetup.java
index 49237f90951..e89df28ab85 100644
--- a/core/src/main/java/bisq/core/app/WalletAppSetup.java
+++ b/core/src/main/java/bisq/core/app/WalletAppSetup.java
@@ -23,8 +23,6 @@
import bisq.core.user.Preferences;
import bisq.core.util.BSFormatter;
-import org.libdohj.Version;
-
import org.bitcoinj.core.VersionMessage;
import org.bitcoinj.store.BlockStoreException;
import org.bitcoinj.store.ChainFileLockedException;
@@ -34,8 +32,10 @@
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.monadic.MonadicBinding;
+import javafx.beans.property.BooleanProperty;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
@@ -70,6 +70,8 @@ public class WalletAppSetup {
private final StringProperty btcInfo = new SimpleStringProperty(Res.get("mainView.footer.btcInfo.initializing"));
@Getter
private int numBtcPeers = 0;
+ @Getter
+ private final BooleanProperty useTorForBTC = new SimpleBooleanProperty();
@Inject
public WalletAppSetup(WalletsManager walletsManager,
@@ -82,6 +84,7 @@ public WalletAppSetup(WalletsManager walletsManager,
this.bisqEnvironment = bisqEnvironment;
this.preferences = preferences;
this.formatter = formatter;
+ this.useTorForBTC.set(preferences.getUseTorForBitcoinJ());
}
void init(@Nullable Consumer chainFileLockedExceptionHandler,
@@ -90,8 +93,8 @@ void init(@Nullable Consumer chainFileLockedExceptionHandler,
Runnable walletPasswordHandler,
Runnable downloadCompleteHandler,
Runnable walletInitializedHandler) {
- log.info("Initialize WalletAppSetup with BitcoinJ version {} and LibDohJ version {} with hash of BitcoinJ commit {}",
- VersionMessage.BITCOINJ_VERSION, Version.VERSION, Version.BITCOINJ_VERSION);
+ log.info("Initialize WalletAppSetup with BitcoinJ version {} and hash of BitcoinJ commit {}",
+ VersionMessage.BITCOINJ_VERSION, "cd30ad5b");
ObjectProperty walletServiceException = new SimpleObjectProperty<>();
btcInfoBinding = EasyBind.combine(walletsSetup.downloadPercentageProperty(),
@@ -114,7 +117,7 @@ void init(@Nullable Consumer chainFileLockedExceptionHandler,
} else if (percentage > 0.0) {
result = Res.get("mainView.footer.btcInfo",
peers,
- Res.get("mainView.footer.btcInfo.synchronizedWith"),
+ Res.get("mainView.footer.btcInfo.synchronizingWith"),
getBtcNetworkAsString() + ": " + formatter.formatToPercentWithSymbol(percentage));
} else {
result = Res.get("mainView.footer.btcInfo",
diff --git a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2P.java b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2P.java
index 89adeacab21..07c74d7e760 100644
--- a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2P.java
+++ b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2P.java
@@ -18,6 +18,7 @@
package bisq.core.app.misc;
import bisq.core.app.SetupUtils;
+import bisq.core.app.TorSetup;
import bisq.core.filter.FilterManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.trade.statistics.TradeStatisticsManager;
@@ -46,6 +47,7 @@ public class AppSetupWithP2P extends AppSetup {
protected final P2PService p2PService;
protected final AccountAgeWitnessService accountAgeWitnessService;
protected final FilterManager filterManager;
+ private final TorSetup torSetup;
protected BooleanProperty p2pNetWorkReady;
protected final TradeStatisticsManager tradeStatisticsManager;
protected ArrayList persistedDataHosts;
@@ -56,23 +58,25 @@ public AppSetupWithP2P(EncryptionService encryptionService,
P2PService p2PService,
TradeStatisticsManager tradeStatisticsManager,
AccountAgeWitnessService accountAgeWitnessService,
- FilterManager filterManager) {
+ FilterManager filterManager,
+ TorSetup torSetup) {
super(encryptionService, keyRing);
this.p2PService = p2PService;
this.tradeStatisticsManager = tradeStatisticsManager;
this.accountAgeWitnessService = accountAgeWitnessService;
this.filterManager = filterManager;
+ this.torSetup = torSetup;
this.persistedDataHosts = new ArrayList<>();
}
@Override
public void initPersistedDataHosts() {
+ torSetup.cleanupTorFiles();
persistedDataHosts.add(p2PService);
// we apply at startup the reading of persisted data but don't want to get it triggered in the constructor
- persistedDataHosts.stream().forEach(e -> {
+ persistedDataHosts.forEach(e -> {
try {
- log.info("call readPersisted at " + e.getClass().getSimpleName());
e.readPersisted();
} catch (Throwable e1) {
log.error("readPersisted error", e1);
@@ -115,7 +119,7 @@ public void onDisconnect(CloseConnectionReason closeConnectionReason, Connection
if (connection.getPeerType() == Connection.PeerType.SEED_NODE &&
closeConnectionReason == CloseConnectionReason.RULE_VIOLATION) {
log.warn("RULE_VIOLATION onDisconnect closeConnectionReason=" + closeConnectionReason);
- log.warn("RULE_VIOLATION onDisconnect connection=" + connection);
+ log.warn("RULE_VIOLATION onDisconnect connection={}", connection);
}
}
diff --git a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java
index 50628e336e2..4a2a89c2953 100644
--- a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java
+++ b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java
@@ -17,6 +17,7 @@
package bisq.core.app.misc;
+import bisq.core.app.TorSetup;
import bisq.core.dao.DaoOptionKeys;
import bisq.core.dao.DaoSetup;
import bisq.core.dao.governance.ballot.BallotListService;
@@ -57,13 +58,15 @@ public AppSetupWithP2PAndDAO(EncryptionService encryptionService,
MyProposalListService myProposalListService,
MyReputationListService myReputationListService,
MyProofOfBurnListService myProofOfBurnListService,
+ TorSetup torSetup,
@Named(DaoOptionKeys.DAO_ACTIVATED) boolean daoActivated) {
super(encryptionService,
keyRing,
p2PService,
tradeStatisticsManager,
accountAgeWitnessService,
- filterManager);
+ filterManager,
+ torSetup);
this.daoSetup = daoSetup;
diff --git a/core/src/main/java/bisq/core/app/misc/ExecutableForAppWithP2p.java b/core/src/main/java/bisq/core/app/misc/ExecutableForAppWithP2p.java
index a48dd4384be..55e41da3827 100644
--- a/core/src/main/java/bisq/core/app/misc/ExecutableForAppWithP2p.java
+++ b/core/src/main/java/bisq/core/app/misc/ExecutableForAppWithP2p.java
@@ -47,7 +47,7 @@
@Slf4j
public abstract class ExecutableForAppWithP2p extends BisqExecutable implements UncaughtExceptionHandler {
private static final long MAX_MEMORY_MB_DEFAULT = 500;
- private static final long CHECK_MEMORY_PERIOD_SEC = 10;
+ private static final long CHECK_MEMORY_PERIOD_SEC = 300;
private volatile boolean stopped;
private static long maxMemory = MAX_MEMORY_MB_DEFAULT;
diff --git a/core/src/main/java/bisq/core/app/misc/ModuleForAppWithP2p.java b/core/src/main/java/bisq/core/app/misc/ModuleForAppWithP2p.java
index 64cfcb465e3..35413918c2d 100644
--- a/core/src/main/java/bisq/core/app/misc/ModuleForAppWithP2p.java
+++ b/core/src/main/java/bisq/core/app/misc/ModuleForAppWithP2p.java
@@ -20,12 +20,12 @@
import bisq.core.alert.AlertModule;
import bisq.core.app.AppOptionKeys;
import bisq.core.app.BisqEnvironment;
+import bisq.core.app.TorSetup;
import bisq.core.arbitration.ArbitratorModule;
import bisq.core.btc.BitcoinModule;
import bisq.core.dao.DaoModule;
import bisq.core.filter.FilterModule;
import bisq.core.network.p2p.seed.DefaultSeedNodeRepository;
-import bisq.core.network.p2p.seed.SeedNodeAddressLookup;
import bisq.core.offer.OfferModule;
import bisq.core.proto.network.CoreNetworkProtoResolver;
import bisq.core.proto.persistable.CorePersistenceProtoResolver;
@@ -74,8 +74,8 @@ protected void configure() {
bind(PersistenceProtoResolver.class).to(CorePersistenceProtoResolver.class).in(Singleton.class);
bind(Preferences.class).in(Singleton.class);
bind(BridgeAddressProvider.class).to(Preferences.class).in(Singleton.class);
+ bind(TorSetup.class).in(Singleton.class);
- bind(SeedNodeAddressLookup.class).in(Singleton.class);
bind(SeedNodeRepository.class).to(DefaultSeedNodeRepository.class).in(Singleton.class);
File storageDir = new File(environment.getRequiredProperty(Storage.STORAGE_DIR));
diff --git a/core/src/main/java/bisq/core/arbitration/Arbitrator.java b/core/src/main/java/bisq/core/arbitration/Arbitrator.java
index a9b6d738c45..ffc6a8f4670 100644
--- a/core/src/main/java/bisq/core/arbitration/Arbitrator.java
+++ b/core/src/main/java/bisq/core/arbitration/Arbitrator.java
@@ -23,6 +23,7 @@
import bisq.common.crypto.PubKeyRing;
import bisq.common.proto.ProtoUtil;
+import bisq.common.util.ExtraDataMapValidator;
import bisq.common.util.Utilities;
import io.bisq.generated.protobuffer.PB;
@@ -91,7 +92,7 @@ public Arbitrator(NodeAddress nodeAddress,
this.registrationSignature = registrationSignature;
this.emailAddress = emailAddress;
this.info = info;
- this.extraDataMap = extraDataMap;
+ this.extraDataMap = ExtraDataMapValidator.getValidatedExtraDataMap(extraDataMap);
}
///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/core/src/main/java/bisq/core/arbitration/ArbitratorService.java b/core/src/main/java/bisq/core/arbitration/ArbitratorService.java
index e29511d60cf..8e781cc5c10 100644
--- a/core/src/main/java/bisq/core/arbitration/ArbitratorService.java
+++ b/core/src/main/java/bisq/core/arbitration/ArbitratorService.java
@@ -107,7 +107,7 @@ public Map getArbitrators() {
.filter(data -> data.getProtectedStoragePayload() instanceof Arbitrator)
.map(data -> (Arbitrator) data.getProtectedStoragePayload())
.filter(a -> bannedArbitrators == null ||
- !bannedArbitrators.contains(a.getNodeAddress().getHostName()))
+ !bannedArbitrators.contains(a.getNodeAddress().getFullAddress()))
.collect(Collectors.toSet());
Map map = new HashMap<>();
diff --git a/core/src/main/java/bisq/core/arbitration/DisputeManager.java b/core/src/main/java/bisq/core/arbitration/DisputeManager.java
index 637357787c1..ed1a665bd5d 100644
--- a/core/src/main/java/bisq/core/arbitration/DisputeManager.java
+++ b/core/src/main/java/bisq/core/arbitration/DisputeManager.java
@@ -49,6 +49,7 @@
import bisq.common.Timer;
import bisq.common.UserThread;
+import bisq.common.app.Version;
import bisq.common.crypto.KeyRing;
import bisq.common.crypto.PubKeyRing;
import bisq.common.handlers.FaultHandler;
@@ -119,6 +120,7 @@ public class DisputeManager implements PersistedDataHost {
private final Map disputeIsClosedSubscriptionsMap = new HashMap<>();
@Getter
private final IntegerProperty numOpenDisputes = new SimpleIntegerProperty();
+ private boolean servicesInitialized;
///////////////////////////////////////////////////////////////////////////////////////////
@@ -176,6 +178,7 @@ public void readPersisted() {
}
public void onAllServicesInitialized() {
+ servicesInitialized = true;
p2PService.addP2PServiceListener(new BootstrapListener() {
@Override
public void onUpdatedDataReceived() {
@@ -259,9 +262,13 @@ private void tryApplyMessages() {
}
private boolean isReadyForTxBroadcast() {
+ // Some messages can't be handled until all the services are properly initialized.
+ // In particular it's not possible to complete the signing of a dispute payout
+ // by an encrypted wallet until after it's been decrypted.
return p2PService.isBootstrapped() &&
walletsSetup.isDownloadComplete() &&
- walletsSetup.hasSufficientPeersForBroadcast();
+ walletsSetup.hasSufficientPeersForBroadcast() &&
+ servicesInitialized;
}
private void applyMessages() {
@@ -337,8 +344,8 @@ public void sendOpenNewDisputeMessage(Dispute dispute, boolean reOpen, ResultHan
final Optional storedDisputeOptional = findDispute(dispute.getTradeId(), dispute.getTraderId());
if (!storedDisputeOptional.isPresent() || reOpen) {
String sysMsg = dispute.isSupportTicket() ?
- Res.get("support.youOpenedTicket")
- : Res.get("support.youOpenedDispute", disputeInfo);
+ Res.get("support.youOpenedTicket", disputeInfo, Version.VERSION)
+ : Res.get("support.youOpenedDispute", disputeInfo, Version.VERSION);
DisputeCommunicationMessage disputeCommunicationMessage = new DisputeCommunicationMessage(
dispute.getTradeId(),
@@ -450,7 +457,7 @@ private String sendPeerOpenedDisputeMessage(Dispute disputeFromOpener, Contract
final Optional storedDisputeOptional = findDispute(dispute.getTradeId(), dispute.getTraderId());
if (!storedDisputeOptional.isPresent()) {
String sysMsg = dispute.isSupportTicket() ?
- Res.get("support.peerOpenedTicket")
+ Res.get("support.peerOpenedTicket", disputeInfo)
: Res.get("support.peerOpenedDispute", disputeInfo);
DisputeCommunicationMessage disputeCommunicationMessage = new DisputeCommunicationMessage(
dispute.getTradeId(),
@@ -877,10 +884,9 @@ private void onDisputeResultMessage(DisputeResultMessage disputeResultMessage) {
}
return;
}
-
+ Dispute dispute = disputeOptional.get();
try {
cleanupRetryMap(uid);
- Dispute dispute = disputeOptional.get();
arbitratorsPubKeyRing = dispute.getArbitratorPubKeyRing();
DisputeCommunicationMessage disputeCommunicationMessage = disputeResult.getDisputeCommunicationMessage();
if (!dispute.getDisputeCommunicationMessages().contains(disputeCommunicationMessage))
@@ -996,10 +1002,25 @@ public void onFailure(TxBroadcastException exception) {
success = true;
}
- } catch (AddressFormatException | WalletException | TransactionVerificationException e) {
- e.printStackTrace();
+ } catch (TransactionVerificationException e) {
errorMessage = "Error at traderSignAndFinalizeDisputedPayoutTx " + e.toString();
- log.error(errorMessage);
+ log.error(errorMessage, e);
+ success = false;
+
+ // We prefer to close the dispute in that case. If there was no deposit tx and a random tx was used
+ // we get a TransactionVerificationException. No reason to keep that dispute open...
+ if (tradeManager.getTradeById(dispute.getTradeId()).isPresent())
+ tradeManager.closeDisputedTrade(dispute.getTradeId());
+ else {
+ Optional openOfferOptional = openOfferManager.getOpenOfferById(dispute.getTradeId());
+ openOfferOptional.ifPresent(openOffer -> openOfferManager.closeOpenOffer(openOffer.getOffer()));
+ }
+ dispute.setIsClosed(true);
+
+ throw new RuntimeException(errorMessage);
+ } catch (AddressFormatException | WalletException e) {
+ errorMessage = "Error at traderSignAndFinalizeDisputedPayoutTx " + e.toString();
+ log.error(errorMessage, e);
success = false;
throw new RuntimeException(errorMessage);
} finally {
diff --git a/core/src/main/java/bisq/core/arbitration/Mediator.java b/core/src/main/java/bisq/core/arbitration/Mediator.java
index b5d4e3ca643..0673b5465c0 100644
--- a/core/src/main/java/bisq/core/arbitration/Mediator.java
+++ b/core/src/main/java/bisq/core/arbitration/Mediator.java
@@ -23,6 +23,7 @@
import bisq.common.crypto.PubKeyRing;
import bisq.common.proto.ProtoUtil;
+import bisq.common.util.ExtraDataMapValidator;
import io.bisq.generated.protobuffer.PB;
@@ -84,7 +85,7 @@ public Mediator(NodeAddress nodeAddress,
this.registrationSignature = registrationSignature;
this.emailAddress = emailAddress;
this.info = info;
- this.extraDataMap = extraDataMap;
+ this.extraDataMap = ExtraDataMapValidator.getValidatedExtraDataMap(extraDataMap);
}
diff --git a/core/src/main/java/bisq/core/btc/BaseCurrencyNetwork.java b/core/src/main/java/bisq/core/btc/BaseCurrencyNetwork.java
index 51c27f66e09..c4468563299 100644
--- a/core/src/main/java/bisq/core/btc/BaseCurrencyNetwork.java
+++ b/core/src/main/java/bisq/core/btc/BaseCurrencyNetwork.java
@@ -17,13 +17,6 @@
package bisq.core.btc;
-import org.libdohj.params.DashMainNetParams;
-import org.libdohj.params.DashRegTestParams;
-import org.libdohj.params.DashTestNet3Params;
-import org.libdohj.params.LitecoinMainNetParams;
-import org.libdohj.params.LitecoinRegTestParams;
-import org.libdohj.params.LitecoinTestNet3Params;
-
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.params.RegTestParams;
@@ -35,14 +28,9 @@ public enum BaseCurrencyNetwork {
BTC_MAINNET(MainNetParams.get(), "BTC", "MAINNET", "Bitcoin"),
BTC_TESTNET(TestNet3Params.get(), "BTC", "TESTNET", "Bitcoin"),
BTC_REGTEST(RegTestParams.get(), "BTC", "REGTEST", "Bitcoin"),
-
- LTC_MAINNET(LitecoinMainNetParams.get(), "LTC", "MAINNET", "Litecoin"),
- LTC_TESTNET(LitecoinTestNet3Params.get(), "LTC", "TESTNET", "Litecoin"),
- LTC_REGTEST(LitecoinRegTestParams.get(), "LTC", "REGTEST", "Litecoin"),
-
- DASH_MAINNET(DashMainNetParams.get(), "DASH", "MAINNET", "Dash"),
- DASH_TESTNET(DashTestNet3Params.get(), "DASH", "TESTNET", "Dash"),
- DASH_REGTEST(DashRegTestParams.get(), "DASH", "REGTEST", "Dash");
+ BTC_DAO_TESTNET(RegTestParams.get(), "BTC", "REGTEST", "Bitcoin"), // server side regtest until v0.9.5
+ BTC_DAO_BETANET(MainNetParams.get(), "BTC", "MAINNET", "Bitcoin"), // mainnet test genesis
+ BTC_DAO_REGTEST(RegTestParams.get(), "BTC", "REGTEST", "Bitcoin"); // server side regtest after v0.9.5, had breaking code changes so we started over again
@Getter
private final NetworkParameters parameters;
@@ -61,27 +49,27 @@ public enum BaseCurrencyNetwork {
}
public boolean isMainnet() {
- return "MAINNET".equals(network);
+ return "BTC_MAINNET".equals(name());
}
public boolean isTestnet() {
- return "TESTNET".equals(network);
+ return "BTC_TESTNET".equals(name());
}
- public boolean isRegtest() {
- return "REGTEST".equals(network);
+ public boolean isDaoTestNet() {
+ return "BTC_DAO_TESTNET".equals(name());
}
- public boolean isBitcoin() {
- return "BTC".equals(currencyCode);
+ public boolean isDaoRegTest() {
+ return "BTC_DAO_REGTEST".equals(name());
}
- public boolean isLitecoin() {
- return "LTC".equals(currencyCode);
+ public boolean isDaoBetaNet() {
+ return "BTC_DAO_BETANET".equals(name());
}
- public boolean isDash() {
- return "DASH".equals(currencyCode);
+ public boolean isRegtest() {
+ return "BTC_REGTEST".equals(name());
}
public long getDefaultMinFeePerByte() {
diff --git a/core/src/main/java/bisq/core/btc/BitcoinModule.java b/core/src/main/java/bisq/core/btc/BitcoinModule.java
index a5de4e8efab..67a8265cc42 100644
--- a/core/src/main/java/bisq/core/btc/BitcoinModule.java
+++ b/core/src/main/java/bisq/core/btc/BitcoinModule.java
@@ -18,6 +18,7 @@
package bisq.core.btc;
import bisq.core.app.AppOptionKeys;
+import bisq.core.app.BisqEnvironment;
import bisq.core.btc.model.AddressEntryList;
import bisq.core.btc.nodes.BtcNodes;
import bisq.core.btc.setup.RegTestHost;
@@ -53,13 +54,25 @@ public BitcoinModule(Environment environment) {
@Override
protected void configure() {
- String regTestHost = environment.getProperty(BtcOptionKeys.REG_TEST_HOST, String.class, RegTestHost.DEFAULT_HOST);
+ // If we we have selected BTC_DAO_REGTEST or BTC_DAO_TESTNET we use our master regtest node,
+ // otherwise the specified host or default (localhost)
+ String regTestHost = environment.getProperty(BtcOptionKeys.REG_TEST_HOST, String.class, "");
+ if (regTestHost.isEmpty()) {
+ regTestHost = BisqEnvironment.getBaseCurrencyNetwork().isDaoTestNet() ?
+ "104.248.31.39" :
+ BisqEnvironment.getBaseCurrencyNetwork().isDaoRegTest() ?
+ "134.209.242.206" :
+ RegTestHost.DEFAULT_HOST;
+ }
+
+ RegTestHost.HOST = regTestHost;
if (Arrays.asList("localhost", "127.0.0.1").contains(regTestHost)) {
bind(RegTestHost.class).toInstance(RegTestHost.LOCALHOST);
+ } else if ("none".equals(regTestHost)) {
+ bind(RegTestHost.class).toInstance(RegTestHost.NONE);
} else {
bind(RegTestHost.class).toInstance(RegTestHost.REMOTE_HOST);
}
- RegTestHost.HOST = regTestHost;
bindConstant().annotatedWith(named(UserAgent.NAME_KEY)).to(environment.getRequiredProperty(UserAgent.NAME_KEY));
bindConstant().annotatedWith(named(UserAgent.VERSION_KEY)).to(environment.getRequiredProperty(UserAgent.VERSION_KEY));
diff --git a/core/src/main/java/bisq/core/btc/exceptions/BsqChangeBelowDustException.java b/core/src/main/java/bisq/core/btc/exceptions/BsqChangeBelowDustException.java
new file mode 100644
index 00000000000..d0bf325151b
--- /dev/null
+++ b/core/src/main/java/bisq/core/btc/exceptions/BsqChangeBelowDustException.java
@@ -0,0 +1,33 @@
+/*
+ * 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 bisq.core.btc.exceptions;
+
+import org.bitcoinj.core.Coin;
+
+import lombok.Getter;
+
+public class BsqChangeBelowDustException extends Exception {
+ @Getter
+ private final Coin outputValue;
+
+ public BsqChangeBelowDustException(String message, Coin outputValue) {
+ super(message);
+
+ this.outputValue = outputValue;
+ }
+}
diff --git a/core/src/main/java/bisq/core/btc/exceptions/TxBroadcastTimeoutException.java b/core/src/main/java/bisq/core/btc/exceptions/TxBroadcastTimeoutException.java
index e54f35d5bea..a9aa4aa0dff 100644
--- a/core/src/main/java/bisq/core/btc/exceptions/TxBroadcastTimeoutException.java
+++ b/core/src/main/java/bisq/core/btc/exceptions/TxBroadcastTimeoutException.java
@@ -41,7 +41,7 @@ public class TxBroadcastTimeoutException extends TxBroadcastException {
*/
public TxBroadcastTimeoutException(Transaction localTx, int delay, Wallet wallet) {
super("The transaction was not broadcasted in " + delay +
- "seconds. txId=" + localTx.getHashAsString());
+ " seconds. txId=" + localTx.getHashAsString());
this.localTx = localTx;
this.delay = delay;
this.wallet = wallet;
diff --git a/core/src/main/java/bisq/core/btc/exceptions/TxMalleabilityException.java b/core/src/main/java/bisq/core/btc/exceptions/TxMalleabilityException.java
deleted file mode 100644
index caa262b4a30..00000000000
--- a/core/src/main/java/bisq/core/btc/exceptions/TxMalleabilityException.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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 bisq.core.btc.exceptions;
-
-import org.bitcoinj.core.Transaction;
-
-import lombok.Getter;
-
-import javax.annotation.Nullable;
-
-
-public class TxMalleabilityException extends TxBroadcastException {
- @Getter
- @Nullable
- private final Transaction localTx;
- @Getter
- @Nullable
- private final Transaction networkTx;
-
- public TxMalleabilityException(Transaction localTx, Transaction networkTx) {
- super("The transaction we received from the Bitcoin network has a different txId as the one we broadcasted.\n" +
- "txId of local tx=" + localTx.getHashAsString() +
- ", txId of received tx=" + localTx.getHashAsString());
- this.localTx = localTx;
- this.networkTx = networkTx;
- }
-
- @Override
- public String toString() {
- return "TxMalleabilityException{" +
- "\n localTx=" + localTx +
- ",\n networkTx=" + networkTx +
- "\n} " + super.toString();
- }
-}
diff --git a/core/src/main/java/bisq/core/btc/listeners/BsqBalanceListener.java b/core/src/main/java/bisq/core/btc/listeners/BsqBalanceListener.java
index 5a49bda668a..7923db370c5 100644
--- a/core/src/main/java/bisq/core/btc/listeners/BsqBalanceListener.java
+++ b/core/src/main/java/bisq/core/btc/listeners/BsqBalanceListener.java
@@ -20,9 +20,10 @@
import org.bitcoinj.core.Coin;
public interface BsqBalanceListener {
- void onUpdateBalances(Coin availableBalance,
+ void onUpdateBalances(Coin availableConfirmedBalance,
Coin availableNonBsqBalance,
Coin unverifiedBalance,
+ Coin unconfirmedChangeBalance,
Coin lockedForVotingBalance,
Coin lockedInBondsBalance,
Coin unlockingBondsBalance);
diff --git a/core/src/main/java/bisq/core/btc/model/AddressEntryList.java b/core/src/main/java/bisq/core/btc/model/AddressEntryList.java
index 08b0ad188b9..6cb1bffc12b 100644
--- a/core/src/main/java/bisq/core/btc/model/AddressEntryList.java
+++ b/core/src/main/java/bisq/core/btc/model/AddressEntryList.java
@@ -25,6 +25,7 @@
import com.google.protobuf.Message;
+import org.bitcoinj.core.Transaction;
import org.bitcoinj.crypto.DeterministicKey;
import org.bitcoinj.wallet.Wallet;
@@ -32,6 +33,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -110,16 +112,45 @@ public void onWalletReady(Wallet wallet) {
list = new ArrayList<>();
add(new AddressEntry(wallet.freshReceiveKey(), AddressEntry.Context.ARBITRATOR));
- // In case we restore from seed words and have balance we need to add the relevant addresses to our list:
+ // In case we restore from seed words and have balance we need to add the relevant addresses to our list.
+ // IssuedReceiveAddresses does not contain all addressed where we expect balance so we need to listen to
+ // incoming txs at blockchain sync to add the rest.
if (wallet.getBalance().isPositive()) {
wallet.getIssuedReceiveAddresses().forEach(address -> {
- log.info("Create AddressEntry for address={}", address);
+ log.info("Create AddressEntry for IssuedReceiveAddress. address={}", address.toString());
add(new AddressEntry((DeterministicKey) wallet.findKeyFromPubHash(address.getHash160()), AddressEntry.Context.AVAILABLE));
});
}
-
persist();
}
+
+ // We add those listeners to get notified about potential new transactions and
+ // add an address entry list in case it does not exist yet. This is mainly needed for restore from seed words
+ // but can help as well in case the addressEntry list would miss an address where the wallet was received
+ // funds (e.g. if the user sends funds to an address which has not been provided in the main UI - like from the
+ // wallet details window).
+ wallet.addCoinsReceivedEventListener((w, tx, prevBalance, newBalance) -> {
+ updateList(tx);
+ });
+ wallet.addCoinsSentEventListener((w, tx, prevBalance, newBalance) -> {
+ updateList(tx);
+ });
+ }
+
+ private void updateList(Transaction tx) {
+ tx.getOutputs().stream()
+ .filter(output -> output.isMine(wallet))
+ .map(output -> output.getAddressFromP2PKHScript(wallet.getNetworkParameters()))
+ .filter(Objects::nonNull)
+ .filter(address -> !listContainsEntryWithAddress(address.toBase58()))
+ .map(address -> (DeterministicKey) wallet.findKeyFromPubHash(address.getHash160()))
+ .filter(Objects::nonNull)
+ .map(deterministicKey -> new AddressEntry(deterministicKey, AddressEntry.Context.AVAILABLE))
+ .forEach(addressEntry -> list.add(addressEntry));
+ }
+
+ private boolean listContainsEntryWithAddress(String addressString) {
+ return list.stream().anyMatch(addressEntry -> Objects.equals(addressEntry.getAddressString(), addressString));
}
private boolean add(AddressEntry addressEntry) {
diff --git a/core/src/main/java/bisq/core/btc/nodes/BtcNodeConverter.java b/core/src/main/java/bisq/core/btc/nodes/BtcNodeConverter.java
index 61bf64a4e50..2cb29b8f49e 100644
--- a/core/src/main/java/bisq/core/btc/nodes/BtcNodeConverter.java
+++ b/core/src/main/java/bisq/core/btc/nodes/BtcNodeConverter.java
@@ -23,7 +23,7 @@
import bisq.network.DnsLookupTor;
import org.bitcoinj.core.PeerAddress;
-import org.bitcoinj.net.OnionCat;
+import org.bitcoinj.net.OnionCatConverter;
import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;
@@ -56,7 +56,7 @@ PeerAddress convertOnionHost(BtcNode node) {
// no DNS lookup for onion addresses
String onionAddress = Objects.requireNonNull(node.getOnionAddress());
try {
- // OnionCat.onionHostToInetAddress converts onion to ipv6 representation
+ // OnionCatConverter.onionHostToInetAddress converts onion to ipv6 representation
// inetAddress is not used but required for wallet persistence. Throws nullPointer if not set.
InetAddress inetAddress = facade.onionHostToInetAddress(onionAddress);
PeerAddress result = new PeerAddress(onionAddress, node.getPort());
@@ -127,7 +127,7 @@ private static PeerAddress create(String hostName, int port) {
static class Facade {
InetAddress onionHostToInetAddress(String onionAddress) throws UnknownHostException {
- return OnionCat.onionHostToInetAddress(onionAddress);
+ return OnionCatConverter.onionHostToInetAddress(onionAddress);
}
InetAddress torLookup(Socks5Proxy proxy, String host) throws DnsLookupException {
diff --git a/core/src/main/java/bisq/core/btc/nodes/BtcNodes.java b/core/src/main/java/bisq/core/btc/nodes/BtcNodes.java
index 4f4c243c382..b97030bf250 100644
--- a/core/src/main/java/bisq/core/btc/nodes/BtcNodes.java
+++ b/core/src/main/java/bisq/core/btc/nodes/BtcNodes.java
@@ -54,7 +54,7 @@ public List getProvidedBtcNodes() {
// emzy
new BtcNode("kirsche.emzy.de", "fz6nsij6jiyuwlsc.onion", "78.47.61.83", BtcNode.DEFAULT_PORT, "@emzy"),
new BtcNode("node2.emzy.de", "c6ac4jdfyeiakex2.onion", "62.75.210.81", BtcNode.DEFAULT_PORT, "@emzy"),
- new BtcNode("node1.emzy.de", "sjyzmwwu6diiit3r.onion", "163.172.171.119", BtcNode.DEFAULT_PORT, "@emzy"),
+ new BtcNode("node1.emzy.de", "sjyzmwwu6diiit3r.onion", "167.86.90.239", BtcNode.DEFAULT_PORT, "@emzy"),
new BtcNode(null, "3xucqntxp5ddoaz5.onion", null, BtcNode.DEFAULT_PORT, "@emzy"), // cannot provide IP because no static IP
// ripcurlx
@@ -68,6 +68,12 @@ public List getProvidedBtcNodes() {
new BtcNode("btc1.sqrrm.net", "3r44ddzjitznyahw.onion", "185.25.48.184", BtcNode.DEFAULT_PORT, "@sqrrm"),
new BtcNode("btc2.sqrrm.net", "i3a5xtzfm4xwtybd.onion", "81.171.22.143", BtcNode.DEFAULT_PORT, "@sqrrm"),
+ // KanoczTomas
+ new BtcNode("btc.ispol.sk", "mbm6ffx6j5ygi2ck.onion", "193.58.196.212", BtcNode.DEFAULT_PORT, "@KanoczTomas"),
+
+ // Devin Bileck
+ new BtcNode("btc1.dnsalias.net", "lva54pnbq2nsmjyr.onion", "165.227.34.198", BtcNode.DEFAULT_PORT, "@devinbileck"),
+
// sgeisler
new BtcNode("bcwat.ch", "z33nukt7ngik3cpe.onion", "5.189.166.193", BtcNode.DEFAULT_PORT, "@sgeisler"),
@@ -79,7 +85,7 @@ public List getProvidedBtcNodes() {
}
public boolean useProvidedBtcNodes() {
- return BisqEnvironment.getBaseCurrencyNetwork().isBitcoin() && BisqEnvironment.getBaseCurrencyNetwork().isMainnet();
+ return BisqEnvironment.getBaseCurrencyNetwork().isMainnet();
}
public static List toBtcNodesList(Collection nodes) {
diff --git a/core/src/main/java/bisq/core/btc/nodes/SeedPeersSocks5Dns.java b/core/src/main/java/bisq/core/btc/nodes/SeedPeersSocks5Dns.java
index 6c1dabbf2b0..20f835de7b5 100644
--- a/core/src/main/java/bisq/core/btc/nodes/SeedPeersSocks5Dns.java
+++ b/core/src/main/java/bisq/core/btc/nodes/SeedPeersSocks5Dns.java
@@ -162,7 +162,7 @@ public static InetSocketAddress lookup(Socks5Proxy proxy, InetSocketAddress addr
InetAddress addrResolved = proxySocket.getInetAddress();
proxySocket.close();
if (addrResolved != null) {
- log.debug("Resolved " + addr.getHostString() + " to " + addrResolved.getHostAddress());
+ //log.debug("Resolved " + addr.getHostString() + " to " + addrResolved.getHostAddress());
return new InetSocketAddress(addrResolved, addr.getPort());
} else {
// note: .onion nodes fall in here when proxy is Tor. But they have no IP address.
diff --git a/core/src/main/java/bisq/core/btc/setup/WalletConfig.java b/core/src/main/java/bisq/core/btc/setup/WalletConfig.java
index 3e88fd63951..95a441b258c 100644
--- a/core/src/main/java/bisq/core/btc/setup/WalletConfig.java
+++ b/core/src/main/java/bisq/core/btc/setup/WalletConfig.java
@@ -80,7 +80,6 @@
import javax.annotation.Nullable;
-import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
@@ -88,7 +87,9 @@
// Does the basic wiring
@Slf4j
public class WalletConfig extends AbstractIdleService {
- private static final int TIMEOUT = 120 * 1000; // connectTimeoutMillis. 60 sec used in bitcoinj, but for Tor we allow more.
+ private static final int TOR_SOCKET_TIMEOUT = 120 * 1000; // 1 sec used in bitcoinj, but since bisq uses Tor we allow more.
+ private static final int TOR_VERSION_EXCHANGE_TIMEOUT = 125 * 1000; // 5 sec used in bitcoinj, but since bisq uses Tor we allow more.
+
///////////////////////////////////////////////////////////////////////////////////////////
// WalletFactory
@@ -125,7 +126,7 @@ public interface BisqWalletFactory extends WalletProtobufSerializer.WalletFactor
private DeterministicSeed seed;
private volatile BlockChain vChain;
- private volatile BlockStore vStore;
+ private volatile SPVBlockStore vStore;
private volatile PeerGroup vPeerGroup;
private boolean useAutoSave = true;
private PeerAddress[] peerAddresses;
@@ -172,8 +173,6 @@ public Wallet create(NetworkParameters params, KeyChainGroup keyChainGroup) {
// We have already the chain here so we can use this to distinguish.
List deterministicKeyChains = keyChainGroup.getDeterministicKeyChains();
if (!deterministicKeyChains.isEmpty() && deterministicKeyChains.get(0) instanceof BisqDeterministicKeyChain) {
- checkArgument(BisqEnvironment.isBaseCurrencySupportingBsq(), "BisqEnvironment.isBaseCurrencySupportingBsq() is false but we get get " +
- "called BisqWalletFactory.create with BisqDeterministicKeyChain");
return new BsqWallet(params, keyChainGroup);
} else {
return new Wallet(params, keyChainGroup);
@@ -184,8 +183,6 @@ public Wallet create(NetworkParameters params, KeyChainGroup keyChainGroup) {
public Wallet create(NetworkParameters params, KeyChainGroup keyChainGroup, boolean isBsqWallet) {
// This is called at first startup when we create the wallet
if (isBsqWallet) {
- checkArgument(BisqEnvironment.isBaseCurrencySupportingBsq(), "BisqEnvironment.isBaseCurrencySupportingBsq() is false but we get get " +
- "called BisqWalletFactory.create with isBsqWallet=true");
return new BsqWallet(params, keyChainGroup);
} else {
return new Wallet(params, keyChainGroup);
@@ -214,9 +211,12 @@ public Wallet create(NetworkParameters params, KeyChainGroup keyChainGroup, bool
}
private PeerGroup createPeerGroup() {
+ PeerGroup peerGroup;
// no proxy case.
if (socks5Proxy == null) {
- return new PeerGroup(params, vChain);
+ peerGroup = new PeerGroup(params, vChain);
+ // For dao testnet (server side regtest) we prevent to connect to a localhost node to avoid confusion
+ // if local btc node is not synced with our dao testnet master node.
} else {
// proxy case (tor).
Proxy proxy = new Proxy(Proxy.Type.SOCKS,
@@ -224,18 +224,23 @@ private PeerGroup createPeerGroup() {
socks5Proxy.getPort()));
ProxySocketFactory proxySocketFactory = new ProxySocketFactory(proxy);
- // we dont use tor mode if we have a local node running
+ // We don't use tor mode if we have a local node running
BlockingClientManager blockingClientManager = bisqEnvironment.isBitcoinLocalhostNodeRunning() ?
new BlockingClientManager() :
new BlockingClientManager(proxySocketFactory);
- PeerGroup peerGroup = new PeerGroup(params, vChain, blockingClientManager);
-
- blockingClientManager.setConnectTimeoutMillis(TIMEOUT);
- peerGroup.setConnectTimeoutMillis(TIMEOUT);
+ peerGroup = new PeerGroup(params, vChain, blockingClientManager);
- return peerGroup;
+ blockingClientManager.setConnectTimeoutMillis(TOR_SOCKET_TIMEOUT);
+ peerGroup.setConnectTimeoutMillis(TOR_VERSION_EXCHANGE_TIMEOUT);
}
+
+ // For dao testnet (server side regtest) we prevent to connect to a localhost node to avoid confusion
+ // if local btc node is not synced with our dao testnet master node.
+ if (BisqEnvironment.getBaseCurrencyNetwork().isDaoRegTest() || BisqEnvironment.getBaseCurrencyNetwork().isDaoTestNet())
+ peerGroup.setUseLocalhostPeerWhenPossible(false);
+
+ return peerGroup;
}
/**
@@ -322,13 +327,6 @@ private List provideWalletExtensions() {
return ImmutableList.of();
}
- /**
- * Override this to use a {@link BlockStore} that isn't the default of {@link SPVBlockStore}.
- */
- private BlockStore provideBlockStore(File file) throws BlockStoreException {
- return new SPVBlockStore(params, file);
- }
-
/**
* This method is invoked on a background thread after all objects are initialised, but before the peer group
* or block chain download is started. You can tweak the objects configuration here.
@@ -394,14 +392,12 @@ protected void startUp() throws Exception {
keyChainGroup = new BisqKeyChainGroup(params, new BisqDeterministicKeyChain(vBtcWallet.getKeyChainSeed()), false);
// BSQ wallet
- if (BisqEnvironment.isBaseCurrencySupportingBsq()) {
- vBsqWalletFile = new File(directory, bsqWalletFileName);
- vBsqWallet = createOrLoadWallet(vBsqWalletFile, shouldReplayWallet, keyChainGroup, true, seed);
- vBsqWallet.setRiskAnalyzer(new BisqRiskAnalysis.Analyzer());
- }
+ vBsqWalletFile = new File(directory, bsqWalletFileName);
+ vBsqWallet = createOrLoadWallet(vBsqWalletFile, shouldReplayWallet, keyChainGroup, true, seed);
+ vBsqWallet.setRiskAnalyzer(new BisqRiskAnalysis.Analyzer());
// Initiate Bitcoin network objects (block store, blockchain and peer group)
- vStore = provideBlockStore(chainFile);
+ vStore = new SPVBlockStore(params, chainFile);
if (!chainFileExists || seed != null) {
if (checkpoints != null) {
// Initialize the chain file with a checkpoint to speed up first-run sync.
@@ -411,11 +407,8 @@ protected void startUp() throws Exception {
// we created both wallets at the same time
time = seed.getCreationTimeSeconds();
if (chainFileExists) {
- log.info("Deleting the chain file in preparation from restore.");
- vStore.close();
- if (!chainFile.delete())
- throw new IOException("Failed to delete chain file in preparation for restore.");
- vStore = new SPVBlockStore(params, chainFile);
+ log.info("Clearing the chain file in preparation from restore.");
+ vStore.clear();
}
} else {
time = vBtcWallet.getEarliestKeyCreationTime();
@@ -427,11 +420,8 @@ protected void startUp() throws Exception {
else
log.warn("Creating a new uncheckpointed block store due to a wallet with a creation time of zero: this will result in a very slow chain sync");
} else if (chainFileExists) {
- log.info("Deleting the chain file in preparation from restore.");
- vStore.close();
- if (!chainFile.delete())
- throw new IOException("Failed to delete chain file in preparation for restore.");
- vStore = new SPVBlockStore(params, chainFile);
+ log.info("Clearing the chain file in preparation from restore.");
+ vStore.clear();
}
}
vChain = new BlockChain(params, vStore);
@@ -446,8 +436,10 @@ protected void startUp() throws Exception {
// before we're actually connected the broadcast waits for an appropriate number of connections.
if (peerAddresses != null) {
for (PeerAddress addr : peerAddresses) vPeerGroup.addAddress(addr);
- log.info("We try to connect to {} btc nodes", numConnectionForBtc);
- vPeerGroup.setMaxConnections(Math.min(numConnectionForBtc, peerAddresses.length));
+ int maxConnections = Math.min(numConnectionForBtc, peerAddresses.length);
+ log.info("We try to connect to {} btc nodes", maxConnections);
+ vPeerGroup.setMaxConnections(maxConnections);
+ vPeerGroup.setAddPeersFromAddressMessage(false);
peerAddresses = null;
} else if (!params.equals(RegTestParams.get())) {
vPeerGroup.addPeerDiscovery(discovery != null ? discovery : new DnsDiscovery(params));
diff --git a/core/src/main/java/bisq/core/btc/setup/WalletsSetup.java b/core/src/main/java/bisq/core/btc/setup/WalletsSetup.java
index 936c617625a..14dd75236ac 100644
--- a/core/src/main/java/bisq/core/btc/setup/WalletsSetup.java
+++ b/core/src/main/java/bisq/core/btc/setup/WalletsSetup.java
@@ -33,7 +33,6 @@
import bisq.common.Timer;
import bisq.common.UserThread;
-import bisq.common.app.Log;
import bisq.common.handlers.ExceptionHandler;
import bisq.common.handlers.ResultHandler;
import bisq.common.storage.FileUtil;
@@ -170,8 +169,6 @@ public WalletsSetup(RegTestHost regTestHost,
///////////////////////////////////////////////////////////////////////////////////////////
public void initialize(@Nullable DeterministicSeed seed, ResultHandler resultHandler, ExceptionHandler exceptionHandler) {
- Log.traceCall();
-
// Tell bitcoinj to execute event handlers on the JavaFX UI thread. This keeps things simple and means
// we cannot forget to switch threads when adding event handlers. Unfortunately, the DownloadListener
// we give to the app kit is currently an exception and runs on a library thread. It'll get fixed in
@@ -236,7 +233,6 @@ protected void onSetupCompleted() {
if (regTestHost == RegTestHost.LOCALHOST) {
walletConfig.setPeerNodesForLocalHost();
} else if (regTestHost == RegTestHost.REMOTE_HOST) {
- walletConfig.setMinBroadcastConnections(1);
configPeerNodesForRegTestServer();
} else {
configPeerNodes(socks5Proxy);
@@ -315,7 +311,11 @@ private int evaluateMode(String socks5DiscoverModeString) {
private void configPeerNodesForRegTestServer() {
try {
- walletConfig.setPeerNodes(new PeerAddress(InetAddress.getByName(RegTestHost.HOST), params.getPort()));
+ if (RegTestHost.HOST.endsWith(".onion")) {
+ walletConfig.setPeerNodes(new PeerAddress(RegTestHost.HOST, params.getPort()));
+ } else {
+ walletConfig.setPeerNodes(new PeerAddress(InetAddress.getByName(RegTestHost.HOST), params.getPort()));
+ }
} catch (UnknownHostException e) {
log.error(e.toString());
e.printStackTrace();
diff --git a/core/src/main/java/bisq/core/btc/wallet/BisqDefaultCoinSelector.java b/core/src/main/java/bisq/core/btc/wallet/BisqDefaultCoinSelector.java
index 496c37ae43e..57923d0ab32 100644
--- a/core/src/main/java/bisq/core/btc/wallet/BisqDefaultCoinSelector.java
+++ b/core/src/main/java/bisq/core/btc/wallet/BisqDefaultCoinSelector.java
@@ -75,17 +75,19 @@ public CoinSelection select(Coin target, List candidates) {
long total = 0;
long targetValue = target.value;
for (TransactionOutput output : sortedOutputs) {
- if (total >= targetValue) {
- long change = total - targetValue;
- if (change == 0 || change >= Restrictions.getMinNonDustOutput().value)
- break;
- }
-
- if (output.getParentTransaction() != null &&
- isTxSpendable(output.getParentTransaction()) &&
- isTxOutputSpendable(output)) {
- selected.add(output);
- total += output.getValue().value;
+ if (!isDustAttackUtxo(output)) {
+ if (total >= targetValue) {
+ long change = total - targetValue;
+ if (change == 0 || change >= Restrictions.getMinNonDustOutput().value)
+ break;
+ }
+
+ if (output.getParentTransaction() != null &&
+ isTxSpendable(output.getParentTransaction()) &&
+ isTxOutputSpendable(output)) {
+ selected.add(output);
+ total += output.getValue().value;
+ }
}
}
// Total may be lower than target here, if the given candidates were insufficient to create to requested
@@ -93,6 +95,8 @@ public CoinSelection select(Coin target, List candidates) {
return new CoinSelection(Coin.valueOf(total), selected);
}
+ protected abstract boolean isDustAttackUtxo(TransactionOutput output);
+
public Coin getChange(Coin target, CoinSelection coinSelection) throws InsufficientMoneyException {
long value = target.value;
long available = coinSelection.valueGathered.value;
@@ -103,7 +107,8 @@ public Coin getChange(Coin target, CoinSelection coinSelection) throws Insuffici
return Coin.valueOf(change);
}
- // We allow spending own pending txs and if permitForeignPendingTx is set as well foreign unconfirmed txs.
+ // We allow spending from own unconfirmed txs and if permitForeignPendingTx is set as well from foreign
+ // unconfirmed txs.
protected boolean isTxSpendable(Transaction tx) {
TransactionConfidence confidence = tx.getConfidence();
TransactionConfidence.ConfidenceType type = confidence.getConfidenceType();
diff --git a/core/src/main/java/bisq/core/btc/wallet/BisqRiskAnalysis.java b/core/src/main/java/bisq/core/btc/wallet/BisqRiskAnalysis.java
index d148202165c..dfd81746c92 100644
--- a/core/src/main/java/bisq/core/btc/wallet/BisqRiskAnalysis.java
+++ b/core/src/main/java/bisq/core/btc/wallet/BisqRiskAnalysis.java
@@ -113,6 +113,13 @@ private Result analyzeIsFinal() {
if (tx.getConfidence().getSource() == TransactionConfidence.Source.SELF)
return Result.OK;
+ // Relative time-locked transactions are risky too. We can't check the locks because usually we don't know the
+ // spent outputs (to know when they were created).
+ if (tx.hasRelativeLockTime()) {
+ nonFinal = tx;
+ return Result.NON_FINAL;
+ }
+
if (wallet == null)
return null;
@@ -157,7 +164,7 @@ public enum RuleViolation {
*/
public static RuleViolation isStandard(Transaction tx) {
// TODO: Finish this function off.
- if (tx.getVersion() > 1 || tx.getVersion() < 1) {
+ if (tx.getVersion() > 2 || tx.getVersion() < 1) {
log.warn("TX considered non-standard due to unknown version number {}", tx.getVersion());
return RuleViolation.VERSION;
}
diff --git a/core/src/main/java/bisq/core/btc/wallet/BsqCoinSelector.java b/core/src/main/java/bisq/core/btc/wallet/BsqCoinSelector.java
index f81fd3b7ed7..72e3b1af347 100644
--- a/core/src/main/java/bisq/core/btc/wallet/BsqCoinSelector.java
+++ b/core/src/main/java/bisq/core/btc/wallet/BsqCoinSelector.java
@@ -19,7 +19,9 @@
import bisq.core.dao.state.DaoStateService;
import bisq.core.dao.state.model.blockchain.TxOutputKey;
+import bisq.core.dao.state.unconfirmed.UnconfirmedBsqChangeOutputListService;
+import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionOutput;
import javax.inject.Inject;
@@ -32,18 +34,42 @@
*/
@Slf4j
public class BsqCoinSelector extends BisqDefaultCoinSelector {
- private DaoStateService daoStateService;
+ private final DaoStateService daoStateService;
+ private final UnconfirmedBsqChangeOutputListService unconfirmedBsqChangeOutputListService;
@Inject
- public BsqCoinSelector(DaoStateService daoStateService) {
- super(true);
+ public BsqCoinSelector(DaoStateService daoStateService, UnconfirmedBsqChangeOutputListService unconfirmedBsqChangeOutputListService) {
+ // permitForeignPendingTx is not relevant here as we do not support pending foreign utxos anyway.
+ super(false);
this.daoStateService = daoStateService;
+ this.unconfirmedBsqChangeOutputListService = unconfirmedBsqChangeOutputListService;
}
@Override
protected boolean isTxOutputSpendable(TransactionOutput output) {
// output.getParentTransaction() cannot be null as it is checked in calling method
- return output.getParentTransaction() != null &&
- daoStateService.isTxOutputSpendable(new TxOutputKey(output.getParentTransaction().getHashAsString(), output.getIndex()));
+ Transaction parentTransaction = output.getParentTransaction();
+ if (parentTransaction == null)
+ return false;
+
+ // If it is a normal confirmed BSQ output we use the default lookup at the daoState
+ if (daoStateService.isTxOutputSpendable(new TxOutputKey(parentTransaction.getHashAsString(), output.getIndex())))
+ return true;
+
+ // It might be that it is an unconfirmed change output which we allow to be used for spending without requiring a confirmation.
+ // We check if we have the output in the dao state, if so we have a confirmed but unspendable output (e.g. confiscated).
+ if (daoStateService.getTxOutput(new TxOutputKey(parentTransaction.getHashAsString(), output.getIndex())).isPresent())
+ return false;
+
+ // Only if its not existing yet in the dao state (unconfirmed) we use our unconfirmedBsqChangeOutputList to
+ // check if it is an own change output.
+ return unconfirmedBsqChangeOutputListService.hasTransactionOutput(output);
+ }
+
+ // For BSQ we do not check for dust attack utxos as they are 5.46 BSQ and a considerable value.
+ // The default 546 sat dust limit is handled in the BitcoinJ side anyway.
+ @Override
+ protected boolean isDustAttackUtxo(TransactionOutput output) {
+ return false;
}
}
diff --git a/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java b/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java
index ef9902e065f..49018f8bca9 100644
--- a/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java
+++ b/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java
@@ -17,18 +17,21 @@
package bisq.core.btc.wallet;
-import bisq.core.app.BisqEnvironment;
+import bisq.core.btc.exceptions.BsqChangeBelowDustException;
import bisq.core.btc.exceptions.InsufficientBsqException;
import bisq.core.btc.exceptions.TransactionVerificationException;
import bisq.core.btc.exceptions.WalletException;
import bisq.core.btc.listeners.BsqBalanceListener;
import bisq.core.btc.setup.WalletsSetup;
+import bisq.core.dao.DaoKillSwitch;
import bisq.core.dao.state.DaoStateListener;
import bisq.core.dao.state.DaoStateService;
import bisq.core.dao.state.model.blockchain.Block;
import bisq.core.dao.state.model.blockchain.Tx;
import bisq.core.dao.state.model.blockchain.TxOutput;
import bisq.core.dao.state.model.blockchain.TxOutputKey;
+import bisq.core.dao.state.model.blockchain.TxType;
+import bisq.core.dao.state.unconfirmed.UnconfirmedBsqChangeOutputListService;
import bisq.core.provider.fee.FeeService;
import bisq.core.user.Preferences;
@@ -47,6 +50,7 @@
import org.bitcoinj.core.TransactionOutput;
import org.bitcoinj.script.Script;
import org.bitcoinj.wallet.CoinSelection;
+import org.bitcoinj.wallet.CoinSelector;
import org.bitcoinj.wallet.SendRequest;
import org.bitcoinj.wallet.Wallet;
import org.bitcoinj.wallet.listeners.AbstractWalletEventListener;
@@ -79,6 +83,7 @@ public class BsqWalletService extends WalletService implements DaoStateListener
private final BsqCoinSelector bsqCoinSelector;
private final NonBsqCoinSelector nonBsqCoinSelector;
private final DaoStateService daoStateService;
+ private final UnconfirmedBsqChangeOutputListService unconfirmedBsqChangeOutputListService;
private final ObservableList walletTransactions = FXCollections.observableArrayList();
private final CopyOnWriteArraySet bsqBalanceListeners = new CopyOnWriteArraySet<>();
@@ -86,10 +91,12 @@ public class BsqWalletService extends WalletService implements DaoStateListener
@Getter
private Coin availableNonBsqBalance = Coin.ZERO;
@Getter
- private Coin availableBalance = Coin.ZERO;
+ private Coin availableConfirmedBalance = Coin.ZERO;
@Getter
private Coin unverifiedBalance = Coin.ZERO;
@Getter
+ private Coin unconfirmedChangeBalance = Coin.ZERO;
+ @Getter
private Coin lockedForVotingBalance = Coin.ZERO;
@Getter
private Coin lockupBondsBalance = Coin.ZERO;
@@ -106,6 +113,7 @@ public BsqWalletService(WalletsSetup walletsSetup,
BsqCoinSelector bsqCoinSelector,
NonBsqCoinSelector nonBsqCoinSelector,
DaoStateService daoStateService,
+ UnconfirmedBsqChangeOutputListService unconfirmedBsqChangeOutputListService,
Preferences preferences,
FeeService feeService) {
super(walletsSetup,
@@ -115,65 +123,65 @@ public BsqWalletService(WalletsSetup walletsSetup,
this.bsqCoinSelector = bsqCoinSelector;
this.nonBsqCoinSelector = nonBsqCoinSelector;
this.daoStateService = daoStateService;
+ this.unconfirmedBsqChangeOutputListService = unconfirmedBsqChangeOutputListService;
+
+ walletsSetup.addSetupCompletedHandler(() -> {
+ wallet = walletsSetup.getBsqWallet();
+ if (wallet != null) {
+ wallet.setCoinSelector(bsqCoinSelector);
+ wallet.addEventListener(walletEventListener);
+
+ //noinspection deprecation
+ wallet.addEventListener(new AbstractWalletEventListener() {
+ @Override
+ public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
+ updateBsqWalletTransactions();
+ }
- if (BisqEnvironment.isBaseCurrencySupportingBsq()) {
- walletsSetup.addSetupCompletedHandler(() -> {
- wallet = walletsSetup.getBsqWallet();
- if (wallet != null) {
- wallet.setCoinSelector(bsqCoinSelector);
- wallet.addEventListener(walletEventListener);
-
- //noinspection deprecation
- wallet.addEventListener(new AbstractWalletEventListener() {
- @Override
- public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
- updateBsqWalletTransactions();
- }
-
- @Override
- public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
- updateBsqWalletTransactions();
- }
+ @Override
+ public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
+ updateBsqWalletTransactions();
+ }
- @Override
- public void onReorganize(Wallet wallet) {
- log.warn("onReorganize ");
- updateBsqWalletTransactions();
- }
+ @Override
+ public void onReorganize(Wallet wallet) {
+ log.warn("onReorganize ");
+ updateBsqWalletTransactions();
+ unconfirmedBsqChangeOutputListService.onReorganize();
+ }
- @Override
- public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) {
- updateBsqWalletTransactions();
- }
+ @Override
+ public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) {
+ updateBsqWalletTransactions();
+ unconfirmedBsqChangeOutputListService.onTransactionConfidenceChanged(tx);
+ }
- @Override
- public void onKeysAdded(List keys) {
- updateBsqWalletTransactions();
- }
+ @Override
+ public void onKeysAdded(List keys) {
+ updateBsqWalletTransactions();
+ }
- @Override
- public void onScriptsChanged(Wallet wallet, List