CORDA-2631 - removed unused version mapping and revert tracking test (#4781)

CORDA-2631 - removed unused version mapping and revert tracking test
This commit is contained in:
Tudor Malene 2019-02-18 14:49:57 +00:00 committed by Gavin Thomas
parent 1ed5fce6a6
commit 626fa19769
6 changed files with 15 additions and 47 deletions

View File

@ -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) 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 @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<? 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 @NotNull
public final java.util.List<net.corda.core.contracts.Command<T>> commandsOfType(Class<T>) public final java.util.List<net.corda.core.contracts.Command<T>> commandsOfType(Class<T>)
@NotNull @NotNull

View File

@ -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. * @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, class Verifier(val ltx: LedgerTransaction, private val transactionClassLoader: ClassLoader) {
private val transactionClassLoader: ClassLoader,
private val inputVersions: Map<ContractClassName, Version>) {
private val inputStates: List<TransactionState<*>> = ltx.inputs.map { it.state } private val inputStates: List<TransactionState<*>> = ltx.inputs.map { it.state }
private val allStates: List<TransactionState<*>> = inputStates + ltx.references.map { it.state } + ltx.outputs private val allStates: List<TransactionState<*>> = inputStates + ltx.references.map { it.state } + ltx.outputs

View File

@ -58,12 +58,7 @@ private constructor(
*/ */
override val networkParameters: NetworkParameters?, override val networkParameters: NetworkParameters?,
/** Referenced states, which are like inputs but won't be consumed. */ /** Referenced states, which are like inputs but won't be consumed. */
override val references: List<StateAndRef<ContractState>>, 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>
//DOCEND 1 //DOCEND 1
) : FullTransaction() { ) : FullTransaction() {
// These are not part of the c'tor above as that defines LedgerTransaction's serialisation format // 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>>, references: List<StateAndRef<ContractState>>,
componentGroups: List<ComponentGroup>? = null, componentGroups: List<ComponentGroup>? = null,
serializedInputs: List<SerializedStateAndRef>? = null, serializedInputs: List<SerializedStateAndRef>? = null,
serializedReferences: List<SerializedStateAndRef>? = null, serializedReferences: List<SerializedStateAndRef>? = null
inputVersions: Map<ContractClassName, Version>
): LedgerTransaction { ): 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.componentGroups = componentGroups
this.serializedInputs = serializedInputs this.serializedInputs = serializedInputs
this.serializedReferences = serializedReferences 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 // 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. // like no-overlap, package namespace ownership and (in future) deterministic Java.
return AttachmentsClassLoaderBuilder.withAttachmentsClassloaderContext(this.attachments + extraAttachments, getParamsWithGoo(), id) { transactionClassLoader -> 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, timeWindow = this.timeWindow,
privacySalt = this.privacySalt, privacySalt = this.privacySalt,
networkParameters = this.networkParameters, networkParameters = this.networkParameters,
references = deserializedReferences, references = deserializedReferences
inputVersions = this.inputVersions
) )
} else { } else {
// This branch is only present for backwards compatibility. // This branch is only present for backwards compatibility.
@ -560,7 +553,7 @@ private constructor(
notary: Party?, notary: Party?,
timeWindow: TimeWindow?, timeWindow: TimeWindow?,
privacySalt: PrivacySalt 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.") @Deprecated("LedgerTransaction should not be created directly, use WireTransaction.toLedgerTransaction instead.")
@DeprecatedConstructorForDeserialization(1) @DeprecatedConstructorForDeserialization(1)
@ -574,7 +567,7 @@ private constructor(
timeWindow: TimeWindow?, timeWindow: TimeWindow?,
privacySalt: PrivacySalt, privacySalt: PrivacySalt,
networkParameters: NetworkParameters 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.") @Deprecated("LedgerTransactions should not be created directly, use WireTransaction.toLedgerTransaction instead.")
fun copy(inputs: List<StateAndRef<ContractState>>, fun copy(inputs: List<StateAndRef<ContractState>>,
@ -596,8 +589,7 @@ private constructor(
timeWindow = timeWindow, timeWindow = timeWindow,
privacySalt = privacySalt, privacySalt = privacySalt,
networkParameters = networkParameters, networkParameters = networkParameters,
references = references, references = references
inputVersions = emptyMap()
) )
} }
@ -622,8 +614,7 @@ private constructor(
timeWindow = timeWindow, timeWindow = timeWindow,
privacySalt = privacySalt, privacySalt = privacySalt,
networkParameters = networkParameters, networkParameters = networkParameters,
references = references, references = references
inputVersions = emptyMap()
) )
} }
} }

View File

@ -190,19 +190,6 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
val resolvedNetworkParameters = resolveParameters(networkParametersHash) ?: throw TransactionResolutionException.UnknownParametersException(id, networkParametersHash!!) 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( val ltx = LedgerTransaction.create(
resolvedInputs, resolvedInputs,
outputs, outputs,
@ -216,8 +203,7 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
resolvedReferences, resolvedReferences,
componentGroups, componentGroups,
serializedResolvedInputs, serializedResolvedInputs,
serializedResolvedReferences, serializedResolvedReferences
appVersionsInInputs
) )
checkTransactionSize(ltx, resolvedNetworkParameters.maxTransactionSize, serializedResolvedInputs, serializedResolvedReferences) checkTransactionSize(ltx, resolvedNetworkParameters.maxTransactionSize, serializedResolvedInputs, serializedResolvedReferences)

View File

@ -139,8 +139,7 @@ class TransactionTests {
timeWindow, timeWindow,
privacySalt, privacySalt,
testNetworkParameters(), testNetworkParameters(),
emptyList(), emptyList()
inputVersions = emptyMap()
) )
transaction.verify() transaction.verify()
@ -192,8 +191,7 @@ class TransactionTests {
timeWindow, timeWindow,
privacySalt, privacySalt,
testNetworkParameters(notaries = listOf(NotaryInfo(DUMMY_NOTARY, true))), testNetworkParameters(notaries = listOf(NotaryInfo(DUMMY_NOTARY, true))),
emptyList(), emptyList()
inputVersions = emptyMap()
) )
assertFailsWith<TransactionVerificationException.NotaryChangeInWrongTransactionType> { buildTransaction().verify() } assertFailsWith<TransactionVerificationException.NotaryChangeInWrongTransactionType> { buildTransaction().verify() }

View File

@ -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(!). // We need to declare this here, if we do it inside [expectEvents] kotlin throws an internal compiler error(!).
val aliceTxExpectations = sequence( val aliceTxExpectations = sequence(
//TODO investigate missing event after introduction of signature constraints non-downgrade rule
/*
expect { tx: SignedTransaction -> expect { tx: SignedTransaction ->
require(tx.id == bobsFakeCash[0].id) require(tx.id == bobsFakeCash[0].id)
},*/ },
expect { tx: SignedTransaction -> expect { tx: SignedTransaction ->
require(tx.id == bobsFakeCash[2].id) require(tx.id == bobsFakeCash[2].id)
}, },
@ -475,12 +473,10 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
) )
aliceTxStream.expectEvents { aliceTxExpectations } aliceTxStream.expectEvents { aliceTxExpectations }
val aliceMappingExpectations = sequence( val aliceMappingExpectations = sequence(
//TODO investigate missing event after introduction of signature constraints non-downgrade rule
/*
expect<StateMachineTransactionMapping> { (stateMachineRunId, transactionId) -> expect<StateMachineTransactionMapping> { (stateMachineRunId, transactionId) ->
require(stateMachineRunId == aliceSmId) require(stateMachineRunId == aliceSmId)
require(transactionId == bobsFakeCash[0].id) require(transactionId == bobsFakeCash[0].id)
},*/ },
expect<StateMachineTransactionMapping> { (stateMachineRunId, transactionId) -> expect<StateMachineTransactionMapping> { (stateMachineRunId, transactionId) ->
require(stateMachineRunId == aliceSmId) require(stateMachineRunId == aliceSmId)
require(transactionId == bobsFakeCash[2].id) require(transactionId == bobsFakeCash[2].id)