Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve handling of removed assets #2306

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion core/src/main/java/bisq/core/locale/CurrencyUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,17 @@ public static List<CryptoCurrency> getMainCryptoCurrencies() {
return result;
}

public static List<CryptoCurrency> getRemovedCryptoCurrencies() {
final List<CryptoCurrency> currencies = new ArrayList<>();
currencies.add(new CryptoCurrency("BCH", "Bitcoin Cash"));
currencies.add(new CryptoCurrency("BCHC", "Bitcoin Clashic"));
currencies.add(new CryptoCurrency("ACH", "AchieveCoin"));
currencies.add(new CryptoCurrency("SC", "SpaceCash"));
currencies.add(new CryptoCurrency("PPI", "PiedPiper Coin"));
currencies.add(new CryptoCurrency("PEPECASH", "Pepe Cash"));
return currencies;
}

// At OKPay you can exchange internally those currencies
public static List<TradeCurrency> getAllAdvancedCashCurrencies() {
ArrayList<TradeCurrency> currencies = new ArrayList<>(Arrays.asList(
Expand Down Expand Up @@ -388,7 +399,12 @@ public static String getNameByCode(String currencyCode) {
if (isCryptoCurrency(currencyCode)) {
// We might not find the name in case we have a call for a removed asset.
// If BTC is the code (used in tests) we also want return Bitcoin as name.
String btcOrRemovedAsset = "BTC".equals(currencyCode) ? "Bitcoin" : Res.get("shared.na");
final Optional<CryptoCurrency> removedCryptoCurrency = getRemovedCryptoCurrencies().stream()
.filter(cryptoCurrency -> cryptoCurrency.getCode().equals(currencyCode))
.findAny();

String btcOrRemovedAsset = "BTC".equals(currencyCode) ? "Bitcoin" :
removedCryptoCurrency.isPresent() ? removedCryptoCurrency.get().getName() : Res.get("shared.na");
return getCryptoCurrency(currencyCode).map(TradeCurrency::getName).orElse(btcOrRemovedAsset);
}
try {
Expand Down
21 changes: 14 additions & 7 deletions core/src/test/java/bisq/core/locale/CurrencyUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@

import bisq.core.btc.BaseCurrencyNetwork;

import bisq.asset.Asset;
import bisq.asset.AssetRegistry;
import bisq.asset.Coin;
import bisq.asset.coins.Ether;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
Expand All @@ -34,18 +39,14 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;



import bisq.asset.Asset;
import bisq.asset.AssetRegistry;
import bisq.asset.Coin;
import bisq.asset.coins.Ether;

public class CurrencyUtilTest {

@Before
public void setup() {

Locale.setDefault(new Locale("en", "US"));
Res.setBaseCurrencyCode("BTC");
Res.setBaseCurrencyName("Bitcoin");
}

@Test
Expand Down Expand Up @@ -128,6 +129,12 @@ public void testFindAsset() {
assertEquals(Coin.Network.REGTEST, bsq.getNetwork());
}

@Test
public void testGetNameAndCodeOfRemovedAsset() {
assertEquals("Bitcoin Cash (BCH)", CurrencyUtil.getNameAndCode("BCH"));
assertEquals("N/A (XYZ)", CurrencyUtil.getNameAndCode("XYZ"));
}

class MockAssetRegistry extends AssetRegistry {
private List<Asset> registeredAssets = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,18 @@ public void applyOpenOffer(OpenOffer openOffer) {
allowAmountUpdate = false;
}

@Override
public boolean initWithData(OfferPayload.Direction direction, TradeCurrency tradeCurrency) {
try {
return super.initWithData(direction, tradeCurrency);
} catch (NullPointerException e) {
if (e.getMessage().contains("tradeCurrency")) {
throw new IllegalArgumentException("Offers of removed assets cannot be edited. You can only cancel it.", e);
}
return false;
}
}

@Override
protected PaymentAccount getPreselectedPaymentAccount() {
return paymentAccount;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package bisq.desktop.main.portfolio.editoffer;

import bisq.desktop.util.validation.SecurityDepositValidator;

import bisq.core.btc.model.AddressEntry;
import bisq.core.btc.wallet.BsqWalletService;
import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.locale.Country;
import bisq.core.locale.CryptoCurrency;
import bisq.core.locale.GlobalSettings;
import bisq.core.locale.Res;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OpenOffer;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.payment.CryptoCurrencyAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.provider.fee.FeeService;
import bisq.core.provider.price.MarketPrice;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.user.Preferences;
import bisq.core.user.User;
import bisq.core.util.BSFormatter;
import bisq.core.util.BsqFormatter;
import bisq.core.util.validation.InputValidator;

import org.bitcoinj.core.Coin;

import javafx.beans.property.SimpleIntegerProperty;

import javafx.collections.FXCollections;

import java.time.Instant;

import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;

import static bisq.desktop.maker.OfferMaker.btcBCHCOffer;
import static bisq.desktop.maker.PreferenceMakers.empty;
import static com.natpryce.makeiteasy.MakeItEasy.make;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(PowerMockRunner.class)
@PrepareForTest({BtcWalletService.class, AddressEntry.class, PriceFeedService.class, User.class,
FeeService.class, PaymentAccount.class, BsqWalletService.class,
SecurityDepositValidator.class, AccountAgeWitnessService.class, BsqFormatter.class, Preferences.class,
BsqWalletService.class})
@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"})
public class EditOfferDataModelTest {

private EditOfferDataModel model;
private User user;

@Rule
public final ExpectedException exception = ExpectedException.none();

@Before
public void setUp() {

final CryptoCurrency btc = new CryptoCurrency("BTC", "bitcoin");
GlobalSettings.setDefaultTradeCurrency(btc);
Res.setup();

final BSFormatter bsFormatter = new BSFormatter();

FeeService feeService = mock(FeeService.class);
AddressEntry addressEntry = mock(AddressEntry.class);
BtcWalletService btcWalletService = mock(BtcWalletService.class);
PriceFeedService priceFeedService = mock(PriceFeedService.class);
user = mock(User.class);
PaymentAccount paymentAccount = mock(PaymentAccount.class);
Preferences preferences = mock(Preferences.class);
BsqFormatter bsqFormatter = mock(BsqFormatter.class);
BsqWalletService bsqWalletService = mock(BsqWalletService.class);
SecurityDepositValidator securityDepositValidator = mock(SecurityDepositValidator.class);
AccountAgeWitnessService accountAgeWitnessService = mock(AccountAgeWitnessService.class);

when(btcWalletService.getOrCreateAddressEntry(anyString(), any())).thenReturn(addressEntry);
when(btcWalletService.getBalanceForAddress(any())).thenReturn(Coin.valueOf(1000L));
when(priceFeedService.updateCounterProperty()).thenReturn(new SimpleIntegerProperty());
when(priceFeedService.getMarketPrice(anyString())).thenReturn(new MarketPrice("USD", 12684.0450, Instant.now().getEpochSecond(), true));
when(feeService.getTxFee(anyInt())).thenReturn(Coin.valueOf(1000L));
when(user.findFirstPaymentAccountWithCurrency(any())).thenReturn(paymentAccount);
when(user.getPaymentAccountsAsObservable()).thenReturn(FXCollections.observableSet());
when(securityDepositValidator.validate(any())).thenReturn(new InputValidator.ValidationResult(false));
when(accountAgeWitnessService.getMyTradeLimit(any(), any())).thenReturn(100000000L);
when(preferences.getUserCountry()).thenReturn(new Country("US", "United States", null));
when(bsqFormatter.formatCoin(any())).thenReturn("0");
when(bsqWalletService.getAvailableBalance()).thenReturn(Coin.ZERO);

model = new EditOfferDataModel(null,
btcWalletService, bsqWalletService, empty, user,
null, null, priceFeedService, null,
accountAgeWitnessService, null, feeService,
null, bsFormatter, null);

}

@Test
public void testEditOfferOfRemovedAsset() {

final CryptoCurrencyAccount bitcoinClashicAccount = new CryptoCurrencyAccount();
bitcoinClashicAccount.setId("BCHC");

when(user.getPaymentAccount(anyString())).thenReturn(bitcoinClashicAccount);

model.applyOpenOffer(new OpenOffer(make(btcBCHCOffer), null));
assertNull(model.getPreselectedPaymentAccount());
}

@Test
public void testInitializeEditOfferWithRemovedAsset() {
exception.expect(IllegalArgumentException.class);
model.initWithData(OfferPayload.Direction.BUY, null);
}
}
2 changes: 2 additions & 0 deletions desktop/src/test/java/bisq/desktop/maker/OfferMaker.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.natpryce.makeiteasy.Property;

import static com.natpryce.makeiteasy.MakeItEasy.a;
import static com.natpryce.makeiteasy.MakeItEasy.with;

public class OfferMaker {

Expand Down Expand Up @@ -79,4 +80,5 @@ public class OfferMaker {
0));

public static final Maker<Offer> btcUsdOffer = a(Offer);
public static final Maker<Offer> btcBCHCOffer = a(Offer).but(with(counterCurrencyCode, "BCHC"));
}