diff --git a/core/src/main/java/bisq/core/account/sign/SignedWitnessService.java b/core/src/main/java/bisq/core/account/sign/SignedWitnessService.java index 6552ab1b05..d00df0fa2e 100644 --- a/core/src/main/java/bisq/core/account/sign/SignedWitnessService.java +++ b/core/src/main/java/bisq/core/account/sign/SignedWitnessService.java @@ -213,6 +213,12 @@ public class SignedWitnessService { log.info("Arbitrator signed witness {}", signedWitness.toString()); } + public void selfSignAccountAgeWitness(AccountAgeWitness accountAgeWitness) throws CryptoException { + log.info("Sign own accountAgeWitness {}", accountAgeWitness); + signAccountAgeWitness(MINIMUM_TRADE_AMOUNT_FOR_SIGNING, accountAgeWitness, + keyRing.getSignatureKeyPair().getPublic()); + } + // Any peer can sign with DSA key public void signAccountAgeWitness(Coin tradeAmount, AccountAgeWitness accountAgeWitness, diff --git a/core/src/main/java/bisq/core/account/witness/AccountAgeWitnessService.java b/core/src/main/java/bisq/core/account/witness/AccountAgeWitnessService.java index f56b27669c..118e4b3d4f 100644 --- a/core/src/main/java/bisq/core/account/witness/AccountAgeWitnessService.java +++ b/core/src/main/java/bisq/core/account/witness/AccountAgeWitnessService.java @@ -177,17 +177,23 @@ public class AccountAgeWitnessService { }); if (p2PService.isBootstrapped()) { - republishAllFiatAccounts(); + onBootStrapped(); } else { p2PService.addP2PServiceListener(new BootstrapListener() { @Override public void onUpdatedDataReceived() { - republishAllFiatAccounts(); + onBootStrapped(); } }); } } + private void onBootStrapped() { + republishAllFiatAccounts(); + signSameNameAccounts(); + } + + // At startup we re-publish the witness data of all fiat accounts to ensure we got our data well distributed. private void republishAllFiatAccounts() { if (user.getPaymentAccounts() != null) @@ -773,6 +779,30 @@ public class AccountAgeWitnessService { } } + public void signSameNameAccounts() { + // Collect accounts that have ownerId to sign unsigned accounts with the same ownderId + var signerAccounts = Objects.requireNonNull(user.getPaymentAccounts()).stream() + .filter(account -> account.getOwnerId() != null && + accountIsSigner(getMyWitness(account.getPaymentAccountPayload()))) + .collect(Collectors.toSet()); + var unsignedAccounts = user.getPaymentAccounts().stream() + .filter(account -> account.getOwnerId() != null && + !signedWitnessService.isSignedAccountAgeWitness( + getMyWitness(account.getPaymentAccountPayload()))) + .collect(Collectors.toSet()); + + signerAccounts.forEach(signer -> unsignedAccounts.forEach(unsigned -> { + if (signer.getOwnerId().equals(unsigned.getOwnerId())) { + try { + signedWitnessService.selfSignAccountAgeWitness( + getMyWitness(unsigned.getPaymentAccountPayload())); + } catch (CryptoException e) { + log.warn("Self signing failed, exception {}", e.toString()); + } + } + })); + } + /////////////////////////////////////////////////////////////////////////////////////////// // Debug logs /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/core/src/main/java/bisq/core/payment/PaymentAccount.java b/core/src/main/java/bisq/core/payment/PaymentAccount.java index d77c5a9f9e..f63ad2ca8f 100644 --- a/core/src/main/java/bisq/core/payment/PaymentAccount.java +++ b/core/src/main/java/bisq/core/payment/PaymentAccount.java @@ -169,4 +169,8 @@ public abstract class PaymentAccount implements PersistablePayload { public String getSaltAsHex() { return Utilities.bytesAsHexString(getSalt()); } + + public String getOwnerId() { + return paymentAccountPayload.getOwnerId(); + } } diff --git a/core/src/main/java/bisq/core/payment/payload/BankAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/BankAccountPayload.java index 1e7af8bb0e..4132b1934a 100644 --- a/core/src/main/java/bisq/core/payment/payload/BankAccountPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/BankAccountPayload.java @@ -179,4 +179,9 @@ public abstract class BankAccountPayload extends CountryBasedPaymentAccountPaylo return super.getAgeWitnessInputData(all.getBytes(StandardCharsets.UTF_8)); } + + @Override + public String getOwnerId() { + return holderName; + } } diff --git a/core/src/main/java/bisq/core/payment/payload/CashDepositAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/CashDepositAccountPayload.java index cde304caa6..10c39c0023 100644 --- a/core/src/main/java/bisq/core/payment/payload/CashDepositAccountPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/CashDepositAccountPayload.java @@ -224,4 +224,9 @@ public class CashDepositAccountPayload extends CountryBasedPaymentAccountPayload return super.getAgeWitnessInputData(all.getBytes(StandardCharsets.UTF_8)); } + + @Override + public String getOwnerId() { + return holderName; + } } diff --git a/core/src/main/java/bisq/core/payment/payload/ChaseQuickPayAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/ChaseQuickPayAccountPayload.java index 2a2b176b62..b8d93695e7 100644 --- a/core/src/main/java/bisq/core/payment/payload/ChaseQuickPayAccountPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/ChaseQuickPayAccountPayload.java @@ -106,4 +106,9 @@ public final class ChaseQuickPayAccountPayload extends PaymentAccountPayload { // slight changes in holder name (e.g. add or remove middle name) return super.getAgeWitnessInputData(email.getBytes(StandardCharsets.UTF_8)); } + + @Override + public String getOwnerId() { + return holderName; + } } diff --git a/core/src/main/java/bisq/core/payment/payload/ClearXchangeAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/ClearXchangeAccountPayload.java index 7b8a3be8c4..139da08889 100644 --- a/core/src/main/java/bisq/core/payment/payload/ClearXchangeAccountPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/ClearXchangeAccountPayload.java @@ -106,4 +106,9 @@ public final class ClearXchangeAccountPayload extends PaymentAccountPayload { // slight changes in holder name (e.g. add or remove middle name) return super.getAgeWitnessInputData(emailOrMobileNr.getBytes(StandardCharsets.UTF_8)); } + + @Override + public String getOwnerId() { + return holderName; + } } diff --git a/core/src/main/java/bisq/core/payment/payload/InteracETransferAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/InteracETransferAccountPayload.java index 1b50a18c47..f404766ad2 100644 --- a/core/src/main/java/bisq/core/payment/payload/InteracETransferAccountPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/InteracETransferAccountPayload.java @@ -120,4 +120,9 @@ public final class InteracETransferAccountPayload extends PaymentAccountPayload ArrayUtils.addAll(question.getBytes(StandardCharsets.UTF_8), answer.getBytes(StandardCharsets.UTF_8)))); } + + @Override + public String getOwnerId() { + return holderName; + } } diff --git a/core/src/main/java/bisq/core/payment/payload/PaymentAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/PaymentAccountPayload.java index 8a19818707..7fa67beb03 100644 --- a/core/src/main/java/bisq/core/payment/payload/PaymentAccountPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/PaymentAccountPayload.java @@ -135,4 +135,8 @@ public abstract class PaymentAccountPayload implements NetworkPayload, UsedForTr protected byte[] getAgeWitnessInputData(byte[] data) { return ArrayUtils.addAll(paymentMethodId.getBytes(StandardCharsets.UTF_8), data); } + + public String getOwnerId() { + return null; + } } diff --git a/core/src/main/java/bisq/core/payment/payload/PopmoneyAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/PopmoneyAccountPayload.java index 56096cc47f..be018ffb55 100644 --- a/core/src/main/java/bisq/core/payment/payload/PopmoneyAccountPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/PopmoneyAccountPayload.java @@ -103,4 +103,9 @@ public final class PopmoneyAccountPayload extends PaymentAccountPayload { public byte[] getAgeWitnessInputData() { return super.getAgeWitnessInputData(accountId.getBytes(StandardCharsets.UTF_8)); } + + @Override + public String getOwnerId() { + return holderName; + } } diff --git a/core/src/main/java/bisq/core/payment/payload/SepaAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/SepaAccountPayload.java index 30bb334d15..c10dacb843 100644 --- a/core/src/main/java/bisq/core/payment/payload/SepaAccountPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/SepaAccountPayload.java @@ -158,4 +158,8 @@ public final class SepaAccountPayload extends CountryBasedPaymentAccountPayload // slight changes in holder name (e.g. add or remove middle name) return super.getAgeWitnessInputData(ArrayUtils.addAll(iban.getBytes(StandardCharsets.UTF_8), bic.getBytes(StandardCharsets.UTF_8))); } + @Override + public String getOwnerId() { + return holderName; + } } diff --git a/core/src/main/java/bisq/core/payment/payload/SepaInstantAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/SepaInstantAccountPayload.java index f74028baaa..cb8b69cd6f 100644 --- a/core/src/main/java/bisq/core/payment/payload/SepaInstantAccountPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/SepaInstantAccountPayload.java @@ -153,4 +153,9 @@ public final class SepaInstantAccountPayload extends CountryBasedPaymentAccountP // slight changes in holder name (e.g. add or remove middle name) return super.getAgeWitnessInputData(ArrayUtils.addAll(iban.getBytes(StandardCharsets.UTF_8), bic.getBytes(StandardCharsets.UTF_8))); } + + @Override + public String getOwnerId() { + return holderName; + } } diff --git a/core/src/main/java/bisq/core/payment/payload/SwishAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/SwishAccountPayload.java index 646a556f6e..6c236ba130 100644 --- a/core/src/main/java/bisq/core/payment/payload/SwishAccountPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/SwishAccountPayload.java @@ -104,4 +104,9 @@ public final class SwishAccountPayload extends PaymentAccountPayload { // slight changes in holder name (e.g. add or remove middle name) return super.getAgeWitnessInputData(mobileNr.getBytes(StandardCharsets.UTF_8)); } + + @Override + public String getOwnerId() { + return holderName; + } } diff --git a/core/src/main/java/bisq/core/payment/payload/USPostalMoneyOrderAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/USPostalMoneyOrderAccountPayload.java index 3f6990e83e..e705e032dc 100644 --- a/core/src/main/java/bisq/core/payment/payload/USPostalMoneyOrderAccountPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/USPostalMoneyOrderAccountPayload.java @@ -107,4 +107,9 @@ public final class USPostalMoneyOrderAccountPayload extends PaymentAccountPayloa return super.getAgeWitnessInputData(ArrayUtils.addAll(holderName.getBytes(StandardCharsets.UTF_8), postalAddress.getBytes(StandardCharsets.UTF_8))); } + + @Override + public String getOwnerId() { + return holderName; + } } diff --git a/core/src/main/java/bisq/core/payment/payload/VenmoAccountPayload.java b/core/src/main/java/bisq/core/payment/payload/VenmoAccountPayload.java index 05861b92e1..230ccdd9a5 100644 --- a/core/src/main/java/bisq/core/payment/payload/VenmoAccountPayload.java +++ b/core/src/main/java/bisq/core/payment/payload/VenmoAccountPayload.java @@ -106,4 +106,9 @@ public final class VenmoAccountPayload extends PaymentAccountPayload { public byte[] getAgeWitnessInputData() { return super.getAgeWitnessInputData(venmoUserName.getBytes(StandardCharsets.UTF_8)); } + + @Override + public String getOwnerId() { + return holderName; + } } diff --git a/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsDataModel.java b/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsDataModel.java index ed281def8e..2cd3dc1ff3 100644 --- a/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsDataModel.java +++ b/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsDataModel.java @@ -130,6 +130,7 @@ class FiatAccountsDataModel extends ActivatableDataModel { user.addPaymentAccount(paymentAccount); accountAgeWitnessService.publishMyAccountAgeWitness(paymentAccount.getPaymentAccountPayload()); + accountAgeWitnessService.signSameNameAccounts(); } public boolean onDeleteAccount(PaymentAccount paymentAccount) {