CORDA-2576 Viral update propagation: select attachments from those loaded by node on startup. (#4745)

* Retrieve contract attachment(s) loaded by node.

* Remove redundant integration test case (downgrade rule checking)

* Address PR review comments.

* Revert changes to classloading dependencies hack.
This commit is contained in:
josecoll 2019-02-14 13:39:14 +00:00 committed by GitHub
parent ce8fa99e59
commit 0bdc8b363a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 2 additions and 58 deletions

View File

@ -441,9 +441,8 @@ open class TransactionBuilder(
require(constraints.none { it in automaticConstraints })
require(isReference || constraints.none { it is HashAttachmentConstraint })
val minimumRequiredContractClassVersion = stateRefs?.map { services.loadContractAttachment(it).contractVersion }?.max() ?: DEFAULT_CORDAPP_VERSION
return services.attachments.getLatestContractAttachments(contractClassName, minimumRequiredContractClassVersion).firstOrNull()
?: throw MissingContractAttachments(states, contractClassName, minimumRequiredContractClassVersion)
return services.cordappProvider.getContractAttachmentID(contractClassName)
?: throw MissingContractAttachments(states, contractClassName)
}
private fun useWhitelistedByZoneAttachmentConstraint(contractClassName: ContractClassName, networkParameters: NetworkParameters) = contractClassName in networkParameters.whitelistedContractImplementations.keys

View File

@ -11,7 +11,6 @@ import net.corda.core.internal.div
import net.corda.core.internal.packageName
import net.corda.core.messaging.startFlow
import net.corda.core.transactions.LedgerTransaction
import net.corda.core.transactions.MissingContractAttachments
import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.getOrThrow
@ -23,15 +22,12 @@ import net.corda.testMessage.MessageState
import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.core.singleIdentity
import net.corda.testing.driver.NodeParameters
import net.corda.testing.driver.internal.incrementalPortAllocation
import net.corda.testing.node.User
import net.corda.testing.node.internal.cordappWithPackages
import net.corda.testing.node.internal.internalDriver
import org.junit.Assume.assumeFalse
import org.junit.Test
import java.sql.DriverManager
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertNotNull
class SignatureConstraintVersioningTests {
@ -83,57 +79,6 @@ class SignatureConstraintVersioningTests {
assertNotNull(stateAndRef)
assertEquals(transformetMessage, stateAndRef!!.state.data.message)
}
@Test
fun `cannot evolve from higher contract class version to lower one`() {
assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win")) // See NodeStatePersistenceTests.kt.
val port = incrementalPortAllocation(21_000).nextPort()
val stateAndRef: StateAndRef<MessageState>? = internalDriver(inMemoryDB = false,
startNodesInProcess = isQuasarAgentSpecified(),
networkParameters = testNetworkParameters(notaries = emptyList(), minimumPlatformVersion = 4)) {
val nodeName = {
val nodeHandle = startNode(NodeParameters(rpcUsers = listOf(user), additionalCordapps = listOf(newCordapp)),
customOverrides = mapOf("h2Settings.address" to "localhost:$port")).getOrThrow()
val nodeName = nodeHandle.nodeInfo.singleIdentity().name
CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
it.proxy.startFlow(::CreateMessage, message, defaultNotaryIdentity).returnValue.getOrThrow()
}
nodeHandle.stop()
nodeName
}()
val result = {
(baseDirectory(nodeName) / "cordapps").deleteRecursively()
val nodeHandle = startNode(NodeParameters(providedName = nodeName, rpcUsers = listOf(user), additionalCordapps = listOf(oldCordapp)),
customOverrides = mapOf("h2Settings.address" to "localhost:$port")).getOrThrow()
//set the attachment with newer version (3) as untrusted one so the node can use only the older attachment with version 2
DriverManager.getConnection("jdbc:h2:tcp://localhost:$port/node", "sa", "").use {
it.createStatement().execute("UPDATE NODE_ATTACHMENTS SET UPLOADER = 'p2p' WHERE VERSION = 3")
}
var result: StateAndRef<MessageState>? = CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
val page = it.proxy.vaultQuery(MessageState::class.java)
page.states.singleOrNull()
}
CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
assertFailsWith(MissingContractAttachments::class) {
it.proxy.startFlow(::ConsumeMessage, result!!, defaultNotaryIdentity).returnValue.getOrThrow()
}
}
result = CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
val page = it.proxy.vaultQuery(MessageState::class.java)
page.states.singleOrNull()
}
nodeHandle.stop()
result
}()
result
}
assertNotNull(stateAndRef)
assertEquals(message, stateAndRef!!.state.data.message)
}
}
@StartableByRPC