From 626fa19769f0c4846df064584a8dfae763b2d2c6 Mon Sep 17 00:00:00 2001
From: Tudor Malene <tudor.malene@r3.com>
Date: Mon, 18 Feb 2019 14:49:57 +0000
Subject: [PATCH] CORDA-2631 - removed unused version mapping and revert
 tracking test (#4781)

CORDA-2631 - removed unused version mapping and revert tracking test
---
 .ci/api-current.txt                           |  1 -
 .../TransactionVerifierServiceInternal.kt     |  4 +--
 .../core/transactions/LedgerTransaction.kt    | 27 +++++++------------
 .../core/transactions/WireTransaction.kt      | 16 +----------
 .../core/transactions/TransactionTests.kt     |  6 ++---
 .../node/messaging/TwoPartyTradeFlowTests.kt  |  8 ++----
 6 files changed, 15 insertions(+), 47 deletions(-)

diff --git a/.ci/api-current.txt b/.ci/api-current.txt
index a75bc444bf..8f6dcc619f 100644
--- a/.ci/api-current.txt
+++ b/.ci/api-current.txt
@@ -5907,7 +5907,6 @@ public final class net.corda.core.transactions.LedgerTransaction extends net.cor
   public <init>(java.util.List<? extends net.corda.core.contracts.StateAndRef<? extends net.corda.core.contracts.ContractState>>, java.util.List<? extends net.corda.core.contracts.TransactionState<? extends net.corda.core.contracts.ContractState>>, java.util.List<? extends net.corda.core.contracts.CommandWithParties<? extends net.corda.core.contracts.CommandData>>, java.util.List<? extends net.corda.core.contracts.Attachment>, net.corda.core.crypto.SecureHash, net.corda.core.identity.Party, net.corda.core.contracts.TimeWindow, net.corda.core.contracts.PrivacySalt)
   @DeprecatedConstructorForDeserialization
   public <init>(java.util.List<? extends net.corda.core.contracts.StateAndRef<? extends net.corda.core.contracts.ContractState>>, java.util.List<? extends net.corda.core.contracts.TransactionState<? extends net.corda.core.contracts.ContractState>>, java.util.List<? extends net.corda.core.contracts.CommandWithParties<? extends net.corda.core.contracts.CommandData>>, java.util.List<? extends net.corda.core.contracts.Attachment>, net.corda.core.crypto.SecureHash, net.corda.core.identity.Party, net.corda.core.contracts.TimeWindow, net.corda.core.contracts.PrivacySalt, net.corda.core.node.NetworkParameters)
-  public <init>(java.util.List, java.util.List, java.util.List, java.util.List, net.corda.core.crypto.SecureHash, net.corda.core.identity.Party, net.corda.core.contracts.TimeWindow, net.corda.core.contracts.PrivacySalt, net.corda.core.node.NetworkParameters, java.util.List, java.util.Map, kotlin.jvm.internal.DefaultConstructorMarker)
   @NotNull
   public final java.util.List<net.corda.core.contracts.Command<T>> commandsOfType(Class<T>)
   @NotNull
diff --git a/core/src/main/kotlin/net/corda/core/internal/TransactionVerifierServiceInternal.kt b/core/src/main/kotlin/net/corda/core/internal/TransactionVerifierServiceInternal.kt
index b16ad3bb24..d0323d123e 100644
--- a/core/src/main/kotlin/net/corda/core/internal/TransactionVerifierServiceInternal.kt
+++ b/core/src/main/kotlin/net/corda/core/internal/TransactionVerifierServiceInternal.kt
@@ -28,9 +28,7 @@ fun LedgerTransaction.prepareVerify(extraAttachments: List<Attachment>) = this.i
  *
  * @param inputVersions A map linking each contract class name to the advertised version of the JAR that defines it. Used for downgrade protection.
  */
-class Verifier(val ltx: LedgerTransaction,
-               private val transactionClassLoader: ClassLoader,
-               private val inputVersions: Map<ContractClassName, Version>) {
+class Verifier(val ltx: LedgerTransaction, private val transactionClassLoader: ClassLoader) {
     private val inputStates: List<TransactionState<*>> = ltx.inputs.map { it.state }
     private val allStates: List<TransactionState<*>> = inputStates + ltx.references.map { it.state } + ltx.outputs
 
diff --git a/core/src/main/kotlin/net/corda/core/transactions/LedgerTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/LedgerTransaction.kt
index eabc125549..01d1058eb8 100644
--- a/core/src/main/kotlin/net/corda/core/transactions/LedgerTransaction.kt
+++ b/core/src/main/kotlin/net/corda/core/transactions/LedgerTransaction.kt
@@ -58,12 +58,7 @@ private constructor(
          */
         override val networkParameters: NetworkParameters?,
         /** Referenced states, which are like inputs but won't be consumed. */
-        override val references: List<StateAndRef<ContractState>>,
-        /**
-         * The versions of the app JARs attached to the transactions that defined the inputs, grouped by contract class name.
-         * This is used to stop adversaries downgrading apps to versions that have exploitable bugs.
-         */
-        private val inputVersions: Map<ContractClassName, Version>
+        override val references: List<StateAndRef<ContractState>>
         //DOCEND 1
 ) : FullTransaction() {
     // These are not part of the c'tor above as that defines LedgerTransaction's serialisation format
@@ -94,10 +89,9 @@ private constructor(
                 references: List<StateAndRef<ContractState>>,
                 componentGroups: List<ComponentGroup>? = null,
                 serializedInputs: List<SerializedStateAndRef>? = null,
-                serializedReferences: List<SerializedStateAndRef>? = null,
-                inputVersions: Map<ContractClassName, Version>
+                serializedReferences: List<SerializedStateAndRef>? = null
         ): LedgerTransaction {
-            return LedgerTransaction(inputs, outputs, commands, attachments, id, notary, timeWindow, privacySalt, networkParameters, references, inputVersions).apply {
+            return LedgerTransaction(inputs, outputs, commands, attachments, id, notary, timeWindow, privacySalt, networkParameters, references).apply {
                 this.componentGroups = componentGroups
                 this.serializedInputs = serializedInputs
                 this.serializedReferences = serializedReferences
@@ -139,7 +133,7 @@ private constructor(
         // Switch thread local deserialization context to using a cached attachments classloader. This classloader enforces various rules
         // like no-overlap, package namespace ownership and (in future) deterministic Java.
         return AttachmentsClassLoaderBuilder.withAttachmentsClassloaderContext(this.attachments + extraAttachments, getParamsWithGoo(), id) { transactionClassLoader ->
-            Verifier(createLtxForVerification(), transactionClassLoader, inputVersions)
+            Verifier(createLtxForVerification(), transactionClassLoader)
         }
     }
 
@@ -196,8 +190,7 @@ private constructor(
                     timeWindow = this.timeWindow,
                     privacySalt = this.privacySalt,
                     networkParameters = this.networkParameters,
-                    references = deserializedReferences,
-                    inputVersions = this.inputVersions
+                    references = deserializedReferences
             )
         } else {
             // This branch is only present for backwards compatibility.
@@ -560,7 +553,7 @@ private constructor(
             notary: Party?,
             timeWindow: TimeWindow?,
             privacySalt: PrivacySalt
-    ) : this(inputs, outputs, commands, attachments, id, notary, timeWindow, privacySalt, null, emptyList(), emptyMap())
+    ) : this(inputs, outputs, commands, attachments, id, notary, timeWindow, privacySalt, null, emptyList())
 
     @Deprecated("LedgerTransaction should not be created directly, use WireTransaction.toLedgerTransaction instead.")
     @DeprecatedConstructorForDeserialization(1)
@@ -574,7 +567,7 @@ private constructor(
             timeWindow: TimeWindow?,
             privacySalt: PrivacySalt,
             networkParameters: NetworkParameters
-    ) : this(inputs, outputs, commands, attachments, id, notary, timeWindow, privacySalt, networkParameters, emptyList(), emptyMap())
+    ) : this(inputs, outputs, commands, attachments, id, notary, timeWindow, privacySalt, networkParameters, emptyList())
 
     @Deprecated("LedgerTransactions should not be created directly, use WireTransaction.toLedgerTransaction instead.")
     fun copy(inputs: List<StateAndRef<ContractState>>,
@@ -596,8 +589,7 @@ private constructor(
                 timeWindow = timeWindow,
                 privacySalt = privacySalt,
                 networkParameters = networkParameters,
-                references = references,
-                inputVersions = emptyMap()
+                references = references
         )
     }
 
@@ -622,8 +614,7 @@ private constructor(
                 timeWindow = timeWindow,
                 privacySalt = privacySalt,
                 networkParameters = networkParameters,
-                references = references,
-                inputVersions = emptyMap()
+                references = references
         )
     }
 }
diff --git a/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt
index c6b9bdd59e..b13f8ec6b1 100644
--- a/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt
+++ b/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt
@@ -190,19 +190,6 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
 
         val resolvedNetworkParameters = resolveParameters(networkParametersHash) ?: throw TransactionResolutionException.UnknownParametersException(id, networkParametersHash!!)
 
-        // For each contract referenced in the inputs, figure out the highest version being used. The outputs must be
-        // at least that version or higher, to prevent adversaries from downgrading the app to an old version that has
-        // known bugs they can then exploit. This is part of the version ratchet that ensures apps can only ever be
-        // upgraded, not downgraded. We don't use resolvedInputs here to keep it lazy. TODO: why?
-        // We do this resolution now instead of in LedgerTransaction because here we have the function to map
-        // StateRefs to their attachments directly.
-        val appVersionsInInputs: Map<ContractClassName, Version> = serializedResolvedInputs
-                .map { it.toStateAndRef() }
-                .groupBy { it.state.contract }
-                .mapValues { (_ , statesAndRefs) ->
-                    statesAndRefs.map { resolveContractAttachment(it.ref).contractVersion }.max() ?: DEFAULT_CORDAPP_VERSION
-                }
-
         val ltx = LedgerTransaction.create(
                 resolvedInputs,
                 outputs,
@@ -216,8 +203,7 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
                 resolvedReferences,
                 componentGroups,
                 serializedResolvedInputs,
-                serializedResolvedReferences,
-                appVersionsInInputs
+                serializedResolvedReferences
         )
 
         checkTransactionSize(ltx, resolvedNetworkParameters.maxTransactionSize, serializedResolvedInputs, serializedResolvedReferences)
diff --git a/core/src/test/kotlin/net/corda/core/transactions/TransactionTests.kt b/core/src/test/kotlin/net/corda/core/transactions/TransactionTests.kt
index 994c30e925..2adc215584 100644
--- a/core/src/test/kotlin/net/corda/core/transactions/TransactionTests.kt
+++ b/core/src/test/kotlin/net/corda/core/transactions/TransactionTests.kt
@@ -139,8 +139,7 @@ class TransactionTests {
                 timeWindow,
                 privacySalt,
                 testNetworkParameters(),
-                emptyList(),
-                inputVersions = emptyMap()
+                emptyList()
         )
 
         transaction.verify()
@@ -192,8 +191,7 @@ class TransactionTests {
                 timeWindow,
                 privacySalt,
                 testNetworkParameters(notaries = listOf(NotaryInfo(DUMMY_NOTARY, true))),
-                emptyList(),
-                inputVersions = emptyMap()
+                emptyList()
         )
 
         assertFailsWith<TransactionVerificationException.NotaryChangeInWrongTransactionType> { buildTransaction().verify() }
diff --git a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt
index a6945a069f..52ede9cae9 100644
--- a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt
+++ b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt
@@ -461,11 +461,9 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
 
             // We need to declare this here, if we do it inside [expectEvents] kotlin throws an internal compiler error(!).
             val aliceTxExpectations = sequence(
-                    //TODO investigate missing event after introduction of signature constraints non-downgrade rule
-                    /*
                     expect { tx: SignedTransaction ->
                         require(tx.id == bobsFakeCash[0].id)
-                    },*/
+                    },
                     expect { tx: SignedTransaction ->
                         require(tx.id == bobsFakeCash[2].id)
                     },
@@ -475,12 +473,10 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
             )
             aliceTxStream.expectEvents { aliceTxExpectations }
             val aliceMappingExpectations = sequence(
-                    //TODO investigate missing event after introduction of signature constraints non-downgrade rule
-                    /*
                     expect<StateMachineTransactionMapping> { (stateMachineRunId, transactionId) ->
                         require(stateMachineRunId == aliceSmId)
                         require(transactionId == bobsFakeCash[0].id)
-                    },*/
+                    },
                     expect<StateMachineTransactionMapping> { (stateMachineRunId, transactionId) ->
                         require(stateMachineRunId == aliceSmId)
                         require(transactionId == bobsFakeCash[2].id)