From c8ffc1eaee4f44d6665ddc87d28a91ea92ba4858 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Wed, 30 Apr 2014 22:16:57 +0200 Subject: [PATCH] PaymentSession: Expose params and throw if transactions don't match requested params. Resolves issue 551. --- .../protocols/payments/PaymentSession.java | 4 ++- .../payments/PaymentSessionTest.java | 29 ++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/com/google/bitcoin/protocols/payments/PaymentSession.java b/core/src/main/java/com/google/bitcoin/protocols/payments/PaymentSession.java index 82b4c859..4044d340 100644 --- a/core/src/main/java/com/google/bitcoin/protocols/payments/PaymentSession.java +++ b/core/src/main/java/com/google/bitcoin/protocols/payments/PaymentSession.java @@ -323,9 +323,11 @@ public class PaymentSession { * @param memo is a message to include in the payment message sent to the merchant. */ public @Nullable Protos.Payment getPayment(List txns, @Nullable Address refundAddr, @Nullable String memo) - throws IOException { + throws IOException, PaymentRequestException.InvalidNetwork { if (!paymentDetails.hasPaymentUrl()) return null; + if (!txns.get(0).getParams().equals(params)) + throw new PaymentRequestException.InvalidNetwork(params.getPaymentProtocolId()); Protos.Payment.Builder payment = Protos.Payment.newBuilder(); if (paymentDetails.hasMerchantData()) payment.setMerchantData(paymentDetails.getMerchantData()); diff --git a/core/src/test/java/com/google/bitcoin/protocols/payments/PaymentSessionTest.java b/core/src/test/java/com/google/bitcoin/protocols/payments/PaymentSessionTest.java index bebffb28..d5534b34 100644 --- a/core/src/test/java/com/google/bitcoin/protocols/payments/PaymentSessionTest.java +++ b/core/src/test/java/com/google/bitcoin/protocols/payments/PaymentSessionTest.java @@ -19,6 +19,7 @@ package com.google.bitcoin.protocols.payments; import com.google.bitcoin.core.*; import com.google.bitcoin.crypto.TrustStoreLoader; +import com.google.bitcoin.params.MainNetParams; import com.google.bitcoin.params.TestNet3Params; import com.google.common.util.concurrent.ListenableFuture; import com.google.protobuf.ByteString; @@ -57,7 +58,7 @@ public class PaymentSessionTest { @Test public void testSimplePayment() throws Exception { // Create a PaymentRequest and make sure the correct values are parsed by the PaymentSession. - MockPaymentSession paymentSession = new MockPaymentSession(newSimplePaymentRequest()); + MockPaymentSession paymentSession = new MockPaymentSession(newSimplePaymentRequest("test")); assertEquals(paymentRequestMemo, paymentSession.getMemo()); assertEquals(nanoCoins, paymentSession.getValue()); assertEquals(simplePaymentUrl, paymentSession.getPaymentUrl()); @@ -130,24 +131,39 @@ public class PaymentSessionTest { assertEquals("The USERTRUST Network, Salt Lake City, US", pkiData.rootAuthorityName); } - private Protos.PaymentRequest newSimplePaymentRequest() { + @Test(expected = PaymentRequestException.InvalidNetwork.class) + public void testWrongNetwork() throws Exception { + // Create a PaymentRequest and make sure the correct values are parsed by the PaymentSession. + MockPaymentSession paymentSession = new MockPaymentSession(newSimplePaymentRequest("main")); + assertEquals(MainNetParams.get(), paymentSession.getNetworkParameters()); + + // Send the payment and verify that the correct information is sent. + // Add a dummy input to tx so it is considered valid. + tx.addInput(new TransactionInput(params, tx, outputToMe.getScriptBytes())); + ArrayList txns = new ArrayList(); + txns.add(tx); + Address refundAddr = new Address(params, serverKey.getPubKeyHash()); + paymentSession.sendPayment(txns, refundAddr, paymentMemo); + assertEquals(1, paymentSession.getPaymentLog().size()); + } + + private Protos.PaymentRequest newSimplePaymentRequest(String netID) { Protos.Output.Builder outputBuilder = Protos.Output.newBuilder() .setAmount(nanoCoins.longValue()) .setScript(ByteString.copyFrom(outputToMe.getScriptBytes())); Protos.PaymentDetails paymentDetails = Protos.PaymentDetails.newBuilder() - .setNetwork("test") + .setNetwork(netID) .setTime(time) .setPaymentUrl(simplePaymentUrl) .addOutputs(outputBuilder) .setMemo(paymentRequestMemo) .setMerchantData(merchantData) .build(); - Protos.PaymentRequest paymentRequest = Protos.PaymentRequest.newBuilder() + return Protos.PaymentRequest.newBuilder() .setPaymentDetailsVersion(1) .setPkiType("none") .setSerializedPaymentDetails(paymentDetails.toByteString()) .build(); - return paymentRequest; } private Protos.PaymentRequest newExpiredPaymentRequest() { @@ -163,12 +179,11 @@ public class PaymentSessionTest { .setMemo(paymentRequestMemo) .setMerchantData(merchantData) .build(); - Protos.PaymentRequest paymentRequest = Protos.PaymentRequest.newBuilder() + return Protos.PaymentRequest.newBuilder() .setPaymentDetailsVersion(1) .setPkiType("none") .setSerializedPaymentDetails(paymentDetails.toByteString()) .build(); - return paymentRequest ; } private class MockPaymentSession extends PaymentSession {