diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7f6e192 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,6 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +max_line_length = 140 \ No newline at end of file diff --git a/HEADER b/HEADER index 44349e8..abd9b84 100644 --- a/HEADER +++ b/HEADER @@ -1,4 +1,4 @@ -Copyright 2020-2021 ONIXLabs +Copyright 2020-2022 ONIXLabs Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 40b9b4d..9337f72 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![ONIX Labs](https://raw.githubusercontent.com/onix-labs/onix-labs.github.io/master/content/logo/master_full_md.png) +![ONIX Labs](https://raw.githubusercontent.com/onix-labs/onixlabs-website/main/src/assets/images/logo/full/original/original-md.png) # ONIXLabs Corda BNMS diff --git a/build.gradle b/build.gradle index e1cde53..4a4ba16 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { corda_artifactory_url = 'https://software.r3.com/artifactory' corda_group = 'net.corda' - corda_release_version = '4.6' + corda_release_version = '4.9' corda_gradle_plugin_group = 'net.corda.plugins' corda_gradle_plugin_version = '5.0.4' @@ -14,10 +14,10 @@ buildscript { junit_version = '5.3.1' onixlabs_group = 'io.onixlabs' - onixlabs_corda_core_release_version = '1.2.0' - onixlabs_corda_idfx_release_version = '2.0.0-rc2' + onixlabs_corda_core_release_version = '4.0.3' + onixlabs_corda_idfx_release_version = '4.0.3' - cordapp_platform_version = 8 + cordapp_platform_version = 11 cordapp_contract_name = 'ONIXLabs Corda BNMS Contract' cordapp_workflow_name = 'ONIXLabs Corda BNMS Workflow' cordapp_vendor_name = 'ONIXLabs' @@ -34,7 +34,6 @@ buildscript { repositories { mavenLocal() mavenCentral() - jcenter() maven { url "$corda_artifactory_url/corda-releases" } maven { url "$corda_artifactory_url/corda-dependencies" } } @@ -45,21 +44,28 @@ buildscript { } } -group 'io.onixlabs' -version '1.0.0' +group getProperty('group') +version getProperty('version') subprojects { repositories { mavenLocal() mavenCentral() - jcenter() maven { url "https://jitpack.io" } maven { url "$corda_artifactory_url/corda-releases" } maven { url "$corda_artifactory_url/corda-dependencies" } maven { url "https://repo.gradle.org/gradle/libs-releases" } maven { - name = "GitHubPackagesCIF" - url = uri("https://maven.pkg.github.com/onix-labs/onixlabs-corda-identity-framework-beta") + name = "GitHubPackages-onixlabs-corda-core" + url = uri("https://maven.pkg.github.com/onix-labs/onixlabs-corda-core") + credentials { + username = project.findProperty("gpr.user") ?: System.getenv("GITHUB_USERNAME") + password = project.findProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN") + } + } + maven { + name = "GitHubPackages-onixlabs-corda-identity-framework" + url = uri("https://maven.pkg.github.com/onix-labs/onixlabs-corda-identity-framework") credentials { username = project.findProperty("gpr.user") ?: System.getenv("GITHUB_USERNAME") password = project.findProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN") @@ -87,10 +93,16 @@ subprojects { } } + task sourceJar(type: Jar) { + from sourceSets.main.allSource + archiveClassifier = "sources" + } + jar { exclude '**/log4j2*.xml' } test { jvmArgs = ["-ea", "-javaagent:../lib/quasar.jar"] + maxHeapSize = "4096m" useJUnitPlatform() } } diff --git a/gradle.properties b/gradle.properties index f3036f2..2414572 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,5 @@ name=onixlabs-corda-bnms group=io.onixlabs - -kotlin.incremental=false -kotlin.code.style=official - +version=2.0.0-rc16 onixlabs.development.jarsign.keystore=../lib/onixlabs.development.pkcs12 onixlabs.development.jarsign.password=5891f47942424d2acbe108691fdb5ba258712fca7e4762be4327241ebf3dbfa3 diff --git a/onixlabs-corda-bnms-contract/build.gradle b/onixlabs-corda-bnms-contract/build.gradle index 07c9086..1687d17 100644 --- a/onixlabs-corda-bnms-contract/build.gradle +++ b/onixlabs-corda-bnms-contract/build.gradle @@ -28,6 +28,7 @@ dependencies { // CorDapp Dependencies cordapp "$onixlabs_group:onixlabs-corda-core-contract:$onixlabs_corda_core_release_version" + cordapp "$onixlabs_group:onixlabs-corda-core-workflow:$onixlabs_corda_core_release_version" cordapp "$onixlabs_group:onixlabs-corda-identity-framework-contract:$onixlabs_corda_idfx_release_version" // Test Dependencies @@ -53,6 +54,7 @@ publishing { groupId = project.parent.group version = project.parent.version artifactId = 'onixlabs-corda-bnms-contract' + artifact sourceJar from components.java } } diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Configuration.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Configuration.kt new file mode 100644 index 0000000..cdd63a2 --- /dev/null +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Configuration.kt @@ -0,0 +1,334 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.contract + +import io.onixlabs.corda.core.contract.Hashable +import io.onixlabs.corda.identityframework.contract.filterByProperty +import io.onixlabs.corda.identityframework.contract.filterByType +import net.corda.core.crypto.SecureHash +import net.corda.core.serialization.CordaSerializable + +/** + * Represents a configuration consisting of a set of settings. + * + * @property settings The set of settings in this configuration. + * @property permissions The set of permissions in this configuration. + * @property roles The set of roles in this configuration. + * @property hash The unique hash of all settings in this configuration. + */ +@CordaSerializable +data class Configuration(val settings: Set> = emptySet()) : Hashable { + + companion object + + val permissions: Set + get() = getSettingsByType() + + val roles: Set + get() = getSettingsByType() + + override val hash: SecureHash + get() = computeHash() + + /** + * Gets all settings by type and optionally by property. + * + * @param V The underlying setting value type. + * @param S the underlying setting type. + * @param settingType The setting type. + * @param valueType The setting's value type. + * @param property The setting's property. + * @param ignoreCase Determines whether to ignore case when filtering by property. + * @return Returns all settings matching the specified type and property. + */ + fun > getSettingsByType( + settingType: Class, + valueType: Class? = null, + property: String? = null, + ignoreCase: Boolean = false + ): Set { + val resultsFilteredByType = settings.filterByType(settingType, valueType) + return if (property != null) resultsFilteredByType.filterByProperty(property, ignoreCase).toSet() + else resultsFilteredByType.toSet() + } + + /** + * Gets all settings by type and optionally by property. + * + * @param T The underlying [Setting] type. + * @param property The setting's property. + * @param ignoreCase Determines whether to ignore case when filtering by property. + * @return Returns all settings matching the specified type and property. + */ + inline fun > getSettingsByType( + property: String? = null, + ignoreCase: Boolean = false + ): Set { + val resultsFilteredByType = settings.filterByType() + return if (property != null) resultsFilteredByType.filterByProperty(property, ignoreCase).toSet() + else resultsFilteredByType.toSet() + } + + /** + * Gets a single setting by type and optionally by property. + * + * @param T The underlying [Setting] type. + * @param settingType The setting type. + * @param valueType The setting's value type. + * @param property The setting's property. + * @param ignoreCase Determines whether to ignore case when filtering by property. + * @return Returns a single setting matching the specified type and property. + */ + fun > getSettingByType( + settingType: Class, + valueType: Class? = null, + property: String? = null, + ignoreCase: Boolean = false + ): S = getSettingsByType(settingType, valueType, property, ignoreCase).single() + + /** + * Gets a single setting by type and optionally by property. + * + * @param T The underlying [Setting] type. + * @param property The setting's property. + * @param ignoreCase Determines whether to ignore case when filtering by property. + * @return Returns a single setting matching the specified type and property. + */ + inline fun > getSettingByType( + property: String? = null, + ignoreCase: Boolean = false + ): T = getSettingsByType(property, ignoreCase).single() + + /** + * Gets a single setting by type and optionally by property, or null if no matching setting exists. + * + * @param T The underlying [Setting] type. + * @param settingType The setting type. + * @param valueType The setting's value type. + * @param property The setting's property. + * @param ignoreCase Determines whether to ignore case when filtering by property. + * @return Returns a single setting matching the specified type and property, or null if no matching setting exists. + */ + fun > getSettingByTypeOrNull( + settingType: Class, + valueType: Class? = null, + property: String? = null, + ignoreCase: Boolean = false + ): S? = getSettingsByType(settingType, valueType, property, ignoreCase).singleOrNull() + + /** + * Gets a single setting by type and optionally by property, or null if no matching setting exists. + * + * @param T The underlying [Setting] type. + * @param property The setting's property. + * @param ignoreCase Determines whether to ignore case when filtering by property. + * @return Returns a single setting matching the specified type and property, or null if no matching setting exists. + */ + inline fun > getSettingByTypeOrNull( + property: String? = null, + ignoreCase: Boolean = false + ): T? = getSettingsByType(property, ignoreCase).singleOrNull() + + /** + * Determines whether the specified setting is contained in this configuration. + * + * @param setting The setting to find in this configuration. + * @return Returns true if the specified setting is contained in this configuration; otherwise, false. + */ + fun hasSetting(setting: Setting<*>): Boolean { + return setting in settings + } + + /** + * Determines whether the specified setting is contained in this configuration. + * + * @param property The setting property to find in this configuration. + * @param ignoreCase Determines whether to ignore case when filtering by property. + * @return Returns true if the specified setting is contained in this configuration; otherwise, false. + */ + fun hasSetting(property: String, ignoreCase: Boolean = false): Boolean { + return settings.any { it.property.equals(property, ignoreCase) } + } + + /** + * Determines whether the specified role is contained in this configuration. + * + * @param role The role to find in this configuration. + * @return Returns true if the specified role is contained in this configuration; otherwise, false. + */ + fun hasRole(role: Role): Boolean { + return hasSetting(role) + } + + /** + * Determines whether the specified role is contained in this configuration. + * + * @param role The role to find in this configuration. + * @return Returns true if the specified role is contained in this configuration; otherwise, false. + */ + fun hasRole(role: String): Boolean { + return roles.any { it.normalizedValue == role.toUpperCase() } + } + + /** + * Determines whether the specified permission is contained in this configuration. + * + * @param permission The permission to find in this configuration. + * @return Returns true if the specified permission is contained in this configuration; otherwise, false. + */ + fun hasPermission(permission: Permission): Boolean { + return hasSetting(permission) + } + + /** + * Determines whether the specified permission is contained in this configuration. + * + * @param permission The permission to find in this configuration. + * @return Returns true if the specified permission is contained in this configuration; otherwise, false. + */ + fun hasPermission(permission: String): Boolean { + return permissions.any { it.normalizedValue == permission.toUpperCase() } + } + + /** + * Adds the specified settings to this configuration. + * + * @param settings The settings to add to this configuration. + * @return Returns a new configuration containing the existing and new settings. + */ + fun addSettings(settings: Iterable>): Configuration { + return copy(settings = this.settings + settings) + } + + /** + * Adds the specified settings to this configuration. + * + * @param settings The settings to add to this configuration. + * @return Returns a new configuration with the specified settings added. + */ + fun addSettings(vararg settings: Setting<*>): Configuration { + return addSettings(settings.toList()) + } + + /** + * Removes the specified settings from this configuration. + * + * @param settings The settings to remove from this configuration. + * @return Returns a new configuration with the specified settings removed. + */ + fun removeSettings(settings: Iterable>): Configuration { + return copy(settings = this.settings - settings) + } + + /** + * Removes the specified settings from this configuration. + * + * @param settings The settings to remove from this configuration. + * @return Returns a new configuration with the specified settings removed. + */ + fun removeSettings(vararg settings: Setting<*>): Configuration { + return removeSettings(settings.toList()) + } + + /** + * Adds the specified roles to this configuration. + * + * @param roles The roles to add to this configuration. + * @return Returns a new configuration with the specified roles added. + */ + fun addRoles(roles: Iterable): Configuration { + return copy(settings = this.settings + roles) + } + + /** + * Adds the specified roles to this configuration. + * + * @param roles The roles to add to this configuration. + * @return Returns a new configuration with the specified roles added. + */ + fun addRoles(vararg roles: Role): Configuration { + return addRoles(roles.toList()) + } + + /** + * Removes the specified roles from this configuration. + * + * @param roles The roles to remove from this configuration. + * @return Returns a new configuration with the specified roles removed. + */ + fun removeRoles(roles: Iterable): Configuration { + return copy(settings = this.settings - roles) + } + + /** + * Removes the specified roles from this configuration. + * + * @param roles The roles to remove from this configuration. + * @return Returns a new configuration with the specified roles removed. + */ + fun removeRoles(vararg roles: Role): Configuration { + return removeRoles(roles.toList()) + } + + /** + * Adds the specified permissions to this configuration. + * + * @param permissions The permissions to add to this configuration. + * @return Returns a new configuration with the specified permissions added. + */ + fun addPermissions(permissions: Iterable): Configuration { + return copy(settings = this.settings + permissions) + } + + /** + * Adds the specified permissions to this configuration. + * + * @param permissions The permissions to add to this configuration. + * @return Returns a new configuration with the specified permissions added. + */ + fun addPermissions(vararg permissions: Permission): Configuration { + return addPermissions(permissions.toList()) + } + + /** + * Removes the specified permissions from this configuration. + * + * @param permissions The permissions to remove from this configuration. + * @return Returns a new configuration with the specified permissions removed. + */ + fun removePermissions(permissions: Iterable): Configuration { + return copy(settings = this.settings - permissions) + } + + /** + * Removes the specified permissions from this configuration. + * + * @param permissions The permissions to remove from this configuration. + * @return Returns a new configuration with the specified permissions removed. + */ + fun removePermissions(vararg permissions: Permission): Configuration { + return removePermissions(permissions.toList()) + } + + /** + * Computes the hash of all settings. + */ + private fun computeHash(): SecureHash { + return if (settings.count() == 0) return SecureHash.zeroHash + else settings.map { it.hash }.sorted().reduce { lhs, rhs -> SecureHash.sha256("$lhs$rhs") } + } +} diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/ConfigurationBuilder.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/ConfigurationBuilder.kt new file mode 100644 index 0000000..803bb54 --- /dev/null +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/ConfigurationBuilder.kt @@ -0,0 +1,202 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.contract + +class ConfigurationBuilder(private val settings: MutableSet>) { + + constructor(configuration: Configuration) : this(configuration.settings.toMutableSet()) + + /** + * Adds the specified setting to this configuration builder. + * + * @param property The property of the setting to add. + * @param value The value of the setting to add. + */ + @ConfigurationBuilderDslContext + fun addSetting(property: String, value: Any) { + addSettings(Setting(property, value)) + } + + /** + * Adds the specified settings to this configuration builder. + * + * @param settings The settings to add to this configuration builder. + */ + @ConfigurationBuilderDslContext + fun addSettings(settings: Iterable>) { + this.settings += settings + } + + /** + * Adds the specified settings to this configuration builder. + * + * @param settings The settings to add to this configuration builder. + */ + @ConfigurationBuilderDslContext + fun addSettings(vararg settings: Setting<*>) { + return addSettings(settings.toList()) + } + + /** + * Removes the specified settings from this configuration builder. + * + * @param settings The settings to remove from this configuration builder. + */ + @ConfigurationBuilderDslContext + fun removeSettings(settings: Iterable>) { + this.settings -= settings + } + + /** + * Removes the specified settings from this configuration builder. + * + * @param settings The settings to remove from this configuration builder. + */ + @ConfigurationBuilderDslContext + fun removeSettings(vararg settings: Setting<*>) { + return removeSettings(settings.toList()) + } + + /** + * Adds the specified roles to this configuration builder. + * + * @param roles The roles to add to this configuration builder. + */ + @ConfigurationBuilderDslContext + fun addRoles(roles: Iterable) { + this.settings += roles + } + + /** + * Adds the specified roles to this configuration builder. + * + * @param roles The roles to add to this configuration builder. + */ + @ConfigurationBuilderDslContext + fun addRoles(vararg roles: Role) { + return addRoles(roles.toList()) + } + + /** + * Adds the specified roles to this configuration builder. + * + * @param roles The roles to add to this configuration builder. + */ + @ConfigurationBuilderDslContext + fun addRoles(vararg roles: String) { + return addRoles(roles.map { Role(it) }) + } + + /** + * Removes the specified roles from this configuration builder. + * + * @param roles The roles to remove from this configuration builder. + */ + @ConfigurationBuilderDslContext + fun removeRoles(roles: Iterable) { + this.settings -= roles + } + + /** + * Removes the specified roles from this configuration builder. + * + * @param roles The roles to remove from this configuration builder. + */ + @ConfigurationBuilderDslContext + fun removeRoles(vararg roles: Role) { + return removeRoles(roles.toList()) + } + + /** + * Removes the specified roles from this configuration builder. + * + * @param roles The roles to remove from this configuration builder. + */ + @ConfigurationBuilderDslContext + fun removeRoles(vararg roles: String) { + return removeRoles(roles.map { Role(it) }) + } + + /** + * Adds the specified permissions to this configuration builder. + * + * @param permissions The permissions to add to this configuration builder. + */ + @ConfigurationBuilderDslContext + fun addPermissions(permissions: Iterable) { + this.settings += permissions + } + + /** + * Adds the specified permissions to this configuration builder. + * + * @param permissions The permissions to add to this configuration builder. + */ + @ConfigurationBuilderDslContext + fun addPermissions(vararg permissions: Permission) { + return addPermissions(permissions.toList()) + } + + /** + * Adds the specified permissions to this configuration builder. + * + * @param permissions The permissions to add to this configuration builder. + */ + @ConfigurationBuilderDslContext + fun addPermissions(vararg permissions: String) { + return addPermissions(permissions.map { Permission(it) }) + } + + /** + * Removes the specified permissions from this configuration builder. + * + * @param permissions The permissions to remove from this configuration builder. + */ + @ConfigurationBuilderDslContext + fun removePermissions(permissions: Iterable) { + this.settings -= permissions + } + + /** + * Removes the specified permissions from this configuration builder. + * + * @param permissions The permissions to remove from this configuration builder. + */ + @ConfigurationBuilderDslContext + fun removePermissions(vararg permissions: Permission) { + return removePermissions(permissions.toList()) + } + + /** + * Removes the specified permissions from this configuration builder. + * + * @param permissions The permissions to remove from this configuration builder. + */ + @ConfigurationBuilderDslContext + fun removePermissions(vararg permissions: String) { + return removePermissions(permissions.map { Permission(it) }) + } + + /** + * Converts this configuration builder to a configuration. + * + * @return Returns a configuration containing the settings built by this configuration builder. + */ + internal fun toConfiguration(): Configuration { + return Configuration(settings) + } +} diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Extensions.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/ConfigurationBuilderDslContext.kt similarity index 68% rename from onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Extensions.kt rename to onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/ConfigurationBuilderDslContext.kt index 214c4cb..0b0f381 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Extensions.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/ConfigurationBuilderDslContext.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,8 @@ package io.onixlabs.corda.bnms.contract -inline fun Iterable.isDistinctBy(selector: (T) -> K): Boolean { - return count() == distinctBy(selector).count() -} - -inline fun Setting<*>.cast(): Setting { - return Setting(property, T::class.java.cast(value)) -} +/** + * Represents the marker for functions that belong to the configuration builder. + */ +@DslMarker +annotation class ConfigurationBuilderDslContext diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Network.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Network.kt index ae6814e..862598f 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Network.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Network.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,15 +16,23 @@ package io.onixlabs.corda.bnms.contract -import io.onixlabs.corda.core.contract.Hashable import net.corda.core.crypto.SecureHash import net.corda.core.identity.AbstractParty -class Network( - value: String, - val operator: AbstractParty? = null -) : Setting(NETWORK, value.toUpperCase()), Hashable { +/** + * Represents a reference to a business network. + * + * @property property The property of the network setting, which is always "Network". + * @property normalizedProperty The normalized property of the network setting, which is always "NETWORK". + * @property value The value of the network, which is usually the name of the business network. + * @property normalizedValue The normalized value of the network. + * @property operator The business network operator, or null if the business network is decentralized. + * @property hash The hash that uniquely identifies the network reference. + */ +class Network(value: String, val operator: AbstractParty? = null) : StringSetting(NETWORK, value) { + + companion object; override val hash: SecureHash - get() = SecureHash.sha256("$value$operator") + get() = SecureHash.sha256("${super.hash}$operator") } diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/NetworkState.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/NetworkState.kt index 964e2d7..f3fa8f0 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/NetworkState.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/NetworkState.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,13 @@ package io.onixlabs.corda.bnms.contract -import io.onixlabs.corda.core.contract.ChainState -import net.corda.core.contracts.LinearState -import net.corda.core.schemas.QueryableState +import net.corda.core.contracts.ContractState -interface NetworkState : ChainState, LinearState, QueryableState { +/** + * Defines a contract state that belongs to a business network. + * + * @property network The business network that the state belongs to. + */ +interface NetworkState : ContractState { val network: Network -} \ No newline at end of file +} diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Permission.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Permission.kt index be8c507..458c118 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Permission.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Permission.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,4 +16,15 @@ package io.onixlabs.corda.bnms.contract -class Permission(value: String) : Setting(PERMISSION, value.toUpperCase()) \ No newline at end of file +/** + * Represents a network permission. + * + * @property property The property of the permission, which is always "Permission". + * @property normalizedProperty The normalized property of the permission, which is always "PERMISSION". + * @property value The value of the permission. + * @property normalizedValue The normalized value of the permission. + * @property hash The hash that uniquely identifies the permission. + */ +class Permission(value: String) : StringSetting(PERMISSION, value) { + companion object +} diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Role.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Role.kt index 071296b..ba8e474 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Role.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Role.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,4 +16,15 @@ package io.onixlabs.corda.bnms.contract -class Role(value: String) : Setting(ROLE, value.toUpperCase()) \ No newline at end of file +/** + * Represents a network role. + * + * @property property The property of the role, which is always "Role". + * @property normalizedProperty The normalized property of the role, which is always "ROLE". + * @property value The value of the role. + * @property normalizedValue The normalized value of the role. + * @property hash The hash that uniquely identifies the role. + */ +class Role(value: String) : StringSetting(ROLE, value) { + companion object +} diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Setting.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Setting.kt index 0a70c08..8e7c907 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Setting.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/Setting.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,17 +16,40 @@ package io.onixlabs.corda.bnms.contract -import io.onixlabs.corda.identityframework.contract.Claim +import io.onixlabs.corda.core.contract.Hashable +import io.onixlabs.corda.identityframework.contract.claims.Claim +import net.corda.core.crypto.SecureHash import java.util.* -open class Setting(property: String, value: T) : Claim(property.toUpperCase(), value) { +/** + * Represents the base class for implementing settings. + * + * @property T The underlying setting value type. + * @property property The property of the setting. + * @property normalizedProperty The normalized property of the setting, which is an upper-case property. + * @property value The value of the setting. + * @property hash The hash that uniquely identifies the setting. + */ +open class Setting(property: String, value: T) : Claim(property, value), Hashable { - internal companion object { - const val NETWORK = "NETWORK" - const val ROLE = "ROLE" - const val PERMISSION = "PERMISSION" + companion object { + internal const val NETWORK = "Network" + internal const val ROLE = "Role" + internal const val PERMISSION = "Permission" } + val normalizedProperty: String + get() = property.toUpperCase() + + override val hash: SecureHash + get() = SecureHash.sha256("$normalizedProperty$value") + + /** + * Determines whether the specified object is equal to the current object. + * + * @param other The object to compare with the current object. + * @return Returns true if the specified object is equal to the current object; otherwise, false. + */ override fun equals(other: Any?): Boolean { return this === other || (other is Setting<*> && other.javaClass == javaClass @@ -34,7 +57,12 @@ open class Setting(property: String, value: T) : Claim(property.toUp && value == other.value) } + /** + * Serves as the default hash function. + * + * @return Returns a hash code for the current object. + */ override fun hashCode(): Int { return Objects.hash(property, value) } -} \ No newline at end of file +} diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/StringSetting.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/StringSetting.kt new file mode 100644 index 0000000..2d37f1b --- /dev/null +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/StringSetting.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.contract + +import net.corda.core.crypto.SecureHash +import java.util.* + +/** + * Represents the base class for implementing string value settings. + * + * @property property The property of the setting. + * @property normalizedProperty The normalized property of the setting, which is an upper-case property. + * @property value The value of the setting. + * @property normalizedValue The normalized value of the setting, which is an upper-case value. + * @property hash The hash that uniquely identifies the setting. + */ +open class StringSetting(property: String, value: String) : Setting(property, value) { + + companion object + + val normalizedValue: String + get() = value.toUpperCase() + + override val hash: SecureHash + get() = SecureHash.sha256("$normalizedProperty$normalizedValue") + + /** + * Determines whether the specified object is equal to the current object. + * + * @param other The object to compare with the current object. + * @return Returns true if the specified object is equal to the current object; otherwise, false. + */ + override fun equals(other: Any?): Boolean { + return this === other || (other is StringSetting + && other.javaClass == javaClass + && normalizedProperty == other.normalizedProperty + && normalizedValue == other.normalizedValue) + } + + /** + * Serves as the default hash function. + * + * @return Returns a hash code for the current object. + */ + override fun hashCode(): Int { + return Objects.hash(normalizedProperty, normalizedValue) + } +} diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/Extensions.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/Extensions.kt index 2fa7296..b315bc1 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/Extensions.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/Extensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,16 +16,31 @@ package io.onixlabs.corda.bnms.contract.membership -import io.onixlabs.corda.identityframework.contract.AttestationStatus -import io.onixlabs.corda.identityframework.contract.toAttestationPointer +import io.onixlabs.corda.identityframework.contract.attestations.AttestationStatus +import io.onixlabs.corda.identityframework.contract.toStaticAttestationPointer import net.corda.core.contracts.StateAndRef +import net.corda.core.contracts.StateRef import net.corda.core.contracts.UniqueIdentifier import net.corda.core.identity.AbstractParty +/** + * Gets the next [Membership] output, appending the previous [Membership] state's [StateRef]. + * + * @return Returns the next [Membership] output, appending the previous [Membership] state's [StateRef]. + */ fun StateAndRef.getNextOutput(): Membership { return state.data.copy(previousStateRef = ref) } +/** + * Creates a [MembershipAttestation] for the specified [Membership]. + * + * @param attestor The attestor who is attesting to the [Membership]. + * @param status The status of the attestation. + * @param metadata Any extra metadata that should be applied to the attestation. + * @param linearId The linear ID of the attestation. + * @return Returns a [MembershipAttestation] for the specified [Membership]. + */ fun StateAndRef.attest( attestor: AbstractParty, status: AttestationStatus, @@ -33,42 +48,99 @@ fun StateAndRef.attest( linearId: UniqueIdentifier = UniqueIdentifier() ) = MembershipAttestation(attestor, this, status, metadata, linearId) +/** + * Creates an accepted [MembershipAttestation] for the specified [Membership]. + * + * @param attestor The attestor who is attesting to the [Membership]. + * @param metadata Any extra metadata that should be applied to the attestation. + * @param linearId The linear ID of the attestation. + * @return Returns an accepted [MembershipAttestation] for the specified [Membership]. + */ fun StateAndRef.accept( attestor: AbstractParty, metadata: Map = emptyMap(), linearId: UniqueIdentifier = UniqueIdentifier() ) = attest(attestor, AttestationStatus.ACCEPTED, metadata, linearId) +/** + * Creates a rejected [MembershipAttestation] for the specified [Membership]. + * + * @param attestor The attestor who is attesting to the [Membership]. + * @param metadata Any extra metadata that should be applied to the attestation. + * @param linearId The linear ID of the attestation. + * @return Returns a rejected [MembershipAttestation] for the specified [Membership]. + */ fun StateAndRef.reject( attestor: AbstractParty, metadata: Map = emptyMap(), linearId: UniqueIdentifier = UniqueIdentifier() ) = attest(attestor, AttestationStatus.REJECTED, metadata, linearId) +/** + * Amends a [MembershipAttestation] pointing to the existing [Membership] state. + * + * @param status The amended status of the [MembershipAttestation]. + * @param metadata Any extra metadata that should be applied to the attestation. + * @return Returns an amended [MembershipAttestation] pointing to the existing [Membership] state. + */ fun StateAndRef.amend( status: AttestationStatus, metadata: Map = this.state.data.metadata ) = this.state.data.amend(ref, status, state.data.pointer, metadata) +/** + * Amends a [MembershipAttestation] pointing to an evolved [Membership] state. + * + * @param status The amended status of the [MembershipAttestation]. + * @param membership The evolved [Membership] state that the amended [MembershipAttestation] will point to. + * @param metadata Any extra metadata that should be applied to the attestation. + * @return Returns an amended [MembershipAttestation] pointing to an evolved [Membership] state. + */ fun StateAndRef.amend( membership: StateAndRef, status: AttestationStatus, metadata: Map = this.state.data.metadata -) = this.state.data.amend(ref, status, membership.toAttestationPointer(), metadata) +) = this.state.data.amend(ref, status, membership.toStaticAttestationPointer(), metadata) +/** + * Amends and accepts a [MembershipAttestation] pointing to the existing [Membership] state. + * + * @param metadata Any extra metadata that should be applied to the attestation. + * @return Returns an amended and accepted [MembershipAttestation] pointing to the existing [Membership] state. + */ fun StateAndRef.accept( metadata: Map = this.state.data.metadata ) = amend(AttestationStatus.ACCEPTED, metadata) +/** + * Amends and accepts a [MembershipAttestation] pointing to an evolved [Membership] state. + * + * @param membership The evolved [Membership] state that the amended [MembershipAttestation] will point to. + * @param metadata Any extra metadata that should be applied to the attestation. + * @return Returns an amended and accepted [MembershipAttestation] pointing to an evolved [Membership] state. + */ fun StateAndRef.accept( membership: StateAndRef, metadata: Map = this.state.data.metadata ) = amend(membership, AttestationStatus.ACCEPTED, metadata) +/** + * Amends and rejects a [MembershipAttestation] pointing to the existing [Membership] state. + * + * @param metadata Any extra metadata that should be applied to the attestation. + * @return Returns an amended and rejected [MembershipAttestation] pointing to the existing [Membership] state. + */ fun StateAndRef.reject( metadata: Map = this.state.data.metadata ) = amend(AttestationStatus.REJECTED, metadata) +/** + * Amends and rejects a [MembershipAttestation] pointing to an evolved [Membership] state. + * + * @param membership The evolved [Membership] state that the amended [MembershipAttestation] will point to. + * @param metadata Any extra metadata that should be applied to the attestation. + * @return Returns an amended and rejected [MembershipAttestation] pointing to an evolved [Membership] state. + */ fun StateAndRef.reject( membership: StateAndRef, metadata: Map = this.state.data.metadata diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/Membership.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/Membership.kt index ec083c9..7df2b1a 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/Membership.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/Membership.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,212 +19,101 @@ package io.onixlabs.corda.bnms.contract.membership import io.onixlabs.corda.bnms.contract.* import io.onixlabs.corda.bnms.contract.membership.MembershipSchema.MembershipEntity import io.onixlabs.corda.bnms.contract.membership.MembershipSchema.MembershipSchemaV1 +import io.onixlabs.corda.core.contract.ChainState import io.onixlabs.corda.core.contract.Hashable -import io.onixlabs.corda.identityframework.contract.AbstractClaim +import io.onixlabs.corda.identityframework.contract.claims.AbstractClaim import net.corda.core.contracts.BelongsToContract +import net.corda.core.contracts.LinearState import net.corda.core.contracts.StateRef import net.corda.core.contracts.UniqueIdentifier import net.corda.core.crypto.SecureHash import net.corda.core.identity.AbstractParty import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.PersistentState +import net.corda.core.schemas.QueryableState +/** + * Represents a membership to a business network. + * + * @property network The business network that this membership belongs to. + * @property holder The holder of the membership. + * @property identity The claims that represent the identity of the holder of the membership. + * @property configuration The configuration of the membership, including settings, roles and permissions. + * @property linearId The unique identifier of the membership. + * @property previousStateRef The state reference of the previous membership state in the chain. + * @property isNetworkOperator Determines whether this membership represents the business network operator. + * @property hash The unique hash that represents this membership. + * @property participants The participants of this membership; namely the holder and optionally the network operator. + */ @BelongsToContract(MembershipContract::class) data class Membership( override val network: Network, val holder: AbstractParty, val identity: Set> = emptySet(), - val settings: Set> = emptySet(), + val configuration: Configuration = Configuration(), override val linearId: UniqueIdentifier = UniqueIdentifier(), override val previousStateRef: StateRef? = null -) : NetworkState, Hashable { +) : NetworkState, ChainState, LinearState, QueryableState, Hashable { + + constructor( + network: Network, + holder: AbstractParty, + identity: Set> = emptySet(), + settings: Set> = emptySet(), + linearId: UniqueIdentifier = UniqueIdentifier() + ) : this(network, holder, identity, Configuration(settings), linearId, null) val isNetworkOperator: Boolean get() = holder == network.operator - val roles: Set - get() = getSettingsByType() - - val permissions: Set - get() = getSettingsByType() - override val hash: SecureHash - get() = SecureHash.sha256("$network$holder$previousStateRef") + get() = SecureHash.sha256("$network$holder${configuration.hash}$previousStateRef") override val participants: List get() = setOf(holder, network.operator).filterNotNull() - fun hasSetting(setting: Setting<*>): Boolean { - return setting in settings - } - - fun hasSetting(property: String): Boolean { - return settings.any { it.property == property.toUpperCase() } - } - - fun > getSettingsByType(settingClass: Class, property: String? = null): Set { - return settings - .filter { it.javaClass == settingClass } - .filter { property?.toUpperCase()?.equals(it.property) ?: true } - .map { settingClass.cast(it) } - .toSet() - } - - inline fun > getSettingsByType(property: String? = null): Set { - return getSettingsByType(T::class.java, property) - } - - fun > getSettingByTypeOrNull(settingClass: Class, property: String? = null): T? { - return getSettingsByType(settingClass, property).singleOrNull() - } - - fun > getSettingByType(settingClass: Class, property: String? = null): T { - return getSettingsByType(settingClass, property).single() - } - - inline fun > getSettingByTypeOrNull(property: String? = null): T? { - return getSettingByTypeOrNull(T::class.java, property) - } - - inline fun > getSettingByType(property: String? = null): T { - return getSettingByType(T::class.java, property) - } - - fun getSettingsByValueType(valueClass: Class, property: String? = null): Set> { - return settings - .filter { it.value.javaClass == valueClass } - .filter { property?.toUpperCase()?.equals(it.property) ?: true } - .map { Setting(it.property, valueClass.cast(it.value)) } - .toSet() - } - - inline fun getSettingsByValueType(property: String? = null): Set> { - return getSettingsByValueType(T::class.java, property) - } - - fun getSettingByValueTypeOrNull(valueClass: Class, property: String? = null): Setting? { - return getSettingsByValueType(valueClass, property).singleOrNull() - } - - fun getSettingByValueType(valueClass: Class, property: String? = null): Setting { - return getSettingsByValueType(valueClass, property).single() - } - - inline fun getSettingByValueTypeOrNull(property: String? = null): Setting? { - return getSettingByValueTypeOrNull(T::class.java, property) - } - - inline fun getSettingByValueType(property: String? = null): Setting { - return getSettingByValueType(T::class.java, property) - } - - fun addSetting(property: String, value: T): Membership where T : Any { - return addSettings(Setting(property, value)) - } - - fun addSettings(settings: Set>): Membership where T : Any { - return copy(settings = this.settings + settings) - } - - fun addSettings(vararg settings: Setting): Membership where T : Any { - return addSettings(settings.toSet()) - } - - fun removeSetting(property: String, value: T): Membership where T : Any { - return removeSettings(Setting(property, value)) - } - - fun removeSettings(settings: Set>): Membership where T : Any { - return copy(settings = this.settings - settings) - } - - fun removeSettings(vararg settings: Setting): Membership where T : Any { - return removeSettings(settings.toSet()) - } - - fun hasRole(role: Role): Boolean { - return role in roles - } - - fun hasRole(role: String): Boolean { - return hasRole(Role(role)) - } - - fun addRoles(roles: Set): Membership { - return addSettings(roles) - } - - fun addRoles(vararg roles: Role): Membership { - return addRoles(roles.toSet()) - } - - fun addRoles(vararg roles: String): Membership { - return addRoles(roles.map { Role(it) }.toSet()) - } - - fun removeRoles(roles: Set): Membership { - return removeSettings(roles) - } - - fun removeRoles(vararg roles: Role): Membership { - return removeRoles(roles.toSet()) - } - - fun removeRoles(vararg roles: String): Membership { - return removeRoles(roles.map { Role(it) }.toSet()) - } - - fun hasPermission(permission: Permission): Boolean { - return permission in permissions - } - - fun hasPermission(permission: String): Boolean { - return hasPermission(Permission(permission)) - } - - fun addPermissions(permissions: Set): Membership { - return addSettings(permissions) - } - - fun addPermissions(vararg permissions: Permission): Membership { - return addPermissions(permissions.toSet()) - } - - fun addPermissions(vararg permissions: String): Membership { - return addPermissions(permissions.map { Permission(it) }.toSet()) - } - - fun removePermissions(permissions: Set): Membership { - return removeSettings(permissions) - } - - fun removePermissions(vararg permissions: Permission): Membership { - return removePermissions(permissions.toSet()) - } - - fun removePermissions(vararg permissions: String): Membership { - return removePermissions(permissions.map { Permission(it) }.toSet()) - } - + /** + * Configures this membership. + * + * @param action The action which will configure this membership. + * @return Returns a new membership state containing the updated configuration. + */ + @ConfigurationBuilderDslContext + fun configure(action: ConfigurationBuilder.() -> Unit): Membership { + val builder = ConfigurationBuilder(configuration) + action(builder) + return copy(configuration = builder.toConfiguration()) + } + + /** + * Generates a persistent state entity from this contract state. + * + * @param schema The mapped schema from which to generate a persistent state entity. + * @return Returns a persistent state entity. + */ override fun generateMappedObject(schema: MappedSchema): PersistentState = when (schema) { - is MembershipSchemaV1 -> MembershipEntity( - linearId = linearId.id, - externalId = linearId.externalId, - holder = holder, - networkValue = network.value, - networkOperator = network.operator, - networkHash = network.hash.toString(), - isNetworkOperator = isNetworkOperator, - hash = hash.toString() - ) + is MembershipSchemaV1 -> MembershipEntity(this) else -> throw IllegalArgumentException("Unrecognised schema: $schema.") } + /** + * Gets the supported schemas of this state. + * + * @return Returns the supported schemas of this state. + */ override fun supportedSchemas(): Iterable { return listOf(MembershipSchemaV1) } + /** + * Ensures that the immutable properties of this membership have not changed. + * + * @param other The membership to compare with the current membership. + * @return Returns true if the immutable properties have not changed; otherwise, false. + */ internal fun immutableEquals(other: Membership): Boolean { - return this === other || (network == other.network && holder == other.holder && linearId == other.linearId) + return this === other || (network == other.network + && holder == other.holder + && linearId == other.linearId) } } diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipAttestation.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipAttestation.kt index b5320a5..073d814 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipAttestation.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipAttestation.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,10 +20,10 @@ import io.onixlabs.corda.bnms.contract.Network import io.onixlabs.corda.bnms.contract.NetworkState import io.onixlabs.corda.bnms.contract.membership.MembershipAttestationSchema.MembershipAttestationEntity import io.onixlabs.corda.bnms.contract.membership.MembershipAttestationSchema.MembershipAttestationSchemaV1 -import io.onixlabs.corda.identityframework.contract.Attestation -import io.onixlabs.corda.identityframework.contract.AttestationPointer -import io.onixlabs.corda.identityframework.contract.AttestationStatus -import io.onixlabs.corda.identityframework.contract.toAttestationPointer +import io.onixlabs.corda.identityframework.contract.attestations.Attestation +import io.onixlabs.corda.identityframework.contract.attestations.AttestationPointer +import io.onixlabs.corda.identityframework.contract.attestations.AttestationStatus +import io.onixlabs.corda.identityframework.contract.toStaticAttestationPointer import net.corda.core.contracts.BelongsToContract import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.StateRef @@ -32,6 +32,22 @@ import net.corda.core.identity.AbstractParty import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.PersistentState +/** + * Represents a membership attestation; a proof that a particular [Membership] state has been witnessed. + * + * @property network The business network that this membership attestation belongs to. + * @property attestor The party who is attesting to the witnessed [Membership] state. + * @property attestees The parties of this attestation, usually the participants of the attested [Membership] state. + * @property pointer The pointer to the attested [Membership] state. + * @property status The status of the attestation. + * @property metadata Additional information about the attestation. + * @property linearId The unique identifier of the attestation. + * @property previousStateRef The state reference of the previous state in the chain. + * @property hash The unique hash which represents this attestation. + * @property participants The participants of this attestation; namely the attestor and attestees. + * @property holder A reference to the only attestee of the attestation; namely the [Membership] holder. + * @property isNetworkOperator Determines whether this membership attestation is attesting to the business network operator's [Membership] state. + */ @BelongsToContract(MembershipAttestationContract::class) class MembershipAttestation internal constructor( override val network: Network, @@ -52,6 +68,19 @@ class MembershipAttestation internal constructor( previousStateRef ), NetworkState { + /** + * Represents a membership attestation; a proof that a particular [Membership] state has been witnessed. + * + * @param attestor The party who is attesting to the witnessed [Membership] state. + * @param membership The [Membership] state that is being witnessed and attested. + * @param status The status of the attestation. + * @param metadata Additional information about the attestation. + * @param linearId The unique identifier of the attestation. + * @param previousStateRef The state reference of the previous state in the chain. + * + * The primary constructor of the [MembershipAttestation] class is deliberately private + * to enforce static attestation pointers via the secondary constructor. + */ constructor( attestor: AbstractParty, membership: StateAndRef, @@ -63,7 +92,7 @@ class MembershipAttestation internal constructor( membership.state.data.network, attestor, setOf(membership.state.data.holder), - membership.toAttestationPointer(), + membership.toStaticAttestationPointer(), status, metadata, linearId, @@ -76,6 +105,15 @@ class MembershipAttestation internal constructor( val isNetworkOperator: Boolean get() = holder == network.operator + /** + * Amends this attestation. + * + * @property previousStateRef The state reference of the previous state in the chain. + * @param status The amended attestation status. + * @param pointer The pointer to the attested state, if a new version of the state is being attested. + * @param metadata Additional information about the attestation. + * @return Returns a new, amended version of this attestation state. + */ override fun amend( previousStateRef: StateRef, status: AttestationStatus, @@ -94,26 +132,22 @@ class MembershipAttestation internal constructor( ) } + /** + * Generates a persistent state entity from this contract state. + * + * @param schema The mapped schema from which to generate a persistent state entity. + * @return Returns a persistent state entity. + */ override fun generateMappedObject(schema: MappedSchema): PersistentState = when (schema) { - is MembershipAttestationSchemaV1 -> MembershipAttestationEntity( - linearId = linearId.id, - externalId = linearId.externalId, - attestor = attestor, - holder = holder, - networkValue = network.value, - networkOperator = network.operator, - networkHash = network.hash.toString(), - pointerStateRef = pointer.stateRef.toString(), - pointerStateClass = pointer.stateClass.canonicalName, - pointerStateLinearId = pointer.stateLinearId!!.id, - pointerHash = pointer.hash.toString(), - status = status, - previousStateRef = previousStateRef?.toString(), - hash = hash.toString() - ) + is MembershipAttestationSchemaV1 -> MembershipAttestationEntity(this) else -> super.generateMappedObject(schema) } + /** + * Gets the supported schemas of this state. + * + * @return Returns the supported schemas of this state. + */ override fun supportedSchemas(): Iterable { return super.supportedSchemas() + MembershipAttestationSchemaV1 } diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipAttestationContract.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipAttestationContract.kt index 8132eff..26b93b4 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipAttestationContract.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipAttestationContract.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,20 +16,23 @@ package io.onixlabs.corda.bnms.contract.membership -import io.onixlabs.corda.identityframework.contract.AttestationContract +import io.onixlabs.corda.core.contract.ContractID +import io.onixlabs.corda.identityframework.contract.attestations.AttestationContract import net.corda.core.contracts.Contract -import net.corda.core.contracts.ContractClassName import net.corda.core.contracts.requireThat import net.corda.core.transactions.LedgerTransaction import java.security.PublicKey +/** + * Represents the smart contract for membership attestations. + */ class MembershipAttestationContract : AttestationContract(), Contract { - companion object { - @JvmStatic - val ID: ContractClassName = this::class.java.enclosingClass.canonicalName - } + companion object : ContractID + /** + * Represents the command rules to issue attestations. + */ internal object Issue { const val CONTRACT_RULE_REFERENCES = "On membership attestation issuing, only one membership state must be referenced." @@ -50,6 +53,9 @@ class MembershipAttestationContract : AttestationContract(), Contract { "On membership attestation issuing, if present, only the network operator can self-attest their membership state." } + /** + * Represents the command rules to amend attestations. + */ internal object Amend { const val CONTRACT_RULE_REFERENCES = "On membership attestation amending, only one membership state must be referenced." @@ -64,6 +70,12 @@ class MembershipAttestationContract : AttestationContract(), Contract { "On membership attestation amending, the attestation network must be equal to the membership network." } + /** + * Provides the extended contract constraints for issuing membership attestations. + * + * @param transaction The ledger transaction to verify. + * @param signers The signers of the transaction. + */ override fun onVerifyIssue(transaction: LedgerTransaction, signers: Set) = requireThat { val memberships = transaction.referenceInputRefsOfType() @@ -79,6 +91,12 @@ class MembershipAttestationContract : AttestationContract(), Contract { Issue.CONTRACT_RULE_SELF_ATTESTATION using (attestation.isNetworkOperator || attestation.attestor != attestation.holder) } + /** + * Provides the extended contract constraints for amending membership attestations. + * + * @param transaction The ledger transaction to verify. + * @param signers The signers of the transaction. + */ override fun onVerifyAmend(transaction: LedgerTransaction, signers: Set) = requireThat { val memberships = transaction.referenceInputRefsOfType() diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipAttestationSchema.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipAttestationSchema.kt index a29758e..34fbbd1 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipAttestationSchema.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipAttestationSchema.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ package io.onixlabs.corda.bnms.contract.membership -import io.onixlabs.corda.identityframework.contract.AttestationStatus +import io.onixlabs.corda.identityframework.contract.attestations.AttestationStatus import net.corda.core.crypto.NullKeys.NULL_PARTY import net.corda.core.identity.AbstractParty import net.corda.core.schemas.MappedSchema @@ -49,20 +49,20 @@ object MembershipAttestationSchema { @Column(name = "network_value", nullable = false) val networkValue: String = "", + @Column(name = "normalized_network_value", nullable = false) + val normalizedNetworkValue: String = "", + @Column(name = "network_operator", nullable = true) val networkOperator: AbstractParty? = null, @Column(name = "network_hash", nullable = false) val networkHash: String = "", - @Column(name = "pointer_state_ref", nullable = false) - val pointerStateRef: String = "", - - @Column(name = "pointer_state_class", nullable = false) - val pointerStateClass: String = "", + @Column(name = "pointer", nullable = false) + val pointer: String = "", - @Column(name = "pointer_state_linear_id", nullable = false) - val pointerStateLinearId: UUID = UUID.randomUUID(), + @Column(name = "pointer_state_type", nullable = false) + val pointerStateType: String = "", @Column(name = "pointer_hash", nullable = false) val pointerHash: String = "", @@ -76,5 +76,22 @@ object MembershipAttestationSchema { @Column(name = "hash", nullable = false, unique = true) val hash: String = "" - ) : PersistentState() + ) : PersistentState() { + constructor(attestation: MembershipAttestation) : this( + linearId = attestation.linearId.id, + externalId = attestation.linearId.externalId, + attestor = attestation.attestor, + holder = attestation.holder, + networkValue = attestation.network.value, + normalizedNetworkValue = attestation.network.normalizedValue, + networkOperator = attestation.network.operator, + networkHash = attestation.network.hash.toString(), + pointer = attestation.pointer.statePointer.toString(), + pointerStateType = attestation.pointer.stateType.canonicalName, + pointerHash = attestation.pointer.hash.toString(), + status = attestation.status, + previousStateRef = attestation.previousStateRef?.toString(), + hash = attestation.hash.toString() + ) + } } diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipContract.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipContract.kt index 0376010..f92fa64 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipContract.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipContract.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,28 +16,25 @@ package io.onixlabs.corda.bnms.contract.membership -import net.corda.core.contracts.* +import io.onixlabs.corda.core.contract.ContractID +import io.onixlabs.corda.core.contract.VerifiedCommandData +import io.onixlabs.corda.core.contract.allowCommands +import net.corda.core.contracts.Contract +import net.corda.core.contracts.requireThat import net.corda.core.transactions.LedgerTransaction import java.security.PublicKey class MembershipContract : Contract { - companion object { - @JvmStatic - val ID: ContractClassName = this::class.java.enclosingClass.canonicalName - } + companion object : ContractID - override fun verify(tx: LedgerTransaction) { - val command = tx.commands.requireSingleCommand() - when (command.value) { - is Issue, is Amend, is Revoke -> command.value.verifyCommand(tx, command.signers.toSet()) - else -> throw IllegalArgumentException("Unrecognised command: ${command.value}") - } - } + override fun verify(tx: LedgerTransaction) = tx.allowCommands( + Issue::class.java, + Amend::class.java, + Revoke::class.java + ) - interface MembershipContractCommand : CommandData { - fun verifyCommand(transaction: LedgerTransaction, signers: Set) - } + interface MembershipContractCommand : VerifiedCommandData object Issue : MembershipContractCommand { @@ -51,9 +48,9 @@ class MembershipContract : Contract { "On membership issuing, the previous state reference of the created membership state must be null." internal const val CONTRACT_RULE_SIGNERS = - "On membership issuing, either the holder or the network operator of the creates membership state must sign the transaction." + "On membership issuing, either the holder or the network operator of the created membership state must sign the transaction." - override fun verifyCommand(transaction: LedgerTransaction, signers: Set) = requireThat { + override fun verify(transaction: LedgerTransaction, signers: Set) = requireThat { val inputs = transaction.inputsOfType() val outputs = transaction.outputsOfType() @@ -84,7 +81,7 @@ class MembershipContract : Contract { internal const val CONTRACT_RULE_SIGNERS = "On membership amending, either the holder or the network operator of the created membership state must sign the transaction." - override fun verifyCommand(transaction: LedgerTransaction, signers: Set) = requireThat { + override fun verify(transaction: LedgerTransaction, signers: Set) = requireThat { val inputs = transaction.inRefsOfType() val outputs = transaction.outputsOfType() @@ -111,7 +108,7 @@ class MembershipContract : Contract { internal const val CONTRACT_RULE_SIGNERS = "On membership revoking, either the holder or the network operator of the consumed membership state must sign the transaction." - override fun verifyCommand(transaction: LedgerTransaction, signers: Set) = requireThat { + override fun verify(transaction: LedgerTransaction, signers: Set) = requireThat { val inputs = transaction.inRefsOfType() val outputs = transaction.outputsOfType() diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipSchema.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipSchema.kt index 7e35f36..001db0d 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipSchema.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/membership/MembershipSchema.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,6 +47,9 @@ object MembershipSchema { @Column(name = "network_value", nullable = false) val networkValue: String = "", + @Column(name = "normalized_network_value", nullable = false) + val normalizedNetworkValue: String = "", + @Column(name = "network_operator", nullable = true) val networkOperator: AbstractParty? = null, @@ -58,5 +61,17 @@ object MembershipSchema { @Column(name = "hash", nullable = false, unique = true) val hash: String = "" - ) : PersistentState() + ) : PersistentState() { + constructor(membership: Membership) : this( + linearId = membership.linearId.id, + externalId = membership.linearId.externalId, + holder = membership.holder, + networkValue = membership.network.value, + normalizedNetworkValue = membership.network.normalizedValue, + networkOperator = membership.network.operator, + networkHash = membership.network.hash.toString(), + isNetworkOperator = membership.isNetworkOperator, + hash = membership.hash.toString() + ) + } } diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/Extensions.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/Extensions.kt index 910ad34..6876320 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/Extensions.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/Extensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,8 @@ package io.onixlabs.corda.bnms.contract.relationship -import io.onixlabs.corda.identityframework.contract.AttestationStatus -import io.onixlabs.corda.identityframework.contract.toAttestationPointer +import io.onixlabs.corda.identityframework.contract.attestations.AttestationStatus +import io.onixlabs.corda.identityframework.contract.toStaticAttestationPointer import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.UniqueIdentifier import net.corda.core.identity.AbstractParty @@ -54,7 +54,7 @@ fun StateAndRef.amend( relationship: StateAndRef, status: AttestationStatus, metadata: Map = this.state.data.metadata -) = this.state.data.amend(ref, status, relationship.toAttestationPointer(), metadata) +) = this.state.data.amend(ref, status, relationship.toStaticAttestationPointer(), metadata) fun StateAndRef.accept( metadata: Map = this.state.data.metadata diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/Relationship.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/Relationship.kt index 788cac2..b5e0c5e 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/Relationship.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/Relationship.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,86 +17,130 @@ package io.onixlabs.corda.bnms.contract.relationship import io.onixlabs.corda.bnms.contract.* +import io.onixlabs.corda.bnms.contract.relationship.RelationshipConfigurationSchema.RelationshipConfigurationEntity import io.onixlabs.corda.bnms.contract.relationship.RelationshipSchema.RelationshipEntity import io.onixlabs.corda.bnms.contract.relationship.RelationshipSchema.RelationshipSchemaV1 import io.onixlabs.corda.bnms.contract.revocation.RevocationLock -import io.onixlabs.corda.core.contract.Hashable -import io.onixlabs.corda.core.contract.participantHash -import net.corda.core.contracts.BelongsToContract -import net.corda.core.contracts.LinearPointer -import net.corda.core.contracts.StateRef -import net.corda.core.contracts.UniqueIdentifier +import io.onixlabs.corda.core.contract.* +import io.onixlabs.corda.core.services.equalTo +import io.onixlabs.corda.core.services.vaultQuery +import net.corda.core.contracts.* import net.corda.core.crypto.SecureHash import net.corda.core.identity.AbstractParty +import net.corda.core.node.services.vault.QueryCriteria import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.PersistentState +import net.corda.core.schemas.QueryableState +/** + * Represents a multi-lateral relationship between participants of a business network. + * + * @property network The business network that this relationship belongs to. + * @property members The members of this relationship and their relationship configuration. + * @property linearId The unique identifier of the relationship. + * @property previousStateRef The state reference of the previous relationship state in the chain. + * @property configurations A resolver for all relationship configurations that belong to this relationship. + * @property hash The unique hash that represents this relationship. + * @property participants The participants of this relationship; namely the relationship members. + */ @BelongsToContract(RelationshipContract::class) data class Relationship( override val network: Network, - val members: Set, - val settings: Set> = emptySet(), + val members: Map = emptyMap(), override val linearId: UniqueIdentifier = UniqueIdentifier(), override val previousStateRef: StateRef? = null -) : NetworkState, Hashable { - - init { - check(members.isDistinctBy { it.member }) { - "Cannot create a relationship with duplicate members." - } +) : NetworkState, ChainState, LinearState, QueryableState, Hashable { - check(settings.isDistinctBy { it.property }) { - "Cannot create a relationship with duplicate settings." - } - } + val configurations: PluralResolvable + get() = RelationshipConfigurationResolver(linearId) override val hash: SecureHash get() = SecureHash.sha256("$network${participants.participantHash}$previousStateRef") override val participants: List - get() = members.map { it.member }.distinct() + get() = members.map { it.key } + /** + * Creates revocation locks for each relationship participant. + * + * @return Returns a list of [RevocationLock] pointing to this relationship for each participant. + */ fun createRevocationLocks(): List> { - return members.map { RevocationLock(it.member, LinearPointer(this.linearId, this.javaClass, false)) } + return participants.map { RevocationLock(it, LinearPointer(this.linearId, this.javaClass, false)) } } + /** + * Configures this relationship for the specified participant. + * + * @param member The member of the relationship which will be configured. + * @param action The action which will configure this relationship. + * @return Returns a new relationship state containing the updated configuration. + */ + @ConfigurationBuilderDslContext + fun configure(member: AbstractParty, action: ConfigurationBuilder.() -> Unit): Relationship { + val configuration = members[member] + ?: throw IllegalArgumentException("The specified member was not found in this relationship: $member.") + val builder = ConfigurationBuilder(configuration) + action(builder) + val mutableMembers = members.toMutableMap() + mutableMembers[member] = builder.toConfiguration() + return copy(members = mutableMembers) + } + + /** + * Generates a persistent state entity from this contract state. + * + * @param schema The mapped schema from which to generate a persistent state entity. + * @return Returns a persistent state entity. + */ override fun generateMappedObject(schema: MappedSchema): PersistentState = when (schema) { - is RelationshipSchemaV1 -> RelationshipEntity( - linearId = linearId.id, - externalId = linearId.externalId, - networkValue = network.value, - networkOperator = network.operator, - networkHash = network.hash.toString(), - hash = hash.toString() - ) + is RelationshipSchemaV1 -> RelationshipEntity(this) else -> throw IllegalArgumentException("Unrecognised schema: $schema.") } + /** + * Gets the supported schemas of this state. + * + * @return Returns the supported schemas of this state. + */ override fun supportedSchemas(): Iterable { return listOf(RelationshipSchemaV1) } - fun addSettings(vararg settings: Setting): Relationship { - return copy(settings = this.settings + settings) - } - - fun addSetting(property: String, value: T): Relationship { - return addSettings(Setting(property, value)) - } - - fun removeSettings(vararg settings: Setting): Relationship { - return copy(settings = this.settings - settings) - } - - inline fun > getSetting(property: String): T? { - return settings.filterIsInstance().singleOrNull { it.property == property.toUpperCase() } + /** + * Ensures that the immutable properties of this relationship have not changed. + * + * @param other The relationship to compare with the current relationship. + * @return Returns true if the immutable properties have not changed; otherwise, false. + */ + internal fun immutableEquals(other: Relationship): Boolean { + return this === other || (network == other.network && linearId == other.linearId) } - inline fun getSettingByValueType(property: String): Setting? { - return settings.singleOrNull { it.property == property.toUpperCase() }?.cast() - } + /** + * Represents the resolver which will be used to resolve relationship configurations for the specified relationship linear ID. + * + * @param relationshipLinearId The relationship linear ID for which to resolve relationship configurations. + */ + private class RelationshipConfigurationResolver( + private val relationshipLinearId: UniqueIdentifier + ) : AbstractPluralResolvable() { + + /** + * The vault query criteria which will be used to resolve relationship configurations. + */ + override val criteria: QueryCriteria get() = vaultQuery { + expression(RelationshipConfigurationEntity::relationshipLinearId equalTo relationshipLinearId.id) + } - internal fun immutableEquals(other: Relationship): Boolean { - return this === other || (network == other.network && linearId == other.linearId) + /** + * Determines whether this [PluralResolvable] is pointing to the specified [StateAndRef] instance. + * + * @param stateAndRef The [StateAndRef] to determine being pointed to. + * @return Returns true if this [PluralResolvable] is pointing to the specified [StateAndRef]; otherwise, false. + */ + override fun isPointingTo(stateAndRef: StateAndRef): Boolean { + return relationshipLinearId == stateAndRef.state.data.relationshipLinearId + } } } diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipAttestation.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipAttestation.kt index e1e96e1..791d673 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipAttestation.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipAttestation.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,13 @@ package io.onixlabs.corda.bnms.contract.relationship import io.onixlabs.corda.bnms.contract.Network import io.onixlabs.corda.bnms.contract.NetworkState +import io.onixlabs.corda.bnms.contract.membership.Membership import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestationSchema.RelationshipAttestationEntity import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestationSchema.RelationshipAttestationSchemaV1 -import io.onixlabs.corda.identityframework.contract.Attestation -import io.onixlabs.corda.identityframework.contract.AttestationPointer -import io.onixlabs.corda.identityframework.contract.AttestationStatus -import io.onixlabs.corda.identityframework.contract.toAttestationPointer +import io.onixlabs.corda.identityframework.contract.attestations.Attestation +import io.onixlabs.corda.identityframework.contract.attestations.AttestationPointer +import io.onixlabs.corda.identityframework.contract.attestations.AttestationStatus +import io.onixlabs.corda.identityframework.contract.toStaticAttestationPointer import net.corda.core.contracts.BelongsToContract import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.StateRef @@ -32,6 +33,20 @@ import net.corda.core.identity.AbstractParty import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.PersistentState +/** + * Represents a relationship attestation; a proof that a particular [Relationship] state has been witnessed. + * + * @property network The business network that this relationship attestation belongs to. + * @property attestor The party who is attesting to the witnessed [Relationship] state. + * @property attestees The parties of this attestation, usually the participants of the attested [Relationship] state. + * @property pointer The pointer to the attested [Relationship] state. + * @property status The status of the attestation. + * @property metadata Additional information about the attestation. + * @property linearId The unique identifier of the attestation. + * @property previousStateRef The state reference of the previous state in the chain. + * @property hash The unique hash which represents this attestation. + * @property participants The participants of this attestation; namely the attestor and attestees. + */ @BelongsToContract(RelationshipAttestationContract::class) class RelationshipAttestation internal constructor( override val network: Network, @@ -63,7 +78,7 @@ class RelationshipAttestation internal constructor( relationship.state.data.network, attestor, relationship.state.data.participants.toSet(), - relationship.toAttestationPointer(), + relationship.toStaticAttestationPointer(), status, metadata, linearId, @@ -89,21 +104,7 @@ class RelationshipAttestation internal constructor( } override fun generateMappedObject(schema: MappedSchema): PersistentState = when (schema) { - is RelationshipAttestationSchemaV1 -> RelationshipAttestationEntity( - linearId = linearId.id, - externalId = linearId.externalId, - attestor = attestor, - networkValue = network.value, - networkOperator = network.operator, - networkHash = network.hash.toString(), - pointerStateRef = pointer.stateRef.toString(), - pointerStateClass = pointer.stateClass.canonicalName, - pointerStateLinearId = pointer.stateLinearId!!.id, - pointerHash = pointer.hash.toString(), - status = status, - previousStateRef = previousStateRef?.toString(), - hash = hash.toString() - ) + is RelationshipAttestationSchemaV1 -> RelationshipAttestationEntity(this) else -> super.generateMappedObject(schema) } diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipAttestationContract.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipAttestationContract.kt index 9ca557d..46f478e 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipAttestationContract.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipAttestationContract.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ package io.onixlabs.corda.bnms.contract.relationship -import io.onixlabs.corda.identityframework.contract.AttestationContract +import io.onixlabs.corda.identityframework.contract.attestations.AttestationContract import net.corda.core.contracts.Contract import net.corda.core.contracts.ContractClassName import net.corda.core.contracts.requireThat diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipAttestationSchema.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipAttestationSchema.kt index 29b0554..1ecf507 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipAttestationSchema.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipAttestationSchema.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ package io.onixlabs.corda.bnms.contract.relationship -import io.onixlabs.corda.identityframework.contract.AttestationStatus +import io.onixlabs.corda.identityframework.contract.attestations.AttestationStatus import net.corda.core.crypto.NullKeys.NULL_PARTY import net.corda.core.identity.AbstractParty import net.corda.core.schemas.MappedSchema @@ -46,20 +46,20 @@ object RelationshipAttestationSchema { @Column(name = "network_value", nullable = false) val networkValue: String = "", + @Column(name = "normalized_network_value", nullable = false) + val normalizedNetworkValue: String = "", + @Column(name = "network_operator", nullable = true) val networkOperator: AbstractParty? = null, @Column(name = "network_hash", nullable = false) val networkHash: String = "", - @Column(name = "pointer_state_ref", nullable = false) - val pointerStateRef: String = "", - - @Column(name = "pointer_state_class", nullable = false) - val pointerStateClass: String = "", + @Column(name = "pointer", nullable = false) + val pointer: String = "", - @Column(name = "pointer_state_linear_id", nullable = false) - val pointerStateLinearId: UUID = UUID.randomUUID(), + @Column(name = "pointer_state_type", nullable = false) + val pointerStateType: String = "", @Column(name = "pointer_hash", nullable = false) val pointerHash: String = "", @@ -73,5 +73,21 @@ object RelationshipAttestationSchema { @Column(name = "hash", nullable = false, unique = true) val hash: String = "" - ) : PersistentState() + ) : PersistentState() { + constructor(attestation: RelationshipAttestation) : this( + linearId = attestation.linearId.id, + externalId = attestation.linearId.externalId, + attestor = attestation.attestor, + networkValue = attestation.network.value, + normalizedNetworkValue = attestation.network.normalizedValue, + networkOperator = attestation.network.operator, + networkHash = attestation.network.hash.toString(), + pointer = attestation.pointer.statePointer.toString(), + pointerStateType = attestation.pointer.stateType.canonicalName, + pointerHash = attestation.pointer.hash.toString(), + status = attestation.status, + previousStateRef = attestation.previousStateRef?.toString(), + hash = attestation.hash.toString() + ) + } } diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipConfiguration.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipConfiguration.kt new file mode 100644 index 0000000..4140594 --- /dev/null +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipConfiguration.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.contract.relationship + +import io.onixlabs.corda.bnms.contract.Configuration +import io.onixlabs.corda.bnms.contract.Network +import io.onixlabs.corda.bnms.contract.NetworkState +import io.onixlabs.corda.bnms.contract.relationship.RelationshipConfigurationSchema.RelationshipConfigurationEntity +import io.onixlabs.corda.bnms.contract.relationship.RelationshipConfigurationSchema.RelationshipConfigurationSchemaV1 +import io.onixlabs.corda.core.contract.AbstractSingularResolvable +import io.onixlabs.corda.core.contract.Hashable +import io.onixlabs.corda.core.contract.SingularResolvable +import io.onixlabs.corda.core.services.vaultQuery +import net.corda.core.contracts.BelongsToContract +import net.corda.core.contracts.LinearState +import net.corda.core.contracts.StateAndRef +import net.corda.core.contracts.UniqueIdentifier +import net.corda.core.crypto.SecureHash +import net.corda.core.identity.AbstractParty +import net.corda.core.node.services.vault.QueryCriteria +import net.corda.core.schemas.MappedSchema +import net.corda.core.schemas.QueryableState + +@BelongsToContract(RelationshipConfigurationContract::class) +class RelationshipConfiguration private constructor( + override val network: Network, + override val participants: List, + val configuration: Configuration, + val relationshipLinearId: UniqueIdentifier, + override val linearId: UniqueIdentifier +) : NetworkState, LinearState, QueryableState, Hashable { + + constructor( + relationship: Relationship, + configuration: Configuration, + linearId: UniqueIdentifier = UniqueIdentifier() + ) : this(relationship.network, relationship.participants, configuration, relationship.linearId, linearId) + + val relationship: SingularResolvable + get() = RelationshipResolver(relationshipLinearId) + + override val hash: SecureHash + get() = SecureHash.sha256("${configuration.hash}$relationshipLinearId") + + override fun generateMappedObject(schema: MappedSchema) = when (schema) { + is RelationshipConfigurationSchemaV1 -> RelationshipConfigurationEntity(this) + else -> throw IllegalArgumentException("Unrecognised schema: $schema.") + } + + override fun supportedSchemas(): Iterable { + return listOf(RelationshipConfigurationSchemaV1) + } + + private class RelationshipResolver( + private val relationshipLinearId: UniqueIdentifier + ) : AbstractSingularResolvable() { + + override val criteria: QueryCriteria get() = vaultQuery { + linearIds(relationshipLinearId) + } + + override fun isPointingTo(stateAndRef: StateAndRef): Boolean { + return relationshipLinearId == stateAndRef.state.data.linearId + } + } +} diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipConfigurationContract.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipConfigurationContract.kt new file mode 100644 index 0000000..c4b2f44 --- /dev/null +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipConfigurationContract.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.contract.relationship + +import net.corda.core.contracts.Contract +import net.corda.core.transactions.LedgerTransaction + +class RelationshipConfigurationContract : Contract { + override fun verify(tx: LedgerTransaction) { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipConfigurationSchema.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipConfigurationSchema.kt new file mode 100644 index 0000000..2f315b0 --- /dev/null +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipConfigurationSchema.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.contract.relationship + +import net.corda.core.identity.AbstractParty +import net.corda.core.schemas.MappedSchema +import net.corda.core.schemas.PersistentState +import java.util.* +import javax.persistence.Column +import javax.persistence.Entity +import javax.persistence.Table + +object RelationshipConfigurationSchema { + + object RelationshipConfigurationSchemaV1 : + MappedSchema(RelationshipSchema.javaClass, 1, listOf(RelationshipConfigurationEntity::class.java)) { + override val migrationResource = "relationship-configuration-schema.changelog-master" + } + + @Entity + @Table(name = "relationship_configuration_states") + class RelationshipConfigurationEntity( + @Column(name = "linear_id", nullable = false) + val linearId: UUID = UUID.randomUUID(), + + @Column(name = "external_id", nullable = true) + val externalId: String? = null, + + @Column(name = "relationship_linear_id", nullable = false) + val relationshipLinearId: UUID = UUID.randomUUID(), + + @Column(name = "relationship_external_id", nullable = true) + val relationshipExternalId: String? = null, + + @Column(name = "network_value", nullable = false) + val networkValue: String = "", + + @Column(name = "normalized_network_value", nullable = false) + val normalizedNetworkValue: String = "", + + @Column(name = "network_operator", nullable = true) + val networkOperator: AbstractParty? = null, + + @Column(name = "network_hash", nullable = false) + val networkHash: String = "", + + @Column(name = "configuration_hash", nullable = false) + val configurationHash: String = "", + + @Column(name = "hash", nullable = false) + val hash: String = "" + ) : PersistentState() { + constructor(configuration: RelationshipConfiguration) : this( + linearId = configuration.linearId.id, + externalId = configuration.linearId.externalId, + relationshipLinearId = configuration.relationshipLinearId.id, + relationshipExternalId = configuration.relationshipLinearId.externalId, + networkValue = configuration.network.value, + normalizedNetworkValue = configuration.network.normalizedValue, + networkOperator = configuration.network.operator, + networkHash = configuration.network.hash.toString(), + configurationHash = configuration.configuration.hash.toString(), + hash = configuration.hash.toString() + ) + } +} diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContract.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContract.kt index 0e9d07f..58beac6 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContract.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContract.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipMember.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipMember.kt deleted file mode 100644 index f52af62..0000000 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipMember.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2020-2021 ONIXLabs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.onixlabs.corda.bnms.contract.relationship - -import io.onixlabs.corda.bnms.contract.Setting -import io.onixlabs.corda.bnms.contract.cast -import io.onixlabs.corda.identityframework.contract.AbstractClaim -import net.corda.core.identity.AbstractParty -import net.corda.core.serialization.CordaSerializable - -@CordaSerializable -data class RelationshipMember( - val member: AbstractParty, - val settings: Set> = emptySet(), - val claims: Set> = emptySet() -) { - inline fun > getSetting(property: String): T? { - return settings.filterIsInstance().singleOrNull { it.property == property.toUpperCase() } - } - - inline fun getSettingByValueType(property: String): Setting? { - return settings.singleOrNull { it.property == property.toUpperCase() }?.cast() - } - - inline fun > getClaim(property: String): T? { - return claims.filterIsInstance().singleOrNull { it.property == property } - } -} \ No newline at end of file diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipSchema.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipSchema.kt index b9b1ab4..f50f8d0 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipSchema.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipSchema.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,6 +43,9 @@ object RelationshipSchema { @Column(name = "network_value", nullable = false) val networkValue: String = "", + @Column(name = "normalized_network_value", nullable = false) + val normalizedNetworkValue: String = "", + @Column(name = "network_operator", nullable = true) val networkOperator: AbstractParty? = null, @@ -51,5 +54,15 @@ object RelationshipSchema { @Column(name = "hash", nullable = false, unique = true) val hash: String = "" - ) : PersistentState() + ) : PersistentState() { + constructor(relationship: Relationship) : this( + linearId = relationship.linearId.id, + externalId = relationship.linearId.externalId, + networkValue = relationship.network.value, + normalizedNetworkValue = relationship.network.normalizedValue, + networkOperator = relationship.network.operator, + networkHash = relationship.network.hash.toString(), + hash = relationship.hash.toString() + ) + } } diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLock.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLock.kt index 6d3bebe..d44689d 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLock.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLock.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,12 +40,7 @@ data class RevocationLock( } override fun generateMappedObject(schema: MappedSchema): PersistentState = when (schema) { - is RevocationLockSchemaV1 -> RevocationLockEntity( - owner = owner, - pointerStateLinearId = pointer.pointer.id, - pointerStateExternalId = pointer.pointer.externalId, - pointerStateClass = pointer.type.canonicalName - ) + is RevocationLockSchemaV1 -> RevocationLockEntity(this) else -> throw IllegalArgumentException("Unrecognised schema: $schema.") } diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockContract.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockContract.kt index 978aaff..cccdb63 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockContract.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockContract.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockSchema.kt b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockSchema.kt index ff25d15..f3612ac 100644 --- a/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockSchema.kt +++ b/onixlabs-corda-bnms-contract/src/main/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockSchema.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,5 +46,12 @@ object RevocationLockSchema { @Column(name = "pointer_state_class", nullable = false) val pointerStateClass: String = "" - ) : PersistentState() -} \ No newline at end of file + ) : PersistentState() { + constructor(revocationLock: RevocationLock<*>) : this( + owner = revocationLock.owner, + pointerStateLinearId = revocationLock.pointer.pointer.id, + pointerStateExternalId = revocationLock.pointer.pointer.externalId, + pointerStateClass = revocationLock.pointer.type.canonicalName + ) + } +} diff --git a/onixlabs-corda-bnms-contract/src/main/resources/migration/membership-attestation-schema.changelog-master.xml b/onixlabs-corda-bnms-contract/src/main/resources/migration/membership-attestation-schema.changelog-master.xml index e9930ab..8b969e6 100644 --- a/onixlabs-corda-bnms-contract/src/main/resources/migration/membership-attestation-schema.changelog-master.xml +++ b/onixlabs-corda-bnms-contract/src/main/resources/migration/membership-attestation-schema.changelog-master.xml @@ -3,4 +3,5 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd"> + \ No newline at end of file diff --git a/onixlabs-corda-bnms-contract/src/main/resources/migration/membership-attestation-schema.changelog-v2.xml b/onixlabs-corda-bnms-contract/src/main/resources/migration/membership-attestation-schema.changelog-v2.xml new file mode 100644 index 0000000..761760d --- /dev/null +++ b/onixlabs-corda-bnms-contract/src/main/resources/migration/membership-attestation-schema.changelog-v2.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/onixlabs-corda-bnms-contract/src/main/resources/migration/membership-schema.changelog-master.xml b/onixlabs-corda-bnms-contract/src/main/resources/migration/membership-schema.changelog-master.xml index 79af8cf..286bf3c 100644 --- a/onixlabs-corda-bnms-contract/src/main/resources/migration/membership-schema.changelog-master.xml +++ b/onixlabs-corda-bnms-contract/src/main/resources/migration/membership-schema.changelog-master.xml @@ -3,4 +3,5 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd"> - \ No newline at end of file + + diff --git a/onixlabs-corda-bnms-contract/src/main/resources/migration/membership-schema.changelog-v2.xml b/onixlabs-corda-bnms-contract/src/main/resources/migration/membership-schema.changelog-v2.xml new file mode 100644 index 0000000..7e23a75 --- /dev/null +++ b/onixlabs-corda-bnms-contract/src/main/resources/migration/membership-schema.changelog-v2.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-attestation-schema.changelog-master.xml b/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-attestation-schema.changelog-master.xml index 388fa15..163dcb2 100644 --- a/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-attestation-schema.changelog-master.xml +++ b/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-attestation-schema.changelog-master.xml @@ -3,4 +3,5 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd"> + \ No newline at end of file diff --git a/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-attestation-schema.changelog-v2.xml b/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-attestation-schema.changelog-v2.xml new file mode 100644 index 0000000..51e0635 --- /dev/null +++ b/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-attestation-schema.changelog-v2.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-configuration-schema.changelog-master.xml b/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-configuration-schema.changelog-master.xml new file mode 100644 index 0000000..37ff2a4 --- /dev/null +++ b/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-configuration-schema.changelog-master.xml @@ -0,0 +1,6 @@ + + + + diff --git a/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-configuration-schema.changelog-v1.xml b/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-configuration-schema.changelog-v1.xml new file mode 100644 index 0000000..3a0b79a --- /dev/null +++ b/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-configuration-schema.changelog-v1.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-schema.changelog-master.xml b/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-schema.changelog-master.xml index 875f769..d869861 100644 --- a/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-schema.changelog-master.xml +++ b/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-schema.changelog-master.xml @@ -3,4 +3,5 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd"> - \ No newline at end of file + + diff --git a/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-schema.changelog-v2.xml b/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-schema.changelog-v2.xml new file mode 100644 index 0000000..e50141e --- /dev/null +++ b/onixlabs-corda-bnms-contract/src/main/resources/migration/relationship-schema.changelog-v2.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/ContractTest.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/ContractTest.kt index 9727def..be4dbf9 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/ContractTest.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/ContractTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ package io.onixlabs.corda.bnms.contract import io.onixlabs.corda.bnms.contract.membership.* import io.onixlabs.corda.bnms.contract.relationship.* import io.onixlabs.corda.bnms.contract.revocation.RevocationLockContract -import io.onixlabs.corda.identityframework.contract.AttestationContract +import io.onixlabs.corda.identityframework.contract.attestations.AttestationContract import net.corda.core.contracts.StateAndRef import net.corda.core.crypto.SecureHash import net.corda.core.identity.AbstractParty @@ -55,7 +55,7 @@ abstract class ContractTest { @BeforeEach private fun setup() { val networkParameters = testNetworkParameters( - minimumPlatformVersion = 5, + minimumPlatformVersion = 11, notaries = listOf(NotaryInfo(TestIdentity(DUMMY_NOTARY_NAME, 20).party, true)) ) _services = MockServices(cordapps, IDENTITY_A, networkParameters, IDENTITY_B, IDENTITY_C) diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/Extensions.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/Extensions.kt index bb3bab4..508c4df 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/Extensions.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/Extensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/MockData.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/MockData.kt index 303c101..fd99160 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/MockData.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/MockData.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ package io.onixlabs.corda.bnms.contract import io.onixlabs.corda.bnms.contract.membership.Membership import io.onixlabs.corda.bnms.contract.relationship.Relationship -import io.onixlabs.corda.bnms.contract.relationship.RelationshipMember import io.onixlabs.corda.bnms.contract.revocation.RevocationLock import net.corda.core.contracts.StateRef import net.corda.core.crypto.SecureHash @@ -53,7 +52,7 @@ val DECENTRALIZED_MEMBERSHIP_IDENTITY_A = Membership(DECENTRALIZED_NETWORK, IDEN val DECENTRALIZED_MEMBERSHIP_IDENTITY_B = Membership(DECENTRALIZED_NETWORK, IDENTITY_B.party) val DECENTRALIZED_MEMBERSHIP_IDENTITY_C = Membership(DECENTRALIZED_NETWORK, IDENTITY_C.party) -val MEMBERS = setOf(RelationshipMember(IDENTITY_A.party), RelationshipMember(IDENTITY_B.party)) +val MEMBERS = mapOf(IDENTITY_A.party to Configuration(), IDENTITY_B.party to Configuration()) val RELATIONSHIP = Relationship(CENTRALIZED_NETWORK, MEMBERS) val REVOCATION_LOCK = RevocationLock(IDENTITY_A.party, DummyLinearContract.State()) \ No newline at end of file diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/MembershipAttestationContractAmendCommandTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/MembershipAttestationContractAmendCommandTests.kt index edcb8d3..8e18f2a 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/MembershipAttestationContractAmendCommandTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/MembershipAttestationContractAmendCommandTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ package io.onixlabs.corda.bnms.contract.attestation import io.onixlabs.corda.bnms.contract.* import io.onixlabs.corda.bnms.contract.membership.MembershipAttestationContract import io.onixlabs.corda.bnms.contract.membership.reject -import io.onixlabs.corda.identityframework.contract.AttestationContract +import io.onixlabs.corda.identityframework.contract.attestations.AttestationContract import net.corda.testing.node.ledger import org.junit.jupiter.api.Test diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/MembershipAttestationContractIssueCommandTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/MembershipAttestationContractIssueCommandTests.kt index 1b3cc08..e40fb13 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/MembershipAttestationContractIssueCommandTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/MembershipAttestationContractIssueCommandTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ package io.onixlabs.corda.bnms.contract.attestation import io.onixlabs.corda.bnms.contract.* import io.onixlabs.corda.bnms.contract.membership.MembershipAttestationContract import io.onixlabs.corda.bnms.contract.membership.accept -import io.onixlabs.corda.identityframework.contract.AttestationContract +import io.onixlabs.corda.identityframework.contract.attestations.AttestationContract import net.corda.testing.node.ledger import org.junit.jupiter.api.Test diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/RelationshipAttestationContractAmendCommandTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/RelationshipAttestationContractAmendCommandTests.kt index 3965d38..15fb9ac 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/RelationshipAttestationContractAmendCommandTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/RelationshipAttestationContractAmendCommandTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ import io.onixlabs.corda.bnms.contract.RELATIONSHIP import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestationContract import io.onixlabs.corda.bnms.contract.relationship.reject import io.onixlabs.corda.bnms.contract.withWrongNetwork -import io.onixlabs.corda.identityframework.contract.AttestationContract +import io.onixlabs.corda.identityframework.contract.attestations.AttestationContract import net.corda.testing.node.ledger import org.junit.jupiter.api.Test diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/RelationshipAttestationContractIssueCommandTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/RelationshipAttestationContractIssueCommandTests.kt index 107f44a..4f0a7be 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/RelationshipAttestationContractIssueCommandTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/attestation/RelationshipAttestationContractIssueCommandTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ package io.onixlabs.corda.bnms.contract.attestation import io.onixlabs.corda.bnms.contract.* import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestationContract import io.onixlabs.corda.bnms.contract.relationship.accept -import io.onixlabs.corda.identityframework.contract.AttestationContract +import io.onixlabs.corda.identityframework.contract.attestations.AttestationContract import net.corda.testing.node.ledger import org.junit.jupiter.api.Test diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/centralized/MembershipContractAmendCommandTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/centralized/MembershipContractAmendCommandTests.kt index 5832e0c..8b6562c 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/centralized/MembershipContractAmendCommandTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/centralized/MembershipContractAmendCommandTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ class MembershipContractAmendCommandTests : ContractTest() { services.ledger { transaction { val issuedMembershipA = issue(CENTRALIZED_MEMBERSHIP_IDENTITY_A) - val amendedMembershipA = issuedMembershipA.getNextOutput().addRoles("Example") + val amendedMembershipA = issuedMembershipA.getNextOutput().configure { addRoles("Example") } input(issuedMembershipA.ref) output(MembershipContract.ID, amendedMembershipA) fails() @@ -59,7 +59,7 @@ class MembershipContractAmendCommandTests : ContractTest() { transaction { val issuedMembershipA = issue(CENTRALIZED_MEMBERSHIP_IDENTITY_A) val issuedMembershipB = CENTRALIZED_MEMBERSHIP_IDENTITY_B - val amendedMembershipA = issuedMembershipA.getNextOutput().addRoles("Example") + val amendedMembershipA = issuedMembershipA.getNextOutput().configure { addRoles("Example") } input(issuedMembershipA.ref) output(MembershipContract.ID, amendedMembershipA) output(MembershipContract.ID, issuedMembershipB) diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/centralized/MembershipContractIssueCommandTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/centralized/MembershipContractIssueCommandTests.kt index 0d1f6f1..4dd0003 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/centralized/MembershipContractIssueCommandTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/centralized/MembershipContractIssueCommandTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/centralized/MembershipContractRevokeCommandTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/centralized/MembershipContractRevokeCommandTests.kt index ff3415a..d6261b6 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/centralized/MembershipContractRevokeCommandTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/centralized/MembershipContractRevokeCommandTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/decentralized/MembershipContractAmendCommandTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/decentralized/MembershipContractAmendCommandTests.kt index 4bd467c..98121ef 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/decentralized/MembershipContractAmendCommandTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/decentralized/MembershipContractAmendCommandTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ class MembershipContractAmendCommandTests : ContractTest() { services.ledger { transaction { val issuedMembershipA = issue(DECENTRALIZED_MEMBERSHIP_IDENTITY_A) - val amendedMembershipA = issuedMembershipA.getNextOutput().addRoles("Example") + val amendedMembershipA = issuedMembershipA.getNextOutput().configure { addRoles("Example") } input(issuedMembershipA.ref) output(MembershipContract.ID, amendedMembershipA) fails() @@ -59,7 +59,7 @@ class MembershipContractAmendCommandTests : ContractTest() { transaction { val issuedMembershipA = issue(DECENTRALIZED_MEMBERSHIP_IDENTITY_A) val issuedMembershipB = DECENTRALIZED_MEMBERSHIP_IDENTITY_B - val amendedMembershipA = issuedMembershipA.getNextOutput().addRoles("Example") + val amendedMembershipA = issuedMembershipA.getNextOutput().configure { addRoles("Example") } input(issuedMembershipA.ref) output(MembershipContract.ID, amendedMembershipA) output(MembershipContract.ID, issuedMembershipB) diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/decentralized/MembershipContractIssueCommandTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/decentralized/MembershipContractIssueCommandTests.kt index 47ee956..9e21efe 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/decentralized/MembershipContractIssueCommandTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/decentralized/MembershipContractIssueCommandTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/decentralized/MembershipContractRevokeCommandTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/decentralized/MembershipContractRevokeCommandTests.kt index a697264..93515fb 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/decentralized/MembershipContractRevokeCommandTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/decentralized/MembershipContractRevokeCommandTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/general/MembershipPermissionTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/general/MembershipPermissionTests.kt index 5e4ee96..f5b88e8 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/general/MembershipPermissionTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/general/MembershipPermissionTests.kt @@ -12,10 +12,10 @@ class MembershipPermissionTests { fun `Membership hasPermission should return true when the expected permission is present`() { // Arrange - val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).addPermissions("Test") + val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).configure { addPermissions("Test") } // Act - val result = membership.hasPermission("Test") + val result = membership.configuration.hasPermission("Test") // Assert assertTrue(result) diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/general/MembershipRoleTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/general/MembershipRoleTests.kt index 57596bc..d90731e 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/general/MembershipRoleTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/general/MembershipRoleTests.kt @@ -12,10 +12,10 @@ class MembershipRoleTests { fun `Membership hasRole should return true when the expected role is present`() { // Arrange - val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).addRoles("Test") + val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).configure { addRoles("Test") } // Act - val result = membership.hasRole("Test") + val result = membership.configuration.hasRole("Test") // Assert assertTrue(result) diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/general/MembershipSettingTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/general/MembershipSettingTests.kt index 651a867..2e5243d 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/general/MembershipSettingTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/membership/general/MembershipSettingTests.kt @@ -12,10 +12,10 @@ class MembershipSettingTests { fun `Membership hasSetting should return true when the expected setting is present`() { // Arrange - val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).addSetting("Test", 123) + val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).configure { addSetting("Test", 123) } // Act - val result = membership.hasSetting(Setting("Test", 123)) + val result = membership.configuration.hasSetting(Setting("Test", 123)) // Assert assertTrue(result) @@ -25,10 +25,10 @@ class MembershipSettingTests { fun `Membership hasSetting should return true when the expected setting by property is present`() { // Arrange - val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).addSetting("Test", 123) + val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).configure { addSetting("Test", 123) } // Act - val result = membership.hasSetting("Test") + val result = membership.configuration.hasSetting("Test") // Assert assertTrue(result) @@ -49,10 +49,10 @@ class MembershipSettingTests { Permission("Example Permission 1"), Permission("Example Permission 2") ) - val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).addSettings(settings) + val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).configure { addSettings(settings) } // Act - val result = membership.getSettingsByType() + val result = membership.configuration.getSettingsByType() // Assert assertEquals(2, result.size) @@ -73,10 +73,10 @@ class MembershipSettingTests { Permission("Example Permission 1"), Permission("Example Permission 2") ) - val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).addSettings(settings) + val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).configure { addSettings(settings) } // Act - val result = membership.getSettingsByType>("Key1") + val result = membership.configuration.getSettingsByType>("Key1") // Assert assertEquals(2, result.size) @@ -97,10 +97,10 @@ class MembershipSettingTests { Permission("Example Permission 1"), Permission("Example Permission 2") ) - val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).addSettings(settings) + val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).configure { addSettings(settings) } // Act - val result = membership.getSettingsByValueType() + val result = membership.configuration.getSettingsByType>() // Assert assertEquals(2, result.size) @@ -121,10 +121,10 @@ class MembershipSettingTests { Permission("Example Permission 1"), Permission("Example Permission 2") ) - val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).addSettings(settings) + val membership = Membership(DECENTRALIZED_NETWORK, IDENTITY_A.party).configure { addSettings(settings) } // Act - val result = membership.getSettingsByType>("Key1") + val result = membership.configuration.getSettingsByType>("Key1") // Assert assertEquals(2, result.size) diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContractAmendCommandTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContractAmendCommandTests.kt index 69e7a2a..9694131 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContractAmendCommandTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContractAmendCommandTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContractIssueCommandTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContractIssueCommandTests.kt index cf9b322..565a0c4 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContractIssueCommandTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContractIssueCommandTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContractRevokeCommandTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContractRevokeCommandTests.kt index 8f9f498..3dd4219 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContractRevokeCommandTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/relationship/RelationshipContractRevokeCommandTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockContractLockCommandTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockContractLockCommandTests.kt index 1e52a0c..20fa2df 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockContractLockCommandTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockContractLockCommandTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockContractUnlockCommandTests.kt b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockContractUnlockCommandTests.kt index 2c808bc..16f186f 100644 --- a/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockContractUnlockCommandTests.kt +++ b/onixlabs-corda-bnms-contract/src/test/kotlin/io/onixlabs/corda/bnms/contract/revocation/RevocationLockContractUnlockCommandTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-integration/build.gradle b/onixlabs-corda-bnms-integration/build.gradle index 48452f5..53ed2db 100644 --- a/onixlabs-corda-bnms-integration/build.gradle +++ b/onixlabs-corda-bnms-integration/build.gradle @@ -36,6 +36,7 @@ publishing { groupId = project.parent.group version = project.parent.version artifactId = 'onixlabs-corda-bnms-integration' + artifact sourceJar from components.java } } diff --git a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipAttestationQueryService.kt b/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipAttestationQueryService.kt deleted file mode 100644 index f344dfd..0000000 --- a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipAttestationQueryService.kt +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2020-2021 ONIXLabs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.onixlabs.corda.bnms.integration - -import io.onixlabs.corda.bnms.contract.Network -import io.onixlabs.corda.bnms.contract.membership.Membership -import io.onixlabs.corda.bnms.contract.membership.MembershipAttestation -import io.onixlabs.corda.bnms.workflow.membership.FindMembershipAttestationFlow -import io.onixlabs.corda.bnms.workflow.membership.FindMembershipAttestationsFlow -import io.onixlabs.corda.core.integration.RPCService -import io.onixlabs.corda.core.workflow.DEFAULT_PAGE_SPECIFICATION -import io.onixlabs.corda.identityframework.contract.AttestationPointer -import io.onixlabs.corda.identityframework.contract.AttestationStatus -import net.corda.core.contracts.StateAndRef -import net.corda.core.contracts.StateRef -import net.corda.core.contracts.UniqueIdentifier -import net.corda.core.crypto.SecureHash -import net.corda.core.identity.AbstractParty -import net.corda.core.messaging.CordaRPCOps -import net.corda.core.node.services.Vault -import net.corda.core.node.services.vault.PageSpecification -import net.corda.core.utilities.getOrThrow -import java.time.Duration - -class MembershipAttestationQueryService(rpc: CordaRPCOps) : RPCService(rpc) { - - fun findMembershipAttestation( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - attestor: AbstractParty? = null, - holder: AbstractParty? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - pointer: AttestationPointer? = null, - pointerStateRef: StateRef? = null, - pointerStateLinearId: UniqueIdentifier? = null, - pointerHash: SecureHash? = null, - status: AttestationStatus? = null, - previousStateRef: StateRef? = null, - hash: SecureHash? = null, - membership: StateAndRef? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION, - flowTimeout: Duration = Duration.ofSeconds(30) - ): StateAndRef? { - return rpc.startFlowDynamic( - FindMembershipAttestationFlow::class.java, - linearId, - externalId, - attestor, - holder, - network, - networkValue, - networkOperator, - networkHash, - pointer, - pointerStateRef, - pointerStateLinearId, - pointerHash, - status, - previousStateRef, - hash, - membership, - stateStatus, - relevancyStatus, - pageSpecification - ).returnValue.getOrThrow(flowTimeout) - } - - fun findMembershipAttestations( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - attestor: AbstractParty? = null, - holder: AbstractParty? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - pointer: AttestationPointer? = null, - pointerStateRef: StateRef? = null, - pointerStateLinearId: UniqueIdentifier? = null, - pointerHash: SecureHash? = null, - status: AttestationStatus? = null, - previousStateRef: StateRef? = null, - hash: SecureHash? = null, - membership: StateAndRef? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION, - flowTimeout: Duration = Duration.ofSeconds(30) - ): List> { - return rpc.startFlowDynamic( - FindMembershipAttestationsFlow::class.java, - linearId, - externalId, - attestor, - holder, - network, - networkValue, - networkOperator, - networkHash, - pointer, - pointerStateRef, - pointerStateLinearId, - pointerHash, - status, - previousStateRef, - hash, - membership, - stateStatus, - relevancyStatus, - pageSpecification - ).returnValue.getOrThrow(flowTimeout) - } -} diff --git a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipAttestationCommandService.kt b/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipAttestationService.kt similarity index 96% rename from onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipAttestationCommandService.kt rename to onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipAttestationService.kt index bd7b08a..d7e39d4 100644 --- a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipAttestationCommandService.kt +++ b/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipAttestationService.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ import io.onixlabs.corda.bnms.workflow.membership.AmendMembershipAttestationFlow import io.onixlabs.corda.bnms.workflow.membership.IssueMembershipAttestationFlow import io.onixlabs.corda.bnms.workflow.membership.RevokeMembershipAttestationFlow import io.onixlabs.corda.core.integration.RPCService -import io.onixlabs.corda.identityframework.contract.AttestationStatus +import io.onixlabs.corda.identityframework.contract.attestations.AttestationStatus import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.UniqueIdentifier import net.corda.core.identity.AbstractParty @@ -32,7 +32,7 @@ import net.corda.core.messaging.* import net.corda.core.transactions.SignedTransaction import java.util.* -class MembershipAttestationCommandService(rpc: CordaRPCOps) : RPCService(rpc) { +class MembershipAttestationService(rpc: CordaRPCOps) : RPCService(rpc) { fun issueMembershipAttestation( membership: StateAndRef, diff --git a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipQueryService.kt b/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipQueryService.kt deleted file mode 100644 index d0fd6fb..0000000 --- a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipQueryService.kt +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2020-2021 ONIXLabs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.onixlabs.corda.bnms.integration - -import io.onixlabs.corda.bnms.contract.Network -import io.onixlabs.corda.bnms.contract.membership.Membership -import io.onixlabs.corda.bnms.workflow.membership.FindMembershipFlow -import io.onixlabs.corda.bnms.workflow.membership.FindMembershipsFlow -import io.onixlabs.corda.core.integration.RPCService -import io.onixlabs.corda.core.workflow.DEFAULT_PAGE_SPECIFICATION -import net.corda.core.contracts.StateAndRef -import net.corda.core.contracts.UniqueIdentifier -import net.corda.core.crypto.SecureHash -import net.corda.core.identity.AbstractParty -import net.corda.core.messaging.CordaRPCOps -import net.corda.core.node.services.Vault -import net.corda.core.node.services.vault.PageSpecification -import net.corda.core.utilities.getOrThrow -import java.time.Duration - -class MembershipQueryService(rpc: CordaRPCOps) : RPCService(rpc) { - - fun findMembership( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - holder: AbstractParty? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - isNetworkOperator: Boolean? = null, - hash: SecureHash? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION, - flowTimeout: Duration = Duration.ofSeconds(30) - ): StateAndRef? { - return rpc.startFlowDynamic( - FindMembershipFlow::class.java, - linearId, - externalId, - holder, - network, - networkValue, - networkOperator, - networkHash, - isNetworkOperator, - hash, - stateStatus, - relevancyStatus, - pageSpecification - ).returnValue.getOrThrow(flowTimeout) - } - - fun findMemberships( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - holder: AbstractParty? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - isNetworkOperator: Boolean? = null, - hash: SecureHash? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION, - flowTimeout: Duration = Duration.ofSeconds(30) - ): List> { - return rpc.startFlowDynamic( - FindMembershipsFlow::class.java, - linearId, - externalId, - holder, - network, - networkValue, - networkOperator, - networkHash, - isNetworkOperator, - hash, - stateStatus, - relevancyStatus, - pageSpecification - ).returnValue.getOrThrow(flowTimeout) - } -} diff --git a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipCommandService.kt b/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipService.kt similarity index 96% rename from onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipCommandService.kt rename to onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipService.kt index 8e6c551..b5a99c6 100644 --- a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipCommandService.kt +++ b/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/MembershipService.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ import io.onixlabs.corda.bnms.workflow.membership.AmendMembershipFlow import io.onixlabs.corda.bnms.workflow.membership.IssueMembershipFlow import io.onixlabs.corda.bnms.workflow.membership.RevokeMembershipFlow import io.onixlabs.corda.core.integration.RPCService -import io.onixlabs.corda.identityframework.contract.AbstractClaim +import io.onixlabs.corda.identityframework.contract.claims.AbstractClaim import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.UniqueIdentifier import net.corda.core.identity.AbstractParty @@ -32,7 +32,7 @@ import net.corda.core.messaging.* import net.corda.core.transactions.SignedTransaction import java.util.* -class MembershipCommandService(rpc: CordaRPCOps) : RPCService(rpc) { +class MembershipService(rpc: CordaRPCOps) : RPCService(rpc) { fun issueMembership( network: Network, diff --git a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipAttestationQueryService.kt b/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipAttestationQueryService.kt deleted file mode 100644 index a1d3301..0000000 --- a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipAttestationQueryService.kt +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2020-2021 ONIXLabs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.onixlabs.corda.bnms.integration - -import io.onixlabs.corda.bnms.contract.Network -import io.onixlabs.corda.bnms.contract.membership.Membership -import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestation -import io.onixlabs.corda.bnms.workflow.relationship.FindRelationshipAttestationFlow -import io.onixlabs.corda.bnms.workflow.relationship.FindRelationshipAttestationsFlow -import io.onixlabs.corda.core.integration.RPCService -import io.onixlabs.corda.core.workflow.DEFAULT_PAGE_SPECIFICATION -import io.onixlabs.corda.identityframework.contract.AttestationPointer -import io.onixlabs.corda.identityframework.contract.AttestationStatus -import net.corda.core.contracts.StateAndRef -import net.corda.core.contracts.StateRef -import net.corda.core.contracts.UniqueIdentifier -import net.corda.core.crypto.SecureHash -import net.corda.core.identity.AbstractParty -import net.corda.core.messaging.CordaRPCOps -import net.corda.core.node.services.Vault -import net.corda.core.node.services.vault.PageSpecification -import net.corda.core.utilities.getOrThrow -import java.time.Duration - -class RelationshipAttestationQueryService(rpc: CordaRPCOps) : RPCService(rpc) { - - fun findRelationshipAttestation( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - attestor: AbstractParty? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - pointer: AttestationPointer? = null, - pointerStateRef: StateRef? = null, - pointerStateLinearId: UniqueIdentifier? = null, - pointerHash: SecureHash? = null, - status: AttestationStatus? = null, - previousStateRef: StateRef? = null, - hash: SecureHash? = null, - membership: StateAndRef? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION, - flowTimeout: Duration = Duration.ofSeconds(30) - ): StateAndRef? { - return rpc.startFlowDynamic( - FindRelationshipAttestationFlow::class.java, - linearId, - externalId, - attestor, - network, - networkValue, - networkOperator, - networkHash, - pointer, - pointerStateRef, - pointerStateLinearId, - pointerHash, - status, - previousStateRef, - hash, - membership, - stateStatus, - relevancyStatus, - pageSpecification - ).returnValue.getOrThrow(flowTimeout) - } - - fun findRelationshipAttestations( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - attestor: AbstractParty? = null, - holder: AbstractParty? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - pointer: AttestationPointer? = null, - pointerStateRef: StateRef? = null, - pointerStateLinearId: UniqueIdentifier? = null, - pointerHash: SecureHash? = null, - status: AttestationStatus? = null, - previousStateRef: StateRef? = null, - hash: SecureHash? = null, - membership: StateAndRef? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION, - flowTimeout: Duration = Duration.ofSeconds(30) - ): List> { - return rpc.startFlowDynamic( - FindRelationshipAttestationsFlow::class.java, - linearId, - externalId, - attestor, - holder, - network, - networkValue, - networkOperator, - networkHash, - pointer, - pointerStateRef, - pointerStateLinearId, - pointerHash, - status, - previousStateRef, - hash, - membership, - stateStatus, - relevancyStatus, - pageSpecification - ).returnValue.getOrThrow(flowTimeout) - } -} diff --git a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipAttestationCommandService.kt b/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipAttestationService.kt similarity index 96% rename from onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipAttestationCommandService.kt rename to onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipAttestationService.kt index 3732a0e..6274a76 100644 --- a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipAttestationCommandService.kt +++ b/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipAttestationService.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ import io.onixlabs.corda.bnms.workflow.relationship.AmendRelationshipAttestation import io.onixlabs.corda.bnms.workflow.relationship.IssueRelationshipAttestationFlow import io.onixlabs.corda.bnms.workflow.relationship.RevokeRelationshipAttestationFlow import io.onixlabs.corda.core.integration.RPCService -import io.onixlabs.corda.identityframework.contract.AttestationStatus +import io.onixlabs.corda.identityframework.contract.attestations.AttestationStatus import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.UniqueIdentifier import net.corda.core.identity.AbstractParty @@ -32,7 +32,7 @@ import net.corda.core.messaging.* import net.corda.core.transactions.SignedTransaction import java.util.* -class RelationshipAttestationCommandService(rpc: CordaRPCOps) : RPCService(rpc) { +class RelationshipAttestationService(rpc: CordaRPCOps) : RPCService(rpc) { fun issueRelationshipAttestation( relationship: StateAndRef, diff --git a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipQueryService.kt b/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipQueryService.kt deleted file mode 100644 index 3049209..0000000 --- a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipQueryService.kt +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2020-2021 ONIXLabs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.onixlabs.corda.bnms.integration - -import io.onixlabs.corda.bnms.contract.Network -import io.onixlabs.corda.bnms.contract.relationship.Relationship -import io.onixlabs.corda.bnms.workflow.relationship.FindRelationshipFlow -import io.onixlabs.corda.bnms.workflow.relationship.FindRelationshipsFlow -import io.onixlabs.corda.core.integration.RPCService -import io.onixlabs.corda.core.workflow.DEFAULT_PAGE_SPECIFICATION -import net.corda.core.contracts.StateAndRef -import net.corda.core.contracts.UniqueIdentifier -import net.corda.core.crypto.SecureHash -import net.corda.core.identity.AbstractParty -import net.corda.core.messaging.CordaRPCOps -import net.corda.core.node.services.Vault -import net.corda.core.node.services.vault.PageSpecification -import net.corda.core.utilities.getOrThrow -import java.time.Duration - -class RelationshipQueryService(rpc: CordaRPCOps) : RPCService(rpc) { - - fun findRelationship( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - hash: SecureHash? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION, - flowTimeout: Duration = Duration.ofSeconds(30) - ): StateAndRef? { - return rpc.startFlowDynamic( - FindRelationshipFlow::class.java, - linearId, - externalId, - network, - networkValue, - networkOperator, - networkHash, - hash, - stateStatus, - relevancyStatus, - pageSpecification - ).returnValue.getOrThrow(flowTimeout) - } - - fun findRelationships( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - hash: SecureHash? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION, - flowTimeout: Duration = Duration.ofSeconds(30) - ): List> { - return rpc.startFlowDynamic( - FindRelationshipsFlow::class.java, - linearId, - externalId, - network, - networkValue, - networkOperator, - networkHash, - hash, - stateStatus, - relevancyStatus, - pageSpecification - ).returnValue.getOrThrow(flowTimeout) - } -} diff --git a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipCommandService.kt b/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipService.kt similarity index 87% rename from onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipCommandService.kt rename to onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipService.kt index 2f23882..8a2c07d 100644 --- a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipCommandService.kt +++ b/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RelationshipService.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,45 +16,43 @@ package io.onixlabs.corda.bnms.integration +import io.onixlabs.corda.bnms.contract.Configuration import io.onixlabs.corda.bnms.contract.Network -import io.onixlabs.corda.bnms.contract.Setting import io.onixlabs.corda.bnms.contract.relationship.Relationship -import io.onixlabs.corda.bnms.contract.relationship.RelationshipMember import io.onixlabs.corda.bnms.workflow.relationship.AmendRelationshipFlow import io.onixlabs.corda.bnms.workflow.relationship.IssueRelationshipFlow import io.onixlabs.corda.bnms.workflow.relationship.RevokeRelationshipFlow import io.onixlabs.corda.core.integration.RPCService import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.UniqueIdentifier +import net.corda.core.identity.AbstractParty import net.corda.core.identity.Party import net.corda.core.messaging.* import net.corda.core.transactions.SignedTransaction import java.util.* -class RelationshipCommandService(rpc: CordaRPCOps) : RPCService(rpc) { +class RelationshipService(rpc: CordaRPCOps) : RPCService(rpc) { fun issueRelationship( network: Network, - members: Set = emptySet(), - settings: Set> = emptySet(), + members: Map = emptyMap(), linearId: UniqueIdentifier = UniqueIdentifier(), notary: Party? = null, checkMembership: Boolean = false ): FlowProgressHandle { - val relationship = Relationship(network, members, settings, linearId) + val relationship = Relationship(network, members, linearId) return issueRelationship(relationship, notary, checkMembership) } fun issueRelationship( network: Network, - members: Set = emptySet(), - settings: Set> = emptySet(), + members: Map = emptyMap(), linearId: UniqueIdentifier = UniqueIdentifier(), notary: Party? = null, checkMembership: Boolean = false, clientId: String = UUID.randomUUID().toString() ): FlowHandleWithClientId { - val relationship = Relationship(network, members, settings, linearId) + val relationship = Relationship(network, members, linearId) return issueRelationship(relationship, notary, checkMembership, clientId) } diff --git a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RevocationLockQueryService.kt b/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RevocationLockQueryService.kt deleted file mode 100644 index 8e1a617..0000000 --- a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RevocationLockQueryService.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2020-2021 ONIXLabs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.onixlabs.corda.bnms.integration - -import io.onixlabs.corda.bnms.workflow.revocation.FindRevocationLockFlow -import io.onixlabs.corda.core.contract.cast -import io.onixlabs.corda.core.integration.RPCService -import net.corda.core.contracts.LinearState -import net.corda.core.contracts.StateAndRef -import net.corda.core.identity.AbstractParty -import net.corda.core.messaging.CordaRPCOps -import net.corda.core.utilities.getOrThrow -import java.time.Duration - -class RevocationLockQueryService(rpc: CordaRPCOps) : RPCService(rpc) { - - inline fun findRevocationLock( - state: T, - owner: AbstractParty = ourIdentity, - flowTimeout: Duration = Duration.ofSeconds(30) - ): StateAndRef? { - return rpc.startFlowDynamic( - FindRevocationLockFlow::class.java, - owner, - state - ).returnValue.getOrThrow(flowTimeout)?.cast() - } -} diff --git a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RevocationLockCommandService.kt b/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RevocationLockService.kt similarity index 71% rename from onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RevocationLockCommandService.kt rename to onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RevocationLockService.kt index 03ce223..a4732ba 100644 --- a/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RevocationLockCommandService.kt +++ b/onixlabs-corda-bnms-integration/src/main/kotlin/io/onixlabs/corda/bnms/integration/RevocationLockService.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import net.corda.core.messaging.* import net.corda.core.transactions.SignedTransaction import java.util.* -class RevocationLockCommandService(rpc: CordaRPCOps) : RPCService(rpc) { +class RevocationLockService(rpc: CordaRPCOps) : RPCService(rpc) { fun lock( state: T, @@ -36,7 +36,12 @@ class RevocationLockCommandService(rpc: CordaRPCOps) : RPCService(rpc) { notary: Party? = null ): FlowProgressHandle { val lock = RevocationLock(owner, state) - return rpc.startTrackedFlow(::LockRevocationLockFlow, lock, notary) + return rpc.startTrackedFlow( + ::LockRevocationLockFlow, + lock, + notary, + LockRevocationLockFlow.tracker() + ) } fun lock( @@ -46,19 +51,34 @@ class RevocationLockCommandService(rpc: CordaRPCOps) : RPCService(rpc) { clientId: String = UUID.randomUUID().toString() ): FlowHandleWithClientId { val lock = RevocationLock(owner, state) - return rpc.startFlowWithClientId(clientId, ::LockRevocationLockFlow, lock, notary) + return rpc.startFlowWithClientId( + clientId, + ::LockRevocationLockFlow, + lock, + notary, + LockRevocationLockFlow.tracker() + ) } fun unlock( lock: StateAndRef> ): FlowProgressHandle { - return rpc.startTrackedFlow(::UnlockRevocationLockFlow, lock) + return rpc.startTrackedFlow( + ::UnlockRevocationLockFlow, + lock, + UnlockRevocationLockFlow.tracker() + ) } fun unlock( lock: StateAndRef>, clientId: String = UUID.randomUUID().toString() ): FlowHandleWithClientId { - return rpc.startFlowWithClientId(clientId, ::UnlockRevocationLockFlow, lock) + return rpc.startFlowWithClientId( + clientId, + ::UnlockRevocationLockFlow, + lock, + UnlockRevocationLockFlow.tracker() + ) } } diff --git a/onixlabs-corda-bnms-workflow/build.gradle b/onixlabs-corda-bnms-workflow/build.gradle index 7120e41..a9c1fe0 100644 --- a/onixlabs-corda-bnms-workflow/build.gradle +++ b/onixlabs-corda-bnms-workflow/build.gradle @@ -54,6 +54,7 @@ publishing { groupId = project.parent.group version = project.parent.version artifactId = 'onixlabs-corda-bnms-workflow' + artifact sourceJar from components.java } } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.FlowLogic.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.FlowLogic.kt index 76932f9..defeaa0 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.FlowLogic.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.FlowLogic.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,136 +16,130 @@ package io.onixlabs.corda.bnms.workflow +import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.membership.Membership import io.onixlabs.corda.bnms.contract.membership.MembershipAttestation import io.onixlabs.corda.bnms.contract.relationship.Relationship import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestation -import io.onixlabs.corda.bnms.workflow.membership.FindMembershipAttestationFlow -import io.onixlabs.corda.bnms.workflow.membership.FindMembershipFlow +import io.onixlabs.corda.bnms.contract.revocation.RevocationLock +import io.onixlabs.corda.core.services.any +import io.onixlabs.corda.core.services.singleOrNull +import io.onixlabs.corda.core.services.vaultServiceFor +import io.onixlabs.corda.core.workflow.currentStep +import net.corda.core.contracts.LinearState import net.corda.core.contracts.StateAndRef import net.corda.core.flows.FlowException import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession +import net.corda.core.identity.AbstractParty import net.corda.core.node.services.Vault -import co.paralleluniverse.fibers.Suspendable -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.contract.Attestation -import io.onixlabs.corda.identityframework.contract.CordaClaim -import io.onixlabs.corda.identityframework.workflow.* -import net.corda.core.flows.* -import net.corda.core.identity.Party -import net.corda.core.transactions.SignedTransaction -import net.corda.core.transactions.TransactionBuilder -import java.security.PublicKey +import net.corda.core.utilities.unwrap + +@Suspendable +fun FlowLogic<*>.checkMembership(checkMembership: Boolean, relationship: Relationship, sessions: Set) { + currentStep(SendCheckMembershipInstructionStep) + sessions.forEach { it.send(checkMembership) } + if (checkMembership) checkMembershipsAndAttestations(relationship) +} + +@Suspendable +fun FlowLogic<*>.checkMembershipHandler(session: FlowSession): Boolean { + currentStep(ReceiveCheckMembershipInstructionStep) + return session.receive().unwrap { it } +} +@Suspendable fun FlowLogic<*>.checkMembershipExists(membership: Membership) { - subFlow(FindMembershipFlow(hash = membership.hash))?.let { - throw FlowException("Membership state with the specified unique hash already exists: ${membership.hash}.") + val existingMembership = serviceHub.vaultServiceFor().singleOrNull { + stateStatus(Vault.StateStatus.ALL) + membershipHash(membership.hash) + } + + if (existingMembership != null) { + throw FlowException("The specified membership already exists: ${existingMembership.state.data}.") } } -fun FlowLogic<*>.checkMembershipsAndAttestations(relationship: Relationship) { - val counterparties = relationship.participants - .map { serviceHub.identityService.requireWellKnownPartyFromAnonymous(it) } - .filter { it !in serviceHub.myInfo.legalIdentities } +@Suspendable +fun FlowLogic<*>.checkMembershipAttestationExistsForIssuance(attestation: MembershipAttestation) { + val existingAttestation = serviceHub.vaultServiceFor().singleOrNull { + membershipAttestationAttestor(attestation.attestor) + membershipAttestationHolder(attestation.holder) + membershipAttestationNetworkHash(attestation.network.hash) + } - counterparties.forEach { - val findMembershipFlow = FindMembershipFlow( - holder = it, - network = relationship.network, - stateStatus = Vault.StateStatus.UNCONSUMED - ) - - val membership = subFlow(findMembershipFlow) ?: throw FlowException( - "Membership for specified holder and network could not be found, or has not been witnessed by this node." - ) - - val findAttestationFlow = FindMembershipAttestationFlow( - attestor = ourIdentity, - membership = membership, - stateStatus = Vault.StateStatus.UNCONSUMED - ) - - subFlow(findAttestationFlow) ?: throw FlowException( - "MembershipAttestation for specified membership could not be found, or has not been witnessed by this node." - ) + if (existingAttestation != null) { + throw FlowException("The specified membership attestation already exists and should be amended: ${existingAttestation.state.data}.") } } -fun FlowLogic<*>.findMembershipForAttestation(attestation: MembershipAttestation): StateAndRef { - return attestation.pointer.resolve(serviceHub) ?: throw FlowException( - "Membership for the specified attestation could not be found, or has not been witnessed by this node." - ) -} +@Suspendable +fun FlowLogic<*>.checkMembershipAttestationExistsForAmendment(attestation: MembershipAttestation) { + val existingAttestation = serviceHub.vaultServiceFor().singleOrNull { + stateStatus(Vault.StateStatus.ALL) + membershipAttestationHash(attestation.hash) + } -fun FlowLogic<*>.findRelationshipForAttestation(attestation: RelationshipAttestation): StateAndRef { - return attestation.pointer.resolve(serviceHub) ?: throw FlowException( - "Relationship for the specified attestation could not be found, or has not been witnessed by this node." - ) + if (existingAttestation != null) { + throw FlowException("The specified membership attestation already exists: ${existingAttestation.state.data}.") + } } -/** - * Generates an unsigned transaction. - * - * @param notary The notary to assign to the transaction. - * @param action The context in which the [TransactionBuilder] will build the transaction. - * @return Returns an unsigned transaction. - */ @Suspendable -internal fun FlowLogic<*>.transaction( - notary: Party, - action: TransactionBuilder.() -> TransactionBuilder -): TransactionBuilder { - currentStep(GENERATING) - return with(TransactionBuilder(notary)) { action(this) } +fun FlowLogic<*>.checkMembershipsAndAttestations(relationship: Relationship, ourAttestorIdentity: AbstractParty = ourIdentity) { + currentStep(CheckMembershipStep) + val counterparties = relationship.participants + .map { serviceHub.identityService.requireWellKnownPartyFromAnonymous(it) } + .filter { it !in serviceHub.myInfo.legalIdentities } + + counterparties.forEach { + val membership = serviceHub.vaultServiceFor().singleOrNull { + membershipHolder(it) + membershipNetworkHash(relationship.network.hash) + } ?: throw FlowException(buildString { + append("Membership with the specified details could not be found, or has not been witnessed by this node: ") + append("Holder = $it, ") + append("Network = ${relationship.network}.") + }) + + serviceHub.vaultServiceFor().singleOrNull { + membershipAttestationAttestor(ourAttestorIdentity) + membershipAttestationPointer(membership.ref) + } ?: throw FlowException(buildString { + append("Membership attestation with the specified details could not be found, or has not been witnessed by this node: ") + append("Holder = ${membership.state.data.holder}, ") + append("Attestor = $ourAttestorIdentity, ") + append("Network = ${membership.state.data.network}.") + }) + } } -/** - * Verifies and signs an unsigned transaction. - * - * @param builder The unsigned transaction to verify and sign. - * @param signingKey The initial signing ket for the transaction. - * @return Returns a verified and signed transaction. - */ @Suspendable -internal fun FlowLogic<*>.verifyAndSign( - builder: TransactionBuilder, - signingKey: PublicKey -): SignedTransaction { - currentStep(VERIFYING) - builder.verify(serviceHub) - - currentStep(SIGNING) - return serviceHub.signInitialTransaction(builder, signingKey) +fun FlowLogic<*>.checkRevocationLockExists(owner: AbstractParty, state: LinearState) { + val revocationLockExists = serviceHub.vaultServiceFor>().any { + revocationLockOwner(owner) + revocationLockPointerStateClass(state.javaClass) + revocationLockPointerStateLinearId(state.linearId.id) + } + + if (revocationLockExists) { + throw FlowException("Revocation of this relationship is locked by counter-party: $owner.") + } } -/** - * Gathers counter-party signatures for a partially signed transaction. - * - * @param transaction The signed transaction for which to obtain additional signatures. - * @param sessions The flow sessions for the required signing counter-parties. - * @return Returns a signed transaction. - */ @Suspendable -internal fun FlowLogic<*>.countersign( - transaction: SignedTransaction, - sessions: Set -): SignedTransaction { - currentStep(COUNTERSIGNING) - return subFlow(CollectSignaturesFlow(transaction, sessions, COUNTERSIGNING.childProgressTracker())) +fun FlowLogic<*>.findMembershipForAttestation(attestation: MembershipAttestation): StateAndRef { + return attestation.pointer.resolve(serviceHub) ?: throw FlowException(buildString { + append("Membership with the specified details could not be found, or has not been witnessed by this node: ") + append("Holder = ${attestation.holder}, ") + append("Network = ${attestation.network}.") + }) } -/** - * Finalizes and records a signed transaction to the vault. - * - * @param transaction The transaction to finalize and record. - * @param sessions The flow sessions for counter-parties who are expected to finalize and record the transaction. - * @return Returns a finalized and recorded transaction. - */ @Suspendable -internal fun FlowLogic<*>.finalize( - transaction: SignedTransaction, - sessions: Set = emptySet() -): SignedTransaction { - currentStep(FINALIZING) - return subFlow(FinalityFlow(transaction, sessions, FINALIZING.childProgressTracker())) +fun FlowLogic<*>.findRelationshipForAttestation(attestation: RelationshipAttestation): StateAndRef { + return attestation.pointer.resolve(serviceHub) ?: throw FlowException(buildString { + append("Relationship with the specified details could not be found, or has not been witnessed by this node: ") + append("Network = ${attestation.network}.") + }) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.Membership.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.Membership.kt new file mode 100644 index 0000000..0acae10 --- /dev/null +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.Membership.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.workflow + +import io.onixlabs.corda.bnms.contract.membership.Membership +import io.onixlabs.corda.bnms.contract.membership.MembershipSchema.MembershipEntity +import io.onixlabs.corda.core.services.QueryDsl +import io.onixlabs.corda.core.services.QueryDslContext +import io.onixlabs.corda.core.services.equalTo +import io.onixlabs.corda.core.services.isNull +import net.corda.core.crypto.SecureHash +import net.corda.core.identity.AbstractParty + +@QueryDslContext +fun QueryDsl.membershipHolder(value: AbstractParty) { + expression(MembershipEntity::holder equalTo value) +} + +@QueryDslContext +fun QueryDsl.membershipNetworkValue(value: String) { + expression(MembershipEntity::networkValue equalTo value) +} + +@QueryDslContext +fun QueryDsl.membershipNormalizedNetworkValue(value: String) { + expression(MembershipEntity::normalizedNetworkValue equalTo value.toUpperCase()) +} + +@QueryDslContext +fun QueryDsl.membershipNetworkOperator(value: AbstractParty?) { + if (value == null) expression(MembershipEntity::networkOperator.isNull()) + else expression(MembershipEntity::networkOperator equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.membershipNetworkHash(value: SecureHash) { + expression(MembershipEntity::networkHash equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.membershipIsNetworkOperator(value: Boolean) { + expression(MembershipEntity::isNetworkOperator equalTo value) +} + +@QueryDslContext +fun QueryDsl.membershipHash(value: SecureHash) { + expression(MembershipEntity::hash equalTo value.toString()) +} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.MembershipAttestation.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.MembershipAttestation.kt new file mode 100644 index 0000000..968f03f --- /dev/null +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.MembershipAttestation.kt @@ -0,0 +1,91 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.workflow + +import io.onixlabs.corda.bnms.contract.membership.MembershipAttestation +import io.onixlabs.corda.bnms.contract.membership.MembershipAttestationSchema.MembershipAttestationEntity +import io.onixlabs.corda.core.services.QueryDsl +import io.onixlabs.corda.core.services.QueryDslContext +import io.onixlabs.corda.core.services.equalTo +import io.onixlabs.corda.core.services.isNull +import io.onixlabs.corda.identityframework.contract.attestations.AttestationStatus +import net.corda.core.contracts.ContractState +import net.corda.core.contracts.StateRef +import net.corda.core.crypto.SecureHash +import net.corda.core.identity.AbstractParty + +@QueryDslContext +fun QueryDsl.membershipAttestationAttestor(value: AbstractParty) { + expression(MembershipAttestationEntity::attestor equalTo value) +} + +@QueryDslContext +fun QueryDsl.membershipAttestationHolder(value: AbstractParty) { + expression(MembershipAttestationEntity::holder equalTo value) +} + +@QueryDslContext +fun QueryDsl.membershipAttestationNetworkValue(value: String) { + expression(MembershipAttestationEntity::networkValue equalTo value) +} + +@QueryDslContext +fun QueryDsl.membershipAttestationNormalizedNetworkValue(value: String) { + expression(MembershipAttestationEntity::normalizedNetworkValue equalTo value.toUpperCase()) +} + +@QueryDslContext +fun QueryDsl.membershipAttestationNetworkOperator(value: AbstractParty?) { + if (value == null) expression(MembershipAttestationEntity::networkOperator.isNull()) + else expression(MembershipAttestationEntity::networkOperator equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.membershipAttestationNetworkHash(value: SecureHash) { + expression(MembershipAttestationEntity::networkHash equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.membershipAttestationPointer(value: Any) { + expression(MembershipAttestationEntity::pointer equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.membershipAttestationPointerStateType(value: Class) { + expression(MembershipAttestationEntity::pointerStateType equalTo value.canonicalName) +} + +@QueryDslContext +fun QueryDsl.membershipAttestationPointerHash(value: SecureHash) { + expression(MembershipAttestationEntity::pointerHash equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.membershipAttestationStatus(value: AttestationStatus) { + expression(MembershipAttestationEntity::status equalTo value) +} + +@QueryDslContext +fun QueryDsl.membershipAttestationPreviousStateRef(value: StateRef?) { + if (value == null) expression(MembershipAttestationEntity::previousStateRef.isNull()) + else expression(MembershipAttestationEntity::previousStateRef equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.membershipAttestationHash(value: SecureHash) { + expression(MembershipAttestationEntity::hash equalTo value.toString()) +} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.Relationship.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.Relationship.kt new file mode 100644 index 0000000..b4cfa43 --- /dev/null +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.Relationship.kt @@ -0,0 +1,58 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.workflow + +import io.onixlabs.corda.bnms.contract.membership.Membership +import io.onixlabs.corda.bnms.contract.membership.MembershipAttestation +import io.onixlabs.corda.bnms.contract.membership.MembershipAttestationSchema +import io.onixlabs.corda.bnms.contract.relationship.Relationship +import io.onixlabs.corda.bnms.contract.relationship.RelationshipSchema.RelationshipEntity +import io.onixlabs.corda.core.services.QueryDsl +import io.onixlabs.corda.core.services.QueryDslContext +import io.onixlabs.corda.core.services.equalTo +import io.onixlabs.corda.core.services.isNull +import io.onixlabs.corda.identityframework.contract.attestations.AttestationStatus +import net.corda.core.contracts.ContractState +import net.corda.core.contracts.StateRef +import net.corda.core.crypto.SecureHash +import net.corda.core.identity.AbstractParty + +@QueryDslContext +fun QueryDsl.relationshipNetworkValue(value: String) { + expression(RelationshipEntity::networkValue equalTo value) +} + +@QueryDslContext +fun QueryDsl.relationshipNormalizedNetworkValue(value: String) { + expression(RelationshipEntity::normalizedNetworkValue equalTo value.toUpperCase()) +} + +@QueryDslContext +fun QueryDsl.relationshipNetworkOperator(value: AbstractParty?) { + if (value == null) expression(RelationshipEntity::networkOperator.isNull()) + else expression(RelationshipEntity::networkOperator equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.relationshipNetworkHash(value: SecureHash) { + expression(RelationshipEntity::networkHash equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.relationshipHash(value: SecureHash) { + expression(RelationshipEntity::hash equalTo value.toString()) +} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.RelationshipAttestation.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.RelationshipAttestation.kt new file mode 100644 index 0000000..25e23a1 --- /dev/null +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.RelationshipAttestation.kt @@ -0,0 +1,86 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.workflow + +import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestation +import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestationSchema.RelationshipAttestationEntity +import io.onixlabs.corda.core.services.QueryDsl +import io.onixlabs.corda.core.services.QueryDslContext +import io.onixlabs.corda.core.services.equalTo +import io.onixlabs.corda.core.services.isNull +import io.onixlabs.corda.identityframework.contract.attestations.AttestationStatus +import net.corda.core.contracts.ContractState +import net.corda.core.contracts.StateRef +import net.corda.core.crypto.SecureHash +import net.corda.core.identity.AbstractParty + +@QueryDslContext +fun QueryDsl.relationshipAttestationAttestor(value: AbstractParty) { + expression(RelationshipAttestationEntity::attestor equalTo value) +} + +@QueryDslContext +fun QueryDsl.relationshipAttestationNetworkValue(value: String) { + expression(RelationshipAttestationEntity::networkValue equalTo value) +} + +@QueryDslContext +fun QueryDsl.relationshipAttestationNormalizedNetworkValue(value: String) { + expression(RelationshipAttestationEntity::normalizedNetworkValue equalTo value.toUpperCase()) +} + +@QueryDslContext +fun QueryDsl.relationshipAttestationNetworkOperator(value: AbstractParty?) { + if (value == null) expression(RelationshipAttestationEntity::networkOperator.isNull()) + else expression(RelationshipAttestationEntity::networkOperator equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.relationshipAttestationNetworkHash(value: SecureHash) { + expression(RelationshipAttestationEntity::networkHash equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.relationshipAttestationPointer(value: Any) { + expression(RelationshipAttestationEntity::pointer equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.relationshipAttestationPointerStateType(value: Class) { + expression(RelationshipAttestationEntity::pointerStateType equalTo value.canonicalName) +} + +@QueryDslContext +fun QueryDsl.relationshipAttestationPointerHash(value: SecureHash) { + expression(RelationshipAttestationEntity::pointerHash equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.relationshipAttestationStatus(value: AttestationStatus) { + expression(RelationshipAttestationEntity::status equalTo value) +} + +@QueryDslContext +fun QueryDsl.relationshipAttestationPreviousStateRef(value: StateRef?) { + if (value == null) expression(RelationshipAttestationEntity::previousStateRef.isNull()) + else expression(RelationshipAttestationEntity::previousStateRef equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.relationshipAttestationHash(value: SecureHash) { + expression(RelationshipAttestationEntity::hash equalTo value.toString()) +} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.RelationshipConfiguration.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.RelationshipConfiguration.kt new file mode 100644 index 0000000..7bee87a --- /dev/null +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.RelationshipConfiguration.kt @@ -0,0 +1,69 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.workflow + +import io.onixlabs.corda.bnms.contract.relationship.RelationshipConfiguration +import io.onixlabs.corda.bnms.contract.relationship.RelationshipConfigurationSchema.RelationshipConfigurationEntity +import io.onixlabs.corda.core.services.QueryDsl +import io.onixlabs.corda.core.services.QueryDslContext +import io.onixlabs.corda.core.services.equalTo +import io.onixlabs.corda.core.services.isNull +import net.corda.core.crypto.SecureHash +import net.corda.core.identity.AbstractParty +import java.util.* + +@QueryDslContext +fun QueryDsl.relationshipConfigurationRelationshipLinearId(value: UUID) { + expression(RelationshipConfigurationEntity::relationshipLinearId equalTo value) +} + +@QueryDslContext +fun QueryDsl.relationshipConfigurationRelationshipExternalId(value: String?) { + if (value == null) expression(RelationshipConfigurationEntity::relationshipExternalId.isNull()) + else expression(RelationshipConfigurationEntity::relationshipExternalId equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.relationshipConfigurationNetworkValue(value: String) { + expression(RelationshipConfigurationEntity::networkValue equalTo value) +} + +@QueryDslContext +fun QueryDsl.relationshipConfigurationNormalizedNetworkValue(value: String) { + expression(RelationshipConfigurationEntity::normalizedNetworkValue equalTo value.toUpperCase()) +} + +@QueryDslContext +fun QueryDsl.relationshipConfigurationNetworkOperator(value: AbstractParty?) { + if (value == null) expression(RelationshipConfigurationEntity::networkOperator.isNull()) + else expression(RelationshipConfigurationEntity::networkOperator equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.relationshipConfigurationNormalizedNetworkHash(value: SecureHash) { + expression(RelationshipConfigurationEntity::networkHash equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.relationshipConfigurationConfigurationHash(value: SecureHash) { + expression(RelationshipConfigurationEntity::configurationHash equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl.relationshipConfigurationHash(value: SecureHash) { + expression(RelationshipConfigurationEntity::hash equalTo value.toString()) +} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.RevocationLock.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.RevocationLock.kt new file mode 100644 index 0000000..958b87e --- /dev/null +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.QueryDsl.RevocationLock.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.workflow + +import io.onixlabs.corda.bnms.contract.revocation.RevocationLock +import io.onixlabs.corda.bnms.contract.revocation.RevocationLockSchema.RevocationLockEntity +import io.onixlabs.corda.core.services.QueryDsl +import io.onixlabs.corda.core.services.QueryDslContext +import io.onixlabs.corda.core.services.equalTo +import io.onixlabs.corda.core.services.isNull +import net.corda.core.contracts.LinearState +import net.corda.core.identity.AbstractParty +import java.util.* + +@QueryDslContext +fun QueryDsl>.revocationLockOwner(value: AbstractParty) { + expression(RevocationLockEntity::owner equalTo value) +} + +@QueryDslContext +fun QueryDsl>.revocationLockPointerStateLinearId(value: UUID) { + expression(RevocationLockEntity::pointerStateLinearId equalTo value) +} + +@QueryDslContext +fun QueryDsl>.pointerStateExternalId(value: String?) { + if (value == null) expression(RevocationLockEntity::pointerStateExternalId.isNull()) + else expression(RevocationLockEntity::pointerStateExternalId equalTo value.toString()) +} + +@QueryDslContext +fun QueryDsl>.revocationLockPointerStateClass(value: Class) { + expression(RevocationLockEntity::pointerStateClass equalTo value.canonicalName) +} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.TransactionBuilder.Membership.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.TransactionBuilder.Membership.kt new file mode 100644 index 0000000..77faf19 --- /dev/null +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.TransactionBuilder.Membership.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.workflow + +import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.bnms.contract.membership.Membership +import io.onixlabs.corda.bnms.contract.membership.MembershipContract +import net.corda.core.contracts.StateAndRef +import net.corda.core.transactions.TransactionBuilder +import java.security.PublicKey + +@Suspendable +fun TransactionBuilder.addIssuedMembership( + state: Membership, + signingKey: PublicKey +): TransactionBuilder = apply { + addOutputState(state) + addCommand(MembershipContract.Issue, signingKey) +} + +@Suspendable +fun TransactionBuilder.addAmendedMembership( + oldMembership: StateAndRef, + newMembership: Membership, + signingKey: PublicKey +): TransactionBuilder = apply { + addInputState(oldMembership) + addOutputState(newMembership, MembershipContract.ID) + addCommand(MembershipContract.Amend, signingKey) +} + +@Suspendable +fun TransactionBuilder.addRevokedMembership( + membership: StateAndRef, + signingKey: PublicKey +): TransactionBuilder = apply { + addInputState(membership) + addCommand(MembershipContract.Revoke, signingKey) +} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.TransactionBuilder.MembershipAttestation.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.TransactionBuilder.MembershipAttestation.kt new file mode 100644 index 0000000..0114226 --- /dev/null +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.TransactionBuilder.MembershipAttestation.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.workflow + +import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.bnms.contract.membership.Membership +import io.onixlabs.corda.bnms.contract.membership.MembershipAttestation +import io.onixlabs.corda.identityframework.workflow.addAmendedAttestation +import io.onixlabs.corda.identityframework.workflow.addIssuedAttestation +import io.onixlabs.corda.identityframework.workflow.addRevokedAttestation +import net.corda.core.contracts.ReferencedStateAndRef +import net.corda.core.contracts.StateAndRef +import net.corda.core.transactions.TransactionBuilder + +@Suspendable +fun TransactionBuilder.addIssuedMembershipAttestation( + membershipAttestation: MembershipAttestation, + membership: ReferencedStateAndRef +): TransactionBuilder = apply { + addIssuedAttestation(membershipAttestation) + addReferenceState(membership) +} + +@Suspendable +fun TransactionBuilder.addAmendedMembershipAttestation( + oldMembershipAttestation: StateAndRef, + newMembershipAttestation: MembershipAttestation, + membership: ReferencedStateAndRef +): TransactionBuilder = apply { + addAmendedAttestation(oldMembershipAttestation, newMembershipAttestation) + addReferenceState(membership) +} + +@Suspendable +fun TransactionBuilder.addRevokedMembershipAttestation( + membershipAttestation: StateAndRef +): TransactionBuilder = apply { + addRevokedAttestation(membershipAttestation) +} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.TransactionBuilder.Relationship.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.TransactionBuilder.Relationship.kt new file mode 100644 index 0000000..3742856 --- /dev/null +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.TransactionBuilder.Relationship.kt @@ -0,0 +1,52 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.workflow + +import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.bnms.contract.relationship.Relationship +import io.onixlabs.corda.bnms.contract.relationship.RelationshipContract +import io.onixlabs.corda.bnms.contract.revocation.RevocationLockContract +import net.corda.core.contracts.StateAndRef +import net.corda.core.transactions.TransactionBuilder + +@Suspendable +fun TransactionBuilder.addIssuedRelationship( + relationship: Relationship +): TransactionBuilder = apply { + addOutputState(relationship, RelationshipContract.ID) + relationship.createRevocationLocks().forEach { addOutputState(it) } + addCommand(RelationshipContract.Issue, relationship.participants.map { it.owningKey }) + addCommand(RevocationLockContract.Lock, relationship.participants.map { it.owningKey }) +} + +@Suspendable +fun TransactionBuilder.addAmendedRelationship( + oldRelationship: StateAndRef, + newRelationship: Relationship +): TransactionBuilder = apply { + addInputState(oldRelationship) + addOutputState(newRelationship, RelationshipContract.ID) + addCommand(RelationshipContract.Amend, newRelationship.participants.map { it.owningKey }) +} + +@Suspendable +fun TransactionBuilder.addRevokedRelationship( + relationship: StateAndRef +): TransactionBuilder = apply { + addInputState(relationship) + addCommand(RelationshipContract.Revoke, relationship.state.data.participants.map { it.owningKey }) +} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.TransactionBuilder.RelationshipAttestation.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.TransactionBuilder.RelationshipAttestation.kt new file mode 100644 index 0000000..75ed95a --- /dev/null +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.TransactionBuilder.RelationshipAttestation.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.workflow + +import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.bnms.contract.relationship.Relationship +import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestation +import io.onixlabs.corda.identityframework.workflow.addAmendedAttestation +import io.onixlabs.corda.identityframework.workflow.addIssuedAttestation +import io.onixlabs.corda.identityframework.workflow.addRevokedAttestation +import net.corda.core.contracts.ReferencedStateAndRef +import net.corda.core.contracts.StateAndRef +import net.corda.core.transactions.TransactionBuilder + +@Suspendable +fun TransactionBuilder.addIssuedRelationshipAttestation( + relationshipAttestation: RelationshipAttestation, + relationship: ReferencedStateAndRef +): TransactionBuilder = apply { + addIssuedAttestation(relationshipAttestation) + addReferenceState(relationship) +} + +@Suspendable +fun TransactionBuilder.addAmendedRelationshipAttestation( + oldRelationshipAttestation: StateAndRef, + newRelationshipAttestation: RelationshipAttestation, + relationship: ReferencedStateAndRef +): TransactionBuilder = apply { + addAmendedAttestation(oldRelationshipAttestation, newRelationshipAttestation) + addReferenceState(relationship) +} + +@Suspendable +fun TransactionBuilder.addRevokedRelationshipAttestation( + relationshipAttestation: StateAndRef +): TransactionBuilder = apply { + addRevokedAttestation(relationshipAttestation) +} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.TransactionBuilder.RevocationLock.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.TransactionBuilder.RevocationLock.kt new file mode 100644 index 0000000..b7bd7ed --- /dev/null +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/Extensions.TransactionBuilder.RevocationLock.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.workflow + +import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.bnms.contract.revocation.RevocationLock +import io.onixlabs.corda.bnms.contract.revocation.RevocationLockContract +import net.corda.core.contracts.StateAndRef +import net.corda.core.transactions.TransactionBuilder + +@Suspendable +fun TransactionBuilder.addLockedRevocationLock( + revocationLock: RevocationLock<*> +): TransactionBuilder = apply { + addOutputState(revocationLock, RevocationLockContract.ID) + addCommand(RevocationLockContract.Lock, revocationLock.owner.owningKey) +} + +@Suspendable +fun TransactionBuilder.addUnlockedRevocationLock( + revocationLock: StateAndRef> +): TransactionBuilder = apply { + addInputState(revocationLock) + addCommand(RevocationLockContract.Unlock, revocationLock.state.data.owner.owningKey) +} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/FlowSteps.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/FlowSteps.kt new file mode 100644 index 0000000..c13c1ee --- /dev/null +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/FlowSteps.kt @@ -0,0 +1,64 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.workflow + +import net.corda.core.utilities.ProgressTracker.Step + +/** + * Represents a progress tracker step indicating that a membership transaction is being sent. + */ +object SendMembershipStep : Step("Sending membership transaction.") + +/** + * Represents a progress tracker step indicating that a membership transaction is being received. + */ +object ReceiveMembershipStep : Step("Receiving membership transaction.") + +/** + * Represents a progress tracker step indicating that a membership attestatopm transaction is being sent. + */ +object SendMembershipAttestationStep : Step("Sending membership attestation transaction.") + +/** + * Represents a progress tracker step indicating that a membership attestation transaction is being received. + */ +object ReceiveMembershipAttestationStep : Step("Receiving membership attestation transaction.") + +/** + * Represents a progress tracker step indicating that the local node's membership and attestations are being sent. + */ +object SendMembershipAndAttestationsStep : Step("Sending our (local) membership and attestations.") + +/** + * Represents a progress tracker step indicating that a counter-party node's membership and attestations are being received. + */ +object ReceiveMembershipAndAttestationsStep : Step("Receiving their (counter-party) membership and attestations.") + +/** + * Represents a progress tracker step indicating that counter-party nodes should check for membership and attestation states. + */ +object SendCheckMembershipInstructionStep : Step("Sending check membership instruction.") + +/** + * Represents a progress tracker step indicating that the local node should check for membership and attestation states. + */ +object ReceiveCheckMembershipInstructionStep : Step("Receiving check membership instruction.") + +/** + * Represents a progress tracker step indicating that the current node should check for membership and attestation states. + */ +object CheckMembershipStep : Step("Checking for membership and attestation states.") diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipAttestationFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipAttestationFlow.kt index 2278c63..0760e59 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipAttestationFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipAttestationFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,18 +18,17 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.membership.MembershipAttestation +import io.onixlabs.corda.bnms.workflow.addAmendedMembershipAttestation +import io.onixlabs.corda.bnms.workflow.checkMembershipAttestationExistsForAmendment import io.onixlabs.corda.bnms.workflow.findMembershipForAttestation -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.core.workflow.initiateFlows -import io.onixlabs.corda.identityframework.workflow.* +import io.onixlabs.corda.core.workflow.* +import io.onixlabs.corda.identityframework.workflow.checkAttestationExistsForAmendment import net.corda.core.contracts.StateAndRef import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker.Step -import io.onixlabs.corda.bnms.workflow.* -import io.onixlabs.corda.core.workflow.checkSufficientSessions class AmendMembershipAttestationFlow( private val oldAttestation: StateAndRef, @@ -40,24 +39,33 @@ class AmendMembershipAttestationFlow( companion object { @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, GENERATING, VERIFYING, SIGNING, FINALIZING) + fun tracker() = ProgressTracker( + InitializeFlowStep, + BuildTransactionStep, + VerifyTransactionStep, + SignTransactionStep, + SendStatesToRecordStep, + FinalizeTransactionStep + ) private const val FLOW_VERSION_1 = 1 } @Suspendable override fun call(): SignedTransaction { - currentStep(INITIALIZING) - checkSufficientSessions(sessions, newAttestation) + currentStep(InitializeFlowStep) + checkSufficientSessionsForContractStates(sessions, newAttestation) + checkMembershipAttestationExistsForAmendment(newAttestation) + val membership = findMembershipForAttestation(newAttestation).referenced() - val transaction = transaction(oldAttestation.state.notary) { - addAmendedAttestation(oldAttestation, newAttestation) - addReferenceState(findMembershipForAttestation(newAttestation).referenced()) + val transaction = buildTransaction(oldAttestation.state.notary) { + addAmendedMembershipAttestation(oldAttestation, newAttestation, membership) } - val signedTransaction = verifyAndSign(transaction, newAttestation.attestor.owningKey) - return finalize(signedTransaction, sessions) + verifyTransaction(transaction) + val signedTransaction = signTransaction(transaction) + return finalizeTransaction(signedTransaction, sessions) } @StartableByRPC @@ -70,16 +78,16 @@ class AmendMembershipAttestationFlow( ) : FlowLogic() { private companion object { - object AMENDING : Step("Amending membership attestation.") { + object AmendMembershipAttestationStep : Step("Amending membership attestation.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(AMENDING) + override val progressTracker = ProgressTracker(AmendMembershipAttestationStep) @Suspendable override fun call(): SignedTransaction { - currentStep(AMENDING) + currentStep(AmendMembershipAttestationStep) val sessions = initiateFlows(observers, newAttestation) return subFlow( @@ -87,7 +95,7 @@ class AmendMembershipAttestationFlow( oldAttestation, newAttestation, sessions, - AMENDING.childProgressTracker() + AmendMembershipAttestationStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipAttestationFlowHandler.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipAttestationFlowHandler.kt index 2e32e36..40e7672 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipAttestationFlowHandler.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipAttestationFlowHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,18 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.core.workflow.ReceiveStatesToRecordStep +import io.onixlabs.corda.core.workflow.RecordFinalizedTransactionStep import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.FINALIZING +import io.onixlabs.corda.core.workflow.finalizeTransactionHandler import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.ReceiveFinalityFlow import net.corda.core.node.StatesToRecord import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step class AmendMembershipAttestationFlowHandler( private val session: FlowSession, @@ -37,33 +39,35 @@ class AmendMembershipAttestationFlowHandler( companion object { @JvmStatic - fun tracker() = ProgressTracker(FINALIZING) + fun tracker() = ProgressTracker( + ReceiveStatesToRecordStep, + RecordFinalizedTransactionStep + ) } @Suspendable override fun call(): SignedTransaction { - currentStep(FINALIZING) - return subFlow(ReceiveFinalityFlow(session, expectedTransactionId, statesToRecord)) + return finalizeTransactionHandler(session, expectedTransactionId, statesToRecord) } @InitiatedBy(AmendMembershipAttestationFlow.Initiator::class) private class Handler(private val session: FlowSession) : FlowLogic() { private companion object { - object OBSERVING : ProgressTracker.Step("Observing membership attestation amendment.") { + object HandleAmendMembershipAttestationStep : Step("Handling membership attestation amendment.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(OBSERVING) + override val progressTracker = ProgressTracker(HandleAmendMembershipAttestationStep) @Suspendable override fun call(): SignedTransaction { - currentStep(OBSERVING) + currentStep(HandleAmendMembershipAttestationStep) return subFlow( AmendMembershipAttestationFlowHandler( session, - progressTracker = OBSERVING.childProgressTracker() + progressTracker = HandleAmendMembershipAttestationStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipFlow.kt index 1bfe492..152b690 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,15 +18,9 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.membership.Membership -import io.onixlabs.corda.bnms.contract.membership.MembershipContract +import io.onixlabs.corda.bnms.workflow.addAmendedMembership import io.onixlabs.corda.bnms.workflow.checkMembershipExists -import io.onixlabs.corda.bnms.workflow.finalize -import io.onixlabs.corda.bnms.workflow.transaction -import io.onixlabs.corda.bnms.workflow.verifyAndSign -import io.onixlabs.corda.core.workflow.checkSufficientSessions -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.core.workflow.initiateFlows -import io.onixlabs.corda.identityframework.workflow.* +import io.onixlabs.corda.core.workflow.* import net.corda.core.contracts.StateAndRef import net.corda.core.flows.* import net.corda.core.identity.Party @@ -43,25 +37,31 @@ class AmendMembershipFlow( companion object { @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, GENERATING, VERIFYING, SIGNING, FINALIZING) + fun tracker() = ProgressTracker( + InitializeFlowStep, + BuildTransactionStep, + VerifyTransactionStep, + SignTransactionStep, + SendStatesToRecordStep, + FinalizeTransactionStep + ) private const val FLOW_VERSION_1 = 1 } @Suspendable override fun call(): SignedTransaction { - currentStep(INITIALIZING) + currentStep(InitializeFlowStep) checkMembershipExists(newMembership) - checkSufficientSessions(sessions, newMembership) + checkSufficientSessionsForContractStates(sessions, newMembership) - val transaction = transaction(oldMembership.state.notary) { - addInputState(oldMembership) - addOutputState(newMembership, MembershipContract.ID) - addCommand(MembershipContract.Amend, ourIdentity.owningKey) + val transaction = buildTransaction(oldMembership.state.notary) { + addAmendedMembership(oldMembership, newMembership, ourIdentity.owningKey) } - val signedTransaction = verifyAndSign(transaction, ourIdentity.owningKey) - return finalize(signedTransaction, sessions) + verifyTransaction(transaction) + val signedTransaction = signTransaction(transaction) + return finalizeTransaction(signedTransaction, sessions) } @StartableByRPC @@ -74,16 +74,16 @@ class AmendMembershipFlow( ) : FlowLogic() { private companion object { - object AMENDING : Step("Amending membership.") { + object AmendMembershipStep : Step("Amending membership.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(AMENDING) + override val progressTracker = ProgressTracker(AmendMembershipStep) @Suspendable override fun call(): SignedTransaction { - currentStep(AMENDING) + currentStep(AmendMembershipStep) val sessions = initiateFlows(observers, newMembership) return subFlow( @@ -91,7 +91,7 @@ class AmendMembershipFlow( oldMembership, newMembership, sessions, - AMENDING.childProgressTracker() + AmendMembershipStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipFlowHandler.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipFlowHandler.kt index aea0381..614f5ae 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipFlowHandler.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipFlowHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,18 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.core.workflow.ReceiveStatesToRecordStep +import io.onixlabs.corda.core.workflow.RecordFinalizedTransactionStep import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.FINALIZING +import io.onixlabs.corda.core.workflow.finalizeTransactionHandler import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.ReceiveFinalityFlow import net.corda.core.node.StatesToRecord import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step class AmendMembershipFlowHandler( private val session: FlowSession, @@ -37,30 +39,37 @@ class AmendMembershipFlowHandler( companion object { @JvmStatic - fun tracker() = ProgressTracker(FINALIZING) + fun tracker() = ProgressTracker( + ReceiveStatesToRecordStep, + RecordFinalizedTransactionStep + ) } @Suspendable override fun call(): SignedTransaction { - currentStep(FINALIZING) - return subFlow(ReceiveFinalityFlow(session, expectedTransactionId, statesToRecord)) + return finalizeTransactionHandler(session, expectedTransactionId, statesToRecord) } @InitiatedBy(AmendMembershipFlow.Initiator::class) private class Handler(private val session: FlowSession) : FlowLogic() { private companion object { - object OBSERVING : ProgressTracker.Step("Observing membership amendment.") { + object HandleAmendedMembershipStep : Step("Handling membership amendment.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(OBSERVING) + override val progressTracker = ProgressTracker(HandleAmendedMembershipStep) @Suspendable override fun call(): SignedTransaction { - currentStep(OBSERVING) - return subFlow(AmendMembershipFlowHandler(session, progressTracker = OBSERVING.childProgressTracker())) + currentStep(HandleAmendedMembershipStep) + return subFlow( + AmendMembershipFlowHandler( + session, + progressTracker = HandleAmendedMembershipStep.childProgressTracker() + ) + ) } } } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/FindMembershipAttestationFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/FindMembershipAttestationFlow.kt deleted file mode 100644 index ee8a9e8..0000000 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/FindMembershipAttestationFlow.kt +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2020-2021 ONIXLabs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.onixlabs.corda.bnms.workflow.membership - -import io.onixlabs.corda.bnms.contract.Network -import io.onixlabs.corda.bnms.contract.membership.Membership -import io.onixlabs.corda.bnms.contract.membership.MembershipAttestation -import io.onixlabs.corda.bnms.contract.membership.MembershipAttestationSchema.MembershipAttestationEntity -import io.onixlabs.corda.core.workflow.DEFAULT_PAGE_SPECIFICATION -import io.onixlabs.corda.core.workflow.FindStateFlow -import io.onixlabs.corda.core.workflow.andWithExpressions -import io.onixlabs.corda.identityframework.contract.AttestationPointer -import io.onixlabs.corda.identityframework.contract.AttestationStatus -import net.corda.core.contracts.StateAndRef -import net.corda.core.contracts.StateRef -import net.corda.core.contracts.UniqueIdentifier -import net.corda.core.crypto.SecureHash -import net.corda.core.flows.StartableByRPC -import net.corda.core.flows.StartableByService -import net.corda.core.identity.AbstractParty -import net.corda.core.node.services.Vault -import net.corda.core.node.services.vault.Builder.equal -import net.corda.core.node.services.vault.PageSpecification -import net.corda.core.node.services.vault.QueryCriteria -import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria - -@StartableByRPC -@StartableByService -class FindMembershipAttestationFlow( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - attestor: AbstractParty? = null, - holder: AbstractParty? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - pointer: AttestationPointer? = null, - pointerStateRef: StateRef? = null, - pointerStateLinearId: UniqueIdentifier? = null, - pointerHash: SecureHash? = null, - status: AttestationStatus? = null, - previousStateRef: StateRef? = null, - hash: SecureHash? = null, - membership: StateAndRef? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - override val pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION -) : FindStateFlow() { - override val criteria: QueryCriteria = VaultQueryCriteria( - contractStateTypes = setOf(contractStateType), - relevancyStatus = relevancyStatus, - status = stateStatus - ).andWithExpressions( - linearId?.let { MembershipAttestationEntity::linearId.equal(it.id) }, - externalId?.let { MembershipAttestationEntity::externalId.equal(it) }, - attestor?.let { MembershipAttestationEntity::attestor.equal(it) }, - holder?.let { MembershipAttestationEntity::holder.equal(it) }, - network?.let { MembershipAttestationEntity::networkHash.equal(it.hash.toString()) }, - networkValue?.let { MembershipAttestationEntity::networkValue.equal(it) }, - networkOperator?.let { MembershipAttestationEntity::networkOperator.equal(it) }, - networkHash?.let { MembershipAttestationEntity::networkHash.equal(it.toString()) }, - pointer?.let { MembershipAttestationEntity::pointerHash.equal(it.hash.toString()) }, - pointerStateRef?.let { MembershipAttestationEntity::pointerStateRef.equal(it.toString()) }, - pointerStateLinearId?.let { MembershipAttestationEntity::pointerStateLinearId.equal(it.id) }, - pointerHash?.let { MembershipAttestationEntity::pointerHash.equal(it.toString()) }, - status?.let { MembershipAttestationEntity::status.equal(it) }, - previousStateRef?.let { MembershipAttestationEntity::previousStateRef.equal(it.toString()) }, - membership?.let { MembershipAttestationEntity::pointerStateRef.equal(it.ref.toString()) }, - hash?.let { MembershipAttestationEntity::hash.equal(it.toString()) } - ) -} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/FindMembershipAttestationsFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/FindMembershipAttestationsFlow.kt deleted file mode 100644 index 20c817b..0000000 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/FindMembershipAttestationsFlow.kt +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2020-2021 ONIXLabs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.onixlabs.corda.bnms.workflow.membership - -import io.onixlabs.corda.bnms.contract.Network -import io.onixlabs.corda.bnms.contract.membership.Membership -import io.onixlabs.corda.bnms.contract.membership.MembershipAttestation -import io.onixlabs.corda.bnms.contract.membership.MembershipAttestationSchema.MembershipAttestationEntity -import io.onixlabs.corda.core.workflow.DEFAULT_PAGE_SPECIFICATION -import io.onixlabs.corda.core.workflow.DEFAULT_SORTING -import io.onixlabs.corda.core.workflow.FindStatesFlow -import io.onixlabs.corda.core.workflow.andWithExpressions -import io.onixlabs.corda.identityframework.contract.AttestationPointer -import io.onixlabs.corda.identityframework.contract.AttestationStatus -import net.corda.core.contracts.StateAndRef -import net.corda.core.contracts.StateRef -import net.corda.core.contracts.UniqueIdentifier -import net.corda.core.crypto.SecureHash -import net.corda.core.flows.StartableByRPC -import net.corda.core.flows.StartableByService -import net.corda.core.identity.AbstractParty -import net.corda.core.node.services.Vault -import net.corda.core.node.services.vault.Builder.equal -import net.corda.core.node.services.vault.PageSpecification -import net.corda.core.node.services.vault.QueryCriteria -import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria -import net.corda.core.node.services.vault.Sort - -@StartableByRPC -@StartableByService -class FindMembershipAttestationsFlow( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - attestor: AbstractParty? = null, - holder: AbstractParty? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - pointer: AttestationPointer? = null, - pointerStateRef: StateRef? = null, - pointerStateLinearId: UniqueIdentifier? = null, - pointerHash: SecureHash? = null, - status: AttestationStatus? = null, - previousStateRef: StateRef? = null, - hash: SecureHash? = null, - membership: StateAndRef? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - override val pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION, - override val sorting: Sort = DEFAULT_SORTING -) : FindStatesFlow() { - override val criteria: QueryCriteria = VaultQueryCriteria( - contractStateTypes = setOf(contractStateType), - relevancyStatus = relevancyStatus, - status = stateStatus - ).andWithExpressions( - linearId?.let { MembershipAttestationEntity::linearId.equal(it.id) }, - externalId?.let { MembershipAttestationEntity::externalId.equal(it) }, - attestor?.let { MembershipAttestationEntity::attestor.equal(it) }, - holder?.let { MembershipAttestationEntity::holder.equal(it) }, - network?.let { MembershipAttestationEntity::networkHash.equal(it.hash.toString()) }, - networkValue?.let { MembershipAttestationEntity::networkValue.equal(it) }, - networkOperator?.let { MembershipAttestationEntity::networkOperator.equal(it) }, - networkHash?.let { MembershipAttestationEntity::networkHash.equal(it.toString()) }, - pointer?.let { MembershipAttestationEntity::pointerHash.equal(it.hash.toString()) }, - pointerStateRef?.let { MembershipAttestationEntity::pointerStateRef.equal(it.toString()) }, - pointerStateLinearId?.let { MembershipAttestationEntity::pointerStateLinearId.equal(it.id) }, - pointerHash?.let { MembershipAttestationEntity::pointerHash.equal(it.toString()) }, - status?.let { MembershipAttestationEntity::status.equal(it) }, - previousStateRef?.let { MembershipAttestationEntity::previousStateRef.equal(it.toString()) }, - membership?.let { MembershipAttestationEntity::pointerStateRef.equal(it.ref.toString()) }, - hash?.let { MembershipAttestationEntity::hash.equal(it.toString()) } - ) -} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/FindMembershipFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/FindMembershipFlow.kt deleted file mode 100644 index 5634a06..0000000 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/FindMembershipFlow.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2020-2021 ONIXLabs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.onixlabs.corda.bnms.workflow.membership - -import io.onixlabs.corda.bnms.contract.Network -import io.onixlabs.corda.bnms.contract.membership.Membership -import io.onixlabs.corda.bnms.contract.membership.MembershipSchema.MembershipEntity -import io.onixlabs.corda.core.workflow.DEFAULT_PAGE_SPECIFICATION -import io.onixlabs.corda.core.workflow.FindStateFlow -import io.onixlabs.corda.core.workflow.andWithExpressions -import net.corda.core.contracts.UniqueIdentifier -import net.corda.core.crypto.SecureHash -import net.corda.core.flows.StartableByRPC -import net.corda.core.flows.StartableByService -import net.corda.core.identity.AbstractParty -import net.corda.core.node.services.Vault -import net.corda.core.node.services.vault.Builder.equal -import net.corda.core.node.services.vault.PageSpecification -import net.corda.core.node.services.vault.QueryCriteria -import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria - -@StartableByRPC -@StartableByService -class FindMembershipFlow( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - holder: AbstractParty? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - isNetworkOperator: Boolean? = null, - hash: SecureHash? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - override val pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION -) : FindStateFlow() { - override val criteria: QueryCriteria = VaultQueryCriteria( - contractStateTypes = setOf(contractStateType), - relevancyStatus = relevancyStatus, - status = stateStatus - ).andWithExpressions( - linearId?.let { MembershipEntity::linearId.equal(it.id) }, - externalId?.let { MembershipEntity::externalId.equal(it) }, - holder?.let { MembershipEntity::holder.equal(it) }, - network?.let { MembershipEntity::networkHash.equal(it.hash.toString()) }, - networkValue?.let { MembershipEntity::networkValue.equal(it) }, - networkOperator?.let { MembershipEntity::networkOperator.equal(it) }, - networkHash?.let { MembershipEntity::networkHash.equal(it.toString()) }, - isNetworkOperator?.let { MembershipEntity::isNetworkOperator.equal(it) }, - hash?.let { MembershipEntity::hash.equal(it.toString()) } - ) -} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/FindMembershipsFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/FindMembershipsFlow.kt deleted file mode 100644 index 97b47e7..0000000 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/FindMembershipsFlow.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2020-2021 ONIXLabs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.onixlabs.corda.bnms.workflow.membership - -import io.onixlabs.corda.bnms.contract.Network -import io.onixlabs.corda.bnms.contract.membership.Membership -import io.onixlabs.corda.bnms.contract.membership.MembershipSchema.MembershipEntity -import io.onixlabs.corda.core.workflow.DEFAULT_PAGE_SPECIFICATION -import io.onixlabs.corda.core.workflow.DEFAULT_SORTING -import io.onixlabs.corda.core.workflow.FindStatesFlow -import io.onixlabs.corda.core.workflow.andWithExpressions -import net.corda.core.contracts.UniqueIdentifier -import net.corda.core.crypto.SecureHash -import net.corda.core.flows.StartableByRPC -import net.corda.core.flows.StartableByService -import net.corda.core.identity.AbstractParty -import net.corda.core.node.services.Vault -import net.corda.core.node.services.vault.Builder.equal -import net.corda.core.node.services.vault.PageSpecification -import net.corda.core.node.services.vault.QueryCriteria -import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria -import net.corda.core.node.services.vault.Sort - -@StartableByRPC -@StartableByService -class FindMembershipsFlow( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - holder: AbstractParty? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - isNetworkOperator: Boolean? = null, - hash: SecureHash? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - override val pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION, - override val sorting: Sort = DEFAULT_SORTING -) : FindStatesFlow() { - override val criteria: QueryCriteria = VaultQueryCriteria( - contractStateTypes = setOf(contractStateType), - relevancyStatus = relevancyStatus, - status = stateStatus - ).andWithExpressions( - linearId?.let { MembershipEntity::linearId.equal(it.id) }, - externalId?.let { MembershipEntity::externalId.equal(it) }, - holder?.let { MembershipEntity::holder.equal(it) }, - network?.let { MembershipEntity::networkHash.equal(it.hash.toString()) }, - networkValue?.let { MembershipEntity::networkValue.equal(it) }, - networkOperator?.let { MembershipEntity::networkOperator.equal(it) }, - networkHash?.let { MembershipEntity::networkHash.equal(it.toString()) }, - isNetworkOperator?.let { MembershipEntity::isNetworkOperator.equal(it) }, - hash?.let { MembershipEntity::hash.equal(it.toString()) } - ) -} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipAttestationFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipAttestationFlow.kt index ee93762..b0f679f 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipAttestationFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipAttestationFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,13 +18,12 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.membership.MembershipAttestation +import io.onixlabs.corda.bnms.workflow.addIssuedMembershipAttestation +import io.onixlabs.corda.bnms.workflow.checkMembershipAttestationExistsForAmendment +import io.onixlabs.corda.bnms.workflow.checkMembershipAttestationExistsForIssuance import io.onixlabs.corda.bnms.workflow.findMembershipForAttestation -import io.onixlabs.corda.core.workflow.checkSufficientSessions -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.core.workflow.getPreferredNotary -import io.onixlabs.corda.core.workflow.initiateFlows -import io.onixlabs.corda.identityframework.workflow.* -import io.onixlabs.corda.bnms.workflow.* +import io.onixlabs.corda.core.workflow.* +import io.onixlabs.corda.identityframework.workflow.checkAttestationExistsForIssuance import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.transactions.SignedTransaction @@ -40,23 +39,33 @@ class IssueMembershipAttestationFlow( companion object { @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, GENERATING, VERIFYING, SIGNING, FINALIZING) + fun tracker() = ProgressTracker( + InitializeFlowStep, + BuildTransactionStep, + VerifyTransactionStep, + SignTransactionStep, + SendStatesToRecordStep, + FinalizeTransactionStep + ) private const val FLOW_VERSION_1 = 1 } @Suspendable override fun call(): SignedTransaction { - currentStep(INITIALIZING) - checkSufficientSessions(sessions, attestation) + currentStep(InitializeFlowStep) + checkSufficientSessionsForContractStates(sessions, attestation) + checkMembershipAttestationExistsForIssuance(attestation) - val transaction = transaction(notary) { - addIssuedAttestation(attestation) - addReferenceState(findMembershipForAttestation(attestation).referenced()) + val membership = findMembershipForAttestation(attestation).referenced() + + val transaction = buildTransaction(notary) { + addIssuedMembershipAttestation(attestation, membership) } - val signedTransaction = verifyAndSign(transaction, attestation.attestor.owningKey) - return finalize(signedTransaction, sessions) + verifyTransaction(transaction) + val signedTransaction = signTransaction(transaction) + return finalizeTransaction(signedTransaction, sessions) } @StartableByRPC @@ -69,16 +78,16 @@ class IssueMembershipAttestationFlow( ) : FlowLogic() { private companion object { - object ISSUING : Step("Issuing membership attestation.") { + object IssueMembershipAttestationStep : Step("Issuing membership attestation.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(ISSUING) + override val progressTracker = ProgressTracker(IssueMembershipAttestationStep) @Suspendable override fun call(): SignedTransaction { - currentStep(ISSUING) + currentStep(IssueMembershipAttestationStep) val sessions = initiateFlows(observers, attestation) return subFlow( @@ -86,7 +95,7 @@ class IssueMembershipAttestationFlow( attestation, notary ?: getPreferredNotary(), sessions, - ISSUING.childProgressTracker() + IssueMembershipAttestationStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipAttestationFlowHandler.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipAttestationFlowHandler.kt index 26ad152..d100629 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipAttestationFlowHandler.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipAttestationFlowHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,18 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.core.workflow.ReceiveStatesToRecordStep +import io.onixlabs.corda.core.workflow.RecordFinalizedTransactionStep import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.FINALIZING +import io.onixlabs.corda.core.workflow.finalizeTransactionHandler import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.ReceiveFinalityFlow import net.corda.core.node.StatesToRecord import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step class IssueMembershipAttestationFlowHandler( private val session: FlowSession, @@ -37,33 +39,35 @@ class IssueMembershipAttestationFlowHandler( companion object { @JvmStatic - fun tracker() = ProgressTracker(FINALIZING) + fun tracker() = ProgressTracker( + ReceiveStatesToRecordStep, + RecordFinalizedTransactionStep + ) } @Suspendable override fun call(): SignedTransaction { - currentStep(FINALIZING) - return subFlow(ReceiveFinalityFlow(session, expectedTransactionId, statesToRecord)) + return finalizeTransactionHandler(session, expectedTransactionId, statesToRecord) } @InitiatedBy(IssueMembershipAttestationFlow.Initiator::class) private class Handler(private val session: FlowSession) : FlowLogic() { private companion object { - object OBSERVING : ProgressTracker.Step("Observing membership attestation issuance.") { + object HandleIssueMembershipAttestationStep : Step("Handling membership attestation issuance.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(OBSERVING) + override val progressTracker = ProgressTracker(HandleIssueMembershipAttestationStep) @Suspendable override fun call(): SignedTransaction { - currentStep(OBSERVING) + currentStep(HandleIssueMembershipAttestationStep) return subFlow( IssueMembershipAttestationFlowHandler( session, - progressTracker = OBSERVING.childProgressTracker() + progressTracker = HandleIssueMembershipAttestationStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipFlow.kt index d05ca0c..4b657de 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,14 +18,9 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.membership.Membership -import io.onixlabs.corda.bnms.contract.membership.MembershipContract +import io.onixlabs.corda.bnms.workflow.addIssuedMembership import io.onixlabs.corda.bnms.workflow.checkMembershipExists -import io.onixlabs.corda.core.workflow.checkSufficientSessions -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.core.workflow.getPreferredNotary -import io.onixlabs.corda.core.workflow.initiateFlows -import io.onixlabs.corda.identityframework.workflow.* -import io.onixlabs.corda.bnms.workflow.* +import io.onixlabs.corda.core.workflow.* import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.transactions.SignedTransaction @@ -41,24 +36,31 @@ class IssueMembershipFlow( companion object { @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, GENERATING, VERIFYING, SIGNING, FINALIZING) + fun tracker() = ProgressTracker( + InitializeFlowStep, + BuildTransactionStep, + VerifyTransactionStep, + SignTransactionStep, + SendStatesToRecordStep, + FinalizeTransactionStep + ) private const val FLOW_VERSION_1 = 1 } @Suspendable override fun call(): SignedTransaction { - currentStep(INITIALIZING) + currentStep(InitializeFlowStep) checkMembershipExists(membership) - checkSufficientSessions(sessions, membership) + checkSufficientSessionsForContractStates(sessions, membership) - val transaction = transaction(notary) { - addOutputState(membership) - addCommand(MembershipContract.Issue, ourIdentity.owningKey) + val transaction = buildTransaction(notary) { + addIssuedMembership(membership, ourIdentity.owningKey) } - val signedTransaction = verifyAndSign(transaction, ourIdentity.owningKey) - return finalize(signedTransaction, sessions) + verifyTransaction(transaction) + val signedTransaction = signTransaction(transaction) + return finalizeTransaction(signedTransaction, sessions) } @StartableByRPC @@ -71,16 +73,16 @@ class IssueMembershipFlow( ) : FlowLogic() { private companion object { - object ISSUING : Step("Issuing membership.") { + object IssueMembershipStep : Step("Issuing membership.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(ISSUING) + override val progressTracker = ProgressTracker(IssueMembershipStep) @Suspendable override fun call(): SignedTransaction { - currentStep(ISSUING) + currentStep(IssueMembershipStep) val sessions = initiateFlows(observers, membership) return subFlow( @@ -88,7 +90,7 @@ class IssueMembershipFlow( membership, notary ?: getPreferredNotary(), sessions, - ISSUING.childProgressTracker() + IssueMembershipStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipFlowHandler.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipFlowHandler.kt index ca7b966..a75eac7 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipFlowHandler.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipFlowHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,18 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.core.workflow.ReceiveStatesToRecordStep +import io.onixlabs.corda.core.workflow.RecordFinalizedTransactionStep import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.FINALIZING +import io.onixlabs.corda.core.workflow.finalizeTransactionHandler import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.ReceiveFinalityFlow import net.corda.core.node.StatesToRecord import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step class IssueMembershipFlowHandler( private val session: FlowSession, @@ -37,30 +39,37 @@ class IssueMembershipFlowHandler( companion object { @JvmStatic - fun tracker() = ProgressTracker(FINALIZING) + fun tracker() = ProgressTracker( + ReceiveStatesToRecordStep, + RecordFinalizedTransactionStep + ) } @Suspendable override fun call(): SignedTransaction { - currentStep(FINALIZING) - return subFlow(ReceiveFinalityFlow(session, expectedTransactionId, statesToRecord)) + return finalizeTransactionHandler(session, expectedTransactionId, statesToRecord) } @InitiatedBy(IssueMembershipFlow.Initiator::class) private class Handler(private val session: FlowSession) : FlowLogic() { private companion object { - object OBSERVING : ProgressTracker.Step("Observing membership issuance.") { + object HandleIssuedMembershipStep : Step("Handling membership issuance.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(OBSERVING) + override val progressTracker = ProgressTracker(HandleIssuedMembershipStep) @Suspendable override fun call(): SignedTransaction { - currentStep(OBSERVING) - return subFlow(IssueMembershipFlowHandler(session, progressTracker = OBSERVING.childProgressTracker())) + currentStep(HandleIssuedMembershipStep) + return subFlow( + IssueMembershipFlowHandler( + session, + progressTracker = HandleIssuedMembershipStep.childProgressTracker() + ) + ) } } } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipAttestationFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipAttestationFlow.kt index 2922af7..710c66d 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipAttestationFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipAttestationFlow.kt @@ -1,13 +1,9 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable -import io.onixlabs.corda.bnms.contract.membership.Membership import io.onixlabs.corda.bnms.contract.membership.MembershipAttestation -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.core.workflow.findTransaction -import io.onixlabs.corda.core.workflow.initiateFlows -import io.onixlabs.corda.identityframework.workflow.INITIALIZING -import io.onixlabs.corda.identityframework.workflow.SENDING +import io.onixlabs.corda.bnms.workflow.SendMembershipAttestationStep +import io.onixlabs.corda.core.workflow.* import net.corda.core.contracts.StateAndRef import net.corda.core.flows.* import net.corda.core.identity.Party @@ -22,20 +18,16 @@ class PublishMembershipAttestationFlow( companion object { @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, SENDING) + fun tracker() = ProgressTracker(InitializeFlowStep, SendMembershipAttestationStep) private const val FLOW_VERSION_1 = 1 } @Suspendable override fun call(): SignedTransaction { - currentStep(INITIALIZING) + currentStep(InitializeFlowStep) val transaction = findTransaction(attestation) - - currentStep(SENDING) - sessions.forEach { subFlow(SendTransactionFlow(it, transaction)) } - - return transaction + return publishTransaction(transaction, sessions, SendMembershipAttestationStep) } @StartableByRPC @@ -47,21 +39,21 @@ class PublishMembershipAttestationFlow( ) : FlowLogic() { private companion object { - object PUBLISHING : ProgressTracker.Step("Publishing membership attestation transaction.") { + object PublishMembershipAttestationStep : ProgressTracker.Step("Publishing membership attestation.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(PUBLISHING) + override val progressTracker = ProgressTracker(PublishMembershipAttestationStep) @Suspendable override fun call(): SignedTransaction { - currentStep(PUBLISHING) + currentStep(PublishMembershipAttestationStep) return subFlow( PublishMembershipAttestationFlow( attestation, initiateFlows(observers), - PUBLISHING.childProgressTracker() + PublishMembershipAttestationStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipAttestationFlowHandler.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipAttestationFlowHandler.kt index 6fd49f0..771ba66 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipAttestationFlowHandler.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipAttestationFlowHandler.kt @@ -1,15 +1,15 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.bnms.workflow.ReceiveMembershipAttestationStep import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.RECEIVING +import io.onixlabs.corda.core.workflow.publishTransactionHandler import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.ReceiveTransactionFlow -import net.corda.core.node.StatesToRecord import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step class PublishMembershipAttestationFlowHandler( private val session: FlowSession, @@ -18,30 +18,34 @@ class PublishMembershipAttestationFlowHandler( companion object { @JvmStatic - fun tracker() = ProgressTracker(RECEIVING) + fun tracker() = ProgressTracker(ReceiveMembershipAttestationStep) } @Suspendable override fun call(): SignedTransaction { - currentStep(RECEIVING) - return subFlow(ReceiveTransactionFlow(session, statesToRecord = StatesToRecord.ALL_VISIBLE)) + return publishTransactionHandler(session, progressTrackerStep = ReceiveMembershipAttestationStep) } @InitiatedBy(PublishMembershipAttestationFlow.Initiator::class) private class Handler(private val session: FlowSession) : FlowLogic() { private companion object { - object RECEIVING : ProgressTracker.Step("Receiving membership attestation transaction.") { + object HandlePublishedMembershipAttestationStep : Step("Handling membership attestation publication.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(RECEIVING) + override val progressTracker = ProgressTracker(HandlePublishedMembershipAttestationStep) @Suspendable override fun call(): SignedTransaction { - currentStep(RECEIVING) - return subFlow(PublishMembershipAttestationFlowHandler(session, RECEIVING.childProgressTracker())) + currentStep(HandlePublishedMembershipAttestationStep) + return subFlow( + PublishMembershipAttestationFlowHandler( + session, + HandlePublishedMembershipAttestationStep.childProgressTracker() + ) + ) } } } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipFlow.kt index 8e06b6a..e06a5b2 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipFlow.kt @@ -2,16 +2,14 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.membership.Membership -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.core.workflow.findTransaction -import io.onixlabs.corda.core.workflow.initiateFlows -import io.onixlabs.corda.identityframework.workflow.INITIALIZING -import io.onixlabs.corda.identityframework.workflow.SENDING +import io.onixlabs.corda.bnms.workflow.SendMembershipStep +import io.onixlabs.corda.core.workflow.* import net.corda.core.contracts.StateAndRef import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step class PublishMembershipFlow( private val membership: StateAndRef, @@ -21,20 +19,19 @@ class PublishMembershipFlow( companion object { @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, SENDING) + fun tracker() = ProgressTracker( + InitializeFlowStep, + SendMembershipStep + ) private const val FLOW_VERSION_1 = 1 } @Suspendable override fun call(): SignedTransaction { - currentStep(INITIALIZING) + currentStep(InitializeFlowStep) val transaction = findTransaction(membership) - - currentStep(SENDING) - sessions.forEach { subFlow(SendTransactionFlow(it, transaction)) } - - return transaction + return publishTransaction(transaction, sessions, SendMembershipStep) } @StartableByRPC @@ -46,21 +43,21 @@ class PublishMembershipFlow( ) : FlowLogic() { private companion object { - object PUBLISHING : ProgressTracker.Step("Publishing membership transaction.") { + object PublishMembershipTransactionStep : Step("Publishing membership.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(PUBLISHING) + override val progressTracker = ProgressTracker(PublishMembershipTransactionStep) @Suspendable override fun call(): SignedTransaction { - currentStep(PUBLISHING) + currentStep(PublishMembershipTransactionStep) return subFlow( PublishMembershipFlow( membership, initiateFlows(observers), - PUBLISHING.childProgressTracker() + PublishMembershipTransactionStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipFlowHandler.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipFlowHandler.kt index cd63360..6e1d076 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipFlowHandler.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/PublishMembershipFlowHandler.kt @@ -1,15 +1,15 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.bnms.workflow.ReceiveMembershipStep import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.RECEIVING +import io.onixlabs.corda.core.workflow.publishTransactionHandler import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.ReceiveTransactionFlow -import net.corda.core.node.StatesToRecord import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step class PublishMembershipFlowHandler( private val session: FlowSession, @@ -18,30 +18,34 @@ class PublishMembershipFlowHandler( companion object { @JvmStatic - fun tracker() = ProgressTracker(RECEIVING) + fun tracker() = ProgressTracker(ReceiveMembershipStep) } @Suspendable override fun call(): SignedTransaction { - currentStep(RECEIVING) - return subFlow(ReceiveTransactionFlow(session, statesToRecord = StatesToRecord.ALL_VISIBLE)) + return publishTransactionHandler(session, progressTrackerStep = ReceiveMembershipStep) } @InitiatedBy(PublishMembershipFlow.Initiator::class) private class Handler(private val session: FlowSession) : FlowLogic() { private companion object { - object RECEIVING : ProgressTracker.Step("Receiving membership transaction.") { + object HandlePublishedMembershipTransactionStep : Step("Handling membership publication.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(RECEIVING) + override val progressTracker = ProgressTracker(HandlePublishedMembershipTransactionStep) @Suspendable override fun call(): SignedTransaction { - currentStep(RECEIVING) - return subFlow(PublishMembershipFlowHandler(session, RECEIVING.childProgressTracker())) + currentStep(HandlePublishedMembershipTransactionStep) + return subFlow( + PublishMembershipFlowHandler( + session, + HandlePublishedMembershipTransactionStep.childProgressTracker() + ) + ) } } } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipAttestationFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipAttestationFlow.kt index 80df2e4..bdc2a33 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipAttestationFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipAttestationFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,11 +18,8 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.membership.MembershipAttestation -import io.onixlabs.corda.core.workflow.checkSufficientSessions -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.core.workflow.initiateFlows -import io.onixlabs.corda.identityframework.workflow.* -import io.onixlabs.corda.bnms.workflow.* +import io.onixlabs.corda.bnms.workflow.addRevokedMembershipAttestation +import io.onixlabs.corda.core.workflow.* import net.corda.core.contracts.StateAndRef import net.corda.core.flows.* import net.corda.core.identity.Party @@ -38,22 +35,30 @@ class RevokeMembershipAttestationFlow( companion object { @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, GENERATING, VERIFYING, SIGNING, FINALIZING) + fun tracker() = ProgressTracker( + InitializeFlowStep, + BuildTransactionStep, + VerifyTransactionStep, + SignTransactionStep, + SendStatesToRecordStep, + FinalizeTransactionStep + ) private const val FLOW_VERSION_1 = 1 } @Suspendable override fun call(): SignedTransaction { - currentStep(INITIALIZING) - checkSufficientSessions(sessions, attestation.state.data) + currentStep(InitializeFlowStep) + checkSufficientSessionsForContractStates(sessions, attestation.state.data) - val transaction = transaction(attestation.state.notary) { - addRevokedAttestation(attestation) + val transaction = buildTransaction(attestation.state.notary) { + addRevokedMembershipAttestation(attestation) } - val signedTransaction = verifyAndSign(transaction, attestation.state.data.attestor.owningKey) - return finalize(signedTransaction, sessions) + verifyTransaction(transaction) + val signedTransaction = signTransaction(transaction) + return finalizeTransaction(signedTransaction, sessions) } @StartableByRPC @@ -65,23 +70,23 @@ class RevokeMembershipAttestationFlow( ) : FlowLogic() { private companion object { - object REVOKING : Step("Revoking membership attestation.") { + object RevokeMembershipAttestationStep : Step("Revoking membership attestation.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(REVOKING) + override val progressTracker = ProgressTracker(RevokeMembershipAttestationStep) @Suspendable override fun call(): SignedTransaction { - currentStep(REVOKING) + currentStep(RevokeMembershipAttestationStep) val sessions = initiateFlows(observers, attestation.state.data) return subFlow( RevokeMembershipAttestationFlow( attestation, sessions, - REVOKING.childProgressTracker() + RevokeMembershipAttestationStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipAttestationFlowHandler.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipAttestationFlowHandler.kt index cfa04cd..0d5f1a5 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipAttestationFlowHandler.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipAttestationFlowHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,18 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.core.workflow.ReceiveStatesToRecordStep +import io.onixlabs.corda.core.workflow.RecordFinalizedTransactionStep import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.FINALIZING +import io.onixlabs.corda.core.workflow.finalizeTransactionHandler import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.ReceiveFinalityFlow import net.corda.core.node.StatesToRecord import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step class RevokeMembershipAttestationFlowHandler( private val session: FlowSession, @@ -37,33 +39,35 @@ class RevokeMembershipAttestationFlowHandler( companion object { @JvmStatic - fun tracker() = ProgressTracker(FINALIZING) + fun tracker() = ProgressTracker( + ReceiveStatesToRecordStep, + RecordFinalizedTransactionStep + ) } @Suspendable override fun call(): SignedTransaction { - currentStep(FINALIZING) - return subFlow(ReceiveFinalityFlow(session, expectedTransactionId, statesToRecord)) + return finalizeTransactionHandler(session, expectedTransactionId, statesToRecord) } @InitiatedBy(RevokeMembershipAttestationFlow.Initiator::class) private class Handler(private val session: FlowSession) : FlowLogic() { private companion object { - object OBSERVING : ProgressTracker.Step("Observing membership attestation revocation.") { + object HandleRevokedMembershipAttestationStep : Step("Handling membership attestation revocation.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(OBSERVING) + override val progressTracker = ProgressTracker(HandleRevokedMembershipAttestationStep) @Suspendable override fun call(): SignedTransaction { - currentStep(OBSERVING) + currentStep(HandleRevokedMembershipAttestationStep) return subFlow( RevokeMembershipAttestationFlowHandler( session, - progressTracker = OBSERVING.childProgressTracker() + progressTracker = HandleRevokedMembershipAttestationStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipFlow.kt index 3c9cb60..19fd840 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,8 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.membership.Membership -import io.onixlabs.corda.bnms.contract.membership.MembershipContract -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.core.workflow.initiateFlows -import io.onixlabs.corda.identityframework.workflow.* -import io.onixlabs.corda.bnms.workflow.* -import io.onixlabs.corda.core.workflow.checkSufficientSessions +import io.onixlabs.corda.bnms.workflow.addRevokedMembership +import io.onixlabs.corda.core.workflow.* import net.corda.core.contracts.StateAndRef import net.corda.core.flows.* import net.corda.core.identity.Party @@ -39,23 +35,30 @@ class RevokeMembershipFlow( companion object { @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, GENERATING, VERIFYING, SIGNING, FINALIZING) + fun tracker() = ProgressTracker( + InitializeFlowStep, + BuildTransactionStep, + VerifyTransactionStep, + SignTransactionStep, + SendStatesToRecordStep, + FinalizeTransactionStep + ) private const val FLOW_VERSION_1 = 1 } @Suspendable override fun call(): SignedTransaction { - currentStep(INITIALIZING) - checkSufficientSessions(sessions, membership.state.data) + currentStep(InitializeFlowStep) + checkSufficientSessionsForContractStates(sessions, membership.state.data) - val transaction = transaction(membership.state.notary) { - addInputState(membership) - addCommand(MembershipContract.Revoke, ourIdentity.owningKey) + val transaction = buildTransaction(membership.state.notary) { + addRevokedMembership(membership, ourIdentity.owningKey) } - val signedTransaction = verifyAndSign(transaction, ourIdentity.owningKey) - return finalize(signedTransaction, sessions) + verifyTransaction(transaction) + val signedTransaction = signTransaction(transaction) + return finalizeTransaction(signedTransaction, sessions) } @StartableByRPC @@ -67,23 +70,23 @@ class RevokeMembershipFlow( ) : FlowLogic() { private companion object { - object REVOKING : Step("Revoking membership.") { + object RevokeMembershipStep : Step("Revoking membership.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(REVOKING) + override val progressTracker = ProgressTracker(RevokeMembershipStep) @Suspendable override fun call(): SignedTransaction { - currentStep(REVOKING) + currentStep(RevokeMembershipStep) val sessions = initiateFlows(observers, membership.state.data) return subFlow( RevokeMembershipFlow( membership, sessions, - REVOKING.childProgressTracker() + RevokeMembershipStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipFlowHandler.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipFlowHandler.kt index 147703b..15814ba 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipFlowHandler.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipFlowHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,18 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.core.workflow.ReceiveStatesToRecordStep +import io.onixlabs.corda.core.workflow.RecordFinalizedTransactionStep import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.FINALIZING +import io.onixlabs.corda.core.workflow.finalizeTransactionHandler import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.ReceiveFinalityFlow import net.corda.core.node.StatesToRecord import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step class RevokeMembershipFlowHandler( private val session: FlowSession, @@ -37,33 +39,35 @@ class RevokeMembershipFlowHandler( companion object { @JvmStatic - fun tracker() = ProgressTracker(FINALIZING) + fun tracker() = ProgressTracker( + ReceiveStatesToRecordStep, + RecordFinalizedTransactionStep + ) } @Suspendable override fun call(): SignedTransaction { - currentStep(FINALIZING) - return subFlow(ReceiveFinalityFlow(session, expectedTransactionId, statesToRecord)) + return finalizeTransactionHandler(session, expectedTransactionId, statesToRecord) } @InitiatedBy(RevokeMembershipFlow.Initiator::class) private class Handler(private val session: FlowSession) : FlowLogic() { private companion object { - object OBSERVING : ProgressTracker.Step("Observing membership revocation.") { + object HandleRevokedMembershipStep : Step("Handling membership revocation.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(OBSERVING) + override val progressTracker = ProgressTracker(HandleRevokedMembershipStep) @Suspendable override fun call(): SignedTransaction { - currentStep(OBSERVING) + currentStep(HandleRevokedMembershipStep) return subFlow( RevokeMembershipFlowHandler( session, - progressTracker = OBSERVING.childProgressTracker() + progressTracker = HandleRevokedMembershipStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/SynchronizeMembershipFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/SynchronizeMembershipFlow.kt index 2760f4d..94c0db4 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/SynchronizeMembershipFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/SynchronizeMembershipFlow.kt @@ -3,13 +3,21 @@ package io.onixlabs.corda.bnms.workflow.membership import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.membership.Membership import io.onixlabs.corda.bnms.contract.membership.MembershipAttestation +import io.onixlabs.corda.bnms.contract.membership.MembershipAttestationSchema.MembershipAttestationEntity +import io.onixlabs.corda.bnms.workflow.ReceiveMembershipAndAttestationsStep +import io.onixlabs.corda.bnms.workflow.SendMembershipAndAttestationsStep +import io.onixlabs.corda.core.services.equalTo +import io.onixlabs.corda.core.services.filter +import io.onixlabs.corda.core.services.vaultServiceFor +import io.onixlabs.corda.core.workflow.InitializeFlowStep import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.INITIALIZING +import io.onixlabs.corda.identityframework.workflow.attestations.PublishAttestationFlow +import io.onixlabs.corda.identityframework.workflow.attestations.PublishAttestationFlowHandler import net.corda.core.contracts.StateAndRef import net.corda.core.flows.* import net.corda.core.identity.Party -import net.corda.core.node.services.Vault import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step import net.corda.core.utilities.unwrap class SynchronizeMembershipFlow( @@ -20,17 +28,18 @@ class SynchronizeMembershipFlow( companion object { @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, SENDING, RECEIVING) + fun tracker() = ProgressTracker( + InitializeFlowStep, + SendMembershipAndAttestationsStep, + ReceiveMembershipAndAttestationsStep + ) private const val FLOW_VERSION_1 = 1 - - private object SENDING : ProgressTracker.Step("Sending our membership and attestations.") - private object RECEIVING : ProgressTracker.Step("Receiving their membership and attestations.") } @Suspendable override fun call(): Pair, Set>>? { - currentStep(INITIALIZING) + currentStep(InitializeFlowStep) val network = ourMembership.state.data.network val holder = ourMembership.state.data.holder @@ -38,13 +47,10 @@ class SynchronizeMembershipFlow( throw FlowException("Membership synchronization can only occur when the membership is owned by this node.") } - val attestations = subFlow( - FindMembershipAttestationsFlow( - holder = holder, - network = network, - stateStatus = Vault.StateStatus.UNCONSUMED - ) - ) + val attestations = serviceHub.vaultServiceFor().filter { + expression(MembershipAttestationEntity::holder equalTo holder) + expression(MembershipAttestationEntity::networkHash equalTo network.hash.toString()) + }.toList() if (network.operator != null && attestations.size > 1) { throw FlowException("Only one membership attestation is required when a network operator is present.") @@ -53,11 +59,11 @@ class SynchronizeMembershipFlow( val isMemberOfNetwork = session.sendAndReceive(network).unwrap { it } if (isMemberOfNetwork) { - currentStep(SENDING) + currentStep(SendMembershipAndAttestationsStep) sendOurMembership() sendOurAttestations(attestations) - currentStep(RECEIVING) + currentStep(ReceiveMembershipAndAttestationsStep) val theirMembership = receiveTheirMembership() val theirAttestations = receiveTheirAttestations() @@ -77,7 +83,7 @@ class SynchronizeMembershipFlow( session.send(attestations.count()) for (attestation in attestations) { - subFlow(PublishMembershipAttestationFlow(attestation, setOf(session))) + subFlow(PublishAttestationFlow(attestation, setOf(session))) } } @@ -93,7 +99,7 @@ class SynchronizeMembershipFlow( val theirAttestationSize = session.receive().unwrap { it } for (index in 0 until theirAttestationSize) { - val transaction = subFlow(PublishMembershipAttestationFlowHandler(session)) + val transaction = subFlow(PublishAttestationFlowHandler(session)) val attestation = transaction.tx.outRefsOfType().single() attestations.add(attestation) } @@ -110,23 +116,23 @@ class SynchronizeMembershipFlow( ) : FlowLogic, Set>>?>() { private companion object { - object SYNCHRONIZING : ProgressTracker.Step("Synchronizing membership.") { + object SynchronizeMembershipAndAttestationsStep : Step("Synchronizing membership.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(SYNCHRONIZING) + override val progressTracker = ProgressTracker(SynchronizeMembershipAndAttestationsStep) @Suspendable override fun call(): Pair, Set>>? { - currentStep(SYNCHRONIZING) + currentStep(SynchronizeMembershipAndAttestationsStep) val session = initiateFlow(counterparty) return subFlow( SynchronizeMembershipFlow( ourMembership, session, - SYNCHRONIZING.childProgressTracker() + SynchronizeMembershipAndAttestationsStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/SynchronizeMembershipFlowHandler.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/SynchronizeMembershipFlowHandler.kt index 0682ab4..ab32289 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/SynchronizeMembershipFlowHandler.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/membership/SynchronizeMembershipFlowHandler.kt @@ -4,14 +4,24 @@ import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.Network import io.onixlabs.corda.bnms.contract.membership.Membership import io.onixlabs.corda.bnms.contract.membership.MembershipAttestation +import io.onixlabs.corda.bnms.contract.membership.MembershipAttestationSchema.MembershipAttestationEntity +import io.onixlabs.corda.bnms.contract.membership.MembershipSchema +import io.onixlabs.corda.bnms.workflow.ReceiveMembershipAndAttestationsStep +import io.onixlabs.corda.bnms.workflow.SendMembershipAndAttestationsStep +import io.onixlabs.corda.core.services.equalTo +import io.onixlabs.corda.core.services.filter +import io.onixlabs.corda.core.services.singleOrNull +import io.onixlabs.corda.core.services.vaultServiceFor +import io.onixlabs.corda.core.workflow.InitializeFlowStep import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.INITIALIZING +import io.onixlabs.corda.identityframework.workflow.attestations.PublishAttestationFlow +import io.onixlabs.corda.identityframework.workflow.attestations.PublishAttestationFlowHandler import net.corda.core.contracts.StateAndRef import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy -import net.corda.core.node.services.Vault import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step import net.corda.core.utilities.unwrap class SynchronizeMembershipFlowHandler( @@ -21,34 +31,35 @@ class SynchronizeMembershipFlowHandler( companion object { @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, RECEIVING, SENDING) - - private object RECEIVING : ProgressTracker.Step("Receiving their membership and attestations.") - private object SENDING : ProgressTracker.Step("Sending our membership and attestations.") + fun tracker() = ProgressTracker( + InitializeFlowStep, + ReceiveMembershipAndAttestationsStep, + SendMembershipAndAttestationsStep + ) } @Suspendable override fun call(): Pair, Set>>? { - currentStep(INITIALIZING) + currentStep(InitializeFlowStep) val network = session.receive().unwrap { it } - val membership = subFlow(FindMembershipFlow(holder = ourIdentity, network = network)) + val membership = serviceHub.vaultServiceFor().singleOrNull { + expression(MembershipSchema.MembershipEntity::holder equalTo ourIdentity) + expression(MembershipSchema.MembershipEntity::networkHash equalTo network.hash.toString()) + } session.send(membership != null) if (membership != null) { - val attestations = subFlow( - FindMembershipAttestationsFlow( - holder = ourIdentity, - network = network, - stateStatus = Vault.StateStatus.UNCONSUMED - ) - ) + val attestations = serviceHub.vaultServiceFor().filter { + expression(MembershipAttestationEntity::holder equalTo ourIdentity) + expression(MembershipAttestationEntity::networkHash equalTo network.hash.toString()) + }.toList() - currentStep(RECEIVING) + currentStep(ReceiveMembershipAndAttestationsStep) val theirMembership = receiveTheirMembership() val theirAttestations = receiveTheirAttestations() - currentStep(SENDING) + currentStep(SendMembershipAndAttestationsStep) sendOurMembership(membership) sendOurAttestations(attestations) return theirMembership to theirAttestations @@ -67,7 +78,7 @@ class SynchronizeMembershipFlowHandler( session.send(attestations.count()) for (attestation in attestations) { - subFlow(PublishMembershipAttestationFlow(attestation, setOf(session))) + subFlow(PublishAttestationFlow(attestation, setOf(session))) } } @@ -83,7 +94,7 @@ class SynchronizeMembershipFlowHandler( val theirAttestationSize = session.receive().unwrap { it } for (index in 0 until theirAttestationSize) { - val transaction = subFlow(PublishMembershipAttestationFlowHandler(session)) + val transaction = subFlow(PublishAttestationFlowHandler(session)) val attestation = transaction.tx.outRefsOfType().single() attestations.add(attestation) } @@ -92,21 +103,27 @@ class SynchronizeMembershipFlowHandler( } @InitiatedBy(SynchronizeMembershipFlow.Initiator::class) - private class Handler(private val session: FlowSession) : - FlowLogic, Set>>?>() { + private class Handler( + private val session: FlowSession + ) : FlowLogic, Set>>?>() { private companion object { - object SYNCHRONIZING : ProgressTracker.Step("Synchronizing membership.") { + object HandleSynchronizedMembershipAndAttestationsStep : Step("Handling membership synchronization.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(SYNCHRONIZING) + override val progressTracker = ProgressTracker(HandleSynchronizedMembershipAndAttestationsStep) @Suspendable override fun call(): Pair, Set>>? { - currentStep(SYNCHRONIZING) - return subFlow(SynchronizeMembershipFlowHandler(session, SYNCHRONIZING.childProgressTracker())) + currentStep(HandleSynchronizedMembershipAndAttestationsStep) + return subFlow( + SynchronizeMembershipFlowHandler( + session, + HandleSynchronizedMembershipAndAttestationsStep.childProgressTracker() + ) + ) } } } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipAttestationFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipAttestationFlow.kt index 0074ce7..5a2d168 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipAttestationFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipAttestationFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,18 +18,15 @@ package io.onixlabs.corda.bnms.workflow.relationship import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestation -import io.onixlabs.corda.bnms.workflow.finalize +import io.onixlabs.corda.bnms.workflow.addAmendedRelationshipAttestation import io.onixlabs.corda.bnms.workflow.findRelationshipForAttestation -import io.onixlabs.corda.bnms.workflow.transaction -import io.onixlabs.corda.bnms.workflow.verifyAndSign -import io.onixlabs.corda.core.workflow.checkSufficientSessions -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.core.workflow.initiateFlows -import io.onixlabs.corda.identityframework.workflow.* +import io.onixlabs.corda.core.workflow.* +import io.onixlabs.corda.identityframework.workflow.checkAttestationExistsForAmendment import net.corda.core.contracts.StateAndRef import net.corda.core.flows.* import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step class AmendRelationshipAttestationFlow( private val oldAttestation: StateAndRef, @@ -40,23 +37,33 @@ class AmendRelationshipAttestationFlow( companion object { @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, GENERATING, VERIFYING, SIGNING, FINALIZING) + fun tracker() = ProgressTracker( + InitializeFlowStep, + BuildTransactionStep, + VerifyTransactionStep, + SignTransactionStep, + SendStatesToRecordStep, + FinalizeTransactionStep + ) private const val FLOW_VERSION_1 = 1 } @Suspendable override fun call(): SignedTransaction { - currentStep(INITIALIZING) - checkSufficientSessions(sessions, newAttestation, oldAttestation.state.data) + currentStep(InitializeFlowStep) + checkSufficientSessionsForContractStates(sessions, newAttestation, oldAttestation.state.data) + checkAttestationExistsForAmendment(newAttestation) - val transaction = transaction(oldAttestation.state.notary) { - addAmendedAttestation(oldAttestation, newAttestation) - addReferenceState(findRelationshipForAttestation(newAttestation).referenced()) + val relationship = findRelationshipForAttestation(newAttestation).referenced() + + val transaction = buildTransaction(oldAttestation.state.notary) { + addAmendedRelationshipAttestation(oldAttestation, newAttestation, relationship) } - val signedTransaction = verifyAndSign(transaction, newAttestation.attestor.owningKey) - return finalize(signedTransaction, sessions) + verifyTransaction(transaction) + val signedTransaction = signTransaction(transaction) + return finalizeTransaction(signedTransaction, sessions) } @StartableByRPC @@ -68,16 +75,16 @@ class AmendRelationshipAttestationFlow( ) : FlowLogic() { private companion object { - object AMENDING : ProgressTracker.Step("Amending relationship attestation.") { + object AmendRelationshipAttestationStep : Step("Amending relationship attestation.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(AMENDING) + override val progressTracker = ProgressTracker(AmendRelationshipAttestationStep) @Suspendable override fun call(): SignedTransaction { - currentStep(AMENDING) + currentStep(AmendRelationshipAttestationStep) val sessions = initiateFlows(emptyList(), newAttestation, oldAttestation.state.data) return subFlow( @@ -85,7 +92,7 @@ class AmendRelationshipAttestationFlow( oldAttestation, newAttestation, sessions, - AMENDING.childProgressTracker() + AmendRelationshipAttestationStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipAttestationFlowHandler.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipAttestationFlowHandler.kt index e5c8386..f7e57cc 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipAttestationFlowHandler.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipAttestationFlowHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,18 @@ package io.onixlabs.corda.bnms.workflow.relationship import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.core.workflow.ReceiveStatesToRecordStep +import io.onixlabs.corda.core.workflow.RecordFinalizedTransactionStep import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.FINALIZING +import io.onixlabs.corda.core.workflow.finalizeTransactionHandler import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.ReceiveFinalityFlow import net.corda.core.node.StatesToRecord import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step class AmendRelationshipAttestationFlowHandler( private val session: FlowSession, @@ -36,30 +38,38 @@ class AmendRelationshipAttestationFlowHandler( companion object { @JvmStatic - fun tracker() = ProgressTracker(FINALIZING) + fun tracker() = ProgressTracker( + ReceiveStatesToRecordStep, + RecordFinalizedTransactionStep + ) } @Suspendable override fun call(): SignedTransaction { - currentStep(FINALIZING) - return subFlow(ReceiveFinalityFlow(session, expectedTransactionId, StatesToRecord.ONLY_RELEVANT)) + return finalizeTransactionHandler(session, expectedTransactionId, StatesToRecord.ONLY_RELEVANT) } @InitiatedBy(AmendRelationshipAttestationFlow.Initiator::class) private class Handler(private val session: FlowSession) : FlowLogic() { private companion object { - object OBSERVING : ProgressTracker.Step("Observing relationship attestation amendment.") { + object HandlingAmendedRelationshipAttestationStep : Step("Handling relationship attestation amendment.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(OBSERVING) + override val progressTracker = ProgressTracker(HandlingAmendedRelationshipAttestationStep) @Suspendable override fun call(): SignedTransaction { - currentStep(OBSERVING) - return subFlow(AmendRelationshipAttestationFlowHandler(session, null, OBSERVING.childProgressTracker())) + currentStep(HandlingAmendedRelationshipAttestationStep) + return subFlow( + AmendRelationshipAttestationFlowHandler( + session, + null, + HandlingAmendedRelationshipAttestationStep.childProgressTracker() + ) + ) } } } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipFlow.kt index 900905a..b4226cb 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,12 +19,8 @@ package io.onixlabs.corda.bnms.workflow.relationship import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.relationship.Relationship import io.onixlabs.corda.bnms.contract.relationship.RelationshipContract -import io.onixlabs.corda.bnms.workflow.checkMembershipsAndAttestations -import io.onixlabs.corda.core.workflow.checkSufficientSessions -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.core.workflow.initiateFlows -import io.onixlabs.corda.identityframework.workflow.* import io.onixlabs.corda.bnms.workflow.* +import io.onixlabs.corda.core.workflow.* import net.corda.core.contracts.StateAndRef import net.corda.core.flows.* import net.corda.core.transactions.SignedTransaction @@ -41,30 +37,35 @@ class AmendRelationshipFlow( companion object { @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, GENERATING, VERIFYING, SIGNING, COUNTERSIGNING, FINALIZING) + fun tracker() = ProgressTracker( + InitializeFlowStep, + SendCheckMembershipInstructionStep, + CheckMembershipStep, + BuildTransactionStep, + VerifyTransactionStep, + SignTransactionStep, + CollectTransactionSignaturesStep, + SendStatesToRecordStep, + FinalizeTransactionStep + ) private const val FLOW_VERSION_1 = 1 } @Suspendable override fun call(): SignedTransaction { - currentStep(INITIALIZING) - checkSufficientSessions(sessions, newRelationship) - sessions.forEach { it.send(checkMembership) } + currentStep(InitializeFlowStep) + checkSufficientSessionsForContractStates(sessions, newRelationship) + checkMembership(checkMembership, newRelationship, sessions) - if (checkMembership) { - checkMembershipsAndAttestations(newRelationship) + val transaction = buildTransaction(oldRelationship.state.notary) { + addAmendedRelationship(oldRelationship, newRelationship) } - val transaction = transaction(oldRelationship.state.notary) { - addInputState(oldRelationship) - addOutputState(newRelationship, RelationshipContract.ID) - addCommand(RelationshipContract.Amend, newRelationship.participants.map { it.owningKey }) - } - - val partiallySignedTransaction = verifyAndSign(transaction, ourIdentity.owningKey) - val fullySignedTransaction = countersign(partiallySignedTransaction, sessions) - return finalize(fullySignedTransaction, sessions) + verifyTransaction(transaction) + val partiallySignedTransaction = signTransaction(transaction) + val fullySignedTransaction = collectSignatures(partiallySignedTransaction, sessions) + return finalizeTransaction(fullySignedTransaction, sessions) } @StartableByRPC @@ -77,16 +78,16 @@ class AmendRelationshipFlow( ) : FlowLogic() { private companion object { - object AMENDING : Step("Amending relationship.") { + object AmendRelationshipStep : Step("Amending relationship.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(AMENDING) + override val progressTracker = ProgressTracker(AmendRelationshipStep) @Suspendable override fun call(): SignedTransaction { - currentStep(AMENDING) + currentStep(AmendRelationshipStep) val sessions = initiateFlows(emptyList(), newRelationship, oldRelationship.state.data) return subFlow( @@ -95,7 +96,7 @@ class AmendRelationshipFlow( newRelationship, sessions, checkMembership, - AMENDING.childProgressTracker() + AmendRelationshipStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipFlowHandler.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipFlowHandler.kt index 1b3a9f4..37281e1 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipFlowHandler.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipFlowHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,16 +18,19 @@ package io.onixlabs.corda.bnms.workflow.relationship import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.relationship.Relationship +import io.onixlabs.corda.bnms.workflow.CheckMembershipStep +import io.onixlabs.corda.bnms.workflow.ReceiveCheckMembershipInstructionStep +import io.onixlabs.corda.bnms.workflow.checkMembershipHandler import io.onixlabs.corda.bnms.workflow.checkMembershipsAndAttestations -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.FINALIZING -import io.onixlabs.corda.identityframework.workflow.SIGNING -import net.corda.core.flows.* +import io.onixlabs.corda.core.workflow.* +import net.corda.core.flows.FlowException +import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession +import net.corda.core.flows.InitiatedBy import net.corda.core.node.StatesToRecord import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker.Step -import net.corda.core.utilities.unwrap class AmendRelationshipFlowHandler( private val session: FlowSession, @@ -36,47 +39,50 @@ class AmendRelationshipFlowHandler( companion object { @JvmStatic - fun tracker() = ProgressTracker(RECEIVING, SIGNING, FINALIZING) - - private object RECEIVING : Step("Receiving check membership instruction.") + fun tracker() = ProgressTracker( + ReceiveCheckMembershipInstructionStep, + SignTransactionStep, + CheckMembershipStep, + ReceiveStatesToRecordStep, + RecordFinalizedTransactionStep + ) } @Suspendable override fun call(): SignedTransaction { - currentStep(RECEIVING) - val checkMembership = session.receive().unwrap { it } - - currentStep(SIGNING) - val transaction = subFlow(object : SignTransactionFlow(session) { - override fun checkTransaction(stx: SignedTransaction) { - if (checkMembership) { - val relationship = stx.tx.outputsOfType().singleOrNull() - ?: throw FlowException("Failed to obtain a relationship from the transaction.") + val checkMembership = checkMembershipHandler(session) + val transaction = collectSignaturesHandler(session) { + if (checkMembership) { + val relationship = it.tx.outputsOfType().singleOrNull() + ?: throw FlowException("Failed to obtain a relationship from the transaction.") - checkMembershipsAndAttestations(relationship) - } + checkMembershipsAndAttestations(relationship) } - }) + } - currentStep(FINALIZING) - return subFlow(ReceiveFinalityFlow(session, transaction.id, StatesToRecord.ONLY_RELEVANT)) + return finalizeTransactionHandler(session, transaction?.id, StatesToRecord.ONLY_RELEVANT) } @InitiatedBy(AmendRelationshipFlow.Initiator::class) private class Handler(private val session: FlowSession) : FlowLogic() { private companion object { - object OBSERVING : Step("Observing relationship amendment.") { + object HandleAmendedRelationshipStep : Step("Handling relationship amendment.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(OBSERVING) + override val progressTracker = ProgressTracker(HandleAmendedRelationshipStep) @Suspendable override fun call(): SignedTransaction { - currentStep(OBSERVING) - return subFlow(AmendRelationshipFlowHandler(session, OBSERVING.childProgressTracker())) + currentStep(HandleAmendedRelationshipStep) + return subFlow( + AmendRelationshipFlowHandler( + session, + HandleAmendedRelationshipStep.childProgressTracker() + ) + ) } } } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/FindRelationshipAttestationFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/FindRelationshipAttestationFlow.kt deleted file mode 100644 index d48c07e..0000000 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/FindRelationshipAttestationFlow.kt +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2020-2021 ONIXLabs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.onixlabs.corda.bnms.workflow.relationship - -import io.onixlabs.corda.bnms.contract.Network -import io.onixlabs.corda.bnms.contract.relationship.Relationship -import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestation -import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestationSchema.RelationshipAttestationEntity -import io.onixlabs.corda.core.workflow.DEFAULT_PAGE_SPECIFICATION -import io.onixlabs.corda.core.workflow.FindStateFlow -import io.onixlabs.corda.core.workflow.andWithExpressions -import io.onixlabs.corda.identityframework.contract.AttestationPointer -import io.onixlabs.corda.identityframework.contract.AttestationStatus -import net.corda.core.contracts.StateAndRef -import net.corda.core.contracts.StateRef -import net.corda.core.contracts.UniqueIdentifier -import net.corda.core.crypto.SecureHash -import net.corda.core.flows.StartableByRPC -import net.corda.core.flows.StartableByService -import net.corda.core.identity.AbstractParty -import net.corda.core.node.services.Vault -import net.corda.core.node.services.vault.Builder.equal -import net.corda.core.node.services.vault.PageSpecification -import net.corda.core.node.services.vault.QueryCriteria -import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria - -@StartableByRPC -@StartableByService -class FindRelationshipAttestationFlow( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - attestor: AbstractParty? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - pointer: AttestationPointer? = null, - pointerStateRef: StateRef? = null, - pointerStateLinearId: UniqueIdentifier? = null, - pointerHash: SecureHash? = null, - status: AttestationStatus? = null, - previousStateRef: StateRef? = null, - hash: SecureHash? = null, - relationship: StateAndRef? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - override val pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION -) : FindStateFlow() { - override val criteria: QueryCriteria = VaultQueryCriteria( - contractStateTypes = setOf(contractStateType), - relevancyStatus = relevancyStatus, - status = stateStatus - ).andWithExpressions( - linearId?.let { RelationshipAttestationEntity::linearId.equal(it.id) }, - externalId?.let { RelationshipAttestationEntity::externalId.equal(it) }, - attestor?.let { RelationshipAttestationEntity::attestor.equal(it) }, - network?.let { RelationshipAttestationEntity::networkHash.equal(it.hash.toString()) }, - networkValue?.let { RelationshipAttestationEntity::networkValue.equal(it) }, - networkOperator?.let { RelationshipAttestationEntity::networkOperator.equal(it) }, - networkHash?.let { RelationshipAttestationEntity::networkHash.equal(it.toString()) }, - pointer?.let { RelationshipAttestationEntity::pointerHash.equal(it.hash.toString()) }, - pointerStateRef?.let { RelationshipAttestationEntity::pointerStateRef.equal(it.toString()) }, - pointerStateLinearId?.let { RelationshipAttestationEntity::pointerStateLinearId.equal(it.id) }, - pointerHash?.let { RelationshipAttestationEntity::pointerHash.equal(it.toString()) }, - status?.let { RelationshipAttestationEntity::status.equal(it) }, - previousStateRef?.let { RelationshipAttestationEntity::previousStateRef.equal(it.toString()) }, - relationship?.let { RelationshipAttestationEntity::pointerStateRef.equal(it.ref.toString()) }, - hash?.let { RelationshipAttestationEntity::hash.equal(it.toString()) } - ) -} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/FindRelationshipAttestationsFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/FindRelationshipAttestationsFlow.kt deleted file mode 100644 index 0f5a54d..0000000 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/FindRelationshipAttestationsFlow.kt +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2020-2021 ONIXLabs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.onixlabs.corda.bnms.workflow.relationship - -import io.onixlabs.corda.bnms.contract.Network -import io.onixlabs.corda.bnms.contract.relationship.Relationship -import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestation -import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestationSchema.RelationshipAttestationEntity -import io.onixlabs.corda.core.workflow.DEFAULT_PAGE_SPECIFICATION -import io.onixlabs.corda.core.workflow.DEFAULT_SORTING -import io.onixlabs.corda.core.workflow.FindStatesFlow -import io.onixlabs.corda.core.workflow.andWithExpressions -import io.onixlabs.corda.identityframework.contract.AttestationPointer -import io.onixlabs.corda.identityframework.contract.AttestationStatus -import net.corda.core.contracts.StateAndRef -import net.corda.core.contracts.StateRef -import net.corda.core.contracts.UniqueIdentifier -import net.corda.core.crypto.SecureHash -import net.corda.core.flows.StartableByRPC -import net.corda.core.flows.StartableByService -import net.corda.core.identity.AbstractParty -import net.corda.core.node.services.Vault -import net.corda.core.node.services.vault.Builder.equal -import net.corda.core.node.services.vault.PageSpecification -import net.corda.core.node.services.vault.QueryCriteria -import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria -import net.corda.core.node.services.vault.Sort - -@StartableByRPC -@StartableByService -class FindRelationshipAttestationsFlow( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - attestor: AbstractParty? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - pointer: AttestationPointer? = null, - pointerStateRef: StateRef? = null, - pointerStateLinearId: UniqueIdentifier? = null, - pointerHash: SecureHash? = null, - status: AttestationStatus? = null, - previousStateRef: StateRef? = null, - hash: SecureHash? = null, - relationship: StateAndRef? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - override val pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION, - override val sorting: Sort = DEFAULT_SORTING -) : FindStatesFlow() { - override val criteria: QueryCriteria = VaultQueryCriteria( - contractStateTypes = setOf(contractStateType), - relevancyStatus = relevancyStatus, - status = stateStatus - ).andWithExpressions( - linearId?.let { RelationshipAttestationEntity::linearId.equal(it.id) }, - externalId?.let { RelationshipAttestationEntity::externalId.equal(it) }, - attestor?.let { RelationshipAttestationEntity::attestor.equal(it) }, - network?.let { RelationshipAttestationEntity::networkHash.equal(it.hash.toString()) }, - networkValue?.let { RelationshipAttestationEntity::networkValue.equal(it) }, - networkOperator?.let { RelationshipAttestationEntity::networkOperator.equal(it) }, - networkHash?.let { RelationshipAttestationEntity::networkHash.equal(it.toString()) }, - pointer?.let { RelationshipAttestationEntity::pointerHash.equal(it.hash.toString()) }, - pointerStateRef?.let { RelationshipAttestationEntity::pointerStateRef.equal(it.toString()) }, - pointerStateLinearId?.let { RelationshipAttestationEntity::pointerStateLinearId.equal(it.id) }, - pointerHash?.let { RelationshipAttestationEntity::pointerHash.equal(it.toString()) }, - status?.let { RelationshipAttestationEntity::status.equal(it) }, - previousStateRef?.let { RelationshipAttestationEntity::previousStateRef.equal(it.toString()) }, - relationship?.let { RelationshipAttestationEntity::pointerStateRef.equal(it.ref.toString()) }, - hash?.let { RelationshipAttestationEntity::hash.equal(it.toString()) } - ) -} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/FindRelationshipFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/FindRelationshipFlow.kt deleted file mode 100644 index 1bc62ce..0000000 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/FindRelationshipFlow.kt +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2020-2021 ONIXLabs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.onixlabs.corda.bnms.workflow.relationship - -import io.onixlabs.corda.bnms.contract.Network -import io.onixlabs.corda.bnms.contract.relationship.Relationship -import io.onixlabs.corda.bnms.contract.relationship.RelationshipSchema.RelationshipEntity -import io.onixlabs.corda.core.workflow.DEFAULT_PAGE_SPECIFICATION -import io.onixlabs.corda.core.workflow.FindStateFlow -import io.onixlabs.corda.core.workflow.andWithExpressions -import net.corda.core.contracts.UniqueIdentifier -import net.corda.core.crypto.SecureHash -import net.corda.core.flows.StartableByRPC -import net.corda.core.flows.StartableByService -import net.corda.core.identity.AbstractParty -import net.corda.core.node.services.Vault -import net.corda.core.node.services.vault.Builder.equal -import net.corda.core.node.services.vault.PageSpecification -import net.corda.core.node.services.vault.QueryCriteria -import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria - -@StartableByRPC -@StartableByService -class FindRelationshipFlow( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - hash: SecureHash? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - override val pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION -) : FindStateFlow() { - override val criteria: QueryCriteria = VaultQueryCriteria( - contractStateTypes = setOf(contractStateType), - relevancyStatus = relevancyStatus, - status = stateStatus - ).andWithExpressions( - linearId?.let { RelationshipEntity::linearId.equal(it.id) }, - externalId?.let { RelationshipEntity::externalId.equal(it) }, - network?.let { RelationshipEntity::networkHash.equal(it.hash.toString()) }, - networkValue?.let { RelationshipEntity::networkValue.equal(it) }, - networkOperator?.let { RelationshipEntity::networkOperator.equal(it) }, - networkHash?.let { RelationshipEntity::networkHash.equal(it.toString()) }, - hash?.let { RelationshipEntity::hash.equal(it.toString()) } - ) -} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/FindRelationshipsFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/FindRelationshipsFlow.kt deleted file mode 100644 index 16599d4..0000000 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/FindRelationshipsFlow.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2020-2021 ONIXLabs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.onixlabs.corda.bnms.workflow.relationship - -import io.onixlabs.corda.bnms.contract.Network -import io.onixlabs.corda.bnms.contract.relationship.Relationship -import io.onixlabs.corda.bnms.contract.relationship.RelationshipSchema.RelationshipEntity -import io.onixlabs.corda.core.workflow.DEFAULT_PAGE_SPECIFICATION -import io.onixlabs.corda.core.workflow.DEFAULT_SORTING -import io.onixlabs.corda.core.workflow.FindStatesFlow -import io.onixlabs.corda.core.workflow.andWithExpressions -import net.corda.core.contracts.UniqueIdentifier -import net.corda.core.crypto.SecureHash -import net.corda.core.flows.StartableByRPC -import net.corda.core.flows.StartableByService -import net.corda.core.identity.AbstractParty -import net.corda.core.node.services.Vault -import net.corda.core.node.services.vault.Builder.equal -import net.corda.core.node.services.vault.PageSpecification -import net.corda.core.node.services.vault.QueryCriteria -import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria -import net.corda.core.node.services.vault.Sort - -@StartableByRPC -@StartableByService -class FindRelationshipsFlow( - linearId: UniqueIdentifier? = null, - externalId: String? = null, - network: Network? = null, - networkValue: String? = null, - networkOperator: AbstractParty? = null, - networkHash: SecureHash? = null, - hash: SecureHash? = null, - stateStatus: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - relevancyStatus: Vault.RelevancyStatus = Vault.RelevancyStatus.ALL, - override val pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION, - override val sorting: Sort = DEFAULT_SORTING -) : FindStatesFlow() { - override val criteria: QueryCriteria = VaultQueryCriteria( - contractStateTypes = setOf(contractStateType), - relevancyStatus = relevancyStatus, - status = stateStatus - ).andWithExpressions( - linearId?.let { RelationshipEntity::linearId.equal(it.id) }, - externalId?.let { RelationshipEntity::externalId.equal(it) }, - network?.let { RelationshipEntity::networkHash.equal(it.hash.toString()) }, - networkValue?.let { RelationshipEntity::networkValue.equal(it) }, - networkOperator?.let { RelationshipEntity::networkOperator.equal(it) }, - networkHash?.let { RelationshipEntity::networkHash.equal(it.toString()) }, - hash?.let { RelationshipEntity::hash.equal(it.toString()) } - ) -} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipAttestationFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipAttestationFlow.kt index 84736fd..de356bf 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipAttestationFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipAttestationFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,15 +18,10 @@ package io.onixlabs.corda.bnms.workflow.relationship import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestation -import io.onixlabs.corda.bnms.workflow.finalize +import io.onixlabs.corda.bnms.workflow.addIssuedRelationshipAttestation import io.onixlabs.corda.bnms.workflow.findRelationshipForAttestation -import io.onixlabs.corda.bnms.workflow.transaction -import io.onixlabs.corda.bnms.workflow.verifyAndSign -import io.onixlabs.corda.core.workflow.checkSufficientSessions -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.core.workflow.getPreferredNotary -import io.onixlabs.corda.core.workflow.initiateFlows -import io.onixlabs.corda.identityframework.workflow.* +import io.onixlabs.corda.core.workflow.* +import io.onixlabs.corda.identityframework.workflow.checkAttestationExistsForIssuance import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.transactions.SignedTransaction @@ -42,23 +37,33 @@ class IssueRelationshipAttestationFlow( companion object { @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, GENERATING, VERIFYING, SIGNING, FINALIZING) + fun tracker() = ProgressTracker( + InitializeFlowStep, + BuildTransactionStep, + VerifyTransactionStep, + SignTransactionStep, + SendStatesToRecordStep, + FinalizeTransactionStep + ) private const val FLOW_VERSION_1 = 1 } @Suspendable override fun call(): SignedTransaction { - currentStep(INITIALIZING) - checkSufficientSessions(sessions, attestation) + currentStep(InitializeFlowStep) + checkSufficientSessionsForContractStates(sessions, attestation) + checkAttestationExistsForIssuance(attestation) - val transaction = transaction(notary) { - addIssuedAttestation(attestation) - addReferenceState(findRelationshipForAttestation(attestation).referenced()) + val relationship = findRelationshipForAttestation(attestation).referenced() + + val transaction = buildTransaction(notary) { + addIssuedRelationshipAttestation(attestation, relationship) } - val signedTransaction = verifyAndSign(transaction, attestation.attestor.owningKey) - return finalize(signedTransaction, sessions) + verifyTransaction(transaction) + val signedTransaction = signTransaction(transaction) + return finalizeTransaction(signedTransaction, sessions) } @StartableByRPC @@ -70,16 +75,16 @@ class IssueRelationshipAttestationFlow( ) : FlowLogic() { private companion object { - object ISSUING : Step("Issuing relationship attestation.") { + object IssueRelationshipAttestationStep : Step("Issuing relationship attestation.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(ISSUING) + override val progressTracker = ProgressTracker(IssueRelationshipAttestationStep) @Suspendable override fun call(): SignedTransaction { - currentStep(ISSUING) + currentStep(IssueRelationshipAttestationStep) val sessions = initiateFlows(emptyList(), attestation) return subFlow( @@ -87,7 +92,7 @@ class IssueRelationshipAttestationFlow( attestation, notary ?: getPreferredNotary(), sessions, - ISSUING.childProgressTracker() + IssueRelationshipAttestationStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipAttestationFlowHandler.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipAttestationFlowHandler.kt index 9a372f8..8e49266 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipAttestationFlowHandler.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipAttestationFlowHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,18 @@ package io.onixlabs.corda.bnms.workflow.relationship import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.core.workflow.ReceiveStatesToRecordStep +import io.onixlabs.corda.core.workflow.RecordFinalizedTransactionStep import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.FINALIZING +import io.onixlabs.corda.core.workflow.finalizeTransactionHandler import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.ReceiveFinalityFlow import net.corda.core.node.StatesToRecord import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step class IssueRelationshipAttestationFlowHandler( private val session: FlowSession, @@ -36,30 +38,38 @@ class IssueRelationshipAttestationFlowHandler( companion object { @JvmStatic - fun tracker() = ProgressTracker(FINALIZING) + fun tracker() = ProgressTracker( + ReceiveStatesToRecordStep, + RecordFinalizedTransactionStep + ) } @Suspendable override fun call(): SignedTransaction { - currentStep(FINALIZING) - return subFlow(ReceiveFinalityFlow(session, expectedTransactionId, StatesToRecord.ONLY_RELEVANT)) + return finalizeTransactionHandler(session, expectedTransactionId, StatesToRecord.ONLY_RELEVANT) } @InitiatedBy(IssueRelationshipAttestationFlow.Initiator::class) private class Handler(private val session: FlowSession) : FlowLogic() { private companion object { - object OBSERVING : ProgressTracker.Step("Observing relationship attestation issuance.") { + object HandleIssuedRelationshipAttestationStep : Step("Handling relationship attestation issuance.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(OBSERVING) + override val progressTracker = ProgressTracker(HandleIssuedRelationshipAttestationStep) @Suspendable override fun call(): SignedTransaction { - currentStep(OBSERVING) - return subFlow(IssueRelationshipAttestationFlowHandler(session, null, OBSERVING.childProgressTracker())) + currentStep(HandleIssuedRelationshipAttestationStep) + return subFlow( + IssueRelationshipAttestationFlowHandler( + session, + null, + HandleIssuedRelationshipAttestationStep.childProgressTracker() + ) + ) } } } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlow.kt index 8002765..fb8368b 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,15 +18,11 @@ package io.onixlabs.corda.bnms.workflow.relationship import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.relationship.Relationship -import io.onixlabs.corda.bnms.contract.relationship.RelationshipContract -import io.onixlabs.corda.bnms.contract.revocation.RevocationLockContract -import io.onixlabs.corda.bnms.workflow.checkMembershipsAndAttestations -import io.onixlabs.corda.core.workflow.checkSufficientSessions -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.core.workflow.getPreferredNotary -import io.onixlabs.corda.core.workflow.initiateFlows -import io.onixlabs.corda.identityframework.workflow.* -import io.onixlabs.corda.bnms.workflow.* +import io.onixlabs.corda.bnms.workflow.CheckMembershipStep +import io.onixlabs.corda.bnms.workflow.SendCheckMembershipInstructionStep +import io.onixlabs.corda.bnms.workflow.addIssuedRelationship +import io.onixlabs.corda.bnms.workflow.checkMembership +import io.onixlabs.corda.core.workflow.* import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.transactions.SignedTransaction @@ -43,31 +39,35 @@ class IssueRelationshipFlow( companion object { @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, GENERATING, VERIFYING, SIGNING, COUNTERSIGNING, FINALIZING) + fun tracker() = ProgressTracker( + InitializeFlowStep, + SendCheckMembershipInstructionStep, + CheckMembershipStep, + BuildTransactionStep, + VerifyTransactionStep, + SignTransactionStep, + CollectTransactionSignaturesStep, + SendStatesToRecordStep, + FinalizeTransactionStep + ) private const val FLOW_VERSION_1 = 1 } @Suspendable override fun call(): SignedTransaction { - currentStep(INITIALIZING) - checkSufficientSessions(sessions, relationship) - sessions.forEach { it.send(checkMembership) } + currentStep(InitializeFlowStep) + checkSufficientSessionsForContractStates(sessions, relationship) + checkMembership(checkMembership, relationship, sessions) - if (checkMembership) { - checkMembershipsAndAttestations(relationship) + val transaction = buildTransaction(notary) { + addIssuedRelationship(relationship) } - val transaction = transaction(notary) { - addOutputState(relationship, RelationshipContract.ID) - relationship.createRevocationLocks().forEach { addOutputState(it) } - addCommand(RelationshipContract.Issue, relationship.participants.map { it.owningKey }) - addCommand(RevocationLockContract.Lock, relationship.participants.map { it.owningKey }) - } - - val partiallySignedTransaction = verifyAndSign(transaction, ourIdentity.owningKey) - val fullySignedTransaction = countersign(partiallySignedTransaction, sessions) - return finalize(fullySignedTransaction, sessions) + verifyTransaction(transaction) + val partiallySignedTransaction = signTransaction(transaction) + val fullySignedTransaction = collectSignatures(partiallySignedTransaction, sessions) + return finalizeTransaction(fullySignedTransaction, sessions) } @StartableByRPC @@ -80,16 +80,16 @@ class IssueRelationshipFlow( ) : FlowLogic() { private companion object { - object ISSUING : Step("Issuing relationship.") { + object IssueRelationshipStep : Step("Issuing relationship.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(ISSUING) + override val progressTracker = ProgressTracker(IssueRelationshipStep) @Suspendable override fun call(): SignedTransaction { - currentStep(ISSUING) + currentStep(IssueRelationshipStep) val sessions = initiateFlows(emptyList(), relationship) return subFlow( @@ -98,7 +98,7 @@ class IssueRelationshipFlow( notary ?: getPreferredNotary(), sessions, checkMembership, - ISSUING.childProgressTracker() + IssueRelationshipStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlowHandler.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlowHandler.kt index 3667528..82a145f 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlowHandler.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlowHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,16 +18,19 @@ package io.onixlabs.corda.bnms.workflow.relationship import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.relationship.Relationship +import io.onixlabs.corda.bnms.workflow.CheckMembershipStep +import io.onixlabs.corda.bnms.workflow.ReceiveCheckMembershipInstructionStep +import io.onixlabs.corda.bnms.workflow.checkMembershipHandler import io.onixlabs.corda.bnms.workflow.checkMembershipsAndAttestations -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.FINALIZING -import io.onixlabs.corda.identityframework.workflow.SIGNING -import net.corda.core.flows.* +import io.onixlabs.corda.core.workflow.* +import net.corda.core.flows.FlowException +import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession +import net.corda.core.flows.InitiatedBy import net.corda.core.node.StatesToRecord import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker.Step -import net.corda.core.utilities.unwrap class IssueRelationshipFlowHandler( private val session: FlowSession, @@ -36,47 +39,45 @@ class IssueRelationshipFlowHandler( companion object { @JvmStatic - fun tracker() = ProgressTracker(RECEIVING, SIGNING, FINALIZING) - - private object RECEIVING : Step("Receiving check membership instruction.") + fun tracker() = ProgressTracker( + ReceiveCheckMembershipInstructionStep, + SignTransactionStep, + CheckMembershipStep, + ReceiveStatesToRecordStep, + RecordFinalizedTransactionStep + ) } @Suspendable override fun call(): SignedTransaction { - currentStep(RECEIVING) - val checkMembership = session.receive().unwrap { it } - - currentStep(SIGNING) - val transaction = subFlow(object : SignTransactionFlow(session) { - override fun checkTransaction(stx: SignedTransaction) { - if (checkMembership) { - val relationship = stx.tx.outputsOfType().singleOrNull() - ?: throw FlowException("Failed to obtain a relationship from the transaction.") + val checkMembership = checkMembershipHandler(session) + val transaction = collectSignaturesHandler(session) { + if (checkMembership) { + val relationship = it.tx.outputsOfType().singleOrNull() + ?: throw FlowException("Failed to obtain a relationship from the transaction.") - checkMembershipsAndAttestations(relationship) - } + checkMembershipsAndAttestations(relationship) } - }) + } - currentStep(FINALIZING) - return subFlow(ReceiveFinalityFlow(session, transaction.id, StatesToRecord.ONLY_RELEVANT)) + return finalizeTransactionHandler(session, transaction?.id, StatesToRecord.ONLY_RELEVANT) } @InitiatedBy(IssueRelationshipFlow.Initiator::class) private class Handler(private val session: FlowSession) : FlowLogic() { private companion object { - object OBSERVING : Step("Observing relationship issuance.") { + object HandleIssueRelationshipStep : Step("Handling relationship issuance.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(OBSERVING) + override val progressTracker = ProgressTracker(HandleIssueRelationshipStep) @Suspendable override fun call(): SignedTransaction { - currentStep(OBSERVING) - return subFlow(IssueRelationshipFlowHandler(session, OBSERVING.childProgressTracker())) + currentStep(HandleIssueRelationshipStep) + return subFlow(IssueRelationshipFlowHandler(session, HandleIssueRelationshipStep.childProgressTracker())) } } } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipAttestationFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipAttestationFlow.kt index 6689162..95af41c 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipAttestationFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipAttestationFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,17 +18,13 @@ package io.onixlabs.corda.bnms.workflow.relationship import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.relationship.RelationshipAttestation -import io.onixlabs.corda.bnms.workflow.finalize -import io.onixlabs.corda.bnms.workflow.transaction -import io.onixlabs.corda.bnms.workflow.verifyAndSign -import io.onixlabs.corda.core.workflow.checkSufficientSessions -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.core.workflow.initiateFlows -import io.onixlabs.corda.identityframework.workflow.* +import io.onixlabs.corda.bnms.workflow.addRevokedRelationshipAttestation +import io.onixlabs.corda.core.workflow.* import net.corda.core.contracts.StateAndRef import net.corda.core.flows.* import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step class RevokeRelationshipAttestationFlow( private val attestation: StateAndRef, @@ -38,22 +34,30 @@ class RevokeRelationshipAttestationFlow( companion object { @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, GENERATING, VERIFYING, SIGNING, FINALIZING) + fun tracker() = ProgressTracker( + InitializeFlowStep, + BuildTransactionStep, + VerifyTransactionStep, + SignTransactionStep, + SendStatesToRecordStep, + FinalizeTransactionStep + ) private const val FLOW_VERSION_1 = 1 } @Suspendable override fun call(): SignedTransaction { - currentStep(INITIALIZING) - checkSufficientSessions(sessions, attestation.state.data) + currentStep(InitializeFlowStep) + checkSufficientSessionsForContractStates(sessions, attestation.state.data) - val transaction = transaction(attestation.state.notary) { - addRevokedAttestation(attestation) + val transaction = buildTransaction(attestation.state.notary) { + addRevokedRelationshipAttestation(attestation) } - val signedTransaction = verifyAndSign(transaction, attestation.state.data.attestor.owningKey) - return finalize(signedTransaction, sessions) + verifyTransaction(transaction) + val signedTransaction = signTransaction(transaction) + return finalizeTransaction(signedTransaction, sessions) } @StartableByRPC @@ -64,23 +68,23 @@ class RevokeRelationshipAttestationFlow( ) : FlowLogic() { private companion object { - object REVOKING : ProgressTracker.Step("Revoking relationship attestation.") { + object RevokeRelationshipAttestationStep : Step("Revoking relationship attestation.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(REVOKING) + override val progressTracker = ProgressTracker(RevokeRelationshipAttestationStep) @Suspendable override fun call(): SignedTransaction { - currentStep(REVOKING) + currentStep(RevokeRelationshipAttestationStep) val sessions = initiateFlows(emptyList(), attestation.state.data) return subFlow( RevokeRelationshipAttestationFlow( attestation, sessions, - REVOKING.childProgressTracker() + RevokeRelationshipAttestationStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipAttestationFlowHandler.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipAttestationFlowHandler.kt index 96ac7f2..9733a21 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipAttestationFlowHandler.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipAttestationFlowHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,18 @@ package io.onixlabs.corda.bnms.workflow.relationship import co.paralleluniverse.fibers.Suspendable +import io.onixlabs.corda.core.workflow.ReceiveStatesToRecordStep +import io.onixlabs.corda.core.workflow.RecordFinalizedTransactionStep import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.FINALIZING +import io.onixlabs.corda.core.workflow.finalizeTransactionHandler import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.ReceiveFinalityFlow import net.corda.core.node.StatesToRecord import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step class RevokeRelationshipAttestationFlowHandler( private val session: FlowSession, @@ -36,30 +38,38 @@ class RevokeRelationshipAttestationFlowHandler( companion object { @JvmStatic - fun tracker() = ProgressTracker(FINALIZING) + fun tracker() = ProgressTracker( + ReceiveStatesToRecordStep, + RecordFinalizedTransactionStep + ) } @Suspendable override fun call(): SignedTransaction { - currentStep(FINALIZING) - return subFlow(ReceiveFinalityFlow(session, expectedTransactionId, StatesToRecord.ONLY_RELEVANT)) + return finalizeTransactionHandler(session, expectedTransactionId, StatesToRecord.ONLY_RELEVANT) } @InitiatedBy(RevokeRelationshipAttestationFlow.Initiator::class) private class Handler(private val session: FlowSession) : FlowLogic() { private companion object { - object OBSERVING : ProgressTracker.Step("Observing relationship attestation revocation.") { - override fun childProgressTracker() = IssueRelationshipAttestationFlowHandler.tracker() + object HandleRevokeRelationshipAttestationStep : Step("Handle relationship attestation revocation.") { + override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(OBSERVING) + override val progressTracker = ProgressTracker(HandleRevokeRelationshipAttestationStep) @Suspendable override fun call(): SignedTransaction { - currentStep(OBSERVING) - return subFlow(IssueRelationshipAttestationFlowHandler(session, null, OBSERVING.childProgressTracker())) + currentStep(HandleRevokeRelationshipAttestationStep) + return subFlow( + IssueRelationshipAttestationFlowHandler( + session, + null, + HandleRevokeRelationshipAttestationStep.childProgressTracker() + ) + ) } } } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipFlow.kt index 791bd2a..346a6ef 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,15 +18,8 @@ package io.onixlabs.corda.bnms.workflow.relationship import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.relationship.Relationship -import io.onixlabs.corda.bnms.contract.relationship.RelationshipContract -import io.onixlabs.corda.bnms.workflow.countersign -import io.onixlabs.corda.bnms.workflow.finalize -import io.onixlabs.corda.bnms.workflow.transaction -import io.onixlabs.corda.bnms.workflow.verifyAndSign -import io.onixlabs.corda.core.workflow.checkSufficientSessions -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.core.workflow.initiateFlows -import io.onixlabs.corda.identityframework.workflow.* +import io.onixlabs.corda.bnms.workflow.addRevokedRelationship +import io.onixlabs.corda.core.workflow.* import net.corda.core.contracts.StateAndRef import net.corda.core.flows.* import net.corda.core.transactions.SignedTransaction @@ -40,25 +33,33 @@ class RevokeRelationshipFlow( ) : FlowLogic() { companion object { - private const val FLOW_VERSION_1 = 1 - @JvmStatic - fun tracker() = ProgressTracker(INITIALIZING, GENERATING, VERIFYING, SIGNING, COUNTERSIGNING, FINALIZING) + fun tracker() = ProgressTracker( + InitializeFlowStep, + BuildTransactionStep, + VerifyTransactionStep, + SignTransactionStep, + CollectTransactionSignaturesStep, + SendStatesToRecordStep, + FinalizeTransactionStep + ) + + private const val FLOW_VERSION_1 = 1 } @Suspendable override fun call(): SignedTransaction { - currentStep(INITIALIZING) - checkSufficientSessions(sessions, relationship.state.data) + currentStep(InitializeFlowStep) + checkSufficientSessionsForContractStates(sessions, relationship.state.data) - val transaction = transaction(relationship.state.notary) { - addInputState(relationship) - addCommand(RelationshipContract.Revoke, relationship.state.data.participants.map { it.owningKey }) + val transaction = buildTransaction(relationship.state.notary) { + addRevokedRelationship(relationship) } - val partiallySignedTransaction = verifyAndSign(transaction, ourIdentity.owningKey) - val fullySignedTransaction = countersign(partiallySignedTransaction, sessions) - return finalize(fullySignedTransaction, sessions) + verifyTransaction(transaction) + val partiallySignedTransaction = signTransaction(transaction) + val fullySignedTransaction = collectSignatures(partiallySignedTransaction, sessions) + return finalizeTransaction(fullySignedTransaction, sessions) } @StartableByRPC @@ -69,23 +70,23 @@ class RevokeRelationshipFlow( ) : FlowLogic() { private companion object { - object REVOKING : Step("Revoking relationship.") { + object RevokeRelationshipStep : Step("Revoking relationship.") { override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(REVOKING) + override val progressTracker = ProgressTracker(RevokeRelationshipStep) @Suspendable override fun call(): SignedTransaction { - currentStep(REVOKING) + currentStep(RevokeRelationshipStep) val sessions = initiateFlows(emptyList(), relationship.state.data) return subFlow( RevokeRelationshipFlow( relationship, sessions, - REVOKING.childProgressTracker() + RevokeRelationshipStep.childProgressTracker() ) ) } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipFlowHandler.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipFlowHandler.kt index 68b5b34..f574a2f 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipFlowHandler.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipFlowHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,14 +18,16 @@ package io.onixlabs.corda.bnms.workflow.relationship import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.relationship.Relationship -import io.onixlabs.corda.bnms.workflow.revocation.FindRevocationLockFlow -import io.onixlabs.corda.core.workflow.currentStep -import io.onixlabs.corda.identityframework.workflow.FINALIZING -import io.onixlabs.corda.identityframework.workflow.SIGNING -import net.corda.core.flows.* +import io.onixlabs.corda.bnms.workflow.checkRevocationLockExists +import io.onixlabs.corda.core.workflow.* +import net.corda.core.flows.FlowException +import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession +import net.corda.core.flows.InitiatedBy import net.corda.core.node.StatesToRecord import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.ProgressTracker.Step class RevokeRelationshipFlowHandler( private val session: FlowSession, @@ -34,44 +36,42 @@ class RevokeRelationshipFlowHandler( companion object { @JvmStatic - fun tracker() = ProgressTracker(SIGNING, FINALIZING) + fun tracker() = ProgressTracker( + SignTransactionStep, + ReceiveStatesToRecordStep, + RecordFinalizedTransactionStep + ) } @Suspendable override fun call(): SignedTransaction { - currentStep(SIGNING) - val transaction = subFlow(object : SignTransactionFlow(session) { - override fun checkTransaction(stx: SignedTransaction) { - val relationshipStateRef = stx.tx.inputs.singleOrNull() ?: throw FlowException( - "Failed to obtain a single state reference from the transaction." - ) + val transaction = collectSignaturesHandler(session) { + val relationshipStateRef = it.tx.inputs.singleOrNull() ?: throw FlowException( + "Failed to obtain a single state reference from the transaction." + ) - val relationship = serviceHub.toStateAndRef(relationshipStateRef) - subFlow(FindRevocationLockFlow(ourIdentity, relationship.state.data))?.let { - throw FlowException("Revocation of this relationship is locked by counter-party: $ourIdentity") - } - } - }) + val relationship = serviceHub.toStateAndRef(relationshipStateRef) + checkRevocationLockExists(ourIdentity, relationship.state.data) + } - currentStep(FINALIZING) - return subFlow(ReceiveFinalityFlow(session, transaction.id, StatesToRecord.ONLY_RELEVANT)) + return finalizeTransactionHandler(session, transaction?.id, StatesToRecord.ONLY_RELEVANT) } @InitiatedBy(RevokeRelationshipFlow.Initiator::class) private class Handler(private val session: FlowSession) : FlowLogic() { private companion object { - object OBSERVING : ProgressTracker.Step("Observing relationship revocation.") { - override fun childProgressTracker() = RevokeRelationshipFlowHandler.tracker() + object HandleRevokeRelationshipStep : Step("Handling relationship revocation.") { + override fun childProgressTracker() = tracker() } } - override val progressTracker = ProgressTracker(OBSERVING) + override val progressTracker = ProgressTracker(HandleRevokeRelationshipStep) @Suspendable override fun call(): SignedTransaction { - currentStep(OBSERVING) - return subFlow(RevokeRelationshipFlowHandler(session, OBSERVING.childProgressTracker())) + currentStep(HandleRevokeRelationshipStep) + return subFlow(RevokeRelationshipFlowHandler(session, HandleRevokeRelationshipStep.childProgressTracker())) } } } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/revocation/FindRevocationLockFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/revocation/FindRevocationLockFlow.kt deleted file mode 100644 index 42ab598..0000000 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/revocation/FindRevocationLockFlow.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2020-2021 ONIXLabs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.onixlabs.corda.bnms.workflow.revocation - -import io.onixlabs.corda.bnms.contract.revocation.RevocationLock -import io.onixlabs.corda.bnms.contract.revocation.RevocationLockSchema.RevocationLockEntity -import io.onixlabs.corda.core.workflow.DEFAULT_PAGE_SPECIFICATION -import io.onixlabs.corda.core.workflow.FindStateFlow -import io.onixlabs.corda.core.workflow.andWithExpressions -import net.corda.core.contracts.LinearState -import net.corda.core.flows.StartableByRPC -import net.corda.core.flows.StartableByService -import net.corda.core.identity.AbstractParty -import net.corda.core.node.services.Vault -import net.corda.core.node.services.vault.Builder.equal -import net.corda.core.node.services.vault.PageSpecification -import net.corda.core.node.services.vault.QueryCriteria -import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria - -@StartableByRPC -@StartableByService -class FindRevocationLockFlow(owner: AbstractParty, state: T) : FindStateFlow>() { - override val pageSpecification: PageSpecification = DEFAULT_PAGE_SPECIFICATION - - override val criteria: QueryCriteria = VaultQueryCriteria( - contractStateTypes = setOf(contractStateType), - relevancyStatus = Vault.RelevancyStatus.RELEVANT, - status = Vault.StateStatus.UNCONSUMED - ).andWithExpressions( - RevocationLockEntity::owner.equal(owner), - RevocationLockEntity::pointerStateLinearId.equal(state.linearId.id), - RevocationLockEntity::pointerStateExternalId.equal(state.linearId.externalId), - RevocationLockEntity::pointerStateClass.equal(state.javaClass.canonicalName) - ) -} diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/revocation/LockRevocationLockFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/revocation/LockRevocationLockFlow.kt index 8aa2c67..749a3b7 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/revocation/LockRevocationLockFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/revocation/LockRevocationLockFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,10 +18,8 @@ package io.onixlabs.corda.bnms.workflow.revocation import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.revocation.RevocationLock -import io.onixlabs.corda.bnms.contract.revocation.RevocationLockContract -import io.onixlabs.corda.core.workflow.getPreferredNotary -import io.onixlabs.corda.identityframework.workflow.* -import io.onixlabs.corda.bnms.workflow.* +import io.onixlabs.corda.bnms.workflow.addLockedRevocationLock +import io.onixlabs.corda.core.workflow.* import net.corda.core.flows.FlowLogic import net.corda.core.flows.StartableByRPC import net.corda.core.flows.StartableByService @@ -33,24 +31,29 @@ import net.corda.core.utilities.ProgressTracker @StartableByService class LockRevocationLockFlow( private val revocationLock: RevocationLock<*>, - private val notary: Party? = null + private val notary: Party? = null, + override val progressTracker: ProgressTracker = tracker() ) : FlowLogic() { companion object { @JvmStatic - fun tracker() = ProgressTracker(GENERATING, VERIFYING, SIGNING, FINALIZING) + fun tracker() = ProgressTracker( + BuildTransactionStep, + VerifyTransactionStep, + SignTransactionStep, + SendStatesToRecordStep, + FinalizeTransactionStep + ) } - override val progressTracker = tracker() - @Suspendable override fun call(): SignedTransaction { - val transaction = transaction(notary ?: getPreferredNotary()) { - addOutputState(revocationLock, RevocationLockContract.ID) - addCommand(RevocationLockContract.Lock, revocationLock.owner.owningKey) + val transaction = buildTransaction(notary ?: getPreferredNotary()) { + addLockedRevocationLock(revocationLock) } - val signedTransaction = verifyAndSign(transaction, revocationLock.owner.owningKey) - return finalize(signedTransaction) + verifyTransaction(transaction) + val signedTransaction = signTransaction(transaction) + return finalizeTransaction(signedTransaction, emptyList()) } } diff --git a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/revocation/UnlockRevocationLockFlow.kt b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/revocation/UnlockRevocationLockFlow.kt index 5ae1886..5c54960 100644 --- a/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/revocation/UnlockRevocationLockFlow.kt +++ b/onixlabs-corda-bnms-workflow/src/main/kotlin/io/onixlabs/corda/bnms/workflow/revocation/UnlockRevocationLockFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,14 +18,8 @@ package io.onixlabs.corda.bnms.workflow.revocation import co.paralleluniverse.fibers.Suspendable import io.onixlabs.corda.bnms.contract.revocation.RevocationLock -import io.onixlabs.corda.bnms.contract.revocation.RevocationLockContract -import io.onixlabs.corda.bnms.workflow.finalize -import io.onixlabs.corda.bnms.workflow.transaction -import io.onixlabs.corda.bnms.workflow.verifyAndSign -import io.onixlabs.corda.identityframework.workflow.FINALIZING -import io.onixlabs.corda.identityframework.workflow.GENERATING -import io.onixlabs.corda.identityframework.workflow.SIGNING -import io.onixlabs.corda.identityframework.workflow.VERIFYING +import io.onixlabs.corda.bnms.workflow.addUnlockedRevocationLock +import io.onixlabs.corda.core.workflow.* import net.corda.core.contracts.StateAndRef import net.corda.core.flows.FlowLogic import net.corda.core.flows.StartableByRPC @@ -36,24 +30,29 @@ import net.corda.core.utilities.ProgressTracker @StartableByRPC @StartableByService class UnlockRevocationLockFlow( - private val revocationLock: StateAndRef> + private val revocationLock: StateAndRef>, + override val progressTracker: ProgressTracker = tracker() ) : FlowLogic() { companion object { @JvmStatic - fun tracker() = ProgressTracker(GENERATING, VERIFYING, SIGNING, FINALIZING) + fun tracker() = ProgressTracker( + BuildTransactionStep, + VerifyTransactionStep, + SignTransactionStep, + SendStatesToRecordStep, + FinalizeTransactionStep + ) } - override val progressTracker = tracker() - @Suspendable override fun call(): SignedTransaction { - val transaction = transaction(revocationLock.state.notary) { - addInputState(revocationLock) - addCommand(RevocationLockContract.Unlock, revocationLock.state.data.owner.owningKey) + val transaction = buildTransaction(revocationLock.state.notary) { + addUnlockedRevocationLock(revocationLock) } - val signedTransaction = verifyAndSign(transaction, revocationLock.state.data.owner.owningKey) - return finalize(signedTransaction) + verifyTransaction(transaction) + val signedTransaction = signTransaction(transaction) + return finalizeTransaction(signedTransaction, emptyList()) } } diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/FlowTest.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/FlowTest.kt index bbfce39..df11639 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/FlowTest.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/FlowTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,10 @@ package io.onixlabs.corda.bnms.workflow +import io.onixlabs.corda.bnms.contract.Configuration import io.onixlabs.corda.bnms.contract.Network import io.onixlabs.corda.bnms.contract.membership.Membership import io.onixlabs.corda.bnms.contract.relationship.Relationship -import io.onixlabs.corda.bnms.contract.relationship.RelationshipMember import io.onixlabs.corda.bnms.contract.revocation.RevocationLock import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party @@ -38,7 +38,7 @@ import org.junit.jupiter.api.TestInstance abstract class FlowTest { protected val NETWORK by lazy { Network("Example Network") } - protected val MEMBERS by lazy { setOf(RelationshipMember(partyA), RelationshipMember(partyB)) } + protected val MEMBERS by lazy { mapOf(partyA to Configuration(), partyB to Configuration()) } protected val MEMBERSHIP by lazy { Membership(NETWORK, partyA) } protected val RELATIONSHIP by lazy { Relationship(NETWORK, MEMBERS) } @@ -79,13 +79,13 @@ abstract class FlowTest { private fun setup() { _network = MockNetwork( MockNetworkParameters( + networkParameters = testNetworkParameters(minimumPlatformVersion = 11), cordappsForAllNodes = listOf( TestCordapp.findCordapp("io.onixlabs.corda.identityframework.contract"), TestCordapp.findCordapp("io.onixlabs.corda.identityframework.workflow"), TestCordapp.findCordapp("io.onixlabs.corda.bnms.contract"), TestCordapp.findCordapp("io.onixlabs.corda.bnms.workflow") - ), - networkParameters = testNetworkParameters(minimumPlatformVersion = 4) + ) ) ) diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/Pipeline.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/Pipeline.kt index 98a7b01..8a98cec 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/Pipeline.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/Pipeline.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendDuplicateMembershipAttestationFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendDuplicateMembershipAttestationFlowTests.kt new file mode 100644 index 0000000..798e014 --- /dev/null +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendDuplicateMembershipAttestationFlowTests.kt @@ -0,0 +1,67 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.workflow.membership + +import io.onixlabs.corda.bnms.contract.membership.Membership +import io.onixlabs.corda.bnms.contract.membership.MembershipAttestation +import io.onixlabs.corda.bnms.contract.membership.accept +import io.onixlabs.corda.bnms.workflow.FlowTest +import io.onixlabs.corda.bnms.workflow.Pipeline +import net.corda.core.contracts.StateAndRef +import net.corda.core.flows.FlowException +import net.corda.core.transactions.SignedTransaction +import org.junit.jupiter.api.Test +import kotlin.test.assertFailsWith + +class AmendDuplicateMembershipAttestationFlowTests : FlowTest() { + + private lateinit var membership: StateAndRef + private lateinit var oldAttestation: StateAndRef + private lateinit var newAttestation: MembershipAttestation + private lateinit var transaction: SignedTransaction + + override fun initialize() { + Pipeline + .create(network) + .run(nodeA) { + IssueMembershipFlow.Initiator(MEMBERSHIP, observers = setOf(partyB)) + } + .run(nodeB) { + membership = it.tx.outRefsOfType().single() + val attestation = membership.accept(partyB) + IssueMembershipAttestationFlow.Initiator(attestation) + } + .finally { + oldAttestation = it.tx.outRefsOfType().single() + transaction = it + } + } + + @Test + fun `AmendMembershipAttestationFlow should fail because an existing membership attestation already exists`() { + val exception = assertFailsWith { + Pipeline + .create(network) + .run(nodeB) { + newAttestation = oldAttestation.state.data + AmendMembershipAttestationFlow.Initiator(oldAttestation, newAttestation) + } + } + + assert(exception.message!!.startsWith("The specified membership attestation already exists:")) + } +} diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipAttestationFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipAttestationFlowTests.kt index 6ccbc5b..05e79ec 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipAttestationFlowTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipAttestationFlowTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ import io.onixlabs.corda.bnms.contract.membership.accept import io.onixlabs.corda.bnms.contract.membership.reject import io.onixlabs.corda.bnms.workflow.FlowTest import io.onixlabs.corda.bnms.workflow.Pipeline -import io.onixlabs.corda.identityframework.contract.AttestationStatus +import io.onixlabs.corda.identityframework.contract.attestations.AttestationStatus import net.corda.core.transactions.SignedTransaction import org.junit.jupiter.api.Test import org.junit.jupiter.api.fail @@ -84,4 +84,4 @@ class AmendMembershipAttestationFlowTests : FlowTest() { } } } -} \ No newline at end of file +} diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipFlowTests.kt index a20f3dd..2245004 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipFlowTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/AmendMembershipFlowTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,7 @@ class AmendMembershipFlowTests : FlowTest() { } .run(nodeA) { val oldMembership = it.tx.outRefsOfType().single() - membership = oldMembership.getNextOutput().addRoles("Administrator") + membership = oldMembership.getNextOutput().configure { addRoles("Administrator") } AmendMembershipFlow.Initiator(oldMembership, membership, observers = setOf(partyB)) } .finally { transaction = it } @@ -72,7 +72,7 @@ class AmendMembershipFlowTests : FlowTest() { ?: fail("Failed to find a recorded membership.") assertEquals(membership, recordedMembership) - assert(recordedMembership.hasRole("Administrator")) + assert(recordedMembership.configuration.hasRole("Administrator")) } } } diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueDuplicateMembershipAttestationFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueDuplicateMembershipAttestationFlowTests.kt new file mode 100644 index 0000000..55d153e --- /dev/null +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueDuplicateMembershipAttestationFlowTests.kt @@ -0,0 +1,71 @@ +/* + * Copyright 2020-2022 ONIXLabs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.onixlabs.corda.bnms.workflow.membership + +import io.onixlabs.corda.bnms.contract.membership.Membership +import io.onixlabs.corda.bnms.contract.membership.accept +import io.onixlabs.corda.bnms.contract.membership.getNextOutput +import io.onixlabs.corda.bnms.workflow.FlowTest +import io.onixlabs.corda.bnms.workflow.Pipeline +import net.corda.core.contracts.StateAndRef +import net.corda.core.flows.FlowException +import net.corda.core.transactions.SignedTransaction +import org.junit.jupiter.api.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith + +class IssueDuplicateMembershipAttestationFlowTests : FlowTest() { + + private lateinit var oldMembership: StateAndRef + private lateinit var newMembership: StateAndRef + private lateinit var transaction: SignedTransaction + + override fun initialize() { + Pipeline + .create(network) + .run(nodeA) { + IssueMembershipFlow.Initiator(MEMBERSHIP, observers = setOf(partyB)) + } + .run(nodeB) { + oldMembership = it.tx.outRefsOfType().single() + val attestation = oldMembership.accept(partyB) + IssueMembershipAttestationFlow.Initiator(attestation) + } + .run(nodeA) { + val membership = oldMembership.getNextOutput().configure { addSetting("Test", "Test") } + AmendMembershipFlow.Initiator(oldMembership, membership, observers = setOf(partyB)) + } + .finally { + newMembership = it.tx.outRefsOfType().single() + transaction = it + } + } + + @Test + fun `IssueMembershipAttestationFlow should fail because an existing membership attestation already exists`() { + val exception = assertFailsWith { + Pipeline + .create(network) + .run(nodeB) { + val attestation = newMembership.accept(partyB) + IssueMembershipAttestationFlow.Initiator(attestation) + } + } + + assert(exception.message!!.startsWith("The specified membership attestation already exists and should be amended:")) + } +} diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipAttestationFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipAttestationFlowTests.kt index e7c85fe..fda6ebe 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipAttestationFlowTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipAttestationFlowTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipFlowTests.kt index a6beb4d..9204543 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipFlowTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/IssueMembershipFlowTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipAttestationFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipAttestationFlowTests.kt index 0768f3e..52ad100 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipAttestationFlowTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipAttestationFlowTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipFlowTests.kt index 614d8fa..42aea0a 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipFlowTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/RevokeMembershipFlowTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/SynchronizeMembershipFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/SynchronizeMembershipFlowTests.kt index 474ed73..a5b045c 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/SynchronizeMembershipFlowTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/membership/SynchronizeMembershipFlowTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +16,16 @@ package io.onixlabs.corda.bnms.workflow.membership -import io.onixlabs.corda.bnms.contract.membership.Membership -import io.onixlabs.corda.bnms.contract.membership.MembershipAttestation -import io.onixlabs.corda.bnms.contract.membership.accept +import io.onixlabs.corda.bnms.contract.membership.* import io.onixlabs.corda.bnms.workflow.FlowTest import io.onixlabs.corda.bnms.workflow.Pipeline +import io.onixlabs.corda.core.services.equalTo +import io.onixlabs.corda.core.services.singleOrNull +import io.onixlabs.corda.core.services.vaultServiceFor import net.corda.core.contracts.StateAndRef import org.junit.jupiter.api.Test import org.junit.jupiter.api.fail +import kotlin.test.assertNotNull class SynchronizeMembershipFlowTests : FlowTest() { @@ -59,41 +61,43 @@ class SynchronizeMembershipFlowTests : FlowTest() { @Test fun `Party A has recorded Party C's Membership`() { - Pipeline - .create(network) - .run(nodeA) { - FindMembershipFlow(holder = partyC, network = NETWORK) - } - .finally { assert(it != null) } + val membership = nodeA.services.vaultServiceFor().singleOrNull { + expression(MembershipSchema.MembershipEntity::holder equalTo partyC) + expression(MembershipSchema.MembershipEntity::networkHash equalTo NETWORK.hash.toString()) + } + + assertNotNull(membership) } @Test fun `Party A has recorded Party B's MembershipAttestation for Party C`() { - Pipeline - .create(network) - .run(nodeA) { - FindMembershipAttestationFlow(holder = partyC, network = NETWORK, attestor = partyB) - } - .finally { assert(it != null) } + val attestation = nodeA.services.vaultServiceFor().singleOrNull { + expression(MembershipAttestationSchema.MembershipAttestationEntity::holder equalTo partyC) + expression(MembershipAttestationSchema.MembershipAttestationEntity::networkHash equalTo NETWORK.hash.toString()) + expression(MembershipAttestationSchema.MembershipAttestationEntity::attestor equalTo partyB) + } + + assertNotNull(attestation) } @Test fun `Party C has recorded Party A's Membership`() { - Pipeline - .create(network) - .run(nodeC) { - FindMembershipFlow(holder = partyA, network = NETWORK) - } - .finally { assert(it != null) } + val membership = nodeC.services.vaultServiceFor().singleOrNull { + expression(MembershipSchema.MembershipEntity::holder equalTo partyA) + expression(MembershipSchema.MembershipEntity::networkHash equalTo NETWORK.hash.toString()) + } + + assertNotNull(membership) } @Test fun `Party C has recorded Party B's MembershipAttestation for Party A`() { - Pipeline - .create(network) - .run(nodeA) { - FindMembershipAttestationFlow(holder = partyA, network = NETWORK, attestor = partyB) - } - .finally { assert(it != null) } + val attestation = nodeC.services.vaultServiceFor().singleOrNull { + expression(MembershipAttestationSchema.MembershipAttestationEntity::holder equalTo partyA) + expression(MembershipAttestationSchema.MembershipAttestationEntity::networkHash equalTo NETWORK.hash.toString()) + expression(MembershipAttestationSchema.MembershipAttestationEntity::attestor equalTo partyB) + } + + assertNotNull(attestation) } } diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipAttestationFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipAttestationFlowTests.kt index 01ecaaa..27385f3 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipAttestationFlowTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipAttestationFlowTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ import io.onixlabs.corda.bnms.contract.relationship.accept import io.onixlabs.corda.bnms.contract.relationship.reject import io.onixlabs.corda.bnms.workflow.FlowTest import io.onixlabs.corda.bnms.workflow.Pipeline -import io.onixlabs.corda.identityframework.contract.AttestationStatus +import io.onixlabs.corda.identityframework.contract.attestations.AttestationStatus import net.corda.core.transactions.SignedTransaction import org.junit.jupiter.api.Test import org.junit.jupiter.api.fail diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipFlowTests.kt index df4d529..9eb2230 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipFlowTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/AmendRelationshipFlowTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,9 @@ class AmendRelationshipFlowTests : FlowTest() { } .run(nodeB) { val oldRelationship = it.tx.outRefsOfType().single() - relationship = oldRelationship.getNextOutput().addSetting("TestValue", 123) + relationship = oldRelationship.getNextOutput().configure(partyA) { + addSetting("TestValue", 123) + } AmendRelationshipFlow.Initiator(oldRelationship, relationship, checkMembership = false) } .finally { transaction = it } @@ -77,9 +79,10 @@ class AmendRelationshipFlowTests : FlowTest() { ?: fail("Failed to find a recorded relationship.") assertEquals(relationship, recordedRelationship) - assertEquals(1, relationship.settings.size) - assertEquals("TESTVALUE", relationship.settings.single().property) - assertEquals(123, relationship.settings.single().value) + assertEquals(1, relationship.members[partyA]!!.settings.size) + assertEquals("TestValue", relationship.members[partyA]!!.settings.single().property) + assertEquals("TESTVALUE", relationship.members[partyA]!!.settings.single().normalizedProperty) + assertEquals(123, relationship.members[partyA]!!.settings.single().value) } } } diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipAttestationFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipAttestationFlowTests.kt index c9077f6..2d7d702 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipAttestationFlowTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipAttestationFlowTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlowTests.kt index 89aa618..b57d34c 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlowTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlowTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlowWithMembershipCheckingTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlowWithMembershipCheckingTests.kt index a3c4c05..f772219 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlowWithMembershipCheckingTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/IssueRelationshipFlowWithMembershipCheckingTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipAttestationFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipAttestationFlowTests.kt index 01c6498..2b335ac 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipAttestationFlowTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipAttestationFlowTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipFlowTests.kt index 38351a8..c1c4f5f 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipFlowTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/relationship/RevokeRelationshipFlowTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/revocation/LockRevocationLockFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/revocation/LockRevocationLockFlowTests.kt index 98a339a..223da94 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/revocation/LockRevocationLockFlowTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/revocation/LockRevocationLockFlowTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/revocation/UnlockRevocationLockFlowTests.kt b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/revocation/UnlockRevocationLockFlowTests.kt index e440c5d..9049400 100644 --- a/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/revocation/UnlockRevocationLockFlowTests.kt +++ b/onixlabs-corda-bnms-workflow/src/test/kotlin/io/onixlabs/corda/bnms/workflow/revocation/UnlockRevocationLockFlowTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 ONIXLabs + * Copyright 2020-2022 ONIXLabs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License.