From 5cdbaccc9164d57e32c561988e387bc147087c6d Mon Sep 17 00:00:00 2001 From: U65535F <132809543+U65535F@users.noreply.github.com> Date: Thu, 27 Feb 2025 12:36:05 +0530 Subject: [PATCH 1/9] address issue 1549 in a bad way --- .../haveno/core/payment/PaymentAccount.java | 13 ++-- .../payment/PaymentAccountTypeAdapter.java | 77 ++++++++++++------- 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/core/src/main/java/haveno/core/payment/PaymentAccount.java b/core/src/main/java/haveno/core/payment/PaymentAccount.java index 8dda8fdedd..04ebacbb8a 100644 --- a/core/src/main/java/haveno/core/payment/PaymentAccount.java +++ b/core/src/main/java/haveno/core/payment/PaymentAccount.java @@ -347,6 +347,11 @@ public abstract class PaymentAccount implements PersistablePayload { jsonMap.put("accountId", getId()); if (paymentAccountPayload != null) jsonMap.put("salt", getSaltAsHex()); return gsonBuilder.create().toJson(jsonMap); + + Gson gson = gsonBuilder + .registerTypeAdapter(PaymentAccount.class, new PaymentAccountTypeAdapter(this.getClass())) + .create(); + return gson.toJson(this); } /** @@ -380,7 +385,6 @@ public abstract class PaymentAccount implements PersistablePayload { @SuppressWarnings("unchecked") public PaymentAccountForm toForm() { - // convert to json map Map jsonMap = gsonBuilder.create().fromJson(toJson(), (Type) Object.class); @@ -388,12 +392,7 @@ public abstract class PaymentAccount implements PersistablePayload { PaymentAccountForm form = new PaymentAccountForm(PaymentAccountForm.FormId.valueOf(paymentMethod.getId())); for (PaymentAccountFormField.FieldId fieldId : getInputFieldIds()) { PaymentAccountFormField field = getEmptyFormField(fieldId); - Object value = jsonMap.get(HavenoUtils.toCamelCase(field.getId().toString())); - if (value instanceof List) { // TODO: list should already be serialized to comma delimited string in PaymentAccount.toJson() (PaymentAccountTypeAdapter?) - field.setValue(String.join(",", (List) value)); - } else { - field.setValue((String) value); - } + field.setValue((String) jsonMap.get(HavenoUtils.toCamelCase(field.getId().toString()))); form.getFields().add(field); } return form; diff --git a/core/src/main/java/haveno/core/payment/PaymentAccountTypeAdapter.java b/core/src/main/java/haveno/core/payment/PaymentAccountTypeAdapter.java index 0226fe4530..6ed108835e 100644 --- a/core/src/main/java/haveno/core/payment/PaymentAccountTypeAdapter.java +++ b/core/src/main/java/haveno/core/payment/PaymentAccountTypeAdapter.java @@ -40,6 +40,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Predicate; +import java.util.stream.Collectors; import static haveno.common.util.ReflectionUtils.getSetterMethodForFieldInClassHierarchy; import static haveno.common.util.ReflectionUtils.getVisibilityModifierAsString; @@ -102,6 +103,12 @@ class PaymentAccountTypeAdapter extends TypeAdapter { // We're not serializing a real payment account instance here. out.beginObject(); + // Write extra fields + out.name("accountName"); + out.value(account.getAccountName()); + out.name("accountId"); + out.value(account.getId()); + writeComments(out, account); out.name("paymentMethodId"); @@ -112,7 +119,8 @@ class PaymentAccountTypeAdapter extends TypeAdapter { // The last field in all json forms is the empty, editable salt field. out.name("salt"); - out.value(""); + out.value(account.getSaltAsHex()); + out.endObject(); } @@ -135,7 +143,11 @@ class PaymentAccountTypeAdapter extends TypeAdapter { } - private void writeInnerMutableFields(JsonWriter out, PaymentAccount account) { + private void writeInnerMutableFields(JsonWriter out, PaymentAccount account) throws IOException { + if (account instanceof CountryBasedPaymentAccount) { + writeAcceptedCountryCodesField(out, account); + } + if (account.hasMultipleCurrencies()) { writeTradeCurrenciesField(out, account); writeSelectedTradeCurrencyField(out, account); @@ -143,23 +155,21 @@ class PaymentAccountTypeAdapter extends TypeAdapter { fieldSettersMap.forEach((field, value) -> { try { - // Write out a json element if there is a @Setter for this field. if (value.isPresent()) { - log.debug("Append form with settable field: {} {} {} setter: {}", - getVisibilityModifierAsString(field), - field.getType().getSimpleName(), - field.getName(), - value); + log.debug("Appending form field: {} {} {} setter: {}", + getVisibilityModifierAsString(field), + field.getType().getSimpleName(), + field.getName(), + value); String fieldName = field.getName(); out.name(fieldName); - if (fieldName.equals("country")) out.value("your two letter country code"); - else out.value("your " + fieldName.toLowerCase()); + if (fieldName.equals("country")) + out.value("your two letter country code"); + else + out.value("your " + fieldName.toLowerCase()); } - } catch (Exception ex) { - String errMsg = format("cannot create a new %s json form", - account.getClass().getSimpleName()); - log.error(capitalize(errMsg) + ".", ex); - throw new IllegalStateException("programmer error: " + errMsg); + } catch (IOException ex) { + throw new RuntimeException("Error writing field " + field.getName(), ex); } }); } @@ -168,18 +178,16 @@ class PaymentAccountTypeAdapter extends TypeAdapter { // field in the json form, though the 'tradeCurrencies' field has no setter method in // the PaymentAccount class hierarchy. At of time of this change, TransferwiseAccount // is the only known exception to the rule. - private void writeTradeCurrenciesField(JsonWriter out, PaymentAccount account) { - try { - String fieldName = "tradeCurrencies"; - log.debug("Append form with non-settable field: {}", fieldName); - out.name(fieldName); - out.value("comma delimited currency code list, e.g., gbp,eur,jpy,usd"); - } catch (Exception ex) { - String errMsg = format("cannot create a new %s json form", - account.getClass().getSimpleName()); - log.error(capitalize(errMsg) + ".", ex); - throw new IllegalStateException("programmer error: " + errMsg); + private void writeTradeCurrenciesField(JsonWriter out, PaymentAccount account) throws IOException { + out.name("tradeCurrencies"); + List tradeCurrencies = account.getTradeCurrencies(); + String tradeCurrenciesValue = ""; + if (tradeCurrencies != null && !tradeCurrencies.isEmpty()) { + tradeCurrenciesValue = tradeCurrencies.stream() + .map(TradeCurrency::getCode) + .collect(Collectors.joining(",")); } + out.value(tradeCurrenciesValue); } // PaymentAccounts that support multiple 'tradeCurrencies' need to define a @@ -199,6 +207,23 @@ class PaymentAccountTypeAdapter extends TypeAdapter { } } + private void writeAcceptedCountryCodesField(JsonWriter out, PaymentAccount account) throws IOException { + out.name("acceptedCountryCodes"); + if (account instanceof CountryBasedPaymentAccount) { + List acceptedCountries = ((CountryBasedPaymentAccount) account).getAcceptedCountries(); + String countryCodesValue = ""; + if (acceptedCountries != null && !acceptedCountries.isEmpty()) { + countryCodesValue = acceptedCountries.stream() + .map(c -> c.code) // assuming 'code' is accessible or use getCode() + .collect(Collectors.joining(",")); + } + out.value(countryCodesValue); + } else { + out.value(""); + } + } + + @Override public PaymentAccount read(JsonReader in) throws IOException { PaymentAccount account = initNewPaymentAccount(); From 32a2848644797c9ac6fe50ffdca1fce16e944471 Mon Sep 17 00:00:00 2001 From: U65535F <132809543+U65535F@users.noreply.github.com> Date: Thu, 27 Feb 2025 13:17:19 +0530 Subject: [PATCH 2/9] fix unreachable code --- .../src/main/java/haveno/core/payment/PaymentAccount.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/core/src/main/java/haveno/core/payment/PaymentAccount.java b/core/src/main/java/haveno/core/payment/PaymentAccount.java index 04ebacbb8a..7a247bc913 100644 --- a/core/src/main/java/haveno/core/payment/PaymentAccount.java +++ b/core/src/main/java/haveno/core/payment/PaymentAccount.java @@ -304,6 +304,7 @@ public abstract class PaymentAccount implements PersistablePayload { // last moment we could apply some special handling if needed (e.g. as it happens for Revolut) } + public String getPreTradeMessage(boolean isBuyer) { if (isBuyer) { return getMessageForBuyer(); @@ -341,13 +342,6 @@ public abstract class PaymentAccount implements PersistablePayload { // ---------------------------- SERIALIZATION ----------------------------- public String toJson() { - Map jsonMap = new HashMap(); - if (paymentAccountPayload != null) jsonMap.putAll(gsonBuilder.create().fromJson(paymentAccountPayload.toJson(), (Type) Object.class)); - jsonMap.put("accountName", getAccountName()); - jsonMap.put("accountId", getId()); - if (paymentAccountPayload != null) jsonMap.put("salt", getSaltAsHex()); - return gsonBuilder.create().toJson(jsonMap); - Gson gson = gsonBuilder .registerTypeAdapter(PaymentAccount.class, new PaymentAccountTypeAdapter(this.getClass())) .create(); From 52100d2ca040c362505ff5f39b936d1ad6f3a116 Mon Sep 17 00:00:00 2001 From: U65535F <132809543+U65535F@users.noreply.github.com> Date: Thu, 27 Feb 2025 13:27:13 +0530 Subject: [PATCH 3/9] remove unused import - hashmap --- core/src/main/java/haveno/core/payment/PaymentAccount.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/haveno/core/payment/PaymentAccount.java b/core/src/main/java/haveno/core/payment/PaymentAccount.java index 7a247bc913..90d6fd87be 100644 --- a/core/src/main/java/haveno/core/payment/PaymentAccount.java +++ b/core/src/main/java/haveno/core/payment/PaymentAccount.java @@ -71,7 +71,7 @@ import javax.annotation.Nullable; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Date; -import java.util.HashMap; +// import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; From f6d0443ba3b199af4f8ce87dbf025f62fa953e8d Mon Sep 17 00:00:00 2001 From: U65535F <132809543+U65535F@users.noreply.github.com> Date: Thu, 27 Feb 2025 14:06:28 +0530 Subject: [PATCH 4/9] delete the commented unused import --- core/src/main/java/haveno/core/payment/PaymentAccount.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/haveno/core/payment/PaymentAccount.java b/core/src/main/java/haveno/core/payment/PaymentAccount.java index 90d6fd87be..bb38165814 100644 --- a/core/src/main/java/haveno/core/payment/PaymentAccount.java +++ b/core/src/main/java/haveno/core/payment/PaymentAccount.java @@ -71,7 +71,6 @@ import javax.annotation.Nullable; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Date; -// import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; From 903cda266892639f8b534975d7f3a6ac4de32cb9 Mon Sep 17 00:00:00 2001 From: U65535F <132809543+U65535F@users.noreply.github.com> Date: Thu, 27 Feb 2025 16:07:53 +0530 Subject: [PATCH 5/9] restore some unnecessary edits --- .../main/java/haveno/core/payment/PaymentAccount.java | 2 +- .../haveno/core/payment/PaymentAccountTypeAdapter.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/haveno/core/payment/PaymentAccount.java b/core/src/main/java/haveno/core/payment/PaymentAccount.java index bb38165814..45a3660a84 100644 --- a/core/src/main/java/haveno/core/payment/PaymentAccount.java +++ b/core/src/main/java/haveno/core/payment/PaymentAccount.java @@ -303,7 +303,6 @@ public abstract class PaymentAccount implements PersistablePayload { // last moment we could apply some special handling if needed (e.g. as it happens for Revolut) } - public String getPreTradeMessage(boolean isBuyer) { if (isBuyer) { return getMessageForBuyer(); @@ -378,6 +377,7 @@ public abstract class PaymentAccount implements PersistablePayload { @SuppressWarnings("unchecked") public PaymentAccountForm toForm() { + // convert to json map Map jsonMap = gsonBuilder.create().fromJson(toJson(), (Type) Object.class); diff --git a/core/src/main/java/haveno/core/payment/PaymentAccountTypeAdapter.java b/core/src/main/java/haveno/core/payment/PaymentAccountTypeAdapter.java index 6ed108835e..b4a1d8f279 100644 --- a/core/src/main/java/haveno/core/payment/PaymentAccountTypeAdapter.java +++ b/core/src/main/java/haveno/core/payment/PaymentAccountTypeAdapter.java @@ -156,11 +156,11 @@ class PaymentAccountTypeAdapter extends TypeAdapter { fieldSettersMap.forEach((field, value) -> { try { if (value.isPresent()) { - log.debug("Appending form field: {} {} {} setter: {}", - getVisibilityModifierAsString(field), - field.getType().getSimpleName(), - field.getName(), - value); + log.debug("Append form with settable field: {} {} {} setter: {}", + getVisibilityModifierAsString(field), + field.getType().getSimpleName(), + field.getName(), + value); String fieldName = field.getName(); out.name(fieldName); if (fieldName.equals("country")) From f386906c5dc68ba8c4658250cab126f3b3e8fe6e Mon Sep 17 00:00:00 2001 From: U65535F <132809543+U65535F@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:44:32 +0530 Subject: [PATCH 6/9] Create testnetsetup.xml --- .github/workflows/testnetsetup.xml | 47 ++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/workflows/testnetsetup.xml diff --git a/.github/workflows/testnetsetup.xml b/.github/workflows/testnetsetup.xml new file mode 100644 index 0000000000..67fa48e06a --- /dev/null +++ b/.github/workflows/testnetsetup.xml @@ -0,0 +1,47 @@ +name: testnet-setup + +on: + workflow_dispatch: + push: + pull_request: + paths-ignore: + - '**/README.md' + +jobs: + build: + runs-on: ubuntu-22.04 + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'adopt' + cache: gradle + + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install -y make wget git rpm libfuse2 flatpak flatpak-builder appstream + flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo + + - name: Build Haveno + run: | + make clean + make + + - name: Set Up Local Monero Testnet + run: | + make monerod1-local + make monerod2-local + start_mining 9tsUiG9bwcU7oTbAdBwBk2PzxFtysge5qcEsHEpetmEKgerHQa1fDqH7a4FiquZmms7yM22jdifVAD7jAb2e63GSJMuhY75 1 + + - name: Upload Test Artifacts + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-reports + path: path/to/test-reports From 766d0de12089eab13727e7b743f505fadf3c443b Mon Sep 17 00:00:00 2001 From: U65535F <132809543+U65535F@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:45:29 +0530 Subject: [PATCH 7/9] Rename xml to yml --- .github/workflows/{testnetsetup.xml => testnetsetup.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{testnetsetup.xml => testnetsetup.yml} (100%) diff --git a/.github/workflows/testnetsetup.xml b/.github/workflows/testnetsetup.yml similarity index 100% rename from .github/workflows/testnetsetup.xml rename to .github/workflows/testnetsetup.yml From 1c13d36d34b3ccf3303e35123829f529336d04ae Mon Sep 17 00:00:00 2001 From: U65535F <132809543+U65535F@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:53:56 +0530 Subject: [PATCH 8/9] Delete .github/workflows/testnetsetup.yml --- .github/workflows/testnetsetup.yml | 47 ------------------------------ 1 file changed, 47 deletions(-) delete mode 100644 .github/workflows/testnetsetup.yml diff --git a/.github/workflows/testnetsetup.yml b/.github/workflows/testnetsetup.yml deleted file mode 100644 index 67fa48e06a..0000000000 --- a/.github/workflows/testnetsetup.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: testnet-setup - -on: - workflow_dispatch: - push: - pull_request: - paths-ignore: - - '**/README.md' - -jobs: - build: - runs-on: ubuntu-22.04 - - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Set up JDK 21 - uses: actions/setup-java@v4 - with: - java-version: '21' - distribution: 'adopt' - cache: gradle - - - name: Install Dependencies - run: | - sudo apt-get update - sudo apt-get install -y make wget git rpm libfuse2 flatpak flatpak-builder appstream - flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo - - - name: Build Haveno - run: | - make clean - make - - - name: Set Up Local Monero Testnet - run: | - make monerod1-local - make monerod2-local - start_mining 9tsUiG9bwcU7oTbAdBwBk2PzxFtysge5qcEsHEpetmEKgerHQa1fDqH7a4FiquZmms7yM22jdifVAD7jAb2e63GSJMuhY75 1 - - - name: Upload Test Artifacts - if: failure() - uses: actions/upload-artifact@v4 - with: - name: test-reports - path: path/to/test-reports From e290fd20fcd3e5ce4efc7b7b66fa192f6c9e9db3 Mon Sep 17 00:00:00 2001 From: U65535F <132809543+U65535F@users.noreply.github.com> Date: Thu, 27 Feb 2025 20:52:25 +0530 Subject: [PATCH 9/9] Remove one more unnecessary edit --- core/src/main/java/haveno/core/payment/PaymentAccount.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/haveno/core/payment/PaymentAccount.java b/core/src/main/java/haveno/core/payment/PaymentAccount.java index 45a3660a84..b692b51faf 100644 --- a/core/src/main/java/haveno/core/payment/PaymentAccount.java +++ b/core/src/main/java/haveno/core/payment/PaymentAccount.java @@ -377,7 +377,7 @@ public abstract class PaymentAccount implements PersistablePayload { @SuppressWarnings("unchecked") public PaymentAccountForm toForm() { - + // convert to json map Map jsonMap = gsonBuilder.create().fromJson(toJson(), (Type) Object.class);