CORDA-2634 - Fix derivation of currentTargetVersion for abstract classes (#4784)

* CORDA-2634 - Fix default currentTargetVersion

* CORDA-2634 - Include abstract flow classes in CorDapp class scanning

* CORDA-2634 - Run test for target platform version 4
This commit is contained in:
Tommy Lillehagen 2019-02-19 08:47:49 +00:00 committed by GitHub
parent 055aabe1bb
commit 21d32681ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 18 deletions

View File

@ -34,14 +34,15 @@ data class CordappImpl(
override val targetPlatformVersion: Int, override val targetPlatformVersion: Int,
val notaryService: Class<out NotaryService>? = null, val notaryService: Class<out NotaryService>? = null,
/** Indicates whether the CorDapp is loaded from external sources, or generated on node startup (virtual). */ /** Indicates whether the CorDapp is loaded from external sources, or generated on node startup (virtual). */
val isLoaded: Boolean = true val isLoaded: Boolean = true,
private val explicitCordappClasses: List<String> = emptyList()
) : Cordapp { ) : Cordapp {
override val name: String = jarName(jarPath) override val name: String = jarName(jarPath)
// TODO: Also add [SchedulableFlow] as a Cordapp class // TODO: Also add [SchedulableFlow] as a Cordapp class
override val cordappClasses: List<String> = run { override val cordappClasses: List<String> = run {
val classList = rpcFlows + initiatedFlows + services + serializationWhitelists.map { javaClass } + notaryService val classList = rpcFlows + initiatedFlows + services + serializationWhitelists.map { javaClass } + notaryService
classList.mapNotNull { it?.name } + contractClassNames classList.mapNotNull { it?.name } + contractClassNames + explicitCordappClasses
} }
companion object { companion object {

View File

@ -55,10 +55,10 @@ object CordappResolver {
val currentCordapp: Cordapp? get() = cordappResolver() val currentCordapp: Cordapp? get() = cordappResolver()
/** /**
* Returns the target version of the current calling CorDapp. Defaults to the current platform version if there isn't one. * Returns the target version of the current calling CorDapp. Defaults to platform version 1 if there isn't one,
* assuming only basic platform capabilities.
*/ */
// TODO It may be the default is wrong and this should be Int? instead val currentTargetVersion: Int get() = currentCordapp?.targetPlatformVersion ?: 1
val currentTargetVersion: Int get() = currentCordapp?.targetPlatformVersion ?: PLATFORM_VERSION
/** /**
* Temporarily apply a fake CorDapp with the given parameters. For use in testing. * Temporarily apply a fake CorDapp with the given parameters. For use in testing.

View File

@ -11,6 +11,7 @@ import net.corda.core.identity.Party
import net.corda.core.internal.AbstractAttachment import net.corda.core.internal.AbstractAttachment
import net.corda.core.internal.PLATFORM_VERSION import net.corda.core.internal.PLATFORM_VERSION
import net.corda.core.internal.cordapp.CordappImpl.Companion.DEFAULT_CORDAPP_VERSION import net.corda.core.internal.cordapp.CordappImpl.Companion.DEFAULT_CORDAPP_VERSION
import net.corda.core.internal.cordapp.CordappResolver
import net.corda.core.node.ServicesForResolution import net.corda.core.node.ServicesForResolution
import net.corda.core.node.ZoneVersionTooLowException import net.corda.core.node.ZoneVersionTooLowException
import net.corda.core.node.services.AttachmentStorage import net.corda.core.node.services.AttachmentStorage
@ -116,20 +117,22 @@ class TransactionBuilderTest {
@Test @Test
fun `multiple commands with same data are joined without duplicates in terms of signers`() { fun `multiple commands with same data are joined without duplicates in terms of signers`() {
val aliceParty = TestIdentity(ALICE_NAME).party // This behaviour is only activated for platform version 4 onwards.
val bobParty = TestIdentity(BOB_NAME).party CordappResolver.withCordapp(targetPlatformVersion = 4) {
val tx = TransactionBuilder(notary) val aliceParty = TestIdentity(ALICE_NAME).party
tx.addCommand(DummyCommandData, notary.owningKey, aliceParty.owningKey) val bobParty = TestIdentity(BOB_NAME).party
tx.addCommand(DummyCommandData, aliceParty.owningKey, bobParty.owningKey) val tx = TransactionBuilder(notary)
tx.addCommand(DummyCommandData, notary.owningKey, aliceParty.owningKey)
tx.addCommand(DummyCommandData, aliceParty.owningKey, bobParty.owningKey)
val commands = tx.commands() val commands = tx.commands()
assertThat(commands).hasSize(1) assertThat(commands).hasSize(1)
assertThat(commands.single()).satisfies { cmd -> assertThat(commands.single()).satisfies { cmd ->
assertThat(cmd.value).isEqualTo(DummyCommandData)
assertThat(cmd.value).isEqualTo(DummyCommandData) assertThat(cmd.signers).hasSize(3)
assertThat(cmd.signers).hasSize(3) assertThat(cmd.signers).contains(notary.owningKey, bobParty.owningKey, aliceParty.owningKey)
assertThat(cmd.signers).contains(notary.owningKey, bobParty.owningKey, aliceParty.owningKey) }
} }
} }

View File

@ -151,7 +151,8 @@ class JarScanningCordappLoader private constructor(private val cordappJarPaths:
getJarHash(url.url), getJarHash(url.url),
minPlatformVersion, minPlatformVersion,
targetPlatformVersion, targetPlatformVersion,
findNotaryService(this) findNotaryService(this),
explicitCordappClasses = findAllCordappClasses(this)
) )
} }
@ -250,6 +251,10 @@ class JarScanningCordappLoader private constructor(private val cordappJarPaths:
return scanResult.getConcreteClassesOfType(FlowLogic::class) return scanResult.getConcreteClassesOfType(FlowLogic::class)
} }
private fun findAllCordappClasses(scanResult: RestrictedScanResult): List<String> {
return scanResult.getAllStandardClasses() + scanResult.getAllInterfaces()
}
private fun findContractClassNames(scanResult: RestrictedScanResult): List<String> { private fun findContractClassNames(scanResult: RestrictedScanResult): List<String> {
val contractClasses = coreContractClasses.flatMap { scanResult.getNamesOfClassesImplementing(it) }.distinct() val contractClasses = coreContractClasses.flatMap { scanResult.getNamesOfClassesImplementing(it) }.distinct()
for (contractClass in contractClasses) { for (contractClass in contractClasses) {
@ -350,6 +355,20 @@ class JarScanningCordappLoader private constructor(private val cordappJarPaths:
.filterNot { it.isAbstractClass } .filterNot { it.isAbstractClass }
} }
fun getAllStandardClasses(): List<String> {
return scanResult
.getAllStandardClasses()
.names
.filter { it.startsWith(qualifiedNamePrefix) }
}
fun getAllInterfaces(): List<String> {
return scanResult
.getAllInterfaces()
.names
.filter { it.startsWith(qualifiedNamePrefix) }
}
override fun close() = scanResult.close() override fun close() = scanResult.close()
} }
} }