Merge branch 'master' into add-live-trading

This commit is contained in:
Manfred Karrer 2019-03-04 11:09:24 -05:00
commit 9e7a619ba4
No known key found for this signature in database
GPG Key ID: 401250966A6B2C46
26 changed files with 851 additions and 42 deletions

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
package bisq.asset.coins;
import bisq.asset.AltCoinAccountDisclaimer;
import bisq.asset.Coin;
import bisq.asset.CryptoNoteAddressValidator;
@AltCoinAccountDisclaimer("account.altcoin.popup.arq.msg")
public class Arqma extends Coin {
public Arqma() {
super("Arqma", "ARQ", new CryptoNoteAddressValidator(0x2cca, 0x6847));
}
}

View File

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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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;
acceptableAddressCodes = new int[]{addressHeader};
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
package bisq.asset.coins;
import bisq.asset.Coin;
public class XDR extends Coin {
public XDR() {
super("XDR", "XDR", new Mile.MileAddressValidator());
}
}

View File

@ -5,6 +5,7 @@
bisq.asset.coins.Actinium
bisq.asset.coins.Adeptio
bisq.asset.coins.Aeon
bisq.asset.coins.Arqma
bisq.asset.coins.Askcoin
bisq.asset.coins.Australiacash
bisq.asset.coins.Beam
@ -32,11 +33,14 @@ 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.Grin
bisq.asset.coins.Hatch
@ -46,10 +50,12 @@ 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
@ -60,6 +66,7 @@ bisq.asset.coins.Noir
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
@ -77,6 +84,7 @@ bisq.asset.coins.UnitedCommunityCoin
bisq.asset.coins.Unobtanium
bisq.asset.coins.Webchain
bisq.asset.coins.WrkzCoin
bisq.asset.coins.XDR
bisq.asset.coins.Zcash
bisq.asset.coins.Zcoin
bisq.asset.coins.ZelCash

View File

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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
package bisq.asset.coins;
import bisq.asset.AbstractAssetTest;
import org.junit.Test;
public class DSTRATest extends AbstractAssetTest {
public DSTRATest() {
super(new DSTRA());
}
@Test
public void testValidAddresses() {
assertValidAddress("DGiwGS8n3tJZuKxUdWF6MyTYvv6xgDcyd7");
assertValidAddress("DQcAKx5bFoeRwAEHE4EHQykyq8u2M1pwFa");
}
@Test
public void testInvalidAddresses() {
assertInvalidAddress("DGiwGS8n3tJZuKxUdWF6MyTYvv6xgDcyd77");
assertInvalidAddress("DGiwGS8n3tJZuKxUdWF6MyTYvv6xgDcyd");
assertInvalidAddress("dGiwGS8n3tJZuKxUdWF6MyTYvv6xgDcyd7");
assertInvalidAddress("FGiwGS8n3tJZuKxUdWF6MyTYvv6xgDcyd7");
assertInvalidAddress("fGiwGS8n3tJZuKxUdWF6MyTYvv6xgDcyd7");
}
}

View File

@ -0,0 +1,41 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package 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");
}
@Test
public void testInvalidAddresses() {
assertInvalidAddress("NGHV9LstnZfrkGx5QJmYhEepbzc66W7LN5x");
assertInvalidAddress("16iWWt1uoG8Dct56Cq6eKHFxvGSDha46Lo");
assertInvalidAddress("38BFQkc9CdyJUxQK8PhebnDcA1tRRwLDW4");
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,6 +25,7 @@ import bisq.core.exceptions.BisqException;
import bisq.core.filter.FilterManager;
import bisq.network.NetworkOptionKeys;
import bisq.network.p2p.network.ConnectionConfig;
import bisq.common.CommonOptionKeys;
import bisq.common.app.Version;
@ -193,7 +194,8 @@ public class BisqEnvironment extends StandardEnvironment {
rpcPort, rpcBlockNotificationPort, dumpBlockchainData, fullDaoNode,
myAddress, banList, dumpStatistics, maxMemory, socks5ProxyBtcAddress,
torRcFile, torRcOptions, externalTorControlPort, externalTorPassword, externalTorCookieFile,
socks5ProxyHttpAddress, useAllProvidedNodes, numConnectionForBtc, genesisTxId, genesisBlockHeight, referralId, daoActivated;
socks5ProxyHttpAddress, useAllProvidedNodes, numConnectionForBtc, genesisTxId, genesisBlockHeight,
referralId, daoActivated, msgThrottlePerSec, msgThrottlePer10Sec, sendMsgThrottleTrigger, sendMsgThrottleSleep;
protected final boolean externalTorUseSafeCookieAuthentication, torStreamIsolation;
@ -283,12 +285,20 @@ public class BisqEnvironment extends StandardEnvironment {
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) ?
@ -467,6 +477,11 @@ public class BisqEnvironment extends StandardEnvironment {
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);

View File

@ -33,6 +33,7 @@ import bisq.core.trade.TradeManager;
import bisq.network.NetworkOptionKeys;
import bisq.network.p2p.P2PService;
import bisq.network.p2p.network.ConnectionConfig;
import bisq.common.CommonOptionKeys;
import bisq.common.UserThread;
@ -416,6 +417,27 @@ public abstract class BisqExecutable implements GracefulShutDownHandler, BisqSet
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))

View File

@ -356,7 +356,7 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
@Override
public long getTTL() {
return TimeUnit.MINUTES.toMillis(7);
return TimeUnit.MINUTES.toMillis(9);
}
@Override

View File

@ -90,8 +90,8 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
private static final long RETRY_REPUBLISH_DELAY_SEC = 10;
private static final long REPUBLISH_AGAIN_AT_STARTUP_DELAY_SEC = 30;
private static final long REPUBLISH_INTERVAL_MS = TimeUnit.MINUTES.toMillis(30);
private static final long REFRESH_INTERVAL_MS = TimeUnit.MINUTES.toMillis(5);
private static final long REPUBLISH_INTERVAL_MS = TimeUnit.MINUTES.toMillis(40);
private static final long REFRESH_INTERVAL_MS = TimeUnit.MINUTES.toMillis(6);
private final KeyRing keyRing;
private final User user;

View File

@ -1018,6 +1018,24 @@ described on the {1} web page.\nUsing wallets from centralized exchanges where (
(b) which don''t use compatible wallet software is risky: it can lead to loss of the traded funds!\nThe arbitrator is \
not a {2} specialist and cannot help in such cases.
account.altcoin.popup.wallet.confirm=I understand and confirm that I know which wallet I need to use.
account.altcoin.popup.arq.msg=Trading ARQ on Bisq requires that you understand and fulfill \
the following requirements:\n\n\
For sending ARQ, you need to use either the official ArQmA GUI wallet or ArQmA CLI wallet with the \
store-tx-info flag enabled (default in new versions). Please be sure you can access the tx key as \
that would be required in case of a dispute.\n\
arqma-wallet-cli (use the command get_tx_key)\n\
arqma-wallet-gui (go to history tab and click on the (P) button for payment proof)\n\n\
At normal block explorers the transfer is not verifiable.\n\n\
You need to provide the arbitrator the following data in case of a dispute:\n\
- The tx private key\n\
- The transaction hash\n\
- The recipient's public address\n\n\
Failure to provide the above data, or if you used an incompatible wallet, will result in losing the \
dispute case. The ARQ sender is responsible for providing verification of the ARQ transfer to the \
arbitrator in case of a dispute.\n\n\
There is no payment ID required, just the normal public address.\n\
If you are not sure about that process visit ArQmA discord channel (https://discord.gg/s9BQpJT) \
or the ArQmA forum (https://labs.arqma.com) to find more information.
account.altcoin.popup.xmr.msg=Trading XMR on Bisq requires that you understand and fulfill \
the following requirements:\n\n\
For sending XMR, you need to use either the official Monero GUI wallet or Monero CLI wallet with the \

View File

@ -36,4 +36,8 @@ public class NetworkOptionKeys {
public static final String EXTERNAL_TOR_COOKIE_FILE = "torControlCookieFile";
public static final String EXTERNAL_TOR_USE_SAFECOOKIE = "torControlUseSafeCookieAuth";
public static final String TOR_STREAM_ISOLATION = "torStreamIsolation";
public static final String MSG_THROTTLE_PER_SEC = "msgThrottlePerSec";
public static final String MSG_THROTTLE_PER_10_SEC = "msgThrottlePer10Sec";
public static final String SEND_MSG_THROTTLE_TRIGGER = "sendMsgThrottleTrigger";
public static final String SEND_MSG_THROTTLE_SLEEP = "sendMsgThrottleSleep";
}

View File

@ -19,6 +19,8 @@ package bisq.network.p2p;
import bisq.network.NetworkOptionKeys;
import bisq.network.Socks5ProxyProvider;
import bisq.network.p2p.network.Connection;
import bisq.network.p2p.network.ConnectionConfig;
import bisq.network.p2p.network.NetworkNode;
import bisq.network.p2p.peers.BanList;
import bisq.network.p2p.peers.Broadcaster;
@ -64,10 +66,12 @@ public class P2PModule extends AppModule {
bind(KeepAliveManager.class).in(Singleton.class);
bind(Broadcaster.class).in(Singleton.class);
bind(BanList.class).in(Singleton.class);
bind(ConnectionConfig.class).in(Singleton.class);
bind(NetworkNode.class).toProvider(NetworkNodeProvider.class).in(Singleton.class);
bind(Socks5ProxyProvider.class).in(Singleton.class);
requestStaticInjection(Connection.class);
Boolean useLocalhostForP2P = environment.getProperty(NetworkOptionKeys.USE_LOCALHOST_FOR_P2P, boolean.class, false);
bind(boolean.class).annotatedWith(Names.named(NetworkOptionKeys.USE_LOCALHOST_FOR_P2P)).toInstance(useLocalhostForP2P);
@ -93,7 +97,11 @@ public class P2PModule extends AppModule {
bindConstant().annotatedWith(named(NetworkOptionKeys.EXTERNAL_TOR_CONTROL_PORT)).to(environment.getRequiredProperty(NetworkOptionKeys.EXTERNAL_TOR_CONTROL_PORT));
bindConstant().annotatedWith(named(NetworkOptionKeys.EXTERNAL_TOR_PASSWORD)).to(environment.getRequiredProperty(NetworkOptionKeys.EXTERNAL_TOR_PASSWORD));
bindConstant().annotatedWith(named(NetworkOptionKeys.EXTERNAL_TOR_COOKIE_FILE)).to(environment.getRequiredProperty(NetworkOptionKeys.EXTERNAL_TOR_COOKIE_FILE));
bindConstant().annotatedWith(named(NetworkOptionKeys.EXTERNAL_TOR_USE_SAFECOOKIE)).to(environment.containsProperty(NetworkOptionKeys.EXTERNAL_TOR_USE_SAFECOOKIE) ? true : false);
bindConstant().annotatedWith(named(NetworkOptionKeys.TOR_STREAM_ISOLATION)).to(environment.containsProperty(NetworkOptionKeys.TOR_STREAM_ISOLATION) ? true : false);
bindConstant().annotatedWith(named(NetworkOptionKeys.EXTERNAL_TOR_USE_SAFECOOKIE)).to(environment.containsProperty(NetworkOptionKeys.EXTERNAL_TOR_USE_SAFECOOKIE));
bindConstant().annotatedWith(named(NetworkOptionKeys.TOR_STREAM_ISOLATION)).to(environment.containsProperty(NetworkOptionKeys.TOR_STREAM_ISOLATION));
bindConstant().annotatedWith(named(NetworkOptionKeys.MSG_THROTTLE_PER_SEC)).to(environment.getRequiredProperty(NetworkOptionKeys.MSG_THROTTLE_PER_SEC));
bindConstant().annotatedWith(named(NetworkOptionKeys.MSG_THROTTLE_PER_10_SEC)).to(environment.getRequiredProperty(NetworkOptionKeys.MSG_THROTTLE_PER_10_SEC));
bindConstant().annotatedWith(named(NetworkOptionKeys.SEND_MSG_THROTTLE_TRIGGER)).to(environment.getRequiredProperty(NetworkOptionKeys.SEND_MSG_THROTTLE_TRIGGER));
bindConstant().annotatedWith(named(NetworkOptionKeys.SEND_MSG_THROTTLE_SLEEP)).to(environment.getRequiredProperty(NetworkOptionKeys.SEND_MSG_THROTTLE_SLEEP));
}
}

View File

@ -48,6 +48,8 @@ import bisq.common.util.Utilities;
import io.bisq.generated.protobuffer.PB;
import javax.inject.Inject;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.Uninterruptibles;
@ -113,18 +115,20 @@ public class Connection implements MessageListener {
// Static
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private static ConnectionConfig connectionConfig;
// Leaving some constants package-private for tests to know limits.
static final int PERMITTED_MESSAGE_SIZE = 200 * 1024; // 200 kb
static final int MAX_PERMITTED_MESSAGE_SIZE = 10 * 1024 * 1024; // 10 MB (425 offers resulted in about 660 kb, mailbox msg will add more to it) offer has usually 2 kb, mailbox 3kb.
//TODO decrease limits again after testing
static final int MSG_THROTTLE_PER_SEC = 200; // With MAX_MSG_SIZE of 200kb results in bandwidth of 40MB/sec or 5 mbit/sec
static final int MSG_THROTTLE_PER_10_SEC = 1000; // With MAX_MSG_SIZE of 200kb results in bandwidth of 20MB/sec or 2.5 mbit/sec
private static final int SOCKET_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(120);
public static int getPermittedMessageSize() {
return PERMITTED_MESSAGE_SIZE;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Class fields
///////////////////////////////////////////////////////////////////////////////////////////
@ -138,6 +142,10 @@ public class Connection implements MessageListener {
// holder of state shared between InputHandler and Connection
private final SharedModel sharedModel;
private final Statistic statistic;
private final int msgThrottlePer10Sec;
private final int msgThrottlePerSec;
private final int sendMsgThrottleTrigger;
private final int sendMsgThrottleSleep;
// set in init
private InputHandler inputHandler;
@ -148,7 +156,7 @@ public class Connection implements MessageListener {
private volatile boolean stopped;
private PeerType peerType;
private final ObjectProperty<NodeAddress> peersNodeAddressProperty = new SimpleObjectProperty<>();
private final List<Tuple2<Long, NetworkEnvelope>> messageTimeStamps = new ArrayList<>();
private final List<Tuple2<Long, String>> messageTimeStamps = new ArrayList<>();
private final CopyOnWriteArraySet<MessageListener> messageListeners = new CopyOnWriteArraySet<>();
private volatile long lastSendTimeStamp = 0;
private final CopyOnWriteArraySet<WeakReference<SupportedCapabilitiesListener>> capabilitiesListeners = new CopyOnWriteArraySet<>();
@ -158,13 +166,21 @@ public class Connection implements MessageListener {
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
Connection(Socket socket, MessageListener messageListener, ConnectionListener connectionListener,
@Nullable NodeAddress peersNodeAddress, NetworkProtoResolver networkProtoResolver) {
Connection(Socket socket,
MessageListener messageListener,
ConnectionListener connectionListener,
@Nullable NodeAddress peersNodeAddress,
NetworkProtoResolver networkProtoResolver) {
this.socket = socket;
this.connectionListener = connectionListener;
uid = UUID.randomUUID().toString();
statistic = new Statistic();
msgThrottlePerSec = connectionConfig.getMsgThrottlePerSec();
msgThrottlePer10Sec = connectionConfig.getMsgThrottlePer10Sec();
sendMsgThrottleTrigger = connectionConfig.getSendMsgThrottleTrigger();
sendMsgThrottleSleep = connectionConfig.getSendMsgThrottleSleep();
addMessageListener(messageListener);
sharedModel = new SharedModel(this, socket);
@ -200,7 +216,6 @@ public class Connection implements MessageListener {
log.trace("New connection created: " + this.toString());
UserThread.execute(() -> connectionListener.onConnection(this));
} catch (Throwable e) {
handleException(e);
}
@ -228,15 +243,16 @@ public class Connection implements MessageListener {
// Throttle outbound network_messages
long now = System.currentTimeMillis();
long elapsed = now - lastSendTimeStamp;
if (elapsed < 20) {
log.debug("We got 2 sendMessage requests in less than 20 ms. We set the thread to sleep " +
"for 50 ms to avoid flooding our peer. lastSendTimeStamp={}, now={}, elapsed={}",
lastSendTimeStamp, now, elapsed);
Thread.sleep(50);
if (elapsed < sendMsgThrottleTrigger) {
log.warn("We got 2 sendMessage requests in less than {} ms. We set the thread to sleep " +
"for {} ms to avoid flooding our peer. lastSendTimeStamp={}, now={}, elapsed={}, networkEnvelope={}",
sendMsgThrottleTrigger, sendMsgThrottleSleep, lastSendTimeStamp, now, elapsed,
networkEnvelope.getClass().getSimpleName());
Thread.sleep(sendMsgThrottleSleep);
}
lastSendTimeStamp = now;
String peersNodeAddress = peersNodeAddressOptional.isPresent() ? peersNodeAddressOptional.get().toString() : "null";
String peersNodeAddress = peersNodeAddressOptional.map(NodeAddress::toString).orElse("null");
PB.NetworkEnvelope proto = networkEnvelope.toProtoNetworkEnvelope();
log.debug("Sending message: {}", Utilities.toTruncatedString(proto.toString(), 10000));
@ -349,24 +365,24 @@ public class Connection implements MessageListener {
long now = System.currentTimeMillis();
boolean violated = false;
//TODO remove message storage after network is tested stable
if (messageTimeStamps.size() >= MSG_THROTTLE_PER_SEC) {
if (messageTimeStamps.size() >= msgThrottlePerSec) {
// check if we got more than 200 (MSG_THROTTLE_PER_SEC) msg per sec.
long compareValue = messageTimeStamps.get(messageTimeStamps.size() - MSG_THROTTLE_PER_SEC).first;
long compareValue = messageTimeStamps.get(messageTimeStamps.size() - msgThrottlePerSec).first;
// if duration < 1 sec we received too much network_messages
violated = now - compareValue < TimeUnit.SECONDS.toMillis(1);
if (violated) {
log.error("violatesThrottleLimit MSG_THROTTLE_PER_SEC ");
log.error("elapsed " + (now - compareValue));
log.error("messageTimeStamps: \n\t" + messageTimeStamps.stream()
.map(e -> "\n\tts=" + e.first.toString() + " message=" + e.second.getClass().getName())
.map(e -> "\n\tts=" + e.first.toString() + " message=" + e.second)
.collect(Collectors.toList()).toString());
}
}
if (messageTimeStamps.size() >= MSG_THROTTLE_PER_10_SEC) {
if (messageTimeStamps.size() >= msgThrottlePer10Sec) {
if (!violated) {
// check if we got more than 50 msg per 10 sec.
long compareValue = messageTimeStamps.get(messageTimeStamps.size() - MSG_THROTTLE_PER_10_SEC).first;
long compareValue = messageTimeStamps.get(messageTimeStamps.size() - msgThrottlePer10Sec).first;
// if duration < 10 sec we received too much network_messages
violated = now - compareValue < TimeUnit.SECONDS.toMillis(10);
@ -374,16 +390,16 @@ public class Connection implements MessageListener {
log.error("violatesThrottleLimit MSG_THROTTLE_PER_10_SEC ");
log.error("elapsed " + (now - compareValue));
log.error("messageTimeStamps: \n\t" + messageTimeStamps.stream()
.map(e -> "\n\tts=" + e.first.toString() + " message=" + e.second.getClass().getName())
.map(e -> "\n\tts=" + e.first.toString() + " message=" + e.second)
.collect(Collectors.toList()).toString());
}
}
}
// we limit to max 1000 (MSG_THROTTLE_PER_10SEC) entries
while(messageTimeStamps.size() > MSG_THROTTLE_PER_10_SEC)
while (messageTimeStamps.size() > msgThrottlePer10Sec)
messageTimeStamps.remove(0);
messageTimeStamps.add(new Tuple2<>(now, networkEnvelope));
messageTimeStamps.add(new Tuple2<>(now, networkEnvelope.getClass().getName()));
return violated;
}
@ -395,7 +411,7 @@ public class Connection implements MessageListener {
@Override
public void onMessage(NetworkEnvelope networkEnvelope, Connection connection) {
checkArgument(connection.equals(this));
UserThread.execute(() -> messageListeners.stream().forEach(e -> e.onMessage(networkEnvelope, connection)));
UserThread.execute(() -> messageListeners.forEach(e -> e.onMessage(networkEnvelope, connection)));
}
@ -478,7 +494,7 @@ public class Connection implements MessageListener {
public void shutDown(CloseConnectionReason closeConnectionReason, @Nullable Runnable shutDownCompleteHandler) {
log.debug("shutDown: nodeAddressOpt={}, closeConnectionReason={}", this.peersNodeAddressOptional, closeConnectionReason);
if (!stopped) {
String peersNodeAddress = peersNodeAddressOptional.isPresent() ? peersNodeAddressOptional.get().toString() : "null";
String peersNodeAddress = peersNodeAddressOptional.map(NodeAddress::toString).orElse("null");
log.debug("\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" +
"ShutDown connection:"
+ "\npeersNodeAddress=" + peersNodeAddress
@ -606,7 +622,7 @@ public class Connection implements MessageListener {
private List<Integer> supportedCapabilities;
public SharedModel(Connection connection, Socket socket) {
SharedModel(Connection connection, Socket socket) {
this.connection = connection;
this.socket = socket;
}
@ -704,7 +720,7 @@ public class Connection implements MessageListener {
stopped = true;
}
public RuleViolation getRuleViolation() {
RuleViolation getRuleViolation() {
return ruleViolation;
}
@ -743,11 +759,11 @@ public class Connection implements MessageListener {
private long lastReadTimeStamp;
private boolean threadNameSet;
public InputHandler(SharedModel sharedModel,
InputStream protoInputStream,
String portInfo,
MessageListener messageListener,
NetworkProtoResolver networkProtoResolver) {
InputHandler(SharedModel sharedModel,
InputStream protoInputStream,
String portInfo,
MessageListener messageListener,
NetworkProtoResolver networkProtoResolver) {
this.sharedModel = sharedModel;
this.protoInputStream = protoInputStream;
this.portInfo = portInfo;

View File

@ -0,0 +1,68 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.network.p2p.network;
import bisq.network.NetworkOptionKeys;
import com.google.inject.name.Named;
import javax.inject.Inject;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ConnectionConfig {
public static final int MSG_THROTTLE_PER_SEC = 200; // With MAX_MSG_SIZE of 200kb results in bandwidth of 40MB/sec or 5 mbit/sec
public static final int MSG_THROTTLE_PER_10_SEC = 1000; // With MAX_MSG_SIZE of 200kb results in bandwidth of 20MB/sec or 2.5 mbit/sec
public static final int SEND_MSG_THROTTLE_TRIGGER = 20; // Time in ms when we trigger a sleep if 2 messages are sent
public static final int SEND_MSG_THROTTLE_SLEEP = 50; // Pause in ms to sleep if we get too many messages to send
@Getter
private int msgThrottlePerSec;
@Getter
private int msgThrottlePer10Sec;
@Getter
private int sendMsgThrottleTrigger;
@Getter
private int sendMsgThrottleSleep;
@Inject
public ConnectionConfig(@Named(NetworkOptionKeys.MSG_THROTTLE_PER_SEC) int msgThrottlePerSec,
@Named(NetworkOptionKeys.MSG_THROTTLE_PER_10_SEC) int msgThrottlePer10Sec,
@Named(NetworkOptionKeys.SEND_MSG_THROTTLE_TRIGGER) int sendMsgThrottleTrigger,
@Named(NetworkOptionKeys.SEND_MSG_THROTTLE_SLEEP) int sendMsgThrottleSleep) {
this.msgThrottlePerSec = msgThrottlePerSec;
this.msgThrottlePer10Sec = msgThrottlePer10Sec;
this.sendMsgThrottleTrigger = sendMsgThrottleTrigger;
this.sendMsgThrottleSleep = sendMsgThrottleSleep;
log.info(this.toString());
}
@Override
public String toString() {
return "ConnectionConfig{" +
"\n msgThrottlePerSec=" + msgThrottlePerSec +
",\n msgThrottlePer10Sec=" + msgThrottlePer10Sec +
",\n sendMsgThrottleTrigger=" + sendMsgThrottleTrigger +
",\n sendMsgThrottleSleep=" + sendMsgThrottleSleep +
"\n}";
}
}