diff --git a/assets/src/main/java/bisq/asset/Base58BitcoinAddressValidator.java b/assets/src/main/java/bisq/asset/Base58BitcoinAddressValidator.java
index 9a99385f60..181f4011ba 100644
--- a/assets/src/main/java/bisq/asset/Base58BitcoinAddressValidator.java
+++ b/assets/src/main/java/bisq/asset/Base58BitcoinAddressValidator.java
@@ -17,8 +17,8 @@
package bisq.asset;
-import org.bitcoinj.core.Address;
import org.bitcoinj.core.AddressFormatException;
+import org.bitcoinj.core.LegacyAddress;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.params.MainNetParams;
@@ -27,7 +27,7 @@ import org.bitcoinj.params.MainNetParams;
*
* @author Chris Beams
* @since 0.7.0
- * @see org.bitcoinj.core.Address#fromBase58(NetworkParameters, String)
+ * @see org.bitcoinj.core.LegacyAddress#fromBase58(NetworkParameters, String)
*/
public class Base58BitcoinAddressValidator implements AddressValidator {
@@ -44,7 +44,7 @@ public class Base58BitcoinAddressValidator implements AddressValidator {
@Override
public AddressValidationResult validate(String address) {
try {
- Address.fromBase58(networkParameters, address);
+ LegacyAddress.fromBase58(networkParameters, address);
} catch (AddressFormatException ex) {
return AddressValidationResult.invalidAddress(ex);
}
diff --git a/assets/src/main/java/bisq/asset/coins/Actinium.java b/assets/src/main/java/bisq/asset/coins/Actinium.java
index d0bfc49b5d..45f0941527 100644
--- a/assets/src/main/java/bisq/asset/coins/Actinium.java
+++ b/assets/src/main/java/bisq/asset/coins/Actinium.java
@@ -33,7 +33,6 @@ public class Actinium extends Coin {
public ActiniumParams() {
addressHeader = 53;
p2shHeader = 55;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Adeptio.java b/assets/src/main/java/bisq/asset/coins/Adeptio.java
index ecfd4b3411..ae10025ecc 100644
--- a/assets/src/main/java/bisq/asset/coins/Adeptio.java
+++ b/assets/src/main/java/bisq/asset/coins/Adeptio.java
@@ -50,7 +50,6 @@ public class Adeptio extends Coin {
public AdeptioParams() {
addressHeader = 23;
p2shHeader = 16;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Animecoin.java b/assets/src/main/java/bisq/asset/coins/Animecoin.java
index 7ddbe6db36..db72f9b4b5 100644
--- a/assets/src/main/java/bisq/asset/coins/Animecoin.java
+++ b/assets/src/main/java/bisq/asset/coins/Animecoin.java
@@ -30,7 +30,6 @@ public class Animecoin extends Coin {
public AnimecoinMainNetParams() {
this.addressHeader = 23;
this.p2shHeader = 9;
- this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Australiacash.java b/assets/src/main/java/bisq/asset/coins/Australiacash.java
index d0dea1b7d8..f120ed5e79 100644
--- a/assets/src/main/java/bisq/asset/coins/Australiacash.java
+++ b/assets/src/main/java/bisq/asset/coins/Australiacash.java
@@ -30,7 +30,6 @@ public class Australiacash extends Coin {
public AustraliacashParams() {
addressHeader = 23;
p2shHeader = 5;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/BitcoinRhodium.java b/assets/src/main/java/bisq/asset/coins/BitcoinRhodium.java
index befb60f205..f827636162 100644
--- a/assets/src/main/java/bisq/asset/coins/BitcoinRhodium.java
+++ b/assets/src/main/java/bisq/asset/coins/BitcoinRhodium.java
@@ -32,7 +32,6 @@ public class BitcoinRhodium extends Coin {
public BitcoinRhodiumParams() {
addressHeader = 61;
p2shHeader = 123;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Bitmark.java b/assets/src/main/java/bisq/asset/coins/Bitmark.java
index c4cac96f85..8bcbe20bb5 100644
--- a/assets/src/main/java/bisq/asset/coins/Bitmark.java
+++ b/assets/src/main/java/bisq/asset/coins/Bitmark.java
@@ -27,7 +27,6 @@ public class Bitmark extends Coin {
public BitmarkParams() {
addressHeader = 85;
p2shHeader = 5;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/CTSCoin.java b/assets/src/main/java/bisq/asset/coins/CTSCoin.java
index 7db46edc26..f21dee31cb 100644
--- a/assets/src/main/java/bisq/asset/coins/CTSCoin.java
+++ b/assets/src/main/java/bisq/asset/coins/CTSCoin.java
@@ -30,7 +30,6 @@ public class CTSCoin extends Coin {
public CtscMainNetParams() {
this.addressHeader = 66;
this.p2shHeader = 16;
- this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Chaucha.java b/assets/src/main/java/bisq/asset/coins/Chaucha.java
index c26b1a2dcf..0f307a719d 100644
--- a/assets/src/main/java/bisq/asset/coins/Chaucha.java
+++ b/assets/src/main/java/bisq/asset/coins/Chaucha.java
@@ -32,7 +32,6 @@ public class Chaucha extends Coin {
public ChauchaParams() {
addressHeader = 88;
p2shHeader = 50;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Credits.java b/assets/src/main/java/bisq/asset/coins/Credits.java
index 1a64f4a391..8e3224f654 100644
--- a/assets/src/main/java/bisq/asset/coins/Credits.java
+++ b/assets/src/main/java/bisq/asset/coins/Credits.java
@@ -50,7 +50,6 @@ public class Credits extends Coin {
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
index e7ec0e2ca3..230dd01dc6 100644
--- a/assets/src/main/java/bisq/asset/coins/DSTRA.java
+++ b/assets/src/main/java/bisq/asset/coins/DSTRA.java
@@ -50,7 +50,6 @@ public class DSTRA extends Coin {
public DSTRAParams() {
addressHeader = 30;
p2shHeader = 33;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/DarkPay.java b/assets/src/main/java/bisq/asset/coins/DarkPay.java
index ac10111f94..8ba492e069 100644
--- a/assets/src/main/java/bisq/asset/coins/DarkPay.java
+++ b/assets/src/main/java/bisq/asset/coins/DarkPay.java
@@ -30,7 +30,6 @@ public class DarkPay extends Coin {
public DarkPayMainNetParams() {
this.addressHeader = 31;
this.p2shHeader = 60;
- this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Dash.java b/assets/src/main/java/bisq/asset/coins/Dash.java
index 754c8528b5..397b3d6111 100644
--- a/assets/src/main/java/bisq/asset/coins/Dash.java
+++ b/assets/src/main/java/bisq/asset/coins/Dash.java
@@ -30,7 +30,6 @@ public class Dash extends Coin {
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 716d1b96da..947388c06b 100644
--- a/assets/src/main/java/bisq/asset/coins/DeepOnion.java
+++ b/assets/src/main/java/bisq/asset/coins/DeepOnion.java
@@ -48,7 +48,6 @@ public class DeepOnion extends Coin {
super();
addressHeader = 31;
p2shHeader = 78;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Dextro.java b/assets/src/main/java/bisq/asset/coins/Dextro.java
index 8f880c2bd2..350a932105 100644
--- a/assets/src/main/java/bisq/asset/coins/Dextro.java
+++ b/assets/src/main/java/bisq/asset/coins/Dextro.java
@@ -51,7 +51,6 @@ public class Dextro extends Coin {
super();
addressHeader = 30;
p2shHeader = 90;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Dogecoin.java b/assets/src/main/java/bisq/asset/coins/Dogecoin.java
index 40a500ea52..e9fedd2813 100644
--- a/assets/src/main/java/bisq/asset/coins/Dogecoin.java
+++ b/assets/src/main/java/bisq/asset/coins/Dogecoin.java
@@ -31,7 +31,6 @@ public class Dogecoin extends Coin {
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
index 9bf904cc71..f050cf632c 100644
--- a/assets/src/main/java/bisq/asset/coins/Doichain.java
+++ b/assets/src/main/java/bisq/asset/coins/Doichain.java
@@ -31,7 +31,6 @@ public class Doichain extends Coin {
public DoichainParams() {
addressHeader = 52;
p2shHeader = 13;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Donu.java b/assets/src/main/java/bisq/asset/coins/Donu.java
index 67c87b41ed..782c53f2bd 100644
--- a/assets/src/main/java/bisq/asset/coins/Donu.java
+++ b/assets/src/main/java/bisq/asset/coins/Donu.java
@@ -50,7 +50,6 @@ public class Donu extends Coin {
public DonuParams() {
addressHeader = 53;
p2shHeader = 5;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Emercoin.java b/assets/src/main/java/bisq/asset/coins/Emercoin.java
index 071eb05d00..5728575412 100644
--- a/assets/src/main/java/bisq/asset/coins/Emercoin.java
+++ b/assets/src/main/java/bisq/asset/coins/Emercoin.java
@@ -31,7 +31,6 @@ public class Emercoin extends Coin {
public EmercoinMainNetParams() {
this.addressHeader = 33;
this.p2shHeader = 92;
- this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Faircoin.java b/assets/src/main/java/bisq/asset/coins/Faircoin.java
index d94efa3a9a..4d2b86cad8 100644
--- a/assets/src/main/java/bisq/asset/coins/Faircoin.java
+++ b/assets/src/main/java/bisq/asset/coins/Faircoin.java
@@ -32,7 +32,6 @@ public class Faircoin extends Coin {
public FaircoinParams() {
addressHeader = 95;
p2shHeader = 36;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Fujicoin.java b/assets/src/main/java/bisq/asset/coins/Fujicoin.java
index 9e2b181e15..c54f26a55c 100644
--- a/assets/src/main/java/bisq/asset/coins/Fujicoin.java
+++ b/assets/src/main/java/bisq/asset/coins/Fujicoin.java
@@ -30,7 +30,6 @@ public class Fujicoin extends Coin {
public FujicoinParams() {
addressHeader = 36;
p2shHeader = 16;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Galilel.java b/assets/src/main/java/bisq/asset/coins/Galilel.java
index 138e965330..9dbabc4b8c 100644
--- a/assets/src/main/java/bisq/asset/coins/Galilel.java
+++ b/assets/src/main/java/bisq/asset/coins/Galilel.java
@@ -30,7 +30,6 @@ public class Galilel extends Coin {
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/GambleCoin.java b/assets/src/main/java/bisq/asset/coins/GambleCoin.java
index a199219d94..27447cf9a0 100644
--- a/assets/src/main/java/bisq/asset/coins/GambleCoin.java
+++ b/assets/src/main/java/bisq/asset/coins/GambleCoin.java
@@ -51,7 +51,6 @@ public class GambleCoin extends Coin {
super();
addressHeader = 28;
p2shHeader = 18;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Genesis.java b/assets/src/main/java/bisq/asset/coins/Genesis.java
index 65c885fd64..fcb49992a8 100644
--- a/assets/src/main/java/bisq/asset/coins/Genesis.java
+++ b/assets/src/main/java/bisq/asset/coins/Genesis.java
@@ -51,7 +51,6 @@ public class Genesis extends Coin {
public GenesisParams() {
addressHeader = 28;
p2shHeader = 63;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Hatch.java b/assets/src/main/java/bisq/asset/coins/Hatch.java
index bbff61765b..0d2d5b3b97 100644
--- a/assets/src/main/java/bisq/asset/coins/Hatch.java
+++ b/assets/src/main/java/bisq/asset/coins/Hatch.java
@@ -30,7 +30,6 @@ public class Hatch extends Coin {
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/Helium.java b/assets/src/main/java/bisq/asset/coins/Helium.java
index cec17a9f7b..592c6cfaa1 100644
--- a/assets/src/main/java/bisq/asset/coins/Helium.java
+++ b/assets/src/main/java/bisq/asset/coins/Helium.java
@@ -33,7 +33,6 @@ public class Helium extends Coin {
public HeliumParams() {
addressHeader = 63;
p2shHeader = 5;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/IdaPay.java b/assets/src/main/java/bisq/asset/coins/IdaPay.java
index 84000ff023..c205b2d7e5 100644
--- a/assets/src/main/java/bisq/asset/coins/IdaPay.java
+++ b/assets/src/main/java/bisq/asset/coins/IdaPay.java
@@ -51,7 +51,6 @@ public class IdaPay extends Coin {
super();
addressHeader = 29;
p2shHeader = 36;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Kekcoin.java b/assets/src/main/java/bisq/asset/coins/Kekcoin.java
index 33f5bc2107..b7927609d7 100644
--- a/assets/src/main/java/bisq/asset/coins/Kekcoin.java
+++ b/assets/src/main/java/bisq/asset/coins/Kekcoin.java
@@ -34,7 +34,6 @@ public class Kekcoin extends Coin {
super();
addressHeader = 45;
p2shHeader = 88;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
-}
\ No newline at end of file
+}
diff --git a/assets/src/main/java/bisq/asset/coins/KnowYourDeveloper.java b/assets/src/main/java/bisq/asset/coins/KnowYourDeveloper.java
index b0f93f3d77..cc9468455a 100644
--- a/assets/src/main/java/bisq/asset/coins/KnowYourDeveloper.java
+++ b/assets/src/main/java/bisq/asset/coins/KnowYourDeveloper.java
@@ -30,7 +30,6 @@ public class KnowYourDeveloper extends Coin {
public KydMainNetParams() {
this.addressHeader = 78;
this.p2shHeader = 85;
- this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Kore.java b/assets/src/main/java/bisq/asset/coins/Kore.java
index 98f635719a..184d426f09 100644
--- a/assets/src/main/java/bisq/asset/coins/Kore.java
+++ b/assets/src/main/java/bisq/asset/coins/Kore.java
@@ -30,7 +30,6 @@ public class Kore extends Coin {
public KoreMainNetParams() {
this.addressHeader = 45;
this.p2shHeader = 85;
- this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/LBRYCredits.java b/assets/src/main/java/bisq/asset/coins/LBRYCredits.java
index 6c256f2ea1..b6e9836266 100644
--- a/assets/src/main/java/bisq/asset/coins/LBRYCredits.java
+++ b/assets/src/main/java/bisq/asset/coins/LBRYCredits.java
@@ -31,7 +31,6 @@ public class LBRYCredits extends Coin {
public LBRYCreditsMainNetParams() {
this.addressHeader = 0x55;
this.p2shHeader = 0x7a;
- this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Litecoin.java b/assets/src/main/java/bisq/asset/coins/Litecoin.java
index 57b61a3cb5..6580f851dd 100644
--- a/assets/src/main/java/bisq/asset/coins/Litecoin.java
+++ b/assets/src/main/java/bisq/asset/coins/Litecoin.java
@@ -30,7 +30,6 @@ public class Litecoin extends Coin {
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
index aaf8d669b9..c5ce3070c1 100644
--- a/assets/src/main/java/bisq/asset/coins/LitecoinPlus.java
+++ b/assets/src/main/java/bisq/asset/coins/LitecoinPlus.java
@@ -31,7 +31,6 @@ public class LitecoinPlus extends Coin {
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/Lytix.java b/assets/src/main/java/bisq/asset/coins/Lytix.java
index d9a0de079b..629a47f3d4 100644
--- a/assets/src/main/java/bisq/asset/coins/Lytix.java
+++ b/assets/src/main/java/bisq/asset/coins/Lytix.java
@@ -33,7 +33,6 @@ public class Lytix extends Coin {
public LytixParams() {
addressHeader = 19;
p2shHeader = 11;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/MobitGlobal.java b/assets/src/main/java/bisq/asset/coins/MobitGlobal.java
index c4e1eb86d2..6b2bfbff12 100644
--- a/assets/src/main/java/bisq/asset/coins/MobitGlobal.java
+++ b/assets/src/main/java/bisq/asset/coins/MobitGlobal.java
@@ -50,7 +50,6 @@ public class MobitGlobal extends Coin {
public MobitGlobalParams() {
addressHeader = 50;
p2shHeader = 110;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/MonetaryUnit.java b/assets/src/main/java/bisq/asset/coins/MonetaryUnit.java
index b1cd79a995..4055768af3 100644
--- a/assets/src/main/java/bisq/asset/coins/MonetaryUnit.java
+++ b/assets/src/main/java/bisq/asset/coins/MonetaryUnit.java
@@ -50,7 +50,6 @@ public class MonetaryUnit extends Coin {
public MonetaryUnitParams() {
addressHeader = 16;
p2shHeader = 76;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Myce.java b/assets/src/main/java/bisq/asset/coins/Myce.java
index ea8a2a781c..0e39bdf549 100644
--- a/assets/src/main/java/bisq/asset/coins/Myce.java
+++ b/assets/src/main/java/bisq/asset/coins/Myce.java
@@ -26,12 +26,11 @@ public class Myce extends Coin {
public Myce() {
super("Myce", "YCE", new Base58BitcoinAddressValidator(new MyceParams()));
}
-
+
public static class MyceParams extends NetworkParametersAdapter {
public MyceParams() {
addressHeader = 50;
p2shHeader = 85;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Navcoin.java b/assets/src/main/java/bisq/asset/coins/Navcoin.java
index 31c0786657..6427555636 100644
--- a/assets/src/main/java/bisq/asset/coins/Navcoin.java
+++ b/assets/src/main/java/bisq/asset/coins/Navcoin.java
@@ -30,7 +30,6 @@ public class Navcoin extends Coin {
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/PIVX.java b/assets/src/main/java/bisq/asset/coins/PIVX.java
index 12bd6a9111..cfde4d8594 100644
--- a/assets/src/main/java/bisq/asset/coins/PIVX.java
+++ b/assets/src/main/java/bisq/asset/coins/PIVX.java
@@ -50,7 +50,6 @@ public class PIVX extends Coin {
public PIVXParams() {
addressHeader = 30;
p2shHeader = 13;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/PZDC.java b/assets/src/main/java/bisq/asset/coins/PZDC.java
index f91c9a623d..18f40b9b91 100644
--- a/assets/src/main/java/bisq/asset/coins/PZDC.java
+++ b/assets/src/main/java/bisq/asset/coins/PZDC.java
@@ -50,7 +50,6 @@ public class PZDC extends Coin {
public PZDCParams() {
addressHeader = 55;
p2shHeader = 13;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Particl.java b/assets/src/main/java/bisq/asset/coins/Particl.java
index 8f14c47dd3..601af39662 100644
--- a/assets/src/main/java/bisq/asset/coins/Particl.java
+++ b/assets/src/main/java/bisq/asset/coins/Particl.java
@@ -32,7 +32,6 @@ public class Particl extends Coin {
public ParticlMainNetParams() {
this.addressHeader = 56;
this.p2shHeader = 60;
- this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
}
}
public static class ParticlMainNetAddressValidator extends Base58BitcoinAddressValidator {
@@ -49,5 +48,5 @@ public class Particl extends Coin {
return super.validate(address);
}
}
-
+
}
diff --git a/assets/src/main/java/bisq/asset/coins/Pinkcoin.java b/assets/src/main/java/bisq/asset/coins/Pinkcoin.java
index b27bece164..0792bd0857 100644
--- a/assets/src/main/java/bisq/asset/coins/Pinkcoin.java
+++ b/assets/src/main/java/bisq/asset/coins/Pinkcoin.java
@@ -33,7 +33,6 @@ public class Pinkcoin extends Coin {
public PinkcoinParams() {
addressHeader = 3;
p2shHeader = 28;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/QMCoin.java b/assets/src/main/java/bisq/asset/coins/QMCoin.java
index 984ba4cb21..75f8deade5 100644
--- a/assets/src/main/java/bisq/asset/coins/QMCoin.java
+++ b/assets/src/main/java/bisq/asset/coins/QMCoin.java
@@ -50,7 +50,6 @@ public class QMCoin extends Coin {
public QMCoinParams() {
addressHeader = 58;
p2shHeader = 120;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Qbase.java b/assets/src/main/java/bisq/asset/coins/Qbase.java
index 94d70f4304..2d076a74dc 100644
--- a/assets/src/main/java/bisq/asset/coins/Qbase.java
+++ b/assets/src/main/java/bisq/asset/coins/Qbase.java
@@ -32,7 +32,6 @@ public class Qbase extends Coin {
public QbaseParams() {
addressHeader = 25;
p2shHeader = 5;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Radium.java b/assets/src/main/java/bisq/asset/coins/Radium.java
index aed79c6303..8c59a1258c 100644
--- a/assets/src/main/java/bisq/asset/coins/Radium.java
+++ b/assets/src/main/java/bisq/asset/coins/Radium.java
@@ -34,7 +34,6 @@ public class Radium extends Coin {
super();
addressHeader = 76;
p2shHeader = 58;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
-}
\ No newline at end of file
+}
diff --git a/assets/src/main/java/bisq/asset/coins/SUB1X.java b/assets/src/main/java/bisq/asset/coins/SUB1X.java
index 14daac5be0..9bcb32386a 100644
--- a/assets/src/main/java/bisq/asset/coins/SUB1X.java
+++ b/assets/src/main/java/bisq/asset/coins/SUB1X.java
@@ -50,7 +50,6 @@ public class SUB1X extends Coin {
public SUB1XParams() {
addressHeader = 80;
p2shHeader = 13;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/SixEleven.java b/assets/src/main/java/bisq/asset/coins/SixEleven.java
index ded86da4ef..706f97e90d 100644
--- a/assets/src/main/java/bisq/asset/coins/SixEleven.java
+++ b/assets/src/main/java/bisq/asset/coins/SixEleven.java
@@ -17,6 +17,7 @@
package bisq.asset.coins;
+import bisq.asset.AddressValidationResult;
import bisq.asset.Base58BitcoinAddressValidator;
import bisq.asset.Coin;
import bisq.asset.NetworkParametersAdapter;
@@ -24,13 +25,27 @@ import bisq.asset.NetworkParametersAdapter;
public class SixEleven extends Coin {
public SixEleven() {
- super("SixEleven", "SIL", new Base58BitcoinAddressValidator(new SixElevenChainParams()));
+ super("SixEleven", "SIL", new SixElevenAddressValidator());
+ }
+
+ public static class SixElevenAddressValidator extends Base58BitcoinAddressValidator {
+
+ public SixElevenAddressValidator() {
+ super(new SixEleven.SixElevenChainParams());
+ }
+
+ @Override
+ public AddressValidationResult validate(String address) {
+ if (!address.matches("^[MN][123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{33}$"))
+ return AddressValidationResult.invalidStructure();
+
+ return super.validate(address);
+ }
}
public static class SixElevenChainParams extends NetworkParametersAdapter {
public SixElevenChainParams() {
addressHeader = 52;
- acceptableAddressCodes = new int[]{addressHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Spectrecoin.java b/assets/src/main/java/bisq/asset/coins/Spectrecoin.java
index ee9f7a763c..404c351208 100644
--- a/assets/src/main/java/bisq/asset/coins/Spectrecoin.java
+++ b/assets/src/main/java/bisq/asset/coins/Spectrecoin.java
@@ -33,7 +33,6 @@ public class Spectrecoin extends Coin {
public SpectrecoinParams() {
addressHeader = 63;
p2shHeader = 136;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/UnitedCommunityCoin.java b/assets/src/main/java/bisq/asset/coins/UnitedCommunityCoin.java
index 9d893980e8..dba97a2c55 100644
--- a/assets/src/main/java/bisq/asset/coins/UnitedCommunityCoin.java
+++ b/assets/src/main/java/bisq/asset/coins/UnitedCommunityCoin.java
@@ -51,7 +51,6 @@ public class UnitedCommunityCoin extends Coin {
super();
addressHeader = 68;
p2shHeader = 18;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Veil.java b/assets/src/main/java/bisq/asset/coins/Veil.java
index 792cba487a..8e9e5ee2f9 100644
--- a/assets/src/main/java/bisq/asset/coins/Veil.java
+++ b/assets/src/main/java/bisq/asset/coins/Veil.java
@@ -50,7 +50,6 @@ public class Veil extends Coin {
public VeilParams() {
addressHeader = 70;
p2shHeader = 5;
- acceptableAddressCodes = new int[]{addressHeader, p2shHeader};
}
}
}
diff --git a/assets/src/main/java/bisq/asset/coins/Vertcoin.java b/assets/src/main/java/bisq/asset/coins/Vertcoin.java
index 1f8dae6471..a24f386ea3 100644
--- a/assets/src/main/java/bisq/asset/coins/Vertcoin.java
+++ b/assets/src/main/java/bisq/asset/coins/Vertcoin.java
@@ -30,7 +30,6 @@ public class Vertcoin extends Coin {
public VertcoinMainNetParams() {
this.addressHeader = 71;
this.p2shHeader = 5;
- this.acceptableAddressCodes = new int[]{this.addressHeader, this.p2shHeader};
}
}
}
diff --git a/build.gradle b/build.gradle
index 13e2c3c172..557b773a60 100644
--- a/build.gradle
+++ b/build.gradle
@@ -27,9 +27,9 @@ configure(subprojects) {
sourceCompatibility = 1.10
ext { // in alphabetical order
- bcVersion = '1.56'
- bitcoinjVersion = 'a88d36d'
- btcdCli4jVersion = '975ff5d4'
+ bcVersion = '1.63'
+ bitcoinjVersion = '0d98efb'
+ btcdCli4jVersion = '27b94333'
codecVersion = '1.13'
easybindVersion = '1.0.3'
easyVersion = '4.0.1'
@@ -40,7 +40,7 @@ configure(subprojects) {
fontawesomefxMaterialdesignfontVersion = '2.0.26-9.1.2'
grpcVersion = '1.25.0'
gsonVersion = '2.8.5'
- guavaVersion = '20.0'
+ guavaVersion = '28.2-jre'
guiceVersion = '4.2.2'
hamcrestVersion = '1.3'
httpclientVersion = '4.5.12'
@@ -69,7 +69,7 @@ configure(subprojects) {
pushyVersion = '0.13.2'
qrgenVersion = '1.3'
sarxosVersion = '0.3.12'
- slf4jVersion = '1.7.25'
+ slf4jVersion = '1.7.30'
sparkVersion = '2.5.2'
springBootVersion = '1.5.10.RELEASE'
@@ -211,11 +211,14 @@ configure(project(':proto')) {
configure(project(':assets')) {
dependencies {
- compile("com.github.bisq-network.bitcoinj:bitcoinj-core:$bitcoinjVersion") {
+ compile("com.github.bisq-network:bitcoinj:$bitcoinjVersion") {
exclude(module: 'jsr305')
exclude(module: 'slf4j-api')
exclude(module: 'guava')
exclude(module: 'protobuf-java')
+ exclude(module: 'bcprov-jdk15on')
+ exclude(module: 'okhttp')
+ exclude(module: 'okio')
}
compile "com.google.guava:guava:$guavaVersion"
compile "org.slf4j:slf4j-api:$slf4jVersion"
@@ -241,11 +244,14 @@ configure(project(':common')) {
compile("com.google.inject:guice:$guiceVersion") {
exclude(module: 'guava')
}
- compile("com.github.bisq-network.bitcoinj:bitcoinj-core:$bitcoinjVersion") {
+ compile("com.github.bisq-network:bitcoinj:$bitcoinjVersion") {
exclude(module: 'jsr305')
exclude(module: 'slf4j-api')
exclude(module: 'guava')
exclude(module: 'protobuf-java')
+ exclude(module: 'bcprov-jdk15on')
+ exclude(module: 'okhttp')
+ exclude(module: 'okio')
}
runtimeOnly("io.grpc:grpc-netty-shaded:$grpcVersion") {
exclude(module: 'guava')
@@ -306,7 +312,9 @@ configure(project(':core')) {
implementation("org.apache.httpcomponents:httpclient:$httpclientVersion") {
exclude(module: 'commons-codec')
}
+ compile "com.google.guava:guava:$guavaVersion"
compile("network.bisq.btcd-cli4j:btcd-cli4j-core:$btcdCli4jVersion") {
+ exclude(module: 'guava')
exclude(module: 'slf4j-api')
exclude(module: 'httpclient')
exclude(module: 'commons-lang3')
@@ -315,6 +323,7 @@ configure(project(':core')) {
exclude(module: 'jackson-databind')
}
compile("network.bisq.btcd-cli4j:btcd-cli4j-daemon:$btcdCli4jVersion") {
+ exclude(module: 'guava')
exclude(module: 'slf4j-api')
exclude(module: 'httpclient')
exclude(module: 'commons-lang3')
diff --git a/common/src/main/java/bisq/common/crypto/Hash.java b/common/src/main/java/bisq/common/crypto/Hash.java
index c07768dcad..b859654d2a 100644
--- a/common/src/main/java/bisq/common/crypto/Hash.java
+++ b/common/src/main/java/bisq/common/crypto/Hash.java
@@ -21,7 +21,7 @@ import org.bitcoinj.core.Utils;
import com.google.common.base.Charsets;
-import org.spongycastle.crypto.digests.RIPEMD160Digest;
+import org.bouncycastle.crypto.digests.RIPEMD160Digest;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
diff --git a/core/src/main/java/bisq/core/api/CoreWalletsService.java b/core/src/main/java/bisq/core/api/CoreWalletsService.java
index 10feea5b8e..950b97958a 100644
--- a/core/src/main/java/bisq/core/api/CoreWalletsService.java
+++ b/core/src/main/java/bisq/core/api/CoreWalletsService.java
@@ -33,7 +33,7 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
-import org.spongycastle.crypto.params.KeyParameter;
+import org.bouncycastle.crypto.params.KeyParameter;
import java.util.List;
import java.util.Optional;
diff --git a/core/src/main/java/bisq/core/app/AsciiLogo.java b/core/src/main/java/bisq/core/app/AsciiLogo.java
new file mode 100644
index 0000000000..f8d30333dd
--- /dev/null
+++ b/core/src/main/java/bisq/core/app/AsciiLogo.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.core.app;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class AsciiLogo {
+ public static void showAsciiLogo() {
+ log.info("\n\n" +
+ " ........ ...... \n" +
+ " .............. ...... \n" +
+ " ................. ...... \n" +
+ " ...... .......... .. ...... \n" +
+ " ...... ...... ...... ............... ..... ......... .......... \n" +
+ " ....... ........ .................. ..... ............. ............... \n" +
+ " ...... ........ .......... ....... ..... ...... ... ........ ....... \n" +
+ " ...... ..... ....... ..... ..... ..... ..... ...... \n" +
+ " ...... ... ... ...... ...... ..... ........... ...... ...... \n" +
+ " ...... ..... .... ...... ...... ..... ............ ..... ...... \n" +
+ " ...... ..... ...... ..... ........ ...... ...... \n" +
+ " ...... .... ... ...... ...... ..... .. ...... ...... ........ \n" +
+ " ........ .. ....... ................. ..... .............. ................... \n" +
+ " .......... ......... ............. ..... ............ ................. \n" +
+ " ...................... ..... .... .... ...... \n" +
+ " ................ ...... \n" +
+ " .... ...... \n" +
+ " ...... \n" +
+ "\n\n");
+ }
+}
diff --git a/core/src/main/java/bisq/core/app/BisqExecutable.java b/core/src/main/java/bisq/core/app/BisqExecutable.java
index bb36e1ffe4..f9961adda2 100644
--- a/core/src/main/java/bisq/core/app/BisqExecutable.java
+++ b/core/src/main/java/bisq/core/app/BisqExecutable.java
@@ -102,6 +102,7 @@ public abstract class BisqExecutable implements GracefulShutDownHandler, BisqSet
///////////////////////////////////////////////////////////////////////////////////////////
protected void doExecute() {
+ AsciiLogo.showAsciiLogo();
configUserThread();
CoreSetup.setup(config);
addCapabilities();
diff --git a/core/src/main/java/bisq/core/app/BisqSetup.java b/core/src/main/java/bisq/core/app/BisqSetup.java
index 164f74a04d..3577f38658 100644
--- a/core/src/main/java/bisq/core/app/BisqSetup.java
+++ b/core/src/main/java/bisq/core/app/BisqSetup.java
@@ -103,7 +103,7 @@ import javafx.beans.value.ChangeListener;
import javafx.collections.ListChangeListener;
import javafx.collections.SetChangeListener;
-import org.spongycastle.crypto.params.KeyParameter;
+import org.bouncycastle.crypto.params.KeyParameter;
import java.io.IOException;
diff --git a/core/src/main/java/bisq/core/app/WalletAppSetup.java b/core/src/main/java/bisq/core/app/WalletAppSetup.java
index 88776606e3..a5f27e899c 100644
--- a/core/src/main/java/bisq/core/app/WalletAppSetup.java
+++ b/core/src/main/java/bisq/core/app/WalletAppSetup.java
@@ -101,7 +101,7 @@ public class WalletAppSetup {
Runnable downloadCompleteHandler,
Runnable walletInitializedHandler) {
log.info("Initialize WalletAppSetup with BitcoinJ version {} and hash of BitcoinJ commit {}",
- VersionMessage.BITCOINJ_VERSION, "cd30ad5b");
+ VersionMessage.BITCOINJ_VERSION, "0d98efb");
ObjectProperty walletServiceException = new SimpleObjectProperty<>();
btcInfoBinding = EasyBind.combine(walletsSetup.downloadPercentageProperty(),
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 a9aa4aa0df..1c97f63d82 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.getTxId().toString());
this.localTx = localTx;
this.delay = delay;
this.wallet = wallet;
diff --git a/core/src/main/java/bisq/core/btc/model/AddressEntry.java b/core/src/main/java/bisq/core/btc/model/AddressEntry.java
index 26c2c50956..3b036b47a4 100644
--- a/core/src/main/java/bisq/core/btc/model/AddressEntry.java
+++ b/core/src/main/java/bisq/core/btc/model/AddressEntry.java
@@ -26,6 +26,7 @@ import com.google.protobuf.ByteString;
import org.bitcoinj.core.Address;
import org.bitcoinj.core.Coin;
+import org.bitcoinj.core.LegacyAddress;
import org.bitcoinj.crypto.DeterministicKey;
import java.util.Optional;
@@ -174,7 +175,7 @@ public final class AddressEntry implements PersistablePayload {
@Nullable
public Address getAddress() {
if (address == null && keyPair != null)
- address = keyPair.toAddress(Config.baseCurrencyNetworkParameters());
+ address = LegacyAddress.fromKey(Config.baseCurrencyNetworkParameters(), keyPair);
return address;
}
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 a3b2ae7856..a3fea3bd40 100644
--- a/core/src/main/java/bisq/core/btc/model/AddressEntryList.java
+++ b/core/src/main/java/bisq/core/btc/model/AddressEntryList.java
@@ -25,8 +25,10 @@ import bisq.common.storage.Storage;
import com.google.protobuf.Message;
import org.bitcoinj.core.Address;
+import org.bitcoinj.core.LegacyAddress;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.crypto.DeterministicKey;
+import org.bitcoinj.script.Script;
import org.bitcoinj.wallet.Wallet;
import com.google.inject.Inject;
@@ -105,9 +107,12 @@ public final class AddressEntryList implements UserThreadMappedPersistableEnvelo
if (!entrySet.isEmpty()) {
Set toBeRemoved = new HashSet<>();
entrySet.forEach(addressEntry -> {
- DeterministicKey keyFromPubHash = (DeterministicKey) wallet.findKeyFromPubHash(addressEntry.getPubKeyHash());
+ DeterministicKey keyFromPubHash = (DeterministicKey) wallet.findKeyFromPubKeyHash(
+ addressEntry.getPubKeyHash(),
+ Script.ScriptType.P2PKH);
if (keyFromPubHash != null) {
- Address addressFromKey = keyFromPubHash.toAddress(Config.baseCurrencyNetworkParameters());
+ Address addressFromKey = LegacyAddress.fromKey(Config.baseCurrencyNetworkParameters(),
+ keyFromPubHash);
// We want to ensure key and address matches in case we have address in entry available already
if (addressEntry.getAddress() == null || addressFromKey.equals(addressEntry.getAddress())) {
addressEntry.setDeterministicKey(keyFromPubHash);
@@ -140,7 +145,7 @@ public final class AddressEntryList implements UserThreadMappedPersistableEnvelo
.filter(this::isAddressNotInEntries)
.forEach(address -> {
log.info("Create AddressEntry for IssuedReceiveAddress. address={}", address.toString());
- DeterministicKey key = (DeterministicKey) wallet.findKeyFromPubHash(address.getHash160());
+ DeterministicKey key = (DeterministicKey) wallet.findKeyFromAddress(address);
if (key != null) {
// Address will be derived from key in getAddress method
entrySet.add(new AddressEntry(key, AddressEntry.Context.AVAILABLE));
@@ -175,7 +180,8 @@ public final class AddressEntryList implements UserThreadMappedPersistableEnvelo
public void swapToAvailable(AddressEntry addressEntry) {
boolean setChangedByRemove = entrySet.remove(addressEntry);
- boolean setChangedByAdd = entrySet.add(new AddressEntry(addressEntry.getKeyPair(), AddressEntry.Context.AVAILABLE));
+ boolean setChangedByAdd = entrySet.add(new AddressEntry(addressEntry.getKeyPair(),
+ AddressEntry.Context.AVAILABLE));
if (setChangedByRemove || setChangedByAdd) {
persist();
}
@@ -208,7 +214,8 @@ public final class AddressEntryList implements UserThreadMappedPersistableEnvelo
.map(output -> output.getAddressFromP2PKHScript(wallet.getNetworkParameters()))
.filter(Objects::nonNull)
.filter(this::isAddressNotInEntries)
- .map(address -> (DeterministicKey) wallet.findKeyFromPubHash(address.getHash160()))
+ .map(address -> (DeterministicKey) wallet.findKeyFromPubKeyHash(address.getHash(),
+ Script.ScriptType.P2PKH))
.filter(Objects::nonNull)
.map(deterministicKey -> new AddressEntry(deterministicKey, AddressEntry.Context.AVAILABLE))
.forEach(this::addAddressEntry);
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 2cb29b8f49..7740b17e35 100644
--- a/core/src/main/java/bisq/core/btc/nodes/BtcNodeConverter.java
+++ b/core/src/main/java/bisq/core/btc/nodes/BtcNodeConverter.java
@@ -55,17 +55,8 @@ class BtcNodeConverter {
PeerAddress convertOnionHost(BtcNode node) {
// no DNS lookup for onion addresses
String onionAddress = Objects.requireNonNull(node.getOnionAddress());
- try {
- // 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());
- result.setAddr(inetAddress);
- return result;
- } catch (UnknownHostException e) {
- log.error("Failed to convert node", e);
- return null;
- }
+ PeerAddress result = new PeerAddress(onionAddress, node.getPort());
+ return result;
}
@Nullable
@@ -107,7 +98,7 @@ class BtcNodeConverter {
// Blocking call. takes about 600 ms ;-(
InetAddress lookupAddress = facade.torLookup(proxy, host);
InetSocketAddress address = new InetSocketAddress(lookupAddress, port);
- return new PeerAddress(address.getAddress(), address.getPort());
+ return new PeerAddress(address);
} catch (Exception e) {
log.error("Failed to create peer address", e);
return null;
@@ -118,7 +109,7 @@ class BtcNodeConverter {
private static PeerAddress create(String hostName, int port) {
try {
InetSocketAddress address = new InetSocketAddress(hostName, port);
- return new PeerAddress(address.getAddress(), address.getPort());
+ return new PeerAddress(address);
} catch (Exception e) {
log.error("Failed to create peer address", e);
return null;
diff --git a/core/src/main/java/bisq/core/btc/setup/BisqDeterministicKeyChain.java b/core/src/main/java/bisq/core/btc/setup/BisqDeterministicKeyChain.java
deleted file mode 100644
index e0d53ddd15..0000000000
--- a/core/src/main/java/bisq/core/btc/setup/BisqDeterministicKeyChain.java
+++ /dev/null
@@ -1,81 +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.setup;
-
-import org.bitcoinj.crypto.ChildNumber;
-import org.bitcoinj.crypto.DeterministicKey;
-import org.bitcoinj.crypto.KeyCrypter;
-import org.bitcoinj.wallet.DeterministicKeyChain;
-import org.bitcoinj.wallet.DeterministicSeed;
-
-import com.google.common.collect.ImmutableList;
-
-import org.spongycastle.crypto.params.KeyParameter;
-
-import java.security.SecureRandom;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class BisqDeterministicKeyChain extends DeterministicKeyChain {
- private static final Logger log = LoggerFactory.getLogger(BisqDeterministicKeyChain.class);
-
- // See https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
- // https://github.com/satoshilabs/slips/blob/master/slip-0044.md
- // We have registered 142 (0x8000008E) as coin_type for BSQ
- public static final ImmutableList BIP44_BSQ_ACCOUNT_PATH = ImmutableList.of(
- new ChildNumber(44, true),
- new ChildNumber(142, true),
- ChildNumber.ZERO_HARDENED);
-
- public BisqDeterministicKeyChain(SecureRandom random) {
- super(random);
- }
-
- public BisqDeterministicKeyChain(DeterministicKey accountKey, boolean isFollowingKey) {
- super(accountKey, isFollowingKey);
- }
-
- public BisqDeterministicKeyChain(DeterministicSeed seed, KeyCrypter crypter) {
- super(seed, crypter);
- }
-
- public BisqDeterministicKeyChain(DeterministicSeed seed) {
- super(seed);
- }
-
-
- @Override
- public DeterministicKeyChain toEncrypted(KeyCrypter keyCrypter, KeyParameter aesKey) {
- return new BisqDeterministicKeyChain(keyCrypter, aesKey, this);
- }
-
- protected DeterministicKeyChain makeKeyChainFromSeed(DeterministicSeed seed) {
- return new BisqDeterministicKeyChain(seed);
- }
-
- protected BisqDeterministicKeyChain(KeyCrypter crypter, KeyParameter aesKey, DeterministicKeyChain chain) {
- super(crypter, aesKey, chain);
- }
-
- @Override
- protected ImmutableList getAccountPath() {
- return BIP44_BSQ_ACCOUNT_PATH;
- }
-
-}
diff --git a/core/src/main/java/bisq/core/btc/setup/BisqKeyChainFactory.java b/core/src/main/java/bisq/core/btc/setup/BisqKeyChainFactory.java
index 0cb088f31d..5c31e0d64c 100644
--- a/core/src/main/java/bisq/core/btc/setup/BisqKeyChainFactory.java
+++ b/core/src/main/java/bisq/core/btc/setup/BisqKeyChainFactory.java
@@ -19,35 +19,56 @@ package bisq.core.btc.setup;
import org.bitcoinj.crypto.ChildNumber;
import org.bitcoinj.crypto.DeterministicKey;
-import org.bitcoinj.crypto.HDUtils;
import org.bitcoinj.crypto.KeyCrypter;
+import org.bitcoinj.script.Script;
+import org.bitcoinj.wallet.DefaultKeyChainFactory;
import org.bitcoinj.wallet.DeterministicKeyChain;
import org.bitcoinj.wallet.DeterministicSeed;
-import org.bitcoinj.wallet.KeyChainFactory;
+import org.bitcoinj.wallet.KeyChainGroupStructure;
import org.bitcoinj.wallet.Protos;
import org.bitcoinj.wallet.UnreadableWalletException;
import com.google.common.collect.ImmutableList;
-class BisqKeyChainFactory implements KeyChainFactory {
- private final boolean useBitcoinDeterministicKeyChain;
+/**
+ * Hack to convert bitcoinj 0.14 wallets to bitcoinj 0.15 format.
+ *
+ * This code is required to be executed only once per user (actually twice, for btc and bsq wallets).
+ * Once all users using bitcoinj 0.14 wallets have executed this code, this class will be no longer needed.
+ *
+ * Since that is almost impossible to guarantee, this hack will stay until we decide to don't be
+ * backwards compatible with pre bitcoinj 0.15 wallets.
+ * In that scenario, users will have to migrate using this procedure:
+ * 1) Run pre bitcoinj 0.15 bisq and copy their seed words on a piece of paper.
+ * 2) Run post bitcoinj 0.15 bisq and use recover from seed.
+ * */
+public class BisqKeyChainFactory extends DefaultKeyChainFactory {
- public BisqKeyChainFactory(boolean useBitcoinDeterministicKeyChain) {
- this.useBitcoinDeterministicKeyChain = useBitcoinDeterministicKeyChain;
+ private boolean isBsqWallet;
+
+ public BisqKeyChainFactory(boolean isBsqWallet) {
+ this.isBsqWallet = isBsqWallet;
}
@Override
- public DeterministicKeyChain makeKeyChain(Protos.Key key, Protos.Key firstSubKey, DeterministicSeed seed, KeyCrypter crypter, boolean isMarried) {
- return useBitcoinDeterministicKeyChain ? new BtcDeterministicKeyChain(seed, crypter) : new BisqDeterministicKeyChain(seed, crypter);
+ public DeterministicKeyChain makeKeyChain(Protos.Key key, Protos.Key firstSubKey, DeterministicSeed seed, KeyCrypter crypter, boolean isMarried, Script.ScriptType outputScriptType, ImmutableList accountPath) {
+ ImmutableList maybeUpdatedAccountPath = accountPath;
+ if (DeterministicKeyChain.ACCOUNT_ZERO_PATH.equals(accountPath)) {
+ // This is a bitcoinj 0.14 wallet that has no account path in the serialized mnemonic
+ KeyChainGroupStructure structure = new BisqKeyChainGroupStructure(isBsqWallet);
+ maybeUpdatedAccountPath = structure.accountPathFor(outputScriptType);
+ }
+
+ return super.makeKeyChain(key, firstSubKey, seed, crypter, isMarried, outputScriptType, maybeUpdatedAccountPath);
}
@Override
- public DeterministicKeyChain makeWatchingKeyChain(Protos.Key key, Protos.Key firstSubKey, DeterministicKey accountKey,
- boolean isFollowingKey, boolean isMarried) throws UnreadableWalletException {
- ImmutableList accountPath = useBitcoinDeterministicKeyChain ? BtcDeterministicKeyChain.BIP44_BTC_ACCOUNT_PATH : BisqDeterministicKeyChain.BIP44_BSQ_ACCOUNT_PATH;
- if (!accountKey.getPath().equals(accountPath))
- throw new UnreadableWalletException("Expecting account key but found key with path: " +
- HDUtils.formatPath(accountKey.getPath()));
- return useBitcoinDeterministicKeyChain ? new BtcDeterministicKeyChain(accountKey, isFollowingKey) : new BisqDeterministicKeyChain(accountKey, isFollowingKey);
+ public DeterministicKeyChain makeWatchingKeyChain(Protos.Key key, Protos.Key firstSubKey, DeterministicKey accountKey, boolean isFollowingKey, boolean isMarried, Script.ScriptType outputScriptType) throws UnreadableWalletException {
+ throw new UnsupportedOperationException("Bisq is not supposed to use this");
+ }
+
+ @Override
+ public DeterministicKeyChain makeSpendingKeyChain(Protos.Key key, Protos.Key firstSubKey, DeterministicKey accountKey, boolean isMarried, Script.ScriptType outputScriptType) throws UnreadableWalletException {
+ throw new UnsupportedOperationException("Bisq is not supposed to use this");
}
}
diff --git a/core/src/main/java/bisq/core/btc/setup/BisqKeyChainGroup.java b/core/src/main/java/bisq/core/btc/setup/BisqKeyChainGroup.java
deleted file mode 100644
index 2146bfea7e..0000000000
--- a/core/src/main/java/bisq/core/btc/setup/BisqKeyChainGroup.java
+++ /dev/null
@@ -1,49 +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.setup;
-
-import org.bitcoinj.core.NetworkParameters;
-import org.bitcoinj.wallet.DeterministicKeyChain;
-import org.bitcoinj.wallet.KeyChainGroup;
-
-import java.security.SecureRandom;
-
-class BisqKeyChainGroup extends KeyChainGroup {
- private final boolean useBitcoinDeterministicKeyChain;
-
- public boolean isUseBitcoinDeterministicKeyChain() {
- return useBitcoinDeterministicKeyChain;
- }
-
- public BisqKeyChainGroup(NetworkParameters params, @SuppressWarnings("SameParameterValue") boolean useBitcoinDeterministicKeyChain) {
- super(params);
- this.useBitcoinDeterministicKeyChain = useBitcoinDeterministicKeyChain;
- }
-
- public BisqKeyChainGroup(NetworkParameters params, DeterministicKeyChain chain, boolean useBitcoinDeterministicKeyChain) {
- super(params, chain);
-
- this.useBitcoinDeterministicKeyChain = useBitcoinDeterministicKeyChain;
- }
-
- @Override
- public void createAndActivateNewHDChain() {
- DeterministicKeyChain chain = useBitcoinDeterministicKeyChain ? new BtcDeterministicKeyChain(new SecureRandom()) : new BisqDeterministicKeyChain(new SecureRandom());
- addAndActivateHDChain(chain);
- }
-}
diff --git a/core/src/main/java/bisq/core/btc/setup/BisqKeyChainGroupStructure.java b/core/src/main/java/bisq/core/btc/setup/BisqKeyChainGroupStructure.java
new file mode 100644
index 0000000000..7c7f6a4e3a
--- /dev/null
+++ b/core/src/main/java/bisq/core/btc/setup/BisqKeyChainGroupStructure.java
@@ -0,0 +1,79 @@
+/*
+ * 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.setup;
+
+import org.bitcoinj.crypto.ChildNumber;
+import org.bitcoinj.script.Script;
+import org.bitcoinj.wallet.KeyChainGroupStructure;
+
+import com.google.common.collect.ImmutableList;
+
+public class BisqKeyChainGroupStructure implements KeyChainGroupStructure {
+
+ // See https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
+ // https://github.com/satoshilabs/slips/blob/master/slip-0044.md
+ // We use 0 (0x80000000) as coin_type for BTC
+ // m / purpose' / coin_type' / account' / change / address_index
+ public static final ImmutableList BIP44_BTC_NON_SEGWIT_ACCOUNT_PATH = ImmutableList.of(
+ new ChildNumber(44, true),
+ new ChildNumber(0, true),
+ ChildNumber.ZERO_HARDENED);
+
+ public static final ImmutableList BIP44_BTC_SEGWIT_ACCOUNT_PATH = ImmutableList.of(
+ new ChildNumber(44, true),
+ new ChildNumber(0, true),
+ ChildNumber.ONE_HARDENED);
+
+ // See https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
+ // https://github.com/satoshilabs/slips/blob/master/slip-0044.md
+ // We have registered 142 (0x8000008E) as coin_type for BSQ
+ public static final ImmutableList BIP44_BSQ_NON_SEGWIT_ACCOUNT_PATH = ImmutableList.of(
+ new ChildNumber(44, true),
+ new ChildNumber(142, true),
+ ChildNumber.ZERO_HARDENED);
+
+ public static final ImmutableList BIP44_BSQ_SEGWIT_ACCOUNT_PATH = ImmutableList.of(
+ new ChildNumber(44, true),
+ new ChildNumber(142, true),
+ ChildNumber.ONE_HARDENED);
+
+ private boolean isBsqWallet;
+
+ public BisqKeyChainGroupStructure (boolean isBsqWallet) {
+ this.isBsqWallet = isBsqWallet;
+ }
+
+ @Override
+ public ImmutableList accountPathFor(Script.ScriptType outputScriptType) {
+ if (!isBsqWallet) {
+ if (outputScriptType == null || outputScriptType == Script.ScriptType.P2PKH)
+ return BIP44_BTC_NON_SEGWIT_ACCOUNT_PATH;
+ else if (outputScriptType == Script.ScriptType.P2WPKH)
+ return BIP44_BTC_SEGWIT_ACCOUNT_PATH;
+ else
+ throw new IllegalArgumentException(outputScriptType.toString());
+ } else {
+ if (outputScriptType == null || outputScriptType == Script.ScriptType.P2PKH)
+ return BIP44_BSQ_NON_SEGWIT_ACCOUNT_PATH;
+ else if (outputScriptType == Script.ScriptType.P2WPKH)
+ return BIP44_BSQ_SEGWIT_ACCOUNT_PATH;
+ else
+ throw new IllegalArgumentException(outputScriptType.toString());
+ }
+ }
+}
diff --git a/core/src/main/java/bisq/core/btc/setup/BsqWallet.java b/core/src/main/java/bisq/core/btc/setup/BsqWallet.java
deleted file mode 100644
index 73c5ac9634..0000000000
--- a/core/src/main/java/bisq/core/btc/setup/BsqWallet.java
+++ /dev/null
@@ -1,29 +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.setup;
-
-import org.bitcoinj.core.NetworkParameters;
-import org.bitcoinj.wallet.KeyChainGroup;
-import org.bitcoinj.wallet.Wallet;
-
-public class BsqWallet extends Wallet {
-
- public BsqWallet(NetworkParameters params, KeyChainGroup keyChainGroup) {
- super(params, keyChainGroup);
- }
-}
diff --git a/core/src/main/java/bisq/core/btc/setup/BtcDeterministicKeyChain.java b/core/src/main/java/bisq/core/btc/setup/BtcDeterministicKeyChain.java
deleted file mode 100644
index fd177aa71a..0000000000
--- a/core/src/main/java/bisq/core/btc/setup/BtcDeterministicKeyChain.java
+++ /dev/null
@@ -1,82 +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.setup;
-
-import org.bitcoinj.crypto.ChildNumber;
-import org.bitcoinj.crypto.DeterministicKey;
-import org.bitcoinj.crypto.KeyCrypter;
-import org.bitcoinj.wallet.DeterministicKeyChain;
-import org.bitcoinj.wallet.DeterministicSeed;
-
-import com.google.common.collect.ImmutableList;
-
-import org.spongycastle.crypto.params.KeyParameter;
-
-import java.security.SecureRandom;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class BtcDeterministicKeyChain extends DeterministicKeyChain {
- private static final Logger log = LoggerFactory.getLogger(BtcDeterministicKeyChain.class);
-
- // See https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
- // https://github.com/satoshilabs/slips/blob/master/slip-0044.md
- // We use 0 (0x80000000) as coin_type for BTC
- // m / purpose' / coin_type' / account' / change / address_index
- public static final ImmutableList BIP44_BTC_ACCOUNT_PATH = ImmutableList.of(
- new ChildNumber(44, true),
- new ChildNumber(0, true),
- ChildNumber.ZERO_HARDENED);
-
- public BtcDeterministicKeyChain(SecureRandom random) {
- super(random);
- }
-
- public BtcDeterministicKeyChain(DeterministicKey accountKey, boolean isFollowingKey) {
- super(accountKey, isFollowingKey);
- }
-
- public BtcDeterministicKeyChain(DeterministicSeed seed, KeyCrypter crypter) {
- super(seed, crypter);
- }
-
- public BtcDeterministicKeyChain(DeterministicSeed seed) {
- super(seed);
- }
-
- @Override
- public DeterministicKeyChain toEncrypted(KeyCrypter keyCrypter, KeyParameter aesKey) {
- return new BtcDeterministicKeyChain(keyCrypter, aesKey, this);
- }
-
- @Override
- protected DeterministicKeyChain makeKeyChainFromSeed(DeterministicSeed seed) {
- return new BtcDeterministicKeyChain(seed);
- }
-
- protected BtcDeterministicKeyChain(KeyCrypter crypter, KeyParameter aesKey, DeterministicKeyChain chain) {
- super(crypter, aesKey, chain);
- }
-
- @Override
- protected ImmutableList getAccountPath() {
- return BIP44_BTC_ACCOUNT_PATH;
- }
-
-}
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 369180bfee..13f18dd4f7 100644
--- a/core/src/main/java/bisq/core/btc/setup/WalletConfig.java
+++ b/core/src/main/java/bisq/core/btc/setup/WalletConfig.java
@@ -20,201 +20,530 @@ package bisq.core.btc.setup;
import bisq.core.btc.nodes.LocalBitcoinNode;
import bisq.core.btc.nodes.ProxySocketFactory;
import bisq.core.btc.wallet.BisqRiskAnalysis;
-
-import bisq.common.app.Version;
import bisq.common.config.Config;
-import org.bitcoinj.core.BlockChain;
-import org.bitcoinj.core.CheckpointManager;
-import org.bitcoinj.core.Context;
-import org.bitcoinj.core.NetworkParameters;
-import org.bitcoinj.core.PeerAddress;
-import org.bitcoinj.core.PeerGroup;
-import org.bitcoinj.core.Utils;
-import org.bitcoinj.core.listeners.DownloadProgressTracker;
-import org.bitcoinj.core.listeners.PeerDataEventListener;
+import com.google.common.collect.*;
+import com.google.common.io.Closeables;
+import com.google.common.util.concurrent.*;
+import org.bitcoinj.core.listeners.*;
+import org.bitcoinj.core.*;
+import org.bitcoinj.crypto.DeterministicKey;
import org.bitcoinj.net.BlockingClientManager;
-import org.bitcoinj.net.discovery.DnsDiscovery;
-import org.bitcoinj.net.discovery.PeerDiscovery;
-import org.bitcoinj.params.MainNetParams;
-import org.bitcoinj.params.RegTestParams;
-import org.bitcoinj.params.TestNet3Params;
-import org.bitcoinj.store.BlockStore;
-import org.bitcoinj.store.BlockStoreException;
-import org.bitcoinj.store.SPVBlockStore;
-import org.bitcoinj.wallet.DeterministicKeyChain;
-import org.bitcoinj.wallet.DeterministicSeed;
-import org.bitcoinj.wallet.KeyChainGroup;
-import org.bitcoinj.wallet.Protos;
-import org.bitcoinj.wallet.Wallet;
-import org.bitcoinj.wallet.WalletExtension;
-import org.bitcoinj.wallet.WalletProtobufSerializer;
+import org.bitcoinj.net.discovery.*;
+import org.bitcoinj.script.Script;
+import org.bitcoinj.store.*;
+import org.bitcoinj.wallet.*;
import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;
-import com.google.common.collect.ImmutableList;
-import com.google.common.util.concurrent.AbstractIdleService;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
+import org.slf4j.*;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Proxy;
-
-import java.nio.channels.FileLock;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.RandomAccessFile;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
+import javax.annotation.*;
+import java.io.*;
+import java.net.*;
+import java.nio.channels.*;
+import java.util.*;
+import java.util.concurrent.*;
import lombok.Getter;
import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
-
-import org.jetbrains.annotations.NotNull;
-
-import javax.annotation.Nullable;
import static bisq.common.util.Preconditions.checkDir;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.base.Preconditions.*;
-// Derived from WalletAppKit
-// Does the basic wiring
-@Slf4j
+/**
+ *
Utility class that wraps the boilerplate needed to set up a new SPV bitcoinj app. Instantiate it with a directory
+ * and file prefix, optionally configure a few things, then use startAsync and optionally awaitRunning. The object will
+ * construct and configure a {@link BlockChain}, {@link SPVBlockStore}, {@link Wallet} and {@link PeerGroup}. Depending
+ * on the value of the blockingStartup property, startup will be considered complete once the block chain has fully
+ * synchronized, so it can take a while.
+ *
+ *
To add listeners and modify the objects that are constructed, you can either do that by overriding the
+ * {@link #onSetupCompleted()} method (which will run on a background thread) and make your changes there,
+ * or by waiting for the service to start and then accessing the objects from wherever you want. However, you cannot
+ * access the objects this class creates until startup is complete.
+ *
+ *
The asynchronous design of this class may seem puzzling (just use {@link #awaitRunning()} if you don't want that).
+ * It is to make it easier to fit bitcoinj into GUI apps, which require a high degree of responsiveness on their main
+ * thread which handles all the animation and user interaction. Even when blockingStart is false, initializing bitcoinj
+ * means doing potentially blocking file IO, generating keys and other potentially intensive operations. By running it
+ * on a background thread, there's no risk of accidentally causing UI lag.
+ *
+ *
Note that {@link #awaitRunning()} can throw an unchecked {@link IllegalStateException}
+ * if anything goes wrong during startup - you should probably handle it and use {@link Exception#getCause()} to figure
+ * out what went wrong more precisely. Same thing if you just use the {@link #startAsync()} method.
+ */
public class WalletConfig extends AbstractIdleService {
+
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.
+ protected static final Logger log = LoggerFactory.getLogger(WalletConfig.class);
- ///////////////////////////////////////////////////////////////////////////////////////////
- // WalletFactory
- ///////////////////////////////////////////////////////////////////////////////////////////
+ protected final NetworkParameters params;
+ protected final String filePrefix;
+ protected volatile BlockChain vChain;
+ protected volatile SPVBlockStore vStore;
+ protected volatile Wallet vBtcWallet;
+ protected volatile Wallet vBsqWallet;
+ protected volatile PeerGroup vPeerGroup;
- public interface BisqWalletFactory extends WalletProtobufSerializer.WalletFactory {
- Wallet create(NetworkParameters params, KeyChainGroup keyChainGroup, boolean isBsqWallet);
- }
+ protected final File directory;
+ protected volatile File vBtcWalletFile;
+ protected volatile File vBsqWalletFile;
+ protected boolean useAutoSave = true;
+ protected PeerAddress[] peerAddresses;
+ protected DownloadProgressTracker downloadListener;
+ protected boolean autoStop = true;
+ protected InputStream checkpoints;
+ protected boolean blockingStartup = true;
+ protected String userAgent, version;
+ protected WalletProtobufSerializer.WalletFactory walletFactory;
+ @Nullable protected DeterministicSeed restoreFromSeed;
+ @Nullable protected DeterministicKey restoreFromKey;
+ @Nullable protected PeerDiscovery discovery;
- ///////////////////////////////////////////////////////////////////////////////////////////
- // Fields
- ///////////////////////////////////////////////////////////////////////////////////////////
+ protected volatile Context context;
- private final Context context;
- private final NetworkParameters params;
- private final File directory;
- private final String btcWalletFileName;
- private final String bsqWalletFileName;
- private final String spvChainFileName;
- private final Socks5Proxy socks5Proxy;
- private final BisqWalletFactory walletFactory;
- private final Config config;
- private final LocalBitcoinNode localBitcoinNode;
- private final String userAgent;
- private int numConnectionsForBtc;
-
- private volatile Wallet vBtcWallet;
- @Nullable
- private volatile Wallet vBsqWallet;
- private volatile File vBtcWalletFile;
- @Nullable
- private volatile File vBsqWalletFile;
- @Nullable
- private DeterministicSeed seed;
-
- private volatile BlockChain vChain;
- private volatile SPVBlockStore vStore;
- private volatile PeerGroup vPeerGroup;
- private boolean useAutoSave = true;
- private PeerAddress[] peerAddresses;
- private PeerDataEventListener downloadListener;
- private boolean autoStop = true;
- private InputStream checkpoints;
- private boolean blockingStartup = true;
+ protected Config config;
+ protected LocalBitcoinNode localBitcoinNode;
+ protected Socks5Proxy socks5Proxy;
+ protected int numConnectionsForBtc;
@Getter
@Setter
private int minBroadcastConnections;
- @Nullable
- private PeerDiscovery discovery;
+ /**
+ * Creates a new WalletConfig, with a newly created {@link Context}. Files will be stored in the given directory.
+ */
+ public WalletConfig(NetworkParameters params, File directory, String filePrefix) {
+ this(new Context(params), directory, filePrefix);
+ }
-
- ///////////////////////////////////////////////////////////////////////////////////////////
- // Constructor
- ///////////////////////////////////////////////////////////////////////////////////////////
-
- public WalletConfig(NetworkParameters params,
- Socks5Proxy socks5Proxy,
- File directory,
- Config config,
- LocalBitcoinNode localBitcoinNode,
- String userAgent,
- int numConnectionsForBtc,
- @SuppressWarnings("SameParameterValue") String btcWalletFileName,
- @SuppressWarnings("SameParameterValue") String bsqWalletFileName,
- @SuppressWarnings("SameParameterValue") String spvChainFileName) {
- this.config = config;
- this.localBitcoinNode = localBitcoinNode;
- this.userAgent = userAgent;
- this.numConnectionsForBtc = numConnectionsForBtc;
- this.context = new Context(params);
+ /**
+ * Creates a new WalletConfig, with the given {@link Context}. Files will be stored in the given directory.
+ */
+ public WalletConfig(Context context,
+ File directory, String filePrefix) {
+ this.context = context;
this.params = checkNotNull(context.getParams());
this.directory = checkDir(directory);
- this.btcWalletFileName = checkNotNull(btcWalletFileName);
- this.bsqWalletFileName = bsqWalletFileName;
- this.spvChainFileName = spvChainFileName;
+ this.filePrefix = checkNotNull(filePrefix);
+ }
+
+ public WalletConfig setSocks5Proxy(Socks5Proxy socks5Proxy) {
+ checkState(state() == State.NEW, "Cannot call after startup");
this.socks5Proxy = socks5Proxy;
+ return this;
+ }
- walletFactory = new BisqWalletFactory() {
- @Override
- public Wallet create(NetworkParameters params, KeyChainGroup keyChainGroup) {
- // This is called when we load an existing wallet
- // 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) {
- return new BsqWallet(params, keyChainGroup);
- } else {
- return new Wallet(params, keyChainGroup);
- }
- }
+ public WalletConfig setConfig(Config config) {
+ checkState(state() == State.NEW, "Cannot call after startup");
+ this.config = config;
+ return this;
+ }
- @Override
- public Wallet create(NetworkParameters params, KeyChainGroup keyChainGroup, boolean isBsqWallet) {
- // This is called at first startup when we create the wallet
- if (isBsqWallet) {
- return new BsqWallet(params, keyChainGroup);
- } else {
- return new Wallet(params, keyChainGroup);
- }
- }
- };
+ public WalletConfig setLocalBitcoinNode(LocalBitcoinNode localBitcoinNode) {
+ checkState(state() == State.NEW, "Cannot call after startup");
+ this.localBitcoinNode = localBitcoinNode;
+ return this;
+ }
- String path = null;
- if (params.equals(MainNetParams.get())) {
- // Checkpoints are block headers that ship inside our app: for a new user, we pick the last header
- // in the checkpoints file and then download the rest from the network. It makes things much faster.
- // Checkpoint files are made using the BuildCheckpoints tool and usually we have to download the
- // last months worth or more (takes a few seconds).
- path = "/wallet/checkpoints.txt";
- } else if (params.equals(TestNet3Params.get())) {
- path = "/wallet/checkpoints.testnet.txt";
- }
- if (path != null) {
- try {
- setCheckpoints(getClass().getResourceAsStream(path));
- } catch (Exception e) {
- e.printStackTrace();
- log.error(e.toString());
- }
+ public WalletConfig setNumConnectionsForBtc(int numConnectionsForBtc) {
+ checkState(state() == State.NEW, "Cannot call after startup");
+ this.numConnectionsForBtc = numConnectionsForBtc;
+ return this;
+ }
+
+
+ /** Will only connect to the given addresses. Cannot be called after startup. */
+ public WalletConfig setPeerNodes(PeerAddress... addresses) {
+ checkState(state() == State.NEW, "Cannot call after startup");
+ this.peerAddresses = addresses;
+ return this;
+ }
+
+ /** Will only connect to localhost. Cannot be called after startup. */
+ public WalletConfig connectToLocalHost() {
+ final InetAddress localHost = InetAddress.getLoopbackAddress();
+ return setPeerNodes(new PeerAddress(params, localHost, params.getPort()));
+ }
+
+ /** If true, the wallet will save itself to disk automatically whenever it changes. */
+ public WalletConfig setAutoSave(boolean value) {
+ checkState(state() == State.NEW, "Cannot call after startup");
+ useAutoSave = value;
+ return this;
+ }
+
+ /**
+ * If you want to learn about the sync process, you can provide a listener here. For instance, a
+ * {@link DownloadProgressTracker} is a good choice. This has no effect unless setBlockingStartup(false) has been called
+ * too, due to some missing implementation code.
+ */
+ public WalletConfig setDownloadListener(DownloadProgressTracker listener) {
+ this.downloadListener = listener;
+ return this;
+ }
+
+ /** If true, will register a shutdown hook to stop the library. Defaults to true. */
+ public WalletConfig setAutoStop(boolean autoStop) {
+ this.autoStop = autoStop;
+ return this;
+ }
+
+ /**
+ * If set, the file is expected to contain a checkpoints file calculated with BuildCheckpoints. It makes initial
+ * block sync faster for new users - please refer to the documentation on the bitcoinj website
+ * (https://bitcoinj.github.io/speeding-up-chain-sync) for further details.
+ */
+ public WalletConfig setCheckpoints(InputStream checkpoints) {
+ if (this.checkpoints != null)
+ Closeables.closeQuietly(checkpoints);
+ this.checkpoints = checkNotNull(checkpoints);
+ return this;
+ }
+
+ /**
+ * If true (the default) then the startup of this service won't be considered complete until the network has been
+ * brought up, peer connections established and the block chain synchronised. Therefore {@link #awaitRunning()} can
+ * potentially take a very long time. If false, then startup is considered complete once the network activity
+ * begins and peer connections/block chain sync will continue in the background.
+ */
+ public WalletConfig setBlockingStartup(boolean blockingStartup) {
+ this.blockingStartup = blockingStartup;
+ return this;
+ }
+
+ /**
+ * Sets the string that will appear in the subver field of the version message.
+ * @param userAgent A short string that should be the name of your app, e.g. "My Wallet"
+ * @param version A short string that contains the version number, e.g. "1.0-BETA"
+ */
+ public WalletConfig setUserAgent(String userAgent, String version) {
+ this.userAgent = checkNotNull(userAgent);
+ this.version = checkNotNull(version);
+ return this;
+ }
+
+ /**
+ * Sets a wallet factory which will be used when the kit creates a new wallet.
+ */
+ public WalletConfig setWalletFactory(WalletProtobufSerializer.WalletFactory walletFactory) {
+ this.walletFactory = walletFactory;
+ return this;
+ }
+
+ /**
+ * If a seed is set here then any existing wallet that matches the file name will be renamed to a backup name,
+ * the chain file will be deleted, and the wallet object will be instantiated with the given seed instead of
+ * a fresh one being created. This is intended for restoring a wallet from the original seed. To implement restore
+ * you would shut down the existing appkit, if any, then recreate it with the seed given by the user, then start
+ * up the new kit. The next time your app starts it should work as normal (that is, don't keep calling this each
+ * time).
+ */
+ public WalletConfig restoreWalletFromSeed(DeterministicSeed seed) {
+ this.restoreFromSeed = seed;
+ return this;
+ }
+
+ /**
+ * If an account key is set here then any existing wallet that matches the file name will be renamed to a backup name,
+ * the chain file will be deleted, and the wallet object will be instantiated with the given key instead of
+ * a fresh seed being created. This is intended for restoring a wallet from an account key. To implement restore
+ * you would shut down the existing appkit, if any, then recreate it with the key given by the user, then start
+ * up the new kit. The next time your app starts it should work as normal (that is, don't keep calling this each
+ * time).
+ */
+ public WalletConfig restoreWalletFromKey(DeterministicKey accountKey) {
+ this.restoreFromKey = accountKey;
+ return this;
+ }
+
+ /**
+ * Sets the peer discovery class to use. If none is provided then DNS is used, which is a reasonable default.
+ */
+ public WalletConfig setDiscovery(@Nullable PeerDiscovery discovery) {
+ this.discovery = discovery;
+ return this;
+ }
+
+ /**
+ *
Override this to return wallet extensions if any are necessary.
+ *
+ *
When this is called, chain(), store(), and peerGroup() will return the created objects, however they are not
+ * initialized/started.
+ */
+ protected List provideWalletExtensions() throws Exception {
+ return ImmutableList.of();
+ }
+
+ /**
+ * 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.
+ */
+ protected void onSetupCompleted() {
+ // Meant to be overridden by subclasses
+ }
+
+ /**
+ * Tests to see if the spvchain file has an operating system file lock on it. Useful for checking if your app
+ * is already running. If another copy of your app is running and you start the appkit anyway, an exception will
+ * be thrown during the startup process. Returns false if the chain file does not exist or is a directory.
+ */
+ public boolean isChainFileLocked() throws IOException {
+ RandomAccessFile file2 = null;
+ try {
+ File file = new File(directory, filePrefix + ".spvchain");
+ if (!file.exists())
+ return false;
+ if (file.isDirectory())
+ return false;
+ file2 = new RandomAccessFile(file, "rw");
+ FileLock lock = file2.getChannel().tryLock();
+ if (lock == null)
+ return true;
+ lock.release();
+ return false;
+ } finally {
+ if (file2 != null)
+ file2.close();
}
}
+ @Override
+ protected void startUp() throws Exception {
+ // Runs in a separate thread.
+ Context.propagate(context);
+ // bitcoinj's WalletAppKit creates the wallet directory if it was not created already,
+ // but WalletConfig should not do that.
+ // if (!directory.exists()) {
+ // if (!directory.mkdirs()) {
+ // throw new IOException("Could not create directory " + directory.getAbsolutePath());
+ // }
+ // }
+ log.info("Starting up with directory = {}", directory);
+ try {
+ File chainFile = new File(directory, filePrefix + ".spvchain");
+ boolean chainFileExists = chainFile.exists();
+ String btcPrefix = "_BTC";
+ vBtcWalletFile = new File(directory, filePrefix + btcPrefix + ".wallet");
+ boolean shouldReplayWallet = (vBtcWalletFile.exists() && !chainFileExists) || restoreFromSeed != null || restoreFromKey != null;
+ vBtcWallet = createOrLoadWallet(shouldReplayWallet, vBtcWalletFile, false);
+ vBtcWallet.allowSpendingUnconfirmedTransactions();
+ vBtcWallet.setRiskAnalyzer(new BisqRiskAnalysis.Analyzer());
+
+ String bsqPrefix = "_BSQ";
+ vBsqWalletFile = new File(directory, filePrefix + bsqPrefix + ".wallet");
+ vBsqWallet = createOrLoadWallet(shouldReplayWallet, vBsqWalletFile, true);
+ vBsqWallet.setRiskAnalyzer(new BisqRiskAnalysis.Analyzer());
+
+ // Initiate Bitcoin network objects (block store, blockchain and peer group)
+ vStore = new SPVBlockStore(params, chainFile);
+ if (!chainFileExists || restoreFromSeed != null || restoreFromKey != null) {
+ if (checkpoints == null && !Utils.isAndroidRuntime()) {
+ checkpoints = CheckpointManager.openStream(params);
+ }
+
+ if (checkpoints != null) {
+ // Initialize the chain file with a checkpoint to speed up first-run sync.
+ long time;
+ if (restoreFromSeed != null) {
+ time = restoreFromSeed.getCreationTimeSeconds();
+ if (chainFileExists) {
+ log.info("Clearing the chain file in preparation for restore.");
+ vStore.clear();
+ }
+ } else if (restoreFromKey != null) {
+ time = restoreFromKey.getCreationTimeSeconds();
+ if (chainFileExists) {
+ log.info("Clearing the chain file in preparation for restore.");
+ vStore.clear();
+ }
+ } else {
+ time = vBtcWallet.getEarliestKeyCreationTime();
+ }
+ if (time > 0)
+ CheckpointManager.checkpoint(params, checkpoints, vStore, time);
+ 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("Clearing the chain file in preparation for restore.");
+ vStore.clear();
+ }
+ }
+ vChain = new BlockChain(params, vStore);
+ vPeerGroup = createPeerGroup();
+ if (minBroadcastConnections > 0 )
+ vPeerGroup.setMinBroadcastConnections(minBroadcastConnections);
+ if (this.userAgent != null)
+ vPeerGroup.setUserAgent(userAgent, version);
+
+ // Set up peer addresses or discovery first, so if wallet extensions try to broadcast a transaction
+ // before we're actually connected the broadcast waits for an appropriate number of connections.
+ if (peerAddresses != null) {
+ for (PeerAddress addr : peerAddresses) vPeerGroup.addAddress(addr);
+ int maxConnections = Math.min(numConnectionsForBtc, peerAddresses.length);
+ log.info("We try to connect to {} btc nodes", maxConnections);
+ vPeerGroup.setMaxConnections(maxConnections);
+ vPeerGroup.setAddPeersFromAddressMessage(false);
+ peerAddresses = null;
+ } else if (!params.getId().equals(NetworkParameters.ID_REGTEST)) {
+ vPeerGroup.addPeerDiscovery(discovery != null ? discovery : new DnsDiscovery(params));
+ }
+ vChain.addWallet(vBtcWallet);
+ vPeerGroup.addWallet(vBtcWallet);
+ vChain.addWallet(vBsqWallet);
+ vPeerGroup.addWallet(vBsqWallet);
+ onSetupCompleted();
+
+ if (blockingStartup) {
+ vPeerGroup.start();
+ // Make sure we shut down cleanly.
+ installShutdownHook();
+ //completeExtensionInitiations(vPeerGroup);
+
+ // TODO: Be able to use the provided download listener when doing a blocking startup.
+ final DownloadProgressTracker listener = new DownloadProgressTracker();
+ vPeerGroup.startBlockChainDownload(listener);
+ listener.await();
+ } else {
+ Futures.addCallback((ListenableFuture>) vPeerGroup.startAsync(), new FutureCallback