Prevent taking of offers with unequal bank account types

Use stricter criteria when deciding which of the taker's accounts (if
any) are valid for a given offer. Specifically, prevent National Bank
accounts from being used to take Same / Specific Bank(s) offers, so the
three payment method types can never being mixed.

This prevents an error on the trading peer when the trade starts, due to
enforcement of equal maker & taker payment method IDs (except for SEPA)
in the Contract payload constructor.

This partially addresses #3602, where the erroneous peer response causes
the taker to be presented with a confusing timeout.
This commit is contained in:
Steven Barclay 2019-11-24 03:34:47 +00:00
parent e5afb17269
commit fc7d31ef83
No known key found for this signature in database
GPG key ID: 9FED6BF1176D500B
2 changed files with 57 additions and 1 deletions

View file

@ -66,10 +66,15 @@ class ReceiptValidator {
return true;
}
// Aside from Sepa or Sepa Instant, payment methods need to match
if (!isEqualPaymentMethods) {
return false;
}
if (predicates.isOfferRequireSameOrSpecificBank(offer, account)) {
return predicates.isMatchingBankId(offer, account);
}
return isEqualPaymentMethods;
return true;
}
}

View file

@ -174,6 +174,57 @@ public class ReceiptValidatorTest {
assertTrue(new ReceiptValidator(offer, account, predicates).isValid());
}
@Test
// Same or Specific Bank offers can't be taken by National Bank accounts. TODO: Consider partially relaxing to allow Specific Banks.
public void testIsValidWhenNationalBankAccountAndOfferIsNot() {
account = mock(NationalBankAccount.class);
when(predicates.isMatchingCurrency(offer, account)).thenReturn(true);
when(predicates.isEqualPaymentMethods(offer, account)).thenReturn(false);
when(predicates.isMatchingCountryCodes(offer, account)).thenReturn(true);
when(predicates.isMatchingSepaOffer(offer, account)).thenReturn(false);
when(predicates.isMatchingSepaInstant(offer, account)).thenReturn(false);
assertFalse(new ReceiptValidator(offer, account, predicates).isValid());
verify(predicates, never()).isOfferRequireSameOrSpecificBank(offer, account);
verify(predicates, never()).isMatchingBankId(offer, account);
}
@Test
// National or Same Bank offers can't be taken by Specific Banks accounts. TODO: Consider partially relaxing to allow National Bank.
public void testIsValidWhenSpecificBanksAccountAndOfferIsNot() {
account = mock(SpecificBanksAccount.class);
when(predicates.isMatchingCurrency(offer, account)).thenReturn(true);
when(predicates.isEqualPaymentMethods(offer, account)).thenReturn(false);
when(predicates.isMatchingCountryCodes(offer, account)).thenReturn(true);
when(predicates.isMatchingSepaOffer(offer, account)).thenReturn(false);
when(predicates.isMatchingSepaInstant(offer, account)).thenReturn(false);
assertFalse(new ReceiptValidator(offer, account, predicates).isValid());
verify(predicates, never()).isOfferRequireSameOrSpecificBank(offer, account);
verify(predicates, never()).isMatchingBankId(offer, account);
}
@Test
// National or Specific Bank offers can't be taken by Same Bank accounts.
public void testIsValidWhenSameBankAccountAndOfferIsNot() {
account = mock(SameBankAccount.class);
when(predicates.isMatchingCurrency(offer, account)).thenReturn(true);
when(predicates.isEqualPaymentMethods(offer, account)).thenReturn(false);
when(predicates.isMatchingCountryCodes(offer, account)).thenReturn(true);
when(predicates.isMatchingSepaOffer(offer, account)).thenReturn(false);
when(predicates.isMatchingSepaInstant(offer, account)).thenReturn(false);
assertFalse(new ReceiptValidator(offer, account, predicates).isValid());
verify(predicates, never()).isOfferRequireSameOrSpecificBank(offer, account);
verify(predicates, never()).isMatchingBankId(offer, account);
}
@Test
public void testIsValidWhenWesternUnionAccount() {
account = mock(WesternUnionAccount.class);