├── .gitignore ├── CONTRIBUTORS.md ├── README.md ├── bn-apps ├── LICENCE ├── README.md ├── TRADEMARK ├── billing │ ├── README.md │ ├── billing-app │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── com │ │ │ │ └── r3 │ │ │ │ └── businessnetworks │ │ │ │ └── billing │ │ │ │ └── flows │ │ │ │ ├── Constants.kt │ │ │ │ ├── bno │ │ │ │ ├── CloseBillingSateFlow.kt │ │ │ │ ├── IssueBillingStateFlow.kt │ │ │ │ ├── RequestReturnOfBillingStateFlow.kt │ │ │ │ ├── RevokeBillingStateFlow.kt │ │ │ │ ├── responders │ │ │ │ │ ├── AttachUnspentChipsResponder.kt │ │ │ │ │ ├── ChipOffBillingStateFlowResponder.kt │ │ │ │ │ └── ReturnBillingStateFlowResponder.kt │ │ │ │ └── service │ │ │ │ │ ├── BNOBillingDatabaseService.kt │ │ │ │ │ └── BNOConfigurationService.kt │ │ │ │ └── member │ │ │ │ ├── AttachUnspentChipsFlow.kt │ │ │ │ ├── ChipOffBillingStateFlow.kt │ │ │ │ ├── DataFlows.kt │ │ │ │ ├── ReturnBillingStateFlow.kt │ │ │ │ ├── responders │ │ │ │ ├── CloseBillingStateFlowResponder.kt │ │ │ │ ├── IssueBillingStateFlowResponder.kt │ │ │ │ ├── RequestReturnOfBillingStateFlowResponder.kt │ │ │ │ └── RevokeBillingStateFlowResponder.kt │ │ │ │ └── service │ │ │ │ ├── MemberBillingDatabaseService.kt │ │ │ │ └── MemberConfigurationService.kt │ │ │ └── test │ │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── r3 │ │ │ │ └── businessnetworks │ │ │ │ └── billing │ │ │ │ └── flows │ │ │ │ ├── bno │ │ │ │ ├── CloseBillingStateFlowTest.kt │ │ │ │ ├── IssueBillingStateFlowTest.kt │ │ │ │ ├── RequestReturnOfBillingStateFlowTest.kt │ │ │ │ └── RevokeBillingStateFlowTest.kt │ │ │ │ └── member │ │ │ │ ├── AttachUnspentChipsFlowTest.kt │ │ │ │ ├── ChipOffBillingStateFlowTest.kt │ │ │ │ ├── DataFlowsTest.kt │ │ │ │ └── ReturnBillingStateFlowTest.kt │ │ │ └── resources │ │ │ └── billing-app.conf │ ├── billing-contracts-and-states │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── com │ │ │ │ └── r3 │ │ │ │ └── businessnetworks │ │ │ │ └── billing │ │ │ │ └── states │ │ │ │ ├── BillingContract.kt │ │ │ │ └── Schemas.kt │ │ │ ├── resources │ │ │ ├── billing.changelog-master.xml │ │ │ └── migration │ │ │ │ ├── billing.changelog-init.xml │ │ │ │ └── billing.changelog-v2.xml │ │ │ └── test │ │ │ └── kotlin │ │ │ └── com │ │ │ └── r3 │ │ │ └── businessnetworks │ │ │ └── billing │ │ │ └── states │ │ │ └── BillingContractTest.kt │ ├── billing-demo │ │ ├── README.md │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── com │ │ │ │ └── r3 │ │ │ │ └── businessnetworks │ │ │ │ └── billing │ │ │ │ └── demo │ │ │ │ ├── contracts │ │ │ │ └── SampleContract.kt │ │ │ │ └── flows │ │ │ │ └── Flows.kt │ │ │ └── test │ │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── r3 │ │ │ │ └── businessnetworks │ │ │ │ └── billing │ │ │ │ └── demo │ │ │ │ └── DemoTest.kt │ │ │ └── resources │ │ │ └── billing-app.conf │ └── resources │ │ ├── billing_state_evolution.png │ │ └── billing_state_machine.png ├── businessnetworks-test-utilities │ ├── build.gradle │ └── src │ │ └── main │ │ └── kotlin │ │ └── com │ │ └── r3 │ │ └── businessnetworks │ │ └── testutilities │ │ ├── AbstractBusinessNetworksFlowDriverTest.kt │ │ └── AbstractBusinessNetworksFlowTest.kt ├── businessnetworks-utilities │ ├── build.gradle │ └── src │ │ └── main │ │ └── kotlin │ │ └── com │ │ └── r3 │ │ └── businessnetworks │ │ └── utilities │ │ └── AbstractConfigurationService.kt ├── cordapp-updates-distribution │ ├── README.md │ ├── TestRepo │ │ └── net │ │ │ └── example │ │ │ ├── test-artifact-2 │ │ │ ├── 1.0 │ │ │ │ ├── test-artifact-2-1.0.jar │ │ │ │ └── test-artifact-2-1.0.pom │ │ │ ├── 2.0 │ │ │ │ ├── test-artifact-2-2.0.jar │ │ │ │ └── test-artifact-2-2.0.pom │ │ │ └── maven-metadata.xml │ │ │ ├── test-artifact-3 │ │ │ ├── 0.1 │ │ │ │ ├── test-artifact-3-0.1.jar │ │ │ │ └── test-artifact-3-0.1.pom │ │ │ ├── 1.5 │ │ │ │ ├── test-artifact-3-1.5.jar │ │ │ │ └── test-artifact-3-1.5.pom │ │ │ └── maven-metadata.xml │ │ │ └── test-artifact │ │ │ ├── 0.1 │ │ │ ├── test-artifact-0.1.jar │ │ │ └── test-artifact-0.1.pom │ │ │ ├── 0.5 │ │ │ ├── test-artifact-0.5.jar │ │ │ └── test-artifact-0.5.pom.xml │ │ │ ├── 1.0 │ │ │ ├── test-artifact-1.0.jar │ │ │ └── test-artifact-1.0.pom │ │ │ ├── 1.5 │ │ │ ├── test-artifact-1.5.jar │ │ │ └── test-artifact-1.5.pom │ │ │ ├── 2.0 │ │ │ ├── test-artifact-2.0.jar │ │ │ └── test-artifact-2.0.pom │ │ │ └── maven-metadata.xml │ ├── corda-updates-app-states │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ └── kotlin │ │ │ └── com │ │ │ └── r3 │ │ │ └── businessnetworks │ │ │ └── cordaupdates │ │ │ └── states │ │ │ └── ScheduleSyncState.kt │ ├── corda-updates-app │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── com │ │ │ │ └── r3 │ │ │ │ └── businessnetworks │ │ │ │ └── cordaupdates │ │ │ │ └── app │ │ │ │ ├── bno │ │ │ │ ├── DatabaseService.kt │ │ │ │ └── ReportCordappVersionFlowResponder.kt │ │ │ │ └── member │ │ │ │ ├── GetConfigurationFlow.kt │ │ │ │ ├── GetSyncedCordappsFlow.kt │ │ │ │ ├── MemberConfiguration.kt │ │ │ │ ├── ReportCordappVersionFlow.kt │ │ │ │ ├── SyncArtifactsFlow.kt │ │ │ │ └── SyncerService.kt │ │ │ └── test │ │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── r3 │ │ │ │ └── businessnetworks │ │ │ │ └── cordaupdates │ │ │ │ ├── app │ │ │ │ ├── ReloadConfigurationFlows.kt │ │ │ │ ├── ReportCordappVersionFlowTest.kt │ │ │ │ └── SyncArtifactsFlowTest.kt │ │ │ │ └── testextensions │ │ │ │ └── FlowOverrides.kt │ │ │ └── resources │ │ │ └── corda-updates-app.conf │ ├── corda-updates-core │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── com │ │ │ │ └── r3 │ │ │ │ └── businessnetworks │ │ │ │ └── cordaupdates │ │ │ │ └── core │ │ │ │ ├── CordaMavenResolver.kt │ │ │ │ └── CordappSyncer.kt │ │ │ └── test │ │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── r3 │ │ │ │ └── businessnetworks │ │ │ │ └── cordaupdates │ │ │ │ └── core │ │ │ │ ├── CordaMavenResolverTests.kt │ │ │ │ └── CordappSyncerTest.kt │ │ │ └── resources │ │ │ └── test-syncer-configuration.conf │ ├── corda-updates-test-utils │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ └── kotlin │ │ │ └── com │ │ │ └── r3 │ │ │ └── businessnetworks │ │ │ └── cordaupdates │ │ │ └── testutils │ │ │ └── RepoVerifier.kt │ ├── corda-updates-transport │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ └── kotlin │ │ │ │ └── com │ │ │ │ └── r3 │ │ │ │ └── businessnetworks │ │ │ │ └── cordaupdates │ │ │ │ └── transport │ │ │ │ ├── CordaTransporterFactory.kt │ │ │ │ ├── Transporters.kt │ │ │ │ └── flows │ │ │ │ ├── AbstractRepositoryHosterResponder.kt │ │ │ │ ├── GetResourceFlow.kt │ │ │ │ ├── PeekResourceFlow.kt │ │ │ │ ├── RepositoryHosterConfigurationService.kt │ │ │ │ └── Utils.kt │ │ │ └── test │ │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── r3 │ │ │ │ └── businessnetworks │ │ │ │ └── cordaupdates │ │ │ │ ├── testextensions │ │ │ │ ├── allowfilter │ │ │ │ │ └── FlowOverrides.kt │ │ │ │ └── denyfilter │ │ │ │ │ └── FlowOverrides.kt │ │ │ │ └── transport │ │ │ │ ├── MavenOverFlowsTests.kt │ │ │ │ ├── ReloadConfigurationFlow.kt │ │ │ │ └── VerifyMavenResourceURITests.kt │ │ │ └── resources │ │ │ ├── corda-updates-app-with-custom-repo-name.conf │ │ │ └── corda-updates-app.conf │ └── design │ │ ├── design.md │ │ └── resources │ │ ├── cds-as-cordapp-flows.png │ │ └── cds-as-cordapp-http.png ├── ledger-sync │ ├── design │ │ ├── design.md │ │ ├── ledger-sync-service.puml │ │ ├── resources │ │ │ ├── ledger-sync-service.svg │ │ │ └── ledger_sync.png │ │ └── websequencediagrams │ ├── ledger-sync-service │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── r3 │ │ │ │ │ └── businessnetworks │ │ │ │ │ └── ledgersync │ │ │ │ │ ├── EvaluateLedgerConsistencyFlow.kt │ │ │ │ │ ├── Helpers.kt │ │ │ │ │ ├── LedgerSyncAndRecoveryFlow.kt │ │ │ │ │ ├── RequestLedgersSyncFlow.kt │ │ │ │ │ └── TransactionRecoveryFlow.kt │ │ │ └── resources │ │ │ │ └── META-INF.services │ │ │ │ └── net.corda.core.serialization.SerializationWhitelist │ │ │ └── test │ │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── r3 │ │ │ │ └── businessnetworks │ │ │ │ └── ledgersync │ │ │ │ ├── BogusContract.kt │ │ │ │ ├── BogusFlow.kt │ │ │ │ ├── ConsistencyTests.kt │ │ │ │ ├── ConsistencyTestsWithVr.kt │ │ │ │ └── ConsistencyTestsWithoutVr.kt │ │ │ └── resources │ │ │ └── ledgersync.conf │ └── readme.rst ├── lib │ ├── README.txt │ └── quasar.jar └── memberships-management │ ├── README.md │ ├── design │ ├── design.md │ ├── resources │ │ ├── Membership_approval.png │ │ ├── Membership_request.png │ │ ├── Membership_revocation.png │ │ ├── Membership_snapshot_distribution.png │ │ └── Metadata_amendment.png │ └── wesequencediagrams │ ├── membership-service-contracts-and-states │ ├── build.gradle │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── com │ │ │ └── r3 │ │ │ └── businessnetworks │ │ │ └── membership │ │ │ └── states │ │ │ ├── Membership.kt │ │ │ └── Schemas.kt │ │ ├── resources │ │ └── migration │ │ │ ├── membership-state-schema-v1.changelog-init.xml │ │ │ ├── membership-state-schema-v1.changelog-master.xml │ │ │ ├── pending-membership-request-schema-v1.changelog-init.xml │ │ │ └── pending-membership-request-schema-v1.changelog-master.xml │ │ └── test │ │ └── kotlin │ │ └── com │ │ └── r3 │ │ └── businessnetworks │ │ └── membership │ │ └── states │ │ └── MembershipContractTest.kt │ ├── membership-service │ ├── build.gradle │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── com │ │ │ └── r3 │ │ │ └── businessnetworks │ │ │ └── membership │ │ │ └── flows │ │ │ ├── ConfigUtils.kt │ │ │ ├── Exceptions.kt │ │ │ ├── GenericsUtils.kt │ │ │ ├── bno │ │ │ ├── ActivateMembershipFlow.kt │ │ │ ├── AmendMembershipMetadataFlowResponder.kt │ │ │ ├── GetMembershipsFlowResponder.kt │ │ │ ├── NotifyMemberFlow.kt │ │ │ ├── RequestMembershipFlowResponder.kt │ │ │ ├── SelfIssueMembershipFlow.kt │ │ │ ├── SuspendMembershipFlow.kt │ │ │ ├── service │ │ │ │ ├── BNOConfigurationService.kt │ │ │ │ └── DatabaseService.kt │ │ │ └── support │ │ │ │ ├── BusinessNetworkOperatorFlowLogic.kt │ │ │ │ ├── BusinessNetworkOperatorInitiatedFlow.kt │ │ │ │ └── BusinessNetworkOperatorInitiatedFlowMembershipList.kt │ │ │ └── member │ │ │ ├── ActivateMembershipFlowResponder.kt │ │ │ ├── AmendMembershipMetadataFlow.kt │ │ │ ├── GetMembershipsFlow.kt │ │ │ ├── NotifyMembersFlowResponder.kt │ │ │ ├── RequestMembershipFlow.kt │ │ │ ├── SuspendMembershipFlowResponder.kt │ │ │ ├── Utils.kt │ │ │ ├── service │ │ │ ├── MemberConfigurationService.kt │ │ │ └── MembershipsCache.kt │ │ │ └── support │ │ │ ├── BusinessNetworkAwareInitiatedFlow.kt │ │ │ └── BusinessNetworkAwareInitiatingFlow.kt │ │ └── test │ │ ├── kotlin │ │ └── com │ │ │ └── r3 │ │ │ └── businessnetworks │ │ │ └── membership │ │ │ ├── flows │ │ │ ├── AbstractFlowTest.kt │ │ │ ├── ActivateMembershipFlowTest.kt │ │ │ ├── AmendMembershipMetadataFlowTest.kt │ │ │ ├── BusinessNetworkAwareInitiatedFlowTest.kt │ │ │ ├── FullBNMSFlowDemo.kt │ │ │ ├── GetMembershipsFlowTest.kt │ │ │ ├── MultipleBusinessNetworksTest.kt │ │ │ ├── RequestMembershipFlowTest.kt │ │ │ ├── SelfIssueMembershipFlowTest.kt │ │ │ ├── SuspendMembershipFlowTest.kt │ │ │ └── service │ │ │ │ └── MembershipsCacheTest.kt │ │ │ └── testextensions │ │ │ ├── AmendMembershipMetadataFlowResponderWithCustomVerification.kt │ │ │ ├── AutoApprovingMembershipFlow.kt │ │ │ └── RequestMembershipFlowResponderWithMetadataVerification.kt │ │ └── resources │ │ ├── membership-service-without-bno-whitelist.conf │ │ └── membership-service.conf │ └── test-utils │ ├── build.gradle │ └── src │ └── main │ └── kotlin │ └── com │ └── r3 │ └── bno │ └── testing │ └── SimpleMetaData.kt ├── build.gradle ├── docs ├── .gitignore ├── Makefile ├── README.md ├── build-docs.sh ├── build.gradle ├── ext │ └── conditional_toctree.py ├── index.html ├── install-docsite-requirements.sh ├── make-docsite.sh ├── requirements.txt └── source │ ├── .gitignore │ ├── _static │ ├── codesets.js │ ├── css │ │ └── custom.css │ ├── favicon.ico │ ├── images │ │ └── fg002_corda_w3.png │ ├── irs.png │ └── versions │ ├── _templates │ ├── layout.html │ └── layout_for_doc_website.html │ ├── business-networks │ ├── business-network-operator-node.rst │ ├── business-network-playbook │ │ ├── governance.rst │ │ ├── intro.rst │ │ ├── operations.rst │ │ └── structure.rst │ ├── how-do-business-networks-start.rst │ ├── interoperability.rst │ ├── intro.rst │ ├── resources │ │ ├── bno1.png │ │ └── interop.png │ ├── roles-and-responsibilities.rst │ └── what-is-a-business-network.rst │ ├── conf.py │ ├── corda-modelling-notation │ ├── complexity │ │ ├── complexity-commands-coupling.rst │ │ ├── complexity-flow-coupling.rst │ │ ├── complexity-linearid-coupling.rst │ │ ├── complexity-overview.rst │ │ └── complexity-stateref-coupling.rst │ ├── high-level-architecture │ │ ├── arch-corda-network.rst │ │ ├── arch-high_level_process.rst │ │ └── arch-overview.rst │ ├── overview │ │ ├── overview-aims.rst │ │ ├── overview-complexity.rst │ │ ├── overview-overview.rst │ │ ├── overview-privacy.rst │ │ ├── overview-views.rst │ │ └── overview-whycdl.rst │ ├── privacy │ │ ├── privacy-analysing.rst │ │ ├── privacy-expressing-requirements.rst │ │ ├── privacy-overview.rst │ │ └── privacy-why-model.rst │ ├── resources │ │ ├── arch │ │ │ ├── CMN2_HLA_Corda_network.png │ │ │ └── CMN2_HLA_High_level_process.png │ │ ├── complexity │ │ │ ├── CMN2_C_Command_coupling_1.png │ │ │ ├── CMN2_C_Command_coupling_2.png │ │ │ ├── CMN2_C_Linearid-coupling-attachment-state.png │ │ │ └── CMN2_C_Linearid_coupling_state_instance.png │ │ ├── old │ │ │ ├── CMN_Agreement_example.png │ │ │ ├── CMN_Attachment_reference_example.png │ │ │ ├── CMN_Attachment_state_example.png │ │ │ ├── CMN_BPMN.png │ │ │ ├── CMN_BPMN_high_level.png │ │ │ ├── CMN_Cash_example.png │ │ │ ├── CMN_Cordapp_split.png │ │ │ ├── CMN_Coupling_commands_dig1.png │ │ │ ├── CMN_Coupling_commands_dig2.png │ │ │ ├── CMN_Coupling_full_example.png │ │ │ ├── CMN_Full_sequence.png │ │ │ ├── CMN_Instance_view.png │ │ │ ├── CMN_Instance_view_arrows.png │ │ │ ├── CMN_Multiplicity_constraints.png │ │ │ ├── CMN_Reduced_sequence.png │ │ │ ├── CMN_Reduced_sequence_with_arrows.png │ │ │ ├── CMN_Required_signers.png │ │ │ ├── CMN_Transaction_constraints.png │ │ │ ├── CMN_Transaction_equivalent.png │ │ │ ├── CMN_Transaction_instance.png │ │ │ ├── CMN_Transaction_instance_with_arrows.png │ │ │ ├── CMN_Visibility_constraint.png │ │ │ ├── CMN_example.png │ │ │ └── CMN_refined_box.png │ │ ├── overview │ │ │ ├── CMN2_O_BPMN_example.png │ │ │ ├── CMN2_O_FS_example.png │ │ │ ├── CMN2_O_Layers.png │ │ │ ├── CMN2_O_SE_example.png │ │ │ ├── CMN2_O_SI_example.png │ │ │ ├── CMN2_O_SM_example.png │ │ │ ├── CMN2_O_State.png │ │ │ └── CMN2_O_TI_example.png │ │ ├── privacy │ │ │ ├── CMN2_P_Example_all_parties.png │ │ │ ├── CMN2_P_Example_partyD.png │ │ │ ├── CMN2_P_Example_state_evolution.png │ │ │ ├── CMN2_P_Example_state_machines.png │ │ │ ├── CMN2_P_privacy_map.png │ │ │ ├── CMN2_P_privacy_map.xlsx │ │ │ ├── CMN2_P_privacy_map_bond_cash.png │ │ │ └── ~$CMN2_P_privacy_map.xlsx │ │ └── views │ │ │ ├── CDL_SE_Branching_transition.png │ │ │ ├── CDL_SE_Reference_state.png │ │ │ ├── CMN2_BPMN_Bpmn_example.png │ │ │ ├── CMN2_BPMN_High_level.png │ │ │ ├── CMN2_Degraded_state.png │ │ │ ├── CMN2_FS_Long.png │ │ │ ├── CMN2_FS_Plantuml_example.png │ │ │ ├── CMN2_FS_Short.png │ │ │ ├── CMN2_SE_State_evolution.png │ │ │ ├── CMN2_SE_Transaction_box.png │ │ │ ├── CMN2_SI_State_instance.png │ │ │ ├── CMN2_SM_Cash_example.png │ │ │ ├── CMN2_SM_Full_example.png │ │ │ ├── CMN2_SM_Multiplicity_constraints.png │ │ │ ├── CMN2_SM_Signing_constraints_box.png │ │ │ ├── CMN2_SM_Signing_constraints_inline.png │ │ │ ├── CMN2_SM_Simplified_example.png │ │ │ ├── CMN2_SM_State_level_constraints.png │ │ │ ├── CMN2_SM_Transaction_equivalent.png │ │ │ ├── CMN2_SM_Transaction_level_constraints.png │ │ │ ├── CMN2_SM_Visibility_constraints.png │ │ │ ├── CMN2_State.png │ │ │ └── CMN2_TI_Transaction_example.png │ ├── todo.txt │ └── views │ │ ├── views-bpmn.rst │ │ ├── views-common-concepts.rst │ │ ├── views-flow-sequence.rst │ │ ├── views-overview.rst │ │ ├── views-state-evolution.rst │ │ ├── views-state-instance.rst │ │ ├── views-state-machine.rst │ │ └── views-transaction-instance.rst │ ├── deployment │ ├── intro.rst │ ├── kubernetes │ │ ├── architecture-overview.rst │ │ ├── considerations.rst │ │ ├── corda-kubernetes-deployment.rst │ │ ├── intro.rst │ │ ├── prerequisites.rst │ │ └── resources │ │ │ └── KubernetesDeploymentArchitecture.png │ └── onprem │ │ ├── additional-info.rst │ │ ├── bank-deploy-overview.rst │ │ ├── concepts-background-information.rst │ │ ├── corda-health-checker.rst │ │ ├── corda-network-access-details.rst │ │ ├── corda-node-architecture-components.rst │ │ ├── flagdays.rst │ │ ├── intro.rst │ │ ├── kill-flow.rst │ │ ├── monitoring.rst │ │ ├── node-firewall-deployment.rst │ │ ├── node-registration.rst │ │ ├── prerequisites-sizing.rst │ │ ├── resources │ │ ├── CordaFirewallConfigAlign.png │ │ ├── access.conf │ │ ├── bridge.conf │ │ ├── config.png │ │ ├── cordadir.png │ │ ├── cordarch.png │ │ ├── firewallpki.png │ │ ├── float.conf │ │ ├── ha.png │ │ ├── node.conf │ │ ├── nodebridgefloat.png │ │ ├── nodebridgefloat_nbrs.png │ │ ├── nodefull.conf │ │ ├── nodereg.png │ │ ├── nodestart.conf │ │ ├── nodestart.png │ │ ├── nonha.png │ │ ├── overview.png │ │ ├── pki-keys.conf │ │ ├── platform.png │ │ ├── registration.png │ │ ├── socks.conf │ │ ├── squidconfig.conf │ │ ├── squidstatus.conf │ │ ├── subzone.png │ │ ├── vault-relations.png │ │ └── vault.png │ │ └── start-components.rst │ ├── design-patterns │ ├── antipatterns │ │ ├── antipatterns-overview.rst │ │ ├── check-ownership-of-all-input-states.rst │ │ ├── dual-roles-for-nodes.rst │ │ └── unknown-commands.rst │ └── patterns │ │ ├── WIP │ │ ├── asset-lock-pattern.rst │ │ ├── asset-lock.rst │ │ ├── billing-with-receipts.rst │ │ ├── business-pattern.rst │ │ ├── design-principles.rst │ │ ├── propose-agree.rst │ │ ├── ref-states.rst │ │ ├── request-tree.rst │ │ ├── resources │ │ │ ├── Asset-Lock-option-1.png │ │ │ ├── Asset-Lock-option-2.png │ │ │ ├── Asset-Lock-option-3.png │ │ │ ├── Asset-Lock-option-4.png │ │ │ ├── Billing-State-evolution-diagram-v2.png │ │ │ ├── Billing-State-evolution-diagram-v3.png │ │ │ ├── Billing-state-with-combine-v2.png │ │ │ ├── Pattern-relationships.png │ │ │ ├── Propose-agree.png │ │ │ ├── Request-tree.png │ │ │ ├── propose-lock-pay-1.jpg │ │ │ ├── propose-lock-pay-2.jpg │ │ │ ├── propose-lock-pay-3.jpg │ │ │ └── propose-lock-pay-4.jpg │ │ ├── template.rst │ │ └── wip-overview.rst │ │ ├── patterns-overview.rst │ │ ├── receipts.rst │ │ ├── resources │ │ ├── P_Receipts_state_evolution.png │ │ └── P_Token_receipts_state_evolution.png │ │ └── token-receipts.rst │ ├── designs │ ├── business-networks-membership-service.rst │ ├── ledger-synchronisation-service.rst │ └── resources │ │ ├── Membership_approval.png │ │ ├── Membership_request.png │ │ ├── Membership_revocation.png │ │ ├── Membership_snapshot_distribution.png │ │ ├── Metadata_amendment.png │ │ └── ledger_sync.png │ ├── faq.rst │ └── index.rst ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # List of Contributors 2 | 3 | We'd like to thank the following people for their contributions to the Corda 4 | Solutions material. We have had huge amounts of help in producing and reviewing 5 | concepts and their implementations. 6 | 7 | Over time some people will have moved to different organisations but we have 8 | tried to represent who they were with at the time of any contributions. 9 | 10 | Please forgive any omissions, and create a pull request, or email , 11 | if you wish to see changes to this list. 12 | 13 | * Alex Koller (R3) 14 | * Clinton Alexander (R3) 15 | * Cristina Buendia (R3) 16 | * Dave Hudson (R3) 17 | * Guy Hochstetler (R3) 18 | * Henrik Carlström (R3) 19 | * Ivan Schasny (R3) 20 | * Mark Raynes (R3) 21 | * Matt Bradbury (R3) 22 | * Matt Layton (Trade IX) 23 | * Mike Hearn (R3) 24 | * Moritz Platt (R3) 25 | * Nigel King (R3) 26 | 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Corda Solutions 2 | 3 | Corda Solutions provides ideas and guidance around solving problems with Corda. The git repo and the associated website offer code and documentation that offer ideas for building and deploying Corda applications. 4 | 5 | Please see [bn-apps](./bn-apps) folder for *Business Networks Toolkit* and [docs](./docs) folder for [solutions.corda.net](http://solutions.corda.net) sources. 6 | 7 | ## Useful Links 8 | 9 | * [Corda Website](http://corda.net) 10 | * [Corda Documentation](http://docs.corda.net) 11 | * [R3 Corda Enterprise Documentation](http://docs.corda.r3.com) 12 | * [Corda Solutions Website](http://solutions.corda.net) -------------------------------------------------------------------------------- /bn-apps/LICENCE: -------------------------------------------------------------------------------- 1 | Copyright 2016, R3 Limited. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /bn-apps/README.md: -------------------------------------------------------------------------------- 1 | Business Networks Toolkit 2 | ================================== 3 | 4 | This repository contains reference implementations of CorDapps that enable Business Networks on Corda. 5 | 6 | Contents: 7 | * [~~Business Networks Membership Service~~](./memberships-management) (deprecated) allows maintaining a business network 8 | * [Ledger Sync Service](./ledger-sync) is a collection of flows, designed to check ledger integrity and to recover lost data from counterparts. 9 | * [CorDapp Distribution Service](./cordapp-updates-distribution) allows Business Network Operators to distribute CorDapp updates to their network participants. 10 | * [Billing Service](./billing) can be used to implement billing and metering on Business Networks. 11 | -------------------------------------------------------------------------------- /bn-apps/TRADEMARK: -------------------------------------------------------------------------------- 1 | Corda and the Corda logo are trademarks of R3CEV LLC and its affiliates. All rights reserved. 2 | 3 | For R3CEV LLC's trademark and logo usage information, please consult our Trademark Usage Policy at 4 | https://www.r3.com/trademark-policy/. 5 | -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'kotlin' 2 | apply plugin: 'net.corda.plugins.cordapp' 3 | apply plugin: 'net.corda.plugins.cordformation' 4 | apply plugin: 'net.corda.plugins.quasar-utils' 5 | 6 | cordapp { 7 | targetPlatformVersion 4 8 | minimumPlatformVersion 4 9 | workflow { 10 | name "billing-app" 11 | vendor "com.r3" 12 | licence "http://www.apache.org/licenses/LICENSE-2.0" 13 | versionId 1 14 | } 15 | signing { 16 | enabled false 17 | } 18 | } 19 | 20 | sourceSets { 21 | main { 22 | resources { 23 | srcDir "config/dev" 24 | } 25 | } 26 | test { 27 | resources { 28 | srcDir "config/test" 29 | } 30 | } 31 | } 32 | 33 | dependencies { 34 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 35 | compile project(":bn-apps:businessnetworks-utilities") 36 | testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" 37 | testCompile "junit:junit:$junit_version" 38 | 39 | // Corda integration dependencies 40 | cordaCompile "$corda_release_group:corda-core:$corda_release_version" 41 | cordaCompile "$corda_release_group:corda-rpc:$corda_release_version" 42 | cordaCompile "$corda_release_group:corda-node-api:$corda_release_version" 43 | cordaRuntime "$corda_release_group:corda:$corda_release_version" 44 | testCompile "$corda_release_group:corda-node-driver:$corda_release_version" 45 | testCompile project(":bn-apps:businessnetworks-test-utilities") 46 | 47 | cordapp project(":bn-apps:billing:billing-contracts-and-states") 48 | } 49 | 50 | tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { 51 | kotlinOptions { 52 | languageVersion = "1.2" 53 | apiVersion = "1.2" 54 | jvmTarget = "1.8" 55 | javaParameters = true // Useful for reflection. 56 | } 57 | } 58 | 59 | task testJar(type: Jar) { 60 | classifier = 'tests' 61 | from sourceSets.test.output 62 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/src/main/kotlin/com/r3/businessnetworks/billing/flows/Constants.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.flows 2 | 3 | import net.corda.core.utilities.seconds 4 | 5 | object Constants { 6 | /** 7 | * Default time tolerance that is used for transaction time windows 8 | */ 9 | val TIME_TOLERANCE = 60.seconds 10 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/src/main/kotlin/com/r3/businessnetworks/billing/flows/bno/responders/AttachUnspentChipsResponder.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.flows.bno.responders 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.billing.flows.member.AttachUnspentChipsFlow 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.flows.FlowSession 7 | import net.corda.core.flows.InitiatedBy 8 | import net.corda.core.flows.ReceiveFinalityFlow 9 | 10 | @InitiatedBy(AttachUnspentChipsFlow::class) 11 | class AttachUnspentChipsResponder(private val session: FlowSession) : FlowLogic() { 12 | @Suspendable 13 | override fun call() { 14 | // nothing to verify here 15 | subFlow(ReceiveFinalityFlow(session)) 16 | } 17 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/src/main/kotlin/com/r3/businessnetworks/billing/flows/bno/responders/ChipOffBillingStateFlowResponder.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.flows.bno.responders 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.billing.flows.member.ChipOffBillingStateFlow 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.flows.FlowSession 7 | import net.corda.core.flows.InitiatedBy 8 | import net.corda.core.flows.ReceiveFinalityFlow 9 | 10 | @InitiatedBy(ChipOffBillingStateFlow::class) 11 | class ChipOffBillingStateFlowResponder(private val session : FlowSession) : FlowLogic() { 12 | @Suspendable 13 | override fun call() { 14 | // we have nothing to check here 15 | subFlow(ReceiveFinalityFlow(session)) 16 | } 17 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/src/main/kotlin/com/r3/businessnetworks/billing/flows/bno/responders/ReturnBillingStateFlowResponder.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.flows.bno.responders 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.billing.flows.member.ReturnBillingStateFlow 5 | import com.r3.businessnetworks.billing.states.BillingContract 6 | import com.r3.businessnetworks.billing.states.BillingState 7 | import net.corda.core.flows.FlowException 8 | import net.corda.core.flows.FlowLogic 9 | import net.corda.core.flows.FlowSession 10 | import net.corda.core.flows.InitiatedBy 11 | import net.corda.core.flows.ReceiveFinalityFlow 12 | import net.corda.core.flows.SignTransactionFlow 13 | import net.corda.core.transactions.SignedTransaction 14 | 15 | @InitiatedBy(ReturnBillingStateFlow::class) 16 | open class ReturnBillingStateFlowResponder(private val session : FlowSession) : FlowLogic() { 17 | @Suspendable 18 | override fun call() { 19 | val stx = subFlow(object : SignTransactionFlow(session) { 20 | override fun checkTransaction(stx : SignedTransaction) = verifyTransaction(stx) 21 | }) 22 | // nothing to verify here 23 | subFlow(ReceiveFinalityFlow(session, stx.id)) 24 | } 25 | 26 | 27 | protected open fun verifyTransaction(stx : SignedTransaction) { 28 | val ledgerTx = stx.toLedgerTransaction(serviceHub, checkSufficientSignatures = false) 29 | ledgerTx.verify() 30 | val command = stx.tx.commands.single() 31 | if (command.value !is BillingContract.Commands.Return) throw FlowException("Wrong command") 32 | 33 | val inputBillingState = ledgerTx.inputStates.single() as BillingState 34 | if (inputBillingState.issuer != ourIdentity) throw FlowException("Wrong issuer") 35 | } 36 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/src/main/kotlin/com/r3/businessnetworks/billing/flows/bno/service/BNOBillingDatabaseService.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.flows.bno.service 2 | 3 | import com.r3.businessnetworks.billing.states.BillingState 4 | import com.r3.businessnetworks.billing.states.BillingStateSchemaV1 5 | import com.r3.businessnetworks.billing.states.BillingStateStatus 6 | import net.corda.core.contracts.StateAndRef 7 | import net.corda.core.identity.Party 8 | import net.corda.core.node.AppServiceHub 9 | import net.corda.core.node.services.CordaService 10 | import net.corda.core.node.services.queryBy 11 | import net.corda.core.node.services.vault.Builder.equal 12 | import net.corda.core.node.services.vault.QueryCriteria 13 | import net.corda.core.serialization.SingletonSerializeAsToken 14 | 15 | /** 16 | * Service that simplifies vault queries 17 | */ 18 | @CordaService 19 | class BNOBillingDatabaseService(private val appServiceHub : AppServiceHub) : SingletonSerializeAsToken(){ 20 | fun getBillingStatesByOwnerAndStatus(owner : Party, status : BillingStateStatus) : List> { 21 | val ownerCriteria = 22 | BillingStateSchemaV1.PersistentBillingState::owner.equal(owner) 23 | val statusCriteria = 24 | BillingStateSchemaV1.PersistentBillingState::status.equal(status) 25 | return appServiceHub.vaultService.queryBy(QueryCriteria.VaultCustomQueryCriteria(ownerCriteria) 26 | .and(QueryCriteria.VaultCustomQueryCriteria(statusCriteria))).states 27 | } 28 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/src/main/kotlin/com/r3/businessnetworks/billing/flows/bno/service/BNOConfigurationService.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.flows.bno.service 2 | 3 | import com.r3.businessnetworks.utilities.AbstractConfigurationService 4 | import net.corda.core.identity.CordaX500Name 5 | import net.corda.core.node.AppServiceHub 6 | import net.corda.core.node.services.CordaService 7 | 8 | /** 9 | * Configuration for Business Network Operators 10 | */ 11 | @CordaService 12 | class BNOConfigurationService(appServiceHub : AppServiceHub) : AbstractConfigurationService(appServiceHub, "billing-app") { 13 | override fun bnoName() : CordaX500Name = throw NotImplementedError("This method should not be used") 14 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/src/main/kotlin/com/r3/businessnetworks/billing/flows/member/responders/CloseBillingStateFlowResponder.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.flows.member.responders 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.billing.flows.bno.CloseBillingStateFlow 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.flows.FlowSession 7 | import net.corda.core.flows.InitiatedBy 8 | import net.corda.core.flows.ReceiveFinalityFlow 9 | 10 | @InitiatedBy(CloseBillingStateFlow::class) 11 | class CloseBillingStateFlowResponder(private val session : FlowSession) : FlowLogic() { 12 | @Suspendable 13 | override fun call() { 14 | //nothing to verify here 15 | subFlow(ReceiveFinalityFlow(session)) 16 | } 17 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/src/main/kotlin/com/r3/businessnetworks/billing/flows/member/responders/IssueBillingStateFlowResponder.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.flows.member.responders 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.billing.flows.bno.IssueBillingStateFlow 5 | import com.r3.businessnetworks.billing.states.BillingContract 6 | import com.r3.businessnetworks.billing.states.BillingState 7 | import net.corda.core.flows.FlowException 8 | import net.corda.core.flows.FlowLogic 9 | import net.corda.core.flows.FlowSession 10 | import net.corda.core.flows.InitiatedBy 11 | import net.corda.core.flows.ReceiveFinalityFlow 12 | import net.corda.core.flows.SignTransactionFlow 13 | import net.corda.core.transactions.SignedTransaction 14 | 15 | @InitiatedBy(IssueBillingStateFlow::class) 16 | open class IssueBillingStateFlowResponder(private val session : FlowSession) : FlowLogic() { 17 | 18 | @Suspendable 19 | override fun call() { 20 | val signResponder = object : SignTransactionFlow(session) { 21 | @Suspendable 22 | override fun checkTransaction(stx : SignedTransaction) = verifyTransaction(stx) 23 | } 24 | val stx = subFlow(signResponder) 25 | subFlow(ReceiveFinalityFlow(session, stx.id)) 26 | } 27 | 28 | protected open fun verifyTransaction(stx : SignedTransaction) { 29 | stx.toLedgerTransaction(serviceHub, checkSufficientSignatures = false).verify() 30 | val billingState = stx.tx.outputStates.single() as BillingState 31 | if (billingState.owner != ourIdentity) throw FlowException("Wrong owner") 32 | if (stx.tx.commands.single().value !is BillingContract.Commands.Issue) throw FlowException("Wrong command") 33 | } 34 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/src/main/kotlin/com/r3/businessnetworks/billing/flows/member/responders/RequestReturnOfBillingStateFlowResponder.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.flows.member.responders 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.billing.flows.bno.RequestReturnOfBillingStateFlow 5 | import com.r3.businessnetworks.billing.flows.bno.ReturnRequest 6 | import com.r3.businessnetworks.billing.flows.member.AttachUnspentChipsAndReturnBillingStateFlow 7 | import com.r3.businessnetworks.billing.flows.member.service.MemberBillingDatabaseService 8 | import com.r3.businessnetworks.billing.states.BillingStateStatus 9 | import net.corda.core.flows.FlowException 10 | import net.corda.core.flows.FlowLogic 11 | import net.corda.core.flows.FlowSession 12 | import net.corda.core.flows.InitiatedBy 13 | import net.corda.core.utilities.unwrap 14 | 15 | /** 16 | * Responder to [RequestReturnOfBillingStateFlow]. 17 | * Verifies received return request, attaches all unspent [BillingChipState]s and returns the [BillingState] to the issuer. 18 | */ 19 | @InitiatedBy(RequestReturnOfBillingStateFlow::class) 20 | class RequestReturnOfBillingStateFlowResponder(private val session : FlowSession) : FlowLogic() { 21 | @Suspendable 22 | override fun call() { 23 | val billingState = session.receive().unwrap { 24 | val databaseService = serviceHub.cordaService(MemberBillingDatabaseService::class.java) 25 | val billingState = databaseService.getBillingStateByLinearId(it.billingStateLinearId) 26 | if (billingState == null || billingState.state.data.issuer != session.counterparty) 27 | throw FlowException("No BillingState has been found for linearId=${it.billingStateLinearId} and issuer=${session.counterparty}") 28 | if (billingState.state.data.status != BillingStateStatus.ACTIVE) 29 | throw FlowException("Only active states can be returned") 30 | billingState 31 | }!! 32 | subFlow(AttachUnspentChipsAndReturnBillingStateFlow(billingState)) 33 | } 34 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/src/main/kotlin/com/r3/businessnetworks/billing/flows/member/responders/RevokeBillingStateFlowResponder.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.flows.member.responders 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.billing.flows.bno.RevokeBillingStateFlow 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.flows.FlowSession 7 | import net.corda.core.flows.InitiatedBy 8 | import net.corda.core.flows.ReceiveFinalityFlow 9 | 10 | @InitiatedBy(RevokeBillingStateFlow::class) 11 | class RevokeBillingStateFlowResponder(val session : FlowSession) : FlowLogic() { 12 | @Suspendable 13 | override fun call() { 14 | // nothing to check here 15 | subFlow(ReceiveFinalityFlow(session)) 16 | } 17 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/src/main/kotlin/com/r3/businessnetworks/billing/flows/member/service/MemberConfigurationService.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.flows.member.service 2 | 3 | import com.r3.businessnetworks.utilities.AbstractConfigurationService 4 | import net.corda.core.identity.CordaX500Name 5 | import net.corda.core.node.AppServiceHub 6 | import net.corda.core.node.services.CordaService 7 | 8 | /** 9 | * Configuration for members 10 | */ 11 | @CordaService 12 | class MemberConfigurationService(appServiceHub : AppServiceHub) : AbstractConfigurationService(appServiceHub, "billing-app") { 13 | override fun bnoName() : CordaX500Name = throw NotImplementedError("This method should not be used") 14 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/src/test/kotlin/com/r3/businessnetworks/billing/flows/bno/CloseBillingStateFlowTest.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.flows.bno 2 | 3 | import com.r3.businessnetworks.billing.states.BillingState 4 | import com.r3.businessnetworks.billing.states.BillingStateStatus 5 | import com.r3.businessnetworks.testutilities.AbstractBusinessNetworksFlowTest 6 | import com.r3.businessnetworks.testutilities.identity 7 | import net.corda.core.node.services.queryBy 8 | import org.junit.Test 9 | import kotlin.test.assertEquals 10 | 11 | class CloseBillingStateFlowTest : AbstractBusinessNetworksFlowTest(1, 1, 12 | listOf("com.r3.businessnetworks.billing.flows", "com.r3.businessnetworks.billing.states")) { 13 | private fun bnoNode() = bnoNodes.single() 14 | private fun participantNode() = participantsNodes.first() 15 | 16 | @Test 17 | fun `test close billing state flow`() { 18 | // issuing and revoking billing state 19 | runFlowAndReturn(bnoNode(), IssueBillingStateFlow(participantNode().identity(), 10L)) 20 | runFlowAndReturn(bnoNode(), RevokeBillingStatesForPartyFlow(participantNode().identity())) 21 | 22 | // closing the revoked state 23 | val revokedBillingState = bnoNode().services.vaultService.queryBy().states.single() 24 | runFlowAndReturn(bnoNode(), CloseBillingStateFlow(revokedBillingState)) 25 | 26 | val closedBillingState = bnoNode().services.vaultService.queryBy().states.single() 27 | assertEquals(BillingStateStatus.CLOSED, closedBillingState.state.data.status) 28 | } 29 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/src/test/kotlin/com/r3/businessnetworks/billing/flows/bno/IssueBillingStateFlowTest.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.flows.bno 2 | 3 | import com.r3.businessnetworks.billing.states.BillingState 4 | import com.r3.businessnetworks.testutilities.AbstractBusinessNetworksFlowTest 5 | import com.r3.businessnetworks.testutilities.identity 6 | import net.corda.core.contracts.StateAndRef 7 | import net.corda.core.node.services.queryBy 8 | import net.corda.testing.node.StartedMockNode 9 | import org.junit.Test 10 | import java.time.Instant 11 | import kotlin.test.assertEquals 12 | 13 | class IssueBillingStateFlowTest : AbstractBusinessNetworksFlowTest( 14 | numberOfBusinessNetworks = 1, 15 | numberOfParticipants = 1, 16 | cordappPackages = listOf( 17 | "com.r3.businessnetworks.billing.flows", 18 | "com.r3.businessnetworks.billing.states") 19 | ) { 20 | 21 | private fun bnoNode() = bnoNodes.single() 22 | private fun participantNode() = participantsNodes.single() 23 | 24 | @Test 25 | fun `test issue`() { 26 | val amount = 100L 27 | val expiryDate = Instant.now() 28 | 29 | runFlowAndReturn(bnoNode(), IssueBillingStateFlow(participantNode().identity(), amount, expiryDate)) 30 | 31 | val vaultBillingState = getBillingStates(participantNode()).single() 32 | assertEquals(amount, vaultBillingState.state.data.issued) 33 | assertEquals(participantNode().identity(), vaultBillingState.state.data.owner) 34 | assertEquals(bnoNode().identity(), vaultBillingState.state.data.issuer) 35 | assertEquals(expiryDate, vaultBillingState.state.data.expiryDate) 36 | } 37 | 38 | private fun getBillingStates(node : StartedMockNode) : List> = 39 | node.services.vaultService.queryBy().states 40 | 41 | } 42 | 43 | 44 | -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/src/test/kotlin/com/r3/businessnetworks/billing/flows/bno/RequestReturnOfBillingStateFlowTest.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.flows.bno 2 | 3 | import com.r3.businessnetworks.billing.flows.member.ChipOffBillingStateFlow 4 | import com.r3.businessnetworks.billing.states.BillingState 5 | import com.r3.businessnetworks.billing.states.BillingStateStatus 6 | import com.r3.businessnetworks.testutilities.AbstractBusinessNetworksFlowTest 7 | import com.r3.businessnetworks.testutilities.identity 8 | import net.corda.core.node.services.queryBy 9 | import org.junit.Test 10 | import kotlin.test.assertEquals 11 | 12 | class RequestReturnOfBillingStateFlowTest : AbstractBusinessNetworksFlowTest(1, 1, 13 | listOf("com.r3.businessnetworks.billing.flows", "com.r3.businessnetworks.billing.states")) { 14 | 15 | private fun bnoNode() = bnoNodes.single() 16 | private fun participantNode() = participantsNodes.single() 17 | 18 | @Test 19 | fun `happy path`() { 20 | runFlowAndReturn(bnoNode(), IssueBillingStateFlow(participantNode().identity(), 10L)) 21 | val billingState = participantNode().services.vaultService.queryBy().states.single() 22 | runFlowAndReturn(participantNode(), ChipOffBillingStateFlow(billingState, 1L, 3)) 23 | runFlowAndReturn(bnoNode(), RequestReturnOfBillingStateForPartyFlow(participantNode().identity())) 24 | val billingStateAfterReturn = participantNode().services.vaultService.queryBy().states.single() 25 | assertEquals(0L, billingStateAfterReturn.state.data.spent) 26 | assertEquals(BillingStateStatus.RETURNED, billingStateAfterReturn.state.data.status) 27 | } 28 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-app/src/test/resources/billing-app.conf: -------------------------------------------------------------------------------- 1 | notaryName = "O=Notary,L=London,C=GB" 2 | bnoName = "O=BNO_0,L=New York,C=US" -------------------------------------------------------------------------------- /bn-apps/billing/billing-contracts-and-states/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version" 4 | } 5 | } 6 | 7 | apply plugin: 'kotlin' 8 | apply plugin: 'net.corda.plugins.cordapp' 9 | apply plugin: 'net.corda.plugins.cordformation' 10 | apply plugin: 'net.corda.plugins.quasar-utils' 11 | apply plugin: "kotlin-jpa" 12 | 13 | cordapp { 14 | targetPlatformVersion 4 15 | minimumPlatformVersion 4 16 | workflow { 17 | name "billing-contracts-and-states" 18 | vendor "com.r3" 19 | licence "http://www.apache.org/licenses/LICENSE-2.0" 20 | versionId 1 21 | } 22 | signing { 23 | enabled false 24 | } 25 | } 26 | 27 | sourceSets { 28 | main { 29 | resources { 30 | srcDir "config/dev" 31 | } 32 | } 33 | test { 34 | resources { 35 | srcDir "config/test" 36 | } 37 | } 38 | } 39 | 40 | dependencies { 41 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 42 | testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" 43 | testCompile "junit:junit:$junit_version" 44 | 45 | // Corda integration dependencies 46 | cordaCompile "$corda_release_group:corda-core:$corda_release_version" 47 | cordaCompile "$corda_release_group:corda-rpc:$corda_release_version" 48 | cordaCompile "$corda_release_group:corda-node-api:$corda_release_version" 49 | cordaRuntime "$corda_release_group:corda:$corda_release_version" 50 | testCompile "$corda_release_group:corda-node-driver:$corda_release_version" 51 | } 52 | 53 | tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { 54 | kotlinOptions { 55 | languageVersion = "1.2" 56 | apiVersion = "1.2" 57 | jvmTarget = "1.8" 58 | javaParameters = true // Useful for reflection. 59 | } 60 | } 61 | 62 | task testJar(type: Jar) { 63 | classifier = 'tests' 64 | from sourceSets.test.output 65 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-contracts-and-states/src/main/kotlin/com/r3/businessnetworks/billing/states/Schemas.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.states 2 | 3 | import net.corda.core.identity.Party 4 | import net.corda.core.schemas.MappedSchema 5 | import net.corda.core.schemas.PersistentState 6 | import net.corda.core.serialization.CordaSerializable 7 | import javax.persistence.Column 8 | import javax.persistence.Entity 9 | import javax.persistence.Table 10 | 11 | @CordaSerializable 12 | object BillingStateSchemaV1 : MappedSchema(schemaFamily = BillingState::class.java, version = 1, mappedTypes = listOf(PersistentBillingState::class.java)) { 13 | @Entity 14 | @Table(name = "billing_states") 15 | class PersistentBillingState ( 16 | @Column(name = "issuer") 17 | var issuer: Party, 18 | @Column(name = "owner") 19 | var owner : Party, 20 | @Column(name = "status") 21 | var status : BillingStateStatus, 22 | @Column(name = "externalId", nullable = true) 23 | var externalId : String?) : PersistentState() 24 | 25 | override val migrationResource = "billing.changelog-master.xml" 26 | } 27 | 28 | @CordaSerializable 29 | object BillingChipStateSchemaV1 : MappedSchema(schemaFamily = BillingChipState::class.java, version = 1, mappedTypes = listOf(PersistentBillingChipState::class.java)) { 30 | @Entity 31 | @Table(name = "billing_chip_states") 32 | class PersistentBillingChipState ( 33 | @Column(name = "issuer") 34 | var issuer: Party, 35 | @Column(name = "owner") 36 | var owner: Party, 37 | @Column(name = "amount") 38 | var amount: Long, 39 | @Column(name = "billing_state_linear_id") 40 | var billingStateLinearId: String) : PersistentState() 41 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-contracts-and-states/src/resources/billing.changelog-master.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /bn-apps/billing/billing-contracts-and-states/src/resources/migration/billing.changelog-init.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /bn-apps/billing/billing-contracts-and-states/src/resources/migration/billing.changelog-v2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /bn-apps/billing/billing-demo/README.md: -------------------------------------------------------------------------------- 1 | Billing Demo 2 | ============ 3 | 4 | # Installing the Billing demo 5 | 6 | 1. Install the Billing service on your node, see billing README.md 7 | 8 | 2. Add the billing-demo-X.0.jar to your Cordapps directory, you can get the jar from the R3 Artifactory: 9 | 10 | https://ci-artifactory.corda.r3cev.com/artifactory/webapp/#/artifacts/browse/tree/General/corda-solutions-releases/com/r3/businessnetworks/billing-demo 11 | 12 | 3. Restart the node. -------------------------------------------------------------------------------- /bn-apps/billing/billing-demo/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'kotlin' 2 | apply plugin: 'net.corda.plugins.cordapp' 3 | apply plugin: 'net.corda.plugins.cordformation' 4 | apply plugin: 'net.corda.plugins.quasar-utils' 5 | 6 | cordapp { 7 | targetPlatformVersion 4 8 | minimumPlatformVersion 4 9 | workflow { 10 | name "billing-demo" 11 | vendor "com.r3" 12 | licence "http://www.apache.org/licenses/LICENSE-2.0" 13 | versionId 1 14 | } 15 | signing { 16 | enabled false 17 | } 18 | } 19 | 20 | sourceSets { 21 | main { 22 | resources { 23 | srcDir "config/dev" 24 | } 25 | } 26 | test { 27 | resources { 28 | srcDir "config/test" 29 | } 30 | } 31 | } 32 | 33 | dependencies { 34 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 35 | compile project(":bn-apps:businessnetworks-utilities") 36 | testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" 37 | testCompile "junit:junit:$junit_version" 38 | 39 | // Corda integration dependencies 40 | cordaCompile "$corda_release_group:corda-core:$corda_release_version" 41 | cordaCompile "$corda_release_group:corda-rpc:$corda_release_version" 42 | cordaCompile "$corda_release_group:corda-node-api:$corda_release_version" 43 | cordaRuntime "$corda_release_group:corda:$corda_release_version" 44 | testCompile "$corda_release_group:corda-node-driver:$corda_release_version" 45 | testCompile project(":bn-apps:businessnetworks-test-utilities") 46 | 47 | cordapp project(":bn-apps:billing:billing-app") 48 | 49 | } 50 | 51 | tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { 52 | kotlinOptions { 53 | languageVersion = "1.2" 54 | apiVersion = "1.2" 55 | jvmTarget = "1.8" 56 | javaParameters = true // Useful for reflection. 57 | } 58 | } 59 | 60 | task testJar(type: Jar) { 61 | classifier = 'tests' 62 | from sourceSets.test.output 63 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-demo/src/test/kotlin/com/r3/businessnetworks/billing/demo/DemoTest.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.billing.demo 2 | 3 | import com.r3.businessnetworks.billing.demo.contracts.SampleContract 4 | import com.r3.businessnetworks.billing.demo.contracts.SampleState 5 | import com.r3.businessnetworks.billing.demo.flows.IssueSampleStateFlow 6 | import com.r3.businessnetworks.billing.demo.flows.TransferSampleStateFlow 7 | import com.r3.businessnetworks.billing.flows.bno.IssueBillingStateFlow 8 | import com.r3.businessnetworks.testutilities.AbstractBusinessNetworksFlowTest 9 | import com.r3.businessnetworks.testutilities.identity 10 | import net.corda.core.node.services.queryBy 11 | import org.junit.Test 12 | 13 | class DemoTest : AbstractBusinessNetworksFlowTest(1, 2, 14 | listOf("com.r3.businessnetworks.billing.demo.contracts", 15 | "com.r3.businessnetworks.billing.demo.flows", 16 | "com.r3.businessnetworks.billing.flows", 17 | "com.r3.businessnetworks.billing.states")){ 18 | 19 | private fun bnoNode() = bnoNodes.single() 20 | private fun participant1Node() = participantsNodes[0] 21 | private fun participant2Node() = participantsNodes[1] 22 | 23 | @Test 24 | fun `test happy path`() { 25 | // issuing billing chips to both parties 26 | // issuer requires more tokens as they need to pay twice 27 | runFlowAndReturn(bnoNode(), IssueBillingStateFlow(participant1Node().identity(), 2 * SampleContract.BILLING_CHIPS_TO_PAY)) 28 | runFlowAndReturn(bnoNode(), IssueBillingStateFlow(participant2Node().identity(), SampleContract.BILLING_CHIPS_TO_PAY)) 29 | 30 | // Issuing a SampleState 31 | runFlowAndReturn(participant1Node(), IssueSampleStateFlow()) 32 | 33 | // transferring SampleState between parties 34 | val sampleState = participant1Node().services.vaultService.queryBy().states.single() 35 | runFlowAndReturn(participant1Node(), TransferSampleStateFlow(sampleState, participant2Node().identity())) 36 | } 37 | } -------------------------------------------------------------------------------- /bn-apps/billing/billing-demo/src/test/resources/billing-app.conf: -------------------------------------------------------------------------------- 1 | notaryName = "O=Notary,L=London,C=GB" 2 | bnoName = "O=BNO_0,L=New York,C=US" -------------------------------------------------------------------------------- /bn-apps/billing/resources/billing_state_evolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/billing/resources/billing_state_evolution.png -------------------------------------------------------------------------------- /bn-apps/billing/resources/billing_state_machine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/billing/resources/billing_state_machine.png -------------------------------------------------------------------------------- /bn-apps/businessnetworks-test-utilities/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'kotlin' 2 | 3 | sourceSets { 4 | main { 5 | resources { 6 | srcDir "config/dev" 7 | } 8 | } 9 | test { 10 | resources { 11 | srcDir "config/test" 12 | } 13 | } 14 | } 15 | 16 | dependencies { 17 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 18 | compileOnly "$corda_release_group:corda-core:$corda_release_version" 19 | compileOnly "$corda_release_group:corda:$corda_release_version" 20 | compileOnly "org.jetbrains.kotlin:kotlin-test:$kotlin_version" 21 | compileOnly "junit:junit:$junit_version" 22 | compileOnly "$corda_release_group:corda-node-driver:$corda_release_version" 23 | } 24 | 25 | tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { 26 | kotlinOptions { 27 | languageVersion = "1.2" 28 | apiVersion = "1.2" 29 | jvmTarget = "1.8" 30 | javaParameters = true // Useful for reflection. 31 | } 32 | } 33 | 34 | task testJar(type: Jar) { 35 | classifier = 'tests' 36 | from sourceSets.test.output 37 | } -------------------------------------------------------------------------------- /bn-apps/businessnetworks-utilities/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'kotlin' 2 | 3 | sourceSets { 4 | main { 5 | resources { 6 | srcDir "config/dev" 7 | } 8 | } 9 | test { 10 | resources { 11 | srcDir "config/test" 12 | } 13 | } 14 | } 15 | 16 | dependencies { 17 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 18 | compileOnly "$corda_release_group:corda-core:$corda_release_version" 19 | compileOnly "$corda_release_group:corda:$corda_release_version" 20 | 21 | testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" 22 | testCompile "junit:junit:$junit_version" 23 | 24 | } 25 | 26 | tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { 27 | kotlinOptions { 28 | languageVersion = "1.2" 29 | apiVersion = "1.2" 30 | jvmTarget = "1.8" 31 | javaParameters = true // Useful for reflection. 32 | } 33 | } 34 | 35 | task testJar(type: Jar) { 36 | classifier = 'tests' 37 | from sourceSets.test.output 38 | } -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact-2/1.0/test-artifact-2-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact-2/1.0/test-artifact-2-1.0.jar -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact-2/1.0/test-artifact-2-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | net.example 5 | test-artifact 6 | 1.0 7 | 8 | -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact-2/2.0/test-artifact-2-2.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact-2/2.0/test-artifact-2-2.0.jar -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact-2/2.0/test-artifact-2-2.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | net.example 5 | test-artifact 6 | 2.0 7 | 8 | -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact-2/maven-metadata.xml: -------------------------------------------------------------------------------- 1 | 2 | net.example 3 | test-artifact-2 4 | 5 | 2.0 6 | 2.0 7 | 8 | 1.0 9 | 2.0 10 | 11 | 20180219191931 12 | 13 | -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact-3/0.1/test-artifact-3-0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact-3/0.1/test-artifact-3-0.1.jar -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact-3/0.1/test-artifact-3-0.1.pom: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | net.example 5 | test-artifact 6 | 0.1 7 | 8 | -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact-3/1.5/test-artifact-3-1.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact-3/1.5/test-artifact-3-1.5.jar -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact-3/1.5/test-artifact-3-1.5.pom: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | net.example 5 | test-artifact 6 | 1.5 7 | 8 | -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact-3/maven-metadata.xml: -------------------------------------------------------------------------------- 1 | 2 | net.example 3 | test-artifact-3 4 | 5 | 1.5 6 | 1.5 7 | 8 | 0.1 9 | 1.5 10 | 11 | 20180219191931 12 | 13 | -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/0.1/test-artifact-0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/0.1/test-artifact-0.1.jar -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/0.1/test-artifact-0.1.pom: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | net.example 5 | test-artifact 6 | 0.1 7 | 8 | -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/0.5/test-artifact-0.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/0.5/test-artifact-0.5.jar -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/0.5/test-artifact-0.5.pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | net.example 5 | test-artifact 6 | 0.5 7 | 8 | -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/1.0/test-artifact-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/1.0/test-artifact-1.0.jar -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/1.0/test-artifact-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | net.example 5 | test-artifact 6 | 1.0 7 | 8 | -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/1.5/test-artifact-1.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/1.5/test-artifact-1.5.jar -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/1.5/test-artifact-1.5.pom: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | net.example 5 | test-artifact 6 | 1.5 7 | 8 | -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/2.0/test-artifact-2.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/2.0/test-artifact-2.0.jar -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/2.0/test-artifact-2.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | net.example 5 | test-artifact 6 | 2.0 7 | 8 | -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/TestRepo/net/example/test-artifact/maven-metadata.xml: -------------------------------------------------------------------------------- 1 | 2 | net.example 3 | test-artifact 4 | 5 | 2.0 6 | 2.0 7 | 8 | 0.1 9 | 0.5 10 | 1.0 11 | 1.5 12 | 2.0 13 | 14 | 20180219191931 15 | 16 | -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-app-states/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'kotlin' 2 | apply plugin: 'net.corda.plugins.cordapp' 3 | apply plugin: 'net.corda.plugins.quasar-utils' 4 | 5 | cordapp { 6 | targetPlatformVersion 4 7 | minimumPlatformVersion 1 8 | contract { 9 | name "corda-updates-app-states" 10 | vendor "com.r3" 11 | licence "http://www.apache.org/licenses/LICENSE-2.0" 12 | versionId 1 13 | } 14 | signing { 15 | enabled false 16 | } 17 | 18 | } 19 | 20 | sourceSets { 21 | main { 22 | resources { 23 | srcDir "config/dev" 24 | } 25 | } 26 | test { 27 | resources { 28 | srcDir "config/test" 29 | } 30 | } 31 | } 32 | 33 | dependencies { 34 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 35 | 36 | // corda dependencies 37 | cordaCompile "$corda_release_group:corda-core:$corda_release_version" 38 | cordaCompile "$corda_release_group:corda-node-api:$corda_release_version" 39 | cordaCompile "$corda_release_group:corda:$corda_release_version" 40 | testCompile "$corda_release_group:corda-node-driver:$corda_release_version" 41 | 42 | // test dependencies 43 | testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" 44 | testCompile "junit:junit:$junit_version" 45 | } 46 | 47 | tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { 48 | kotlinOptions { 49 | languageVersion = "1.2" 50 | apiVersion = "1.2" 51 | jvmTarget = "1.8" 52 | javaParameters = true // Useful for reflection. 53 | } 54 | } -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'kotlin' 2 | apply plugin: 'net.corda.plugins.cordapp' 3 | apply plugin: 'net.corda.plugins.quasar-utils' 4 | 5 | cordapp { 6 | targetPlatformVersion 4 7 | minimumPlatformVersion 1 8 | workflow { 9 | name "corda-updates-app" 10 | vendor "com.r3" 11 | licence "http://www.apache.org/licenses/LICENSE-2.0" 12 | versionId 1 13 | } 14 | signing { 15 | enabled false 16 | } 17 | } 18 | 19 | sourceSets { 20 | main { 21 | resources { 22 | srcDir "config/dev" 23 | } 24 | } 25 | test { 26 | resources { 27 | srcDir "config/test" 28 | } 29 | } 30 | } 31 | 32 | dependencies { 33 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 34 | 35 | // cordapps 36 | cordapp project(":bn-apps:cordapp-updates-distribution:corda-updates-core") 37 | cordapp project(":bn-apps:cordapp-updates-distribution:corda-updates-app-states") 38 | 39 | // corda dependencies 40 | cordaCompile "$corda_release_group:corda-core:$corda_release_version" 41 | cordaCompile "$corda_release_group:corda-node-api:$corda_release_version" 42 | cordaCompile "$corda_release_group:corda:$corda_release_version" 43 | testCompile "$corda_release_group:corda-node-driver:$corda_release_version" 44 | 45 | // test dependencies 46 | testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" 47 | testCompile "junit:junit:$junit_version" 48 | testCompile project(":bn-apps:cordapp-updates-distribution:corda-updates-test-utils") 49 | } 50 | 51 | tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { 52 | kotlinOptions { 53 | languageVersion = "1.2" 54 | apiVersion = "1.2" 55 | jvmTarget = "1.8" 56 | javaParameters = true // Useful for reflection. 57 | } 58 | } -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-app/src/main/kotlin/com/r3/businessnetworks/cordaupdates/app/member/GetConfigurationFlow.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.cordaupdates.app.member 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.cordaupdates.core.SyncerConfiguration 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.flows.StartableByRPC 7 | import net.corda.core.utilities.ProgressTracker 8 | 9 | @StartableByRPC 10 | class GetCDSConfigurationFlow : FlowLogic() { 11 | // TODO: remove for Corda v4 12 | companion object { 13 | object LOADING_CONFIGURATION : ProgressTracker.Step("Loading configuration") 14 | 15 | fun tracker() = ProgressTracker( 16 | LOADING_CONFIGURATION 17 | ) 18 | } 19 | 20 | override val progressTracker = tracker() 21 | 22 | @Suspendable 23 | override fun call() : SyncerConfiguration { 24 | progressTracker.currentStep = LOADING_CONFIGURATION 25 | return SyncerService.loadSyncerConfiguration(serviceHub) 26 | } 27 | } -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-app/src/main/kotlin/com/r3/businessnetworks/cordaupdates/app/member/GetSyncedCordappsFlow.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.cordaupdates.app.member 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.cordaupdates.core.ArtifactMetadata 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.flows.StartableByRPC 7 | import net.corda.core.serialization.CordaSerializable 8 | import net.corda.core.utilities.ProgressTracker 9 | import java.time.Instant 10 | 11 | @CordaSerializable 12 | data class SyncedCordappsResponse(val cordapps : List, val lastUpdated : Instant?) 13 | 14 | @StartableByRPC 15 | class GetSyncedCordappsFlow : FlowLogic() { 16 | companion object { 17 | object GETTING_VERSIONS : ProgressTracker.Step("Getting versions") 18 | 19 | fun tracker() = ProgressTracker( 20 | GETTING_VERSIONS 21 | ) 22 | } 23 | 24 | override val progressTracker : ProgressTracker = tracker() 25 | 26 | @Suspendable 27 | override fun call() : SyncedCordappsResponse { 28 | progressTracker.currentStep = GETTING_VERSIONS 29 | val cache = serviceHub.cordaService(ArtifactsMetadataCache::class.java) 30 | return SyncedCordappsResponse(cache.cache, cache.lastUpdated) 31 | } 32 | } -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-app/src/main/kotlin/com/r3/businessnetworks/cordaupdates/app/member/ReportCordappVersionFlow.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.cordaupdates.app.member 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import net.corda.core.flows.FlowLogic 5 | import net.corda.core.flows.FlowSession 6 | import net.corda.core.flows.InitiatingFlow 7 | import net.corda.core.identity.Party 8 | import net.corda.core.serialization.CordaSerializable 9 | 10 | /** 11 | * Represents a single version of a cordapp. 12 | * 13 | * @param group cordapp group, i.e. "net.corda" 14 | * @param name cordapp name, i.e. "corda-finance" 15 | * @param version cordapp version, i.e. "1.0" 16 | * @param updated last updated timestamp 17 | */ 18 | @CordaSerializable 19 | data class CordappVersionInfo(val group : String, val name : String, val version : String, val updated : Long = System.currentTimeMillis()) 20 | 21 | /** 22 | * Reports a version of a cordapp to the BNO 23 | */ 24 | @InitiatingFlow 25 | class ReportCordappVersionFlow(private val group : String, private val name : String, private val version : String) : FlowLogic() { 26 | @Suspendable 27 | override fun call() { 28 | val configuration : MemberConfiguration = serviceHub.cordaService(MemberConfiguration::class.java) 29 | val bno : Party = configuration.bnoParty() 30 | val session : FlowSession = initiateFlow(bno) 31 | session.send(CordappVersionInfo(group, name, version)) 32 | } 33 | } -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-app/src/test/kotlin/com/r3/businessnetworks/cordaupdates/app/ReloadConfigurationFlows.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.cordaupdates.app 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.cordaupdates.app.member.MemberConfiguration 5 | import com.r3.businessnetworks.cordaupdates.transport.flows.RepositoryHosterConfigurationService 6 | import net.corda.core.flows.FlowLogic 7 | import net.corda.core.flows.StartableByRPC 8 | import java.io.File 9 | 10 | @StartableByRPC 11 | class ReloadMemberConfigurationFlow(private val fileName : String) : FlowLogic() { 12 | @Suspendable 13 | override fun call() { 14 | val config = File(ReloadMemberConfigurationFlow::class.java.classLoader.getResource(fileName).toURI()) 15 | val configuration = serviceHub.cordaService(MemberConfiguration::class.java) 16 | configuration.reloadConfigurationFromFile(config) 17 | } 18 | } 19 | 20 | @StartableByRPC 21 | class ReloadBNOConfigurationFlow(private val fileName : String) : FlowLogic() { 22 | @Suspendable 23 | override fun call() { 24 | val config = File(ReloadBNOConfigurationFlow::class.java.classLoader.getResource(fileName).toURI()) 25 | val configuration = serviceHub.cordaService(RepositoryHosterConfigurationService::class.java) 26 | configuration.reloadConfigurationFromFile(config) 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-app/src/test/kotlin/com/r3/businessnetworks/cordaupdates/testextensions/FlowOverrides.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.cordaupdates.testextensions 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.cordaupdates.app.bno.ReportCordappVersionFlowResponder 5 | import com.r3.businessnetworks.cordaupdates.app.member.ReportCordappVersionFlow 6 | import com.r3.businessnetworks.cordaupdates.transport.flows.GetResourceFlow 7 | import com.r3.businessnetworks.cordaupdates.transport.flows.GetResourceFlowResponder 8 | import com.r3.businessnetworks.cordaupdates.transport.flows.PeekResourceFlow 9 | import com.r3.businessnetworks.cordaupdates.transport.flows.PeekResourceFlowResponder 10 | import net.corda.core.flows.FlowSession 11 | import net.corda.core.flows.InitiatedBy 12 | 13 | @InitiatedBy(ReportCordappVersionFlow::class) 14 | class ReportCordappVerionFlowResponderWithSessionFilter(session : FlowSession) : ReportCordappVersionFlowResponder(session) { 15 | @Suspendable 16 | override fun isSessionAllowed(session : FlowSession) = false 17 | } -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-app/src/test/resources/corda-updates-app.conf: -------------------------------------------------------------------------------- 1 | syncInterval = 9999999 2 | notary = "O=Notary,L=London,C=GB" 3 | bno = "O=BNO,L=London,C=GB" -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-core/src/test/resources/test-syncer-configuration.conf: -------------------------------------------------------------------------------- 1 | localRepoPath = "/var/temp" 2 | httpProxyType = "HTTP" 3 | httpProxyHost = "10.0.0.1" 4 | httpProxyPort = 187 5 | httpProxyUsername = "ProxyUsername" 6 | httpProxyPassword = "ProxyPassword" 7 | rpcHost = "localhost" 8 | rpcPort = 8007 9 | rpcUsername = "RpcUsername" 10 | rpcPassword = "RpcPassword" 11 | cordappSources = [ 12 | { 13 | remoteRepoUrl = "http://search.maven.org", 14 | cordapps = ["com.test:test-1", "com.test:test-2"] 15 | }, 16 | { 17 | remoteRepoUrl = "http://search2.maven.org", 18 | cordapps = ["com.test:test-1", "com.test:test-2"], 19 | httpUsername: "User2" 20 | httpPassword: "Password2" 21 | } 22 | ] -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-test-utils/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'kotlin' 2 | 3 | sourceSets { 4 | main { 5 | resources { 6 | srcDir "config/dev" 7 | } 8 | } 9 | test { 10 | resources { 11 | srcDir "config/test" 12 | } 13 | } 14 | } 15 | 16 | dependencies { 17 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 18 | compile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" 19 | compile "junit:junit:$junit_version" 20 | } 21 | 22 | tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { 23 | kotlinOptions { 24 | languageVersion = "1.2" 25 | apiVersion = "1.2" 26 | jvmTarget = "1.8" 27 | javaParameters = true // Useful for reflection. 28 | } 29 | } 30 | compileKotlin { 31 | kotlinOptions { 32 | languageVersion = "1.2" 33 | } 34 | } -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-transport/src/main/kotlin/com/r3/businessnetworks/cordaupdates/transport/CordaTransporterFactory.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.cordaupdates.transport 2 | 3 | import org.eclipse.aether.RepositorySystemSession 4 | import org.eclipse.aether.repository.RemoteRepository 5 | import org.eclipse.aether.spi.connector.transport.Transporter 6 | import org.eclipse.aether.spi.connector.transport.TransporterFactory 7 | import org.eclipse.aether.transfer.NoTransporterException 8 | 9 | /** 10 | * Implementation of Maven Resolver's [TransporterFactory] for Corda transport. 11 | * 12 | * Corda transport expects a repository URL to be specified in the format of "corda:x500Name/repositoryName", i.e. for example "corda:O=BNO,L=New York,C=US/default". 13 | * repositoryName allows a single node to serve artifacts from multiple repositories. 14 | */ 15 | class CordaTransporterFactory : TransporterFactory { 16 | companion object { 17 | const val CORDA_FLOWS_TRANSPORT = "corda" 18 | } 19 | 20 | override fun getPriority() = 5.0f 21 | 22 | override fun newInstance(session : RepositorySystemSession, repository : RemoteRepository) : Transporter { 23 | return when(repository.protocol.toLowerCase()) { 24 | CORDA_FLOWS_TRANSPORT -> FlowsTransporter(session, repository) 25 | else -> throw NoTransporterException(repository) 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-transport/src/main/kotlin/com/r3/businessnetworks/cordaupdates/transport/flows/AbstractRepositoryHosterResponder.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.cordaupdates.transport.flows 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import net.corda.core.flows.FlowException 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.flows.FlowSession 7 | import net.corda.core.serialization.CordaSerializable 8 | 9 | /** 10 | * This class puts every incoming session through a [SessionFilter] if one has been specified in the configuration. 11 | * In the case if no [SessionFilter] has been specified - every request will be let through. 12 | * 13 | * @throws FlowException if the incoming request doesn't satisfy [SessionFilter] requirements 14 | * 15 | * TODO: this logic should be implemented as flow overrides once the feature is available 16 | */ 17 | abstract class AbstractRepositoryHosterResponder(val session : FlowSession) : FlowLogic() { 18 | @Suspendable 19 | override fun call() : T { 20 | if (!isSessionAllowed(session)) { 21 | throw FlowException("Counterparty ${session.counterparty} is not allowed to access repository") 22 | } 23 | return postPermissionCheck() 24 | } 25 | 26 | @Suspendable 27 | protected abstract fun postPermissionCheck() : T 28 | 29 | /** 30 | * Override this method to implement session filtering 31 | * See: https://docs.corda.net/head/flow-overriding.html 32 | */ 33 | @Suspendable 34 | protected open fun isSessionAllowed(session : FlowSession) = true 35 | } 36 | 37 | /** 38 | * Request that is used to get / peek a resource from a remote repository. Repository with [repositoryName] has to be configured at the repository hoster's node 39 | */ 40 | @CordaSerializable 41 | data class ResourceRequest (val repositoryName : String, val resourceLocation : String) 42 | -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-transport/src/test/kotlin/com/r3/businessnetworks/cordaupdates/testextensions/allowfilter/FlowOverrides.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.cordaupdates.testextensions.allowfilter 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.cordaupdates.transport.flows.GetResourceFlow 5 | import com.r3.businessnetworks.cordaupdates.transport.flows.GetResourceFlowResponder 6 | import com.r3.businessnetworks.cordaupdates.transport.flows.PeekResourceFlow 7 | import com.r3.businessnetworks.cordaupdates.transport.flows.PeekResourceFlowResponder 8 | import net.corda.core.flows.FlowSession 9 | import net.corda.core.flows.InitiatedBy 10 | 11 | @InitiatedBy(GetResourceFlow::class) 12 | class GetResourceFlowResponderWithSessionFilter(session : FlowSession) : GetResourceFlowResponder(session) { 13 | @Suspendable 14 | override fun isSessionAllowed(session : FlowSession) = true 15 | } 16 | 17 | @InitiatedBy(PeekResourceFlow::class) 18 | class PeekResourceFlowResponderWithSessionFilter(session : FlowSession) : PeekResourceFlowResponder(session) { 19 | @Suspendable 20 | override fun isSessionAllowed(session : FlowSession) = true 21 | } -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-transport/src/test/kotlin/com/r3/businessnetworks/cordaupdates/testextensions/denyfilter/FlowOverrides.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.cordaupdates.testextensions.denyfilter 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.cordaupdates.transport.flows.GetResourceFlow 5 | import com.r3.businessnetworks.cordaupdates.transport.flows.GetResourceFlowResponder 6 | import com.r3.businessnetworks.cordaupdates.transport.flows.PeekResourceFlow 7 | import com.r3.businessnetworks.cordaupdates.transport.flows.PeekResourceFlowResponder 8 | import net.corda.core.flows.FlowSession 9 | import net.corda.core.flows.InitiatedBy 10 | 11 | @InitiatedBy(GetResourceFlow::class) 12 | class GetResourceFlowResponderWithSessionFilter(session : FlowSession) : GetResourceFlowResponder(session) { 13 | @Suspendable 14 | override fun isSessionAllowed(session : FlowSession) = false 15 | } 16 | 17 | @InitiatedBy(PeekResourceFlow::class) 18 | class PeekResourceFlowResponderWithSessionFilter(session : FlowSession) : PeekResourceFlowResponder(session) { 19 | @Suspendable 20 | override fun isSessionAllowed(session : FlowSession) = false 21 | } -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-transport/src/test/kotlin/com/r3/businessnetworks/cordaupdates/transport/ReloadConfigurationFlow.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.cordaupdates.transport 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.cordaupdates.transport.flows.RepositoryHosterConfigurationService 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.flows.StartableByRPC 7 | import java.io.File 8 | 9 | @StartableByRPC 10 | class ReloadConfigurationFlow(private val fileName : String) : FlowLogic() { 11 | @Suspendable 12 | override fun call() { 13 | val config = File(ReloadConfigurationFlow::class.java.classLoader.getResource(fileName).toURI()) 14 | val configuration = serviceHub.cordaService(RepositoryHosterConfigurationService::class.java) 15 | configuration.reloadConfigurationFromFile(config) 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-transport/src/test/kotlin/com/r3/businessnetworks/cordaupdates/transport/VerifyMavenResourceURITests.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.cordaupdates.transport 2 | 3 | import com.r3.businessnetworks.cordaupdates.transport.flows.Utils.verifyMavenResourceURI 4 | import net.corda.core.flows.FlowException 5 | import org.junit.Test 6 | 7 | class VerifyMavenResourceURITests { 8 | 9 | @Test 10 | fun `artifact request should succeed`() = verifyMavenResourceURI("com/google/guava/guava/27.0-jre/guava-27.0-jre-javadoc.jar.asc") 11 | 12 | @Test 13 | fun `maven metadata request should succeed`() = verifyMavenResourceURI("com/google/guava/maven-metadata.xml") 14 | 15 | @Test(expected = FlowException::class) 16 | fun `should not contain spaces`() = verifyMavenResourceURI("com/google/guava/guava/27.0-jre/guava-27.0-jre-javadoc.jar.asc ") 17 | 18 | @Test(expected = FlowException::class) 19 | fun `name not contain double dot`() = verifyMavenResourceURI("com/google/guava/guava/27.0-jre/guava..-27.0-jre-javadoc.jar.asc") 20 | 21 | @Test(expected = FlowException::class) 22 | fun `no double dots are allowed`() = verifyMavenResourceURI("com/google/guava/guava/27..0-jre/guava-27.0-jre-javadoc.jar.asc") 23 | 24 | @Test(expected = FlowException::class) 25 | fun `subgroups should not be empty`() = verifyMavenResourceURI("com//guava/guava/27.0-jre/guava-27.0-jre-javadoc.jar.asc") 26 | 27 | @Test(expected = FlowException::class) 28 | fun `special characters are not allowed`() = verifyMavenResourceURI("com/guava$/guava/27.0-jre/guava-27.0-jre-javadoc.jar.asc") 29 | 30 | @Test(expected = FlowException::class) 31 | fun `artifact request url should contain at least 4 parts`() = verifyMavenResourceURI("guava/27.0-jre/guava-27.0-jre-javadoc.jar.asc") 32 | 33 | @Test(expected = FlowException::class) 34 | fun `maven metadata request url should contain at least 2 parts`() = verifyMavenResourceURI("maven-metadata.xml") 35 | } -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-transport/src/test/resources/corda-updates-app-with-custom-repo-name.conf: -------------------------------------------------------------------------------- 1 | repositories { 2 | customRepo = "file:../TestRepo" 3 | } -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/corda-updates-transport/src/test/resources/corda-updates-app.conf: -------------------------------------------------------------------------------- 1 | repositories { 2 | default = "file:../TestRepo" 3 | } -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/design/resources/cds-as-cordapp-flows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/cordapp-updates-distribution/design/resources/cds-as-cordapp-flows.png -------------------------------------------------------------------------------- /bn-apps/cordapp-updates-distribution/design/resources/cds-as-cordapp-http.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/cordapp-updates-distribution/design/resources/cds-as-cordapp-http.png -------------------------------------------------------------------------------- /bn-apps/ledger-sync/design/ledger-sync-service.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | == Get Memberships Flow == 3 | 4 | Initiator -> "Business Network Operator": Get Members 5 | "Business Network Operator" --> Initiator: Set of BN members 6 | 7 | == Evaluate Ledger Consistency Flow == 8 | 9 | loop for all node ∈ BN members 10 | Initiator -> Initiator: Retrieve and hash transaction IDs\n\ 11 | of transactions with //Counterparty// 12 | Initiator -> Counterparty: Compound hash of transactions 13 | Counterparty -> Counterparty: Retrieve, hash transaction IDs of transactions\n\ 14 | with //Initiator// and compare with hash received 15 | Counterparty --> Initiator: Do hashes match? 16 | end 17 | 18 | == Request Ledger Sync Flow == 19 | 20 | loop for all node ∈ BN Members 21 | alt hash_match == false 22 | Initiator -> Counterparty: Set of IDs of transactions with //Counterparty// 23 | Counterparty --> Initiator: Set of findings, indicating missing transaction\n\ 24 | both on the //Inititator// and //Counterparty// side 25 | end 26 | end 27 | 28 | == Transaction Recovery Flow == 29 | 30 | loop for all finding ∈ findings 31 | alt contains recoverable transactions 32 | Initiator -> Counterparty: Set of IDs of recoverable transactions with //Counterparty// 33 | loop for all id ∈ relevant_transaction_ids 34 | Counterparty --> Initiator: Transaction 35 | end 36 | end 37 | end 38 | @enduml -------------------------------------------------------------------------------- /bn-apps/ledger-sync/design/resources/ledger_sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/ledger-sync/design/resources/ledger_sync.png -------------------------------------------------------------------------------- /bn-apps/ledger-sync/design/websequencediagrams: -------------------------------------------------------------------------------- 1 | title Ledger Synchronisation 2 | 3 | Sync Initiator->BNO: Requests membership snapshot 4 | BNO->Sync Initiator: Sends membership snapshot 5 | loop For each BN Member 6 | note left of Sync Initiator 7 | Builds a snapshot of transaction ids, 8 | where both the Sync Initiator and the 9 | BN Member are participants. 10 | end note 11 | Sync Initiator->BN Member: Sends the snapshot 12 | note right of BN Member 13 | Builds a snapshot of transaction ids, 14 | where both the Sync Initiator and the 15 | BN Member are participants. 16 | end note 17 | note right of BN Member: Calculates the delta between the 2 snapshots 18 | alt [OPTIONALLY] If the BN Member is missing some transactions 19 | BN Member->Sync Initiator: Requests the Sync Initiator to send missing transactions 20 | loop For each missing transaction 21 | Sync Initiator->BN Member: Sends a missing transaction 22 | note right of BN Member 23 | The BN Member applies his own logic here. 24 | For example he might persist the transaction into his vault, 25 | raise an alert to the monitoring system that the ledger was out of sync, 26 | or perform any other custom action. 27 | end note 28 | end 29 | end 30 | alt If the Sync Initiator is missing some transactions 31 | loop For each missing transaction 32 | BN Member->Sync Initiator: Sends a missing transaction 33 | note left of Sync Initiator 34 | The Sync Initiator applies his own logic here. 35 | For example he might persist the transaction into his vault, 36 | raise an alert to the monitoring system that the ledger was out of sync, 37 | or perform any other custom action. 38 | end note 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /bn-apps/ledger-sync/ledger-sync-service/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'kotlin' 2 | apply plugin: 'net.corda.plugins.cordapp' 3 | apply plugin: 'net.corda.plugins.cordformation' 4 | apply plugin: 'net.corda.plugins.quasar-utils' 5 | 6 | cordapp { 7 | targetPlatformVersion 4 8 | minimumPlatformVersion 1 9 | workflow { 10 | name "ledger-sync-service" 11 | vendor "com.r3" 12 | licence "http://www.apache.org/licenses/LICENSE-2.0" 13 | versionId 1 14 | } 15 | signing { 16 | enabled false 17 | } 18 | 19 | } 20 | 21 | sourceSets { 22 | main { 23 | resources { 24 | srcDir "config/dev" 25 | } 26 | } 27 | test { 28 | resources { 29 | srcDir "config/test" 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 36 | 37 | testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" 38 | testCompile "junit:junit:$junit_version" 39 | 40 | // Corda integration dependencies 41 | cordaCompile "$corda_release_group:corda-core:$corda_release_version" 42 | cordaCompile "$corda_release_group:corda-rpc:$corda_release_version" 43 | cordaCompile "$corda_release_group:corda-node-api:$corda_release_version" 44 | cordaRuntime "$corda_release_group:corda:$corda_release_version" 45 | 46 | testCompile "$corda_release_group:corda-node-driver:$corda_release_version" 47 | testCompile "com.r3:vr-db-service:2.0-SNAPSHOT" 48 | } 49 | 50 | tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { 51 | kotlinOptions { 52 | languageVersion = "1.2" 53 | apiVersion = "1.2" 54 | jvmTarget = "1.8" 55 | javaParameters = true // Useful for reflection. 56 | } 57 | } -------------------------------------------------------------------------------- /bn-apps/ledger-sync/ledger-sync-service/src/main/resources/META-INF.services/net.corda.core.serialization.SerializationWhitelist: -------------------------------------------------------------------------------- 1 | com.r3.businessnetworks.ledgersync.LedgerSyncWhitelist -------------------------------------------------------------------------------- /bn-apps/ledger-sync/ledger-sync-service/src/test/kotlin/com/r3/businessnetworks/ledgersync/BogusContract.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.ledgersync 2 | 3 | import net.corda.core.contracts.Contract 4 | import net.corda.core.contracts.TypeOnlyCommandData 5 | import net.corda.core.transactions.LedgerTransaction 6 | 7 | const val BOGUS_CONTRACT_ID = "com.r3.businessnetworks.ledgersync.BogusContract" 8 | 9 | class BogusContract : Contract { 10 | override fun verify(tx: LedgerTransaction) { 11 | // accept everything. this is a simple test fixture only. 12 | } 13 | 14 | sealed class Commands : TypeOnlyCommandData() { 15 | class Bogus : Commands() 16 | } 17 | } -------------------------------------------------------------------------------- /bn-apps/ledger-sync/ledger-sync-service/src/test/kotlin/com/r3/businessnetworks/ledgersync/ConsistencyTestsWithoutVr.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.ledgersync 2 | 3 | import net.corda.core.utilities.getOrThrow 4 | import net.corda.testing.node.internal.startFlow 5 | import org.junit.Test 6 | import kotlin.test.assertEquals 7 | 8 | class ConsistencyTestsWithoutVr : ConsistencyTests() { 9 | override val cordappPackages: List = listOf( 10 | "com.r3.businessnetworks.membership", 11 | "com.r3.businessnetworks.membership.states", 12 | "com.r3.businessnetworks.ledgersync" 13 | ) 14 | 15 | @Test 16 | fun `VR is not detected`() { 17 | val future = node1.fromNetwork().services.startFlow(VaultRecyclerExistFlow()).resultFuture 18 | mockNetwork.runNetwork() 19 | assertEquals(false, future.getOrThrow()) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /bn-apps/ledger-sync/ledger-sync-service/src/test/resources/ledgersync.conf: -------------------------------------------------------------------------------- 1 | pageSize = 100 -------------------------------------------------------------------------------- /bn-apps/lib/README.txt: -------------------------------------------------------------------------------- 1 | The Quasar.jar in this directory is for runtime instrumentation of classes by Quasar. 2 | 3 | When running corda outside of the given gradle building you must add the following flag with the 4 | correct path to your call to Java: 5 | 6 | java -javaagent:path-to-quasar-jar.jar ... 7 | 8 | See the Quasar docs for more information: http://docs.paralleluniverse.co/quasar/ -------------------------------------------------------------------------------- /bn-apps/lib/quasar.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/lib/quasar.jar -------------------------------------------------------------------------------- /bn-apps/memberships-management/design/resources/Membership_approval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/memberships-management/design/resources/Membership_approval.png -------------------------------------------------------------------------------- /bn-apps/memberships-management/design/resources/Membership_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/memberships-management/design/resources/Membership_request.png -------------------------------------------------------------------------------- /bn-apps/memberships-management/design/resources/Membership_revocation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/memberships-management/design/resources/Membership_revocation.png -------------------------------------------------------------------------------- /bn-apps/memberships-management/design/resources/Membership_snapshot_distribution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/memberships-management/design/resources/Membership_snapshot_distribution.png -------------------------------------------------------------------------------- /bn-apps/memberships-management/design/resources/Metadata_amendment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/bn-apps/memberships-management/design/resources/Metadata_amendment.png -------------------------------------------------------------------------------- /bn-apps/memberships-management/design/wesequencediagrams: -------------------------------------------------------------------------------- 1 | title Membership request 2 | 3 | Non-member->BNO: Proposes a transaction which issues Membership in PENDING state onto the ledger 4 | note right of BNO: Verifies and signs the transaction 5 | BNO->Non-member: Sends the signature 6 | note left of Non-member: Notarises the transaction 7 | 8 | 9 | title Membership approval 10 | 11 | note left of BNO: Does KYC checks 12 | note left of BNO: Creates a transaction which updates Membership's status to ACTIVE 13 | note left of BNO: Notarises the transaction 14 | BNO->Pending member: Notifies that the membership has been activated 15 | BNO->All BN members: [OPTIONALLY] Notifies about a new joiner 16 | 17 | 18 | 19 | title Membership revocation 20 | 21 | note left of BNO: Creates a transaction which updates Membership's status to REVOKED 22 | note left of BNO: Notarises the transaction 23 | BNO->All BN members: Notifies about the membership revocation 24 | 25 | 26 | 27 | title Metadata amendment 28 | 29 | note left of BN member: Creates a transaction which updates metadata of an ACTIVE Membership 30 | BN member->BNO: Proposes the transaction to the BNO 31 | note right of BNO: Verifies and signs the transaction 32 | BNO->BN member: Sends the signature 33 | note left of BN member: Notarises the transaction 34 | BN member->Other BN members: [OPTIONALLY] notifies about changes to the metadata 35 | 36 | 37 | title Membership snapshot distribution 38 | 39 | loop 40 | BN member->BNO: Requests snapshot from BNO 41 | note right of BNO: Builds the snapshot from local cache 42 | BNO->BN member: Sends the snapshot with the expiration time 43 | note left of BN member: Caches the snapshot until it expires 44 | -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service-contracts-and-states/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version" 4 | } 5 | } 6 | 7 | apply plugin: 'kotlin' 8 | apply plugin: 'net.corda.plugins.cordapp' 9 | apply plugin: 'net.corda.plugins.cordformation' 10 | apply plugin: 'net.corda.plugins.quasar-utils' 11 | apply plugin: "kotlin-jpa" 12 | 13 | cordapp { 14 | targetPlatformVersion 4 15 | minimumPlatformVersion 1 16 | contract { 17 | name "business-network-membership-service-states" 18 | vendor "com.r3" 19 | licence "http://www.apache.org/licenses/LICENSE-2.0" 20 | versionId 1 21 | } 22 | signing { 23 | enabled false 24 | } 25 | 26 | } 27 | 28 | sourceSets { 29 | main { 30 | resources { 31 | srcDir "config/dev" 32 | } 33 | } 34 | test { 35 | resources { 36 | srcDir "config/test" 37 | } 38 | } 39 | } 40 | 41 | dependencies { 42 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 43 | testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" 44 | testCompile "junit:junit:$junit_version" 45 | testImplementation project(":bn-apps:memberships-management:test-utils") 46 | 47 | // Corda integration dependencies 48 | cordaCompile "$corda_release_group:corda-core:$corda_release_version" 49 | cordaCompile "$corda_release_group:corda-rpc:$corda_release_version" 50 | cordaCompile "$corda_release_group:corda-node-api:$corda_release_version" 51 | cordaRuntime "$corda_release_group:corda:$corda_release_version" 52 | testCompile "$corda_release_group:corda-node-driver:$corda_release_version" 53 | } 54 | 55 | tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { 56 | kotlinOptions { 57 | languageVersion = "1.2" 58 | apiVersion = "1.2" 59 | jvmTarget = "1.8" 60 | javaParameters = true // Useful for reflection. 61 | } 62 | } -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service-contracts-and-states/src/main/kotlin/com/r3/businessnetworks/membership/states/Schemas.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.states 2 | 3 | import net.corda.core.identity.Party 4 | import net.corda.core.schemas.MappedSchema 5 | import net.corda.core.schemas.PersistentState 6 | import net.corda.core.serialization.CordaSerializable 7 | import javax.persistence.Column 8 | import javax.persistence.Entity 9 | import javax.persistence.Table 10 | 11 | @CordaSerializable 12 | object MembershipStateSchemaV1 : MappedSchema(schemaFamily = MembershipState::class.java, version = 1, mappedTypes = listOf(PersistentMembershipState::class.java)) { 13 | @Entity 14 | @Table(name = "membership_states") 15 | class PersistentMembershipState( 16 | @Column(name = "member_name") 17 | var member: Party, 18 | @Column(name = "bno_name") 19 | var bno: Party, 20 | @Column(name = "network_id") 21 | var networkID: String?, 22 | @Column(name = "status") 23 | var status: MembershipStatus) : PersistentState() 24 | } 25 | 26 | -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service-contracts-and-states/src/resources/migration/membership-state-schema-v1.changelog-init.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service-contracts-and-states/src/resources/migration/membership-state-schema-v1.changelog-master.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service-contracts-and-states/src/resources/migration/pending-membership-request-schema-v1.changelog-init.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service-contracts-and-states/src/resources/migration/pending-membership-request-schema-v1.changelog-master.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/main/kotlin/com/r3/businessnetworks/membership/flows/ConfigUtils.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.flows 2 | 3 | import com.typesafe.config.Config 4 | import com.typesafe.config.ConfigFactory 5 | import java.io.File 6 | import java.nio.file.Paths 7 | 8 | /** 9 | * Attempts to load application config from cordapps/config/membership-service.conf with fallback to membership-service.conf on the classpath 10 | */ 11 | object ConfigUtils { 12 | fun loadConfig(): Config { 13 | val propertiesFileName = "membership-service.conf" 14 | val defaultLocation = (Paths.get("cordapps").resolve("config").resolve(propertiesFileName)).toFile() 15 | return if (defaultLocation.exists()) ConfigFactory.parseFile(defaultLocation) 16 | else ConfigFactory.parseFile(File(ConfigUtils::class.java.classLoader.getResource(propertiesFileName).toURI())) 17 | } 18 | } -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/main/kotlin/com/r3/businessnetworks/membership/flows/Exceptions.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.flows 2 | 3 | import com.r3.businessnetworks.membership.states.MembershipState 4 | import net.corda.core.flows.FlowException 5 | import net.corda.core.identity.Party 6 | 7 | sealed class BNMSException(message: String) : FlowException(message) 8 | class NotAMemberException(val counterparty: Party) : BNMSException("Counterparty $counterparty is not a member of this business network") 9 | class MembershipNotActiveException(val counterparty: Party) : BNMSException("Counterparty's $counterparty membership in this business network is not active") 10 | class NotBNOException(val membership: MembershipState) : BNMSException("This node is not the business network operator for this membership") 11 | class BNONotWhitelisted(val bno: Party) : BNMSException("Party $bno is not whitelisted as BNO") 12 | class MembershipNotFound(val party: Party) : BNMSException("Membership for party $party not found") 13 | -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/main/kotlin/com/r3/businessnetworks/membership/flows/GenericsUtils.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.flows 2 | 3 | import com.r3.businessnetworks.membership.states.MembershipState 4 | import net.corda.core.contracts.StateAndRef 5 | import net.corda.core.crypto.SecureHash 6 | import net.corda.core.crypto.sha256 7 | import net.corda.core.internal.location 8 | 9 | fun StateAndRef>.getAttachmentIdForGenericParam(): SecureHash { 10 | return this.state.data.getAttachmentIdForGenericParam() 11 | } 12 | 13 | fun MembershipState.getAttachmentIdForGenericParam(): SecureHash { 14 | val bytesOfCordapp = this.membershipMetadata.javaClass.location.readBytes() 15 | return bytesOfCordapp.sha256() 16 | } 17 | 18 | fun StateAndRef>.isAttachmentRequired(): Boolean { 19 | return this.state.data.isAttachmentRequired() 20 | } 21 | 22 | fun MembershipState.isAttachmentRequired(): Boolean { 23 | return this.membershipMetadata.javaClass.protectionDomain.codeSource != null 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/main/kotlin/com/r3/businessnetworks/membership/flows/bno/GetMembershipsFlowResponder.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.flows.bno 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.membership.flows.bno.service.DatabaseService 5 | import com.r3.businessnetworks.membership.flows.bno.support.BusinessNetworkOperatorInitiatedFlowMembershipList 6 | import com.r3.businessnetworks.membership.flows.member.GetMembershipsFlow 7 | import com.r3.businessnetworks.membership.flows.member.MembershipListRequest 8 | import com.r3.businessnetworks.membership.flows.member.MembershipsListResponse 9 | import com.r3.businessnetworks.membership.states.MembershipState 10 | import net.corda.core.contracts.StateAndRef 11 | import net.corda.core.flows.FlowSession 12 | import net.corda.core.flows.InitiatedBy 13 | 14 | 15 | /** 16 | * Responder to the [GetMembershipsFlow]. Only active members can request a membership list. 17 | */ 18 | @InitiatedBy(GetMembershipsFlow::class) 19 | open class GetMembershipsFlowResponder(flowSession: FlowSession) : BusinessNetworkOperatorInitiatedFlowMembershipList(flowSession) { 20 | @Suspendable 21 | override fun onCounterpartyMembershipVerified(counterpartyMembership: StateAndRef>) { 22 | logger.info("Sending membership list to ${flowSession.counterparty}") 23 | //build memberships snapshot 24 | flowSession.receive() 25 | val databaseService = serviceHub.cordaService(DatabaseService::class.java) 26 | val membershipsWhereWeAreBNO = databaseService.getAllMemberships(ourIdentity) 27 | flowSession.send(MembershipsListResponse(membershipsWhereWeAreBNO)) 28 | } 29 | } -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/main/kotlin/com/r3/businessnetworks/membership/flows/bno/NotifyMemberFlow.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.flows.bno 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.membership.flows.bno.support.BusinessNetworkOperatorFlowLogic 5 | import com.r3.businessnetworks.membership.states.MembershipState 6 | import net.corda.core.contracts.StateAndRef 7 | import net.corda.core.flows.FlowLogic 8 | import net.corda.core.flows.InitiatingFlow 9 | import net.corda.core.identity.Party 10 | import net.corda.core.serialization.CordaSerializable 11 | 12 | @CordaSerializable 13 | data class OnMembershipChanged(val changedMembership: StateAndRef>) 14 | 15 | /** 16 | * Flow that is used by BNO to notify active BN members about changes to the membership list. 17 | */ 18 | class NotifyActiveMembersFlow(private val notification: Any) : BusinessNetworkOperatorFlowLogic() { 19 | @Suspendable 20 | override fun call() { 21 | val memberships = getActiveMembershipStates() 22 | memberships.forEach { subFlow(NotifyMemberFlow(notification, it.state.data.member)) } 23 | } 24 | } 25 | 26 | /** 27 | * Flow that is used by BNO to notify a BN member about changes to the membership list. 28 | */ 29 | @InitiatingFlow 30 | class NotifyMemberFlow(private val notification: Any, private val member: Party) : FlowLogic() { 31 | @Suspendable 32 | override fun call() { 33 | initiateFlow(member).send(notification) 34 | } 35 | } 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/main/kotlin/com/r3/businessnetworks/membership/flows/bno/service/BNOConfigurationService.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.flows.bno.service 2 | 3 | import com.r3.businessnetworks.utilities.AbstractConfigurationService 4 | import net.corda.core.identity.CordaX500Name 5 | import net.corda.core.node.AppServiceHub 6 | import net.corda.core.node.services.CordaService 7 | 8 | /** 9 | * Configuration that is used by BNO app. The configuration is red from cordapps/config/membership-service.conf with a fallback to 10 | * membership-service.conf on the classpath. 11 | */ 12 | @CordaService 13 | class BNOConfigurationService(private val serviceHub: AppServiceHub) : AbstractConfigurationService(serviceHub, "membership-service") { 14 | override fun bnoName(): CordaX500Name = throw NotImplementedError("This method should not be used") 15 | } -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/main/kotlin/com/r3/businessnetworks/membership/flows/bno/support/BusinessNetworkOperatorFlowLogic.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.flows.bno.support 2 | 3 | import com.r3.businessnetworks.membership.flows.MembershipNotFound 4 | import com.r3.businessnetworks.membership.flows.NotBNOException 5 | import com.r3.businessnetworks.membership.flows.bno.service.DatabaseService 6 | import com.r3.businessnetworks.membership.states.MembershipState 7 | import net.corda.core.contracts.StateAndRef 8 | import net.corda.core.flows.FlowLogic 9 | import net.corda.core.identity.Party 10 | 11 | /** 12 | * Extend from this class if you are a business network operator and you want to make your life easier when writing 13 | * flows by getting access to the useful methods in this class. 14 | */ 15 | abstract class BusinessNetworkOperatorFlowLogic : FlowLogic() { 16 | protected fun verifyThatWeAreBNO(membership: MembershipState) { 17 | if (ourIdentity != membership.bno) { 18 | throw NotBNOException(membership) 19 | } 20 | } 21 | 22 | protected fun findMembershipStateForParty(party: Party, networkID: String?): StateAndRef> { 23 | val databaseService = serviceHub.cordaService(DatabaseService::class.java) 24 | return databaseService.getMembershipOnNetwork(party, ourIdentity, networkID) ?: throw MembershipNotFound(party) 25 | } 26 | 27 | protected fun getActiveMembershipStates(): List>> { 28 | val databaseService = serviceHub.cordaService(DatabaseService::class.java) 29 | return databaseService.getActiveMemberships(ourIdentity) 30 | } 31 | } -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/main/kotlin/com/r3/businessnetworks/membership/flows/member/ActivateMembershipFlowResponder.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.flows.member 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.membership.flows.bno.ActivateMembershipFlow 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.flows.FlowSession 7 | import net.corda.core.flows.InitiatedBy 8 | import net.corda.core.flows.ReceiveFinalityFlow 9 | 10 | @InitiatedBy(ActivateMembershipFlow::class) 11 | open class ActivateMembershipFlowResponder(private val session: FlowSession) : FlowLogic() { 12 | @Suspendable 13 | override fun call() { 14 | if (session.getCounterpartyFlowInfo().flowVersion != 1 && session.counterparty != ourIdentity) { 15 | subFlow(ReceiveFinalityFlow(session)) 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/main/kotlin/com/r3/businessnetworks/membership/flows/member/SuspendMembershipFlowResponder.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.flows.member 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.membership.flows.bno.SuspendMembershipFlow 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.flows.FlowSession 7 | import net.corda.core.flows.InitiatedBy 8 | import net.corda.core.flows.ReceiveFinalityFlow 9 | 10 | @InitiatedBy(SuspendMembershipFlow::class) 11 | open class SuspendMembershipFlowResponder(val session: FlowSession) : FlowLogic() { 12 | @Suspendable 13 | override fun call() { 14 | if (session.getCounterpartyFlowInfo().flowVersion == 1) { 15 | // do nothing 16 | } else { 17 | subFlow(ReceiveFinalityFlow(session)) 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/main/kotlin/com/r3/businessnetworks/membership/flows/member/Utils.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.flows.member 2 | 3 | import com.r3.businessnetworks.membership.flows.BNONotWhitelisted 4 | import com.r3.businessnetworks.membership.flows.member.service.MemberConfigurationService 5 | import com.r3.businessnetworks.membership.states.MembershipState 6 | import net.corda.core.contracts.StateAndRef 7 | import net.corda.core.identity.Party 8 | import net.corda.core.node.ServiceHub 9 | import net.corda.core.utilities.loggerFor 10 | 11 | object Utils { 12 | val logger = loggerFor() 13 | 14 | /** 15 | * A convenience method to convert MembershipState to a MembershipState. All states which metadata is not T will be filtered out. 16 | */ 17 | inline fun Map>>.ofType() = this.filterValues { 18 | val matches = it.state.data.membershipMetadata is T 19 | if (!matches) { 20 | logger.warn("Membership ${it.state.data} doesn't match the requested metadata type of ${T::class.java}. Not including into the snapshot.") 21 | } 22 | matches 23 | }.mapValues { it.value as StateAndRef> } 24 | 25 | 26 | fun throwExceptionIfNotBNO(bno: Party, serviceHub: ServiceHub) { 27 | // Only configured BNOs should be accepted 28 | val configuration = serviceHub.cordaService(MemberConfigurationService::class.java) 29 | if (bno !in configuration.bnoIdentities()) { 30 | throw BNONotWhitelisted(bno) 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/main/kotlin/com/r3/businessnetworks/membership/flows/member/service/MemberConfigurationService.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.flows.member.service 2 | 3 | import com.r3.businessnetworks.utilities.AbstractConfigurationService 4 | import net.corda.core.identity.CordaX500Name 5 | import net.corda.core.identity.Party 6 | import net.corda.core.node.AppServiceHub 7 | import net.corda.core.node.services.CordaService 8 | import net.corda.core.utilities.loggerFor 9 | 10 | /** 11 | * Configuration that is used by member app. 12 | */ 13 | @CordaService 14 | class MemberConfigurationService(private val serviceHub: AppServiceHub) : AbstractConfigurationService(serviceHub, "membership-service") { 15 | companion object { 16 | // X500 name of the BNO 17 | const val BNO_WHITELIST = "bnoWhitelist" 18 | val logger = loggerFor() 19 | } 20 | 21 | override fun bnoName(): CordaX500Name = throw NotImplementedError("This method should not be used") 22 | override fun notaryName() = throw NotImplementedError("This method should not be used") 23 | 24 | /** 25 | * BNOs should be explicitly whitelisted. Any attempt to communicate with not whitelisted BNO would fail. 26 | */ 27 | fun bnoIdentities(): Set { 28 | val config = _config ?: throw IllegalArgumentException("Configuration for membership service is missing") 29 | return (if (config.hasPath(BNO_WHITELIST)) config.getStringList(BNO_WHITELIST) else listOf()) 30 | .asSequence().map { 31 | val x500Name = CordaX500Name.parse(it) 32 | val party = serviceHub.identityService.wellKnownPartyFromX500Name(x500Name) 33 | if (party == null) { 34 | logger.warn("BNO identity $it can't be resolver on the network") 35 | } 36 | party 37 | }.filterNotNull().toSet() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/main/kotlin/com/r3/businessnetworks/membership/flows/member/support/BusinessNetworkAwareInitiatedFlow.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.flows.member.support 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.membership.flows.NotAMemberException 5 | import com.r3.businessnetworks.membership.flows.member.GetMembershipsFlow 6 | import net.corda.core.flows.FlowLogic 7 | import net.corda.core.flows.FlowSession 8 | import net.corda.core.identity.Party 9 | 10 | /** 11 | * Extend from this class if you are a business network member and you don't want to be checking yourself whether 12 | * the initiating party is also a member. Your code (inside onCounterpartyMembershipVerified) will be called only after 13 | * that check is performed. If the initiating party is not a member an exception is thrown. 14 | */ 15 | 16 | abstract class BusinessNetworkAwareInitiatedFlow(protected val flowSession: FlowSession, private val networkID: String?) : FlowLogic() { 17 | @Suspendable 18 | override fun call(): T { 19 | verifyMembership(flowSession.counterparty, networkID) 20 | return onOtherPartyMembershipVerified() 21 | } 22 | 23 | /** 24 | * Will be called once counterpart's membership is successfully verified 25 | */ 26 | @Suspendable 27 | abstract fun onOtherPartyMembershipVerified(): T 28 | 29 | /** 30 | * Identity of the BNO to verify counterpart's membership against 31 | */ 32 | abstract fun bnoIdentity(): Party 33 | 34 | @Suspendable 35 | private fun verifyMembership(initiator: Party, networkID: String?) { 36 | // Memberships list contains valid active memberships only. So we need to just make sure that the membership exists. 37 | subFlow(GetMembershipsFlow(bnoIdentity(), networkID))[initiator] ?: throw NotAMemberException(initiator) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/main/kotlin/com/r3/businessnetworks/membership/flows/member/support/BusinessNetworkAwareInitiatingFlow.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.flows.member.support 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.membership.flows.member.Utils.throwExceptionIfNotBNO 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.identity.Party 7 | 8 | /** 9 | * This flow is supposed to be extended by Business Network members for any member->BNO communications. 10 | * The flow verifies that the BNO is whitelisted in member's cordapp configuration. 11 | */ 12 | abstract class BusinessNetworkAwareInitiatingFlow(val bno: Party) : FlowLogic() { 13 | @Suspendable 14 | override fun call(): T { 15 | throwExceptionIfNotBNO(bno, serviceHub) 16 | return afterBNOIdentityVerified() 17 | } 18 | 19 | @Suspendable 20 | abstract fun afterBNOIdentityVerified(): T 21 | } -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/test/kotlin/com/r3/businessnetworks/membership/flows/SelfIssueMembershipFlowTest.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.flows 2 | 3 | import com.natpryce.hamkrest.assertion.assertThat 4 | import com.natpryce.hamkrest.equalTo 5 | import com.natpryce.hamkrest.isA 6 | import com.natpryce.hamkrest.throws 7 | import com.r3.businessnetworks.membership.states.MembershipContract 8 | import net.corda.core.flows.FlowException 9 | import org.junit.Test 10 | 11 | 12 | class SelfIssueMembershipFlowTest : AbstractFlowTest( 13 | numberOfBusinessNetworks = 2, 14 | numberOfParticipants = 4, 15 | participantRespondingFlows = listOf(NotificationsCounterFlow::class.java)) { 16 | 17 | @Test 18 | fun `self issue happy path`() { 19 | val bnoNode = bnoNodes.first() 20 | //membership state before activation 21 | val stx = runSelfIssueMembershipFlow(bnoNode) 22 | val outputTxState = stx.tx.outputs.single() 23 | val command = stx.tx.commands.single() 24 | assertThat(MembershipContract.CONTRACT_NAME, equalTo(outputTxState.contract)) 25 | assertThat(command.value, isA()) 26 | stx.verifyRequiredSignatures() 27 | } 28 | 29 | @Test 30 | fun `Flow should fail if membership already exists`() { 31 | val bnoNode = bnoNodes.first() 32 | 33 | runRequestMembershipFlow(bnoNode, bnoNode) 34 | assertThat({ runSelfIssueMembershipFlow(bnoNode) }, throws()) 35 | } 36 | 37 | @Test 38 | fun `only BNO should be able to start the flow`() { 39 | val participantNode = participantsNodes.first() 40 | assertThat({ runSelfIssueMembershipFlow(participantNode) }, throws()) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/test/kotlin/com/r3/businessnetworks/membership/testextensions/AmendMembershipMetadataFlowResponderWithCustomVerification.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.testextensions 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.membership.flows.bno.AmendMembershipMetadataFlowResponder 5 | import com.r3.businessnetworks.membership.flows.member.AmendMembershipMetadataFlow 6 | import net.corda.core.flows.FlowException 7 | import net.corda.core.flows.FlowSession 8 | import net.corda.core.flows.InitiatedBy 9 | import net.corda.core.transactions.TransactionBuilder 10 | 11 | @InitiatedBy(AmendMembershipMetadataFlow::class) 12 | class AmendMembershipMetadataFlowResponderWithCustomVerification(session: FlowSession) : AmendMembershipMetadataFlowResponder(session) { 13 | @Suspendable 14 | override fun verifyTransaction(builder: TransactionBuilder) { 15 | throw FlowException("Invalid metadata") 16 | } 17 | } -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/test/kotlin/com/r3/businessnetworks/membership/testextensions/AutoApprovingMembershipFlow.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.testextensions 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.businessnetworks.membership.flows.bno.RequestMembershipFlowResponder 5 | import com.r3.businessnetworks.membership.flows.bno.service.BNOConfigurationService 6 | import com.r3.businessnetworks.membership.flows.member.RequestMembershipFlow 7 | import com.r3.businessnetworks.membership.states.MembershipState 8 | import net.corda.core.flows.FlowSession 9 | import net.corda.core.flows.InitiatedBy 10 | 11 | @InitiatedBy(RequestMembershipFlow::class) 12 | class AutoApprovingMembershipFlow(session: FlowSession) : RequestMembershipFlowResponder(session) { 13 | 14 | @Suspendable 15 | override fun activateRightAway(membershipState: MembershipState, configuration: BNOConfigurationService): Boolean { 16 | return true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/test/kotlin/com/r3/businessnetworks/membership/testextensions/RequestMembershipFlowResponderWithMetadataVerification.kt: -------------------------------------------------------------------------------- 1 | package com.r3.businessnetworks.membership.testextensions 2 | 3 | import com.r3.businessnetworks.membership.flows.bno.RequestMembershipFlowResponder 4 | import com.r3.businessnetworks.membership.flows.member.RequestMembershipFlow 5 | import net.corda.core.flows.FlowException 6 | import net.corda.core.flows.FlowSession 7 | import net.corda.core.flows.InitiatedBy 8 | import net.corda.core.transactions.TransactionBuilder 9 | 10 | @InitiatedBy(RequestMembershipFlow::class) 11 | class RequestMembershipFlowResponderWithMetadataVerification(session: FlowSession) : RequestMembershipFlowResponder(session) { 12 | override fun verifyTransaction(builder: TransactionBuilder) { 13 | throw FlowException("Invalid metadata") 14 | } 15 | } -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/test/resources/membership-service-without-bno-whitelist.conf: -------------------------------------------------------------------------------- 1 | bnoName = "O=BNO,L=New York,C=US" 2 | notaryName = "O=Notary,L=London,C=GB" -------------------------------------------------------------------------------- /bn-apps/memberships-management/membership-service/src/test/resources/membership-service.conf: -------------------------------------------------------------------------------- 1 | bnoName = "O=BNO,L=New York,C=US" 2 | notaryName = "O=Notary,L=London,C=GB" 3 | bnoWhitelist = ["O=BNO_0,L=New York,C=US", "O=BNO_1,L=New York,C=US", "O=BNO_2,L=New York,C=US", "O=BNO_3,L=New York,C=US", "O=BNO_4,L=New York,C=US"] -------------------------------------------------------------------------------- /bn-apps/memberships-management/test-utils/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | dependencies { 3 | classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version" 4 | } 5 | } 6 | 7 | apply plugin: 'kotlin' 8 | apply plugin: 'net.corda.plugins.cordapp' 9 | apply plugin: 'net.corda.plugins.cordformation' 10 | apply plugin: 'net.corda.plugins.quasar-utils' 11 | apply plugin: "kotlin-jpa" 12 | 13 | cordapp { 14 | targetPlatformVersion 4 15 | minimumPlatformVersion 1 16 | contract { 17 | name "solutions-testing-cordapp" 18 | vendor "com.r3" 19 | licence "http://www.apache.org/licenses/LICENSE-2.0" 20 | versionId 1 21 | } 22 | signing { 23 | enabled false 24 | } 25 | } 26 | 27 | dependencies { 28 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 29 | testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" 30 | testCompile "junit:junit:$junit_version" 31 | 32 | // Corda integration dependencies 33 | cordaCompile "$corda_release_group:corda-core:$corda_release_version" 34 | cordaCompile "$corda_release_group:corda-rpc:$corda_release_version" 35 | cordaCompile "$corda_release_group:corda-node-api:$corda_release_version" 36 | cordaRuntime "$corda_release_group:corda:$corda_release_version" 37 | testCompile "$corda_release_group:corda-node-driver:$corda_release_version" 38 | } 39 | 40 | tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { 41 | kotlinOptions { 42 | languageVersion = "1.2" 43 | apiVersion = "1.2" 44 | jvmTarget = "1.8" 45 | javaParameters = true // Useful for reflection. 46 | } 47 | } -------------------------------------------------------------------------------- /bn-apps/memberships-management/test-utils/src/main/kotlin/com/r3/bno/testing/SimpleMetaData.kt: -------------------------------------------------------------------------------- 1 | package com.r3.bno.testing 2 | 3 | import net.corda.core.serialization.CordaSerializable 4 | 5 | @CordaSerializable 6 | data class SimpleMembershipMetadata(val role: String = "", val displayedName: String = "") 7 | 8 | @CordaSerializable 9 | data class SomeCustomMembershipMetadata(val someCustomField: String) -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse, ctags, Mac metadata, log files 2 | .DS_Store 3 | .vscode 4 | 5 | # General build files 6 | **/build/* 7 | **/builddoctrees/* 8 | -------------------------------------------------------------------------------- /docs/build-docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Compiles the docs in the source folder from rst format to html using Sphinx (Sphinx should be installed in your Python folder to work) 4 | /C/Python27/Scripts/sphinx-build.exe -b html -d build\doctrees source build/html 5 | -------------------------------------------------------------------------------- /docs/ext/conditional_toctree.py: -------------------------------------------------------------------------------- 1 | import re 2 | from docutils.parsers.rst import directives 3 | from sphinx.directives.other import TocTree 4 | 5 | def setup(app): 6 | app.add_directive('conditional-toctree', ConditionalTocTree) 7 | ConditionalTocTree.defined_tags = app.tags.tags.keys() 8 | return {'version': '1.0.0'} 9 | 10 | def tag(argument): 11 | return directives.choice(argument, ('htmlmode', 'pdfmode')) 12 | 13 | class ConditionalTocTree(TocTree): 14 | 15 | defined_tags = [] 16 | has_content = True 17 | required_arguments = 0 18 | optional_arguments = 0 19 | final_argument_whitespace = False 20 | option_spec = { 21 | 'maxdepth': int, 22 | 'name': directives.unchanged, 23 | 'caption': directives.unchanged_required, 24 | 'glob': directives.flag, 25 | 'hidden': directives.flag, 26 | 'includehidden': directives.flag, 27 | 'titlesonly': directives.flag, 28 | 'reversed': directives.flag, 29 | 'if_tag': tag, 30 | } 31 | 32 | def run(self): 33 | if_tag = self.options.get('if_tag') 34 | if if_tag in self.defined_tags: 35 | return TocTree.run(self) 36 | else: 37 | return [] 38 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/install-docsite-requirements.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # The purpose of this file is to install the requirements for the docsite 3 | # You can call it manually if running make manually, otherwise gradle will run it for you 4 | 5 | set -xeo pipefail 6 | 7 | # Install the virtualenv 8 | if [ ! -d "virtualenv" ] 9 | then 10 | # If the canonical working directory contains whitespace, virtualenv installs broken scripts. 11 | # But if we pass in an absolute path that uses symlinks to avoid whitespace, that fixes the problem. 12 | # If you run this script manually (not via gradle) from such a path alias, it's available in PWD: 13 | absolutevirtualenv="$PWD/virtualenv" 14 | # Check if python2.7 is installed explicitly otherwise fall back to the default python 15 | if type "python2.7" > /dev/null; then 16 | virtualenv -p python2.7 "$absolutevirtualenv" 17 | else 18 | virtualenv "$absolutevirtualenv" 19 | fi 20 | fi 21 | 22 | # Activate the virtualenv 23 | if [ -d "virtualenv/bin" ] 24 | then 25 | # it's a Unix system 26 | source virtualenv/bin/activate 27 | else 28 | source virtualenv/Scripts/activate 29 | fi 30 | 31 | # Install PIP requirements 32 | if [ ! -d "virtualenv/lib/python2.7/site-packages/sphinx" ] 33 | then 34 | echo "Installing pip dependencies ... " 35 | pip install -r requirements.txt 36 | fi 37 | -------------------------------------------------------------------------------- /docs/make-docsite.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # The purpose of this file is to make the docsite in a python virtualenv 3 | # You can call it manually if running make manually, otherwise gradle will run it for you 4 | 5 | # Activate the virtualenv 6 | if [ -d "virtualenv/bin" ] 7 | then 8 | # it's a Unix system 9 | source virtualenv/bin/activate 10 | else 11 | source virtualenv/Scripts/activate 12 | fi 13 | 14 | make html 15 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | alabaster==0.7.8 2 | Babel==2.3.4 3 | certifi==2018.4.16 4 | chardet==3.0.4 5 | CommonMark==0.5.5 6 | docutils==0.12 7 | future==0.16.0 8 | idna==2.6 9 | imagesize==0.7.1 10 | Jinja2==2.10.1 11 | m2r==0.1.14 12 | MarkupSafe==0.23 13 | mistune==0.8.3 14 | packaging==17.1 15 | pdfrw==0.4 16 | Pillow==6.2.0 17 | Pygments==2.3.1 18 | pyparsing==2.2.0 19 | pytz==2016.4 20 | reportlab==3.4.0 21 | requests==2.20.0 22 | rst2pdf==0.93 23 | six==1.10.0 24 | snowballstemmer==1.2.1 25 | Sphinx==1.7.4 26 | sphinx-rtd-theme==0.1.9 27 | sphinxcontrib-websupport==1.0.1 28 | typing==3.6.4 29 | urllib3==1.24.2 30 | -------------------------------------------------------------------------------- /docs/source/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse, ctags, Mac metadata, log files 2 | .DS_Store 3 | 4 | # General build files 5 | **/build/* 6 | 7 | -------------------------------------------------------------------------------- /docs/source/_static/codesets.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | $(".codeset").each(function(index, el) { 3 | var c = $("
KotlinJava
"); 4 | var kotlinButton = c.children()[0]; 5 | var javaButton = c.children()[1]; 6 | kotlinButton.onclick = function() { 7 | $(el).children(".highlight-java")[0].style.display = "none"; 8 | $(el).children(".highlight-kotlin")[0].style.display = "block"; 9 | javaButton.setAttribute("class", ""); 10 | kotlinButton.setAttribute("class", "current"); 11 | }; 12 | javaButton.onclick = function() { 13 | $(el).children(".highlight-java")[0].style.display = "block"; 14 | $(el).children(".highlight-kotlin")[0].style.display = "none"; 15 | kotlinButton.setAttribute("class", ""); 16 | javaButton.setAttribute("class", "current"); 17 | }; 18 | 19 | if ($(el).children(".highlight-java").length == 0) { 20 | // No Java for this example. 21 | javaButton.style.display = "none"; 22 | } 23 | c.insertBefore(el); 24 | }); 25 | }); -------------------------------------------------------------------------------- /docs/source/_static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/_static/favicon.ico -------------------------------------------------------------------------------- /docs/source/_static/images/fg002_corda_w3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/_static/images/fg002_corda_w3.png -------------------------------------------------------------------------------- /docs/source/_static/irs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/_static/irs.png -------------------------------------------------------------------------------- /docs/source/_static/versions: -------------------------------------------------------------------------------- 1 | { 2 | "https://docs.corda.r3.com/releases/release-V3.0": "V3.0" 3 | } 4 | -------------------------------------------------------------------------------- /docs/source/_templates/layout.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | {% extends "!layout.html" %} 6 | {% block sidebartitle %} 7 | {{ super() }} 8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /docs/source/_templates/layout_for_doc_website.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% extends "!layout.html" %} 4 | {% block sidebartitle %} 5 | {{ super() }} 6 | % endblock %} 7 | 8 | {% block footer %} 9 | 25 | 26 | 36 | {% endblock %} 37 | -------------------------------------------------------------------------------- /docs/source/business-networks/business-network-playbook/intro.rst: -------------------------------------------------------------------------------- 1 | Business Network Playbook 2 | ------------------------- 3 | 4 | Having set the scene for Corda business networks, it is useful to think about specific tasks and their 5 | implications for how any particular business network will commence, be governed, and operated. We introduce these considerations in the form of a "playbook". 6 | 7 | The playbook is not intended to be exhaustive, and is considered a living document. More content will be added as 8 | everyone gains insight into what makes for the recommended practices for all participants within a Corda business 9 | network ecosystem. 10 | 11 | .. toctree:: 12 | :maxdepth: 1 13 | 14 | structure 15 | governance 16 | operations 17 | -------------------------------------------------------------------------------- /docs/source/business-networks/business-network-playbook/structure.rst: -------------------------------------------------------------------------------- 1 | S. Structure 2 | ------------ 3 | 4 | Any business network requires an operating structure. This may mean we are reusing, extending, or 5 | repurposing, an existing non-DLT based business network organisation. We may also be creating a new legal entity. Activities in this section aim to help establish a strawman structure. More detailed needs are addressed in following sections. 6 | 7 | S.1. Define Business Network Mission 8 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 9 | 10 | - Describe the purpose of the network. If existing, does repurposing the network on Corda alter the mission? 11 | - Describe asset type(s) involved, exchanged, affected in the business transactions. 12 | - Describe the participants at a high level (details covered later). 13 | 14 | S.2. Assign Business Network Roles 15 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 16 | 17 | - Business Network Governor (BNG)? 18 | - Business Network Operator (BNO)? 19 | - If the BN already exists, are there roles already established that should be included or mapped to the above roles? 20 | 21 | S.3. Define the Governance Body Model 22 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 23 | 24 | - Model structure, e.g., hierarchical, committee, etc. 25 | - Responsibilities 26 | - References: 27 | 28 | - https://www2.deloitte.com/content/dam/Deloitte/global/Documents/Financial-Services/dttl-fsi-US-FSI-Developinganeffectivegovernance-031913.pdf 29 | - https://pdfs.semanticscholar.org/275d/b03e55f0224bb66f7c1c36c586d86d75fc3b.pdf 30 | - https://www.swift.com/about-us/organisation-governance 31 | -------------------------------------------------------------------------------- /docs/source/business-networks/how-do-business-networks-start.rst: -------------------------------------------------------------------------------- 1 | How Do Business Networks Start? 2 | ------------------------------- 3 | 4 | Now that we have an idea of what a business network is, we might now ask how a Corda business network gets started? 5 | 6 | While no single approach exists, there are a few common routes. Sometimes a business network already exists, and it simply adopts Corda. Other cases might involve the creation of a governing consortium or may be the result of a prototype or proof-of-concept design. It is worth noting that while there are many possible journeys toward creating a Corda business network, the outcome is, generally, similar. 7 | 8 | Top-Down (Business-Led) 9 | ^^^^^^^^^^^^^^^^^^^^^^^ 10 | 11 | A top-down journey usually starts by recognising a valuable business problem, identifying likely participants, and creating a new venture, or consortium. Typically, this route requires the creation and adoption of technical standards, and a definition of governance principles. This usually evolves to include specialised resources such as Corda developers and legal advisors. 12 | 13 | Bottom-Up (Technology-Led) 14 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 15 | 16 | Sometimes a business network is the result of a developer or technology team building a prototype, or proof-of-concept to address a business problem. In these cases, the technology should align with a suitable problem and governance structure. While it may be easy to dismiss this as a solution looking for a problem, there has been a surprising degree of success with this type of approach, and this embraces the possibility of there being very simple solutions to non-controversial problems. 17 | 18 | Adoptive 19 | ^^^^^^^^ 20 | 21 | In some instances, a structure similar to a Corda business network may already exist. In such cases it is wise to consider 22 | adopting it. It may be possible to leverage existing governing policies and operational procedures where they are applicable, and modifying them were necessary to accommodate the blockchain nuances. 23 | 24 | -------------------------------------------------------------------------------- /docs/source/business-networks/interoperability.rst: -------------------------------------------------------------------------------- 1 | Interoperability 2 | ---------------- 3 | Our vision for Corda is a platform that allows the universal interoperability of public networks but with the privacy of point-to-point communication. The Corda Network provides a global and openly governed environment with strong identity and privacy assurances, whereas business networks enable parties known to each other to execute transactions following agreed upon business processing in an efficient and trusted manner. 4 | 5 | Our architecture supports interoperability among business networks. Since Corda nodes support the loading of multiple CorDapps, it is possible for a node to participate in multiple business networks simultaneously whilst still conforming to the policies and processes that each defines. 6 | 7 | This is important as it facilitates atomic transactions across different asset types which is a core element of R3's overall vision. The following diagram illustrates this: 8 | 9 | .. image:: resources/interop.png 10 | :scale: 80% 11 | :align: center 12 | 13 | 14 | Here we see a three interoperable business networks with assets and contracts defined in three separate node plugins (CorDapps). Alice, Carl, Demi and Clara are participants in multiple networks whilst the remaining parties are only involved in one. 15 | 16 | We can make the following observations: 17 | 18 | - The networks are (potentially) independently operated and governed. 19 | - Each network enforces its own access control policies and processes. 20 | - Multi-assets transactions are validated by contracts in multiple CorDapps. 21 | - The owners of each node make their own determination about which business networks they choose to participate. 22 | 23 | -------------------------------------------------------------------------------- /docs/source/business-networks/intro.rst: -------------------------------------------------------------------------------- 1 | Corda Business Networks 2 | ======================= 3 | In 2016, the design concepts for Corda were described for the first time in Mike Hearn's `technical whitepaper 4 | `_. It defined a general platform for decentralised application development. While the paper described the concept of "CorDapps" (Corda Distributed Applications) and how these might be constructed, it did not attempt to provide much more detail. 5 | 6 | Building and managing distributed applications is more involved than just creating software. In a CorDapp, information and/or assets are exchanged, or transacted, between participants because they represent something meaningful to each participant. But how is the meaningfulness of the exchanged information determined, on what basis, and by whom? Such are the considerations we aim to understand. 7 | 8 | Our problem is not particularly new. There are many examples of companies and consortiums predating blockchain or 9 | DLT (Distributed Ledger) technology that have brought people together to transact value. 10 | The blockchain vision enabled by Corda is different because it was designed to eliminate many of the 11 | problems inherent in earlier approaches. 12 | 13 | First, let us give our problem a name: We have a group, or network, of independent parties that want to 14 | use Corda to transact something of value, and as we're transacting something valuable then this almost inevitably implies a commercial, or business purpose. As such, we can talk about a "Business Network". 15 | 16 | .. toctree:: 17 | :maxdepth: 1 18 | 19 | what-is-a-business-network 20 | how-do-business-networks-start 21 | roles-and-responsibilities 22 | business-network-operator-node 23 | interoperability 24 | business-network-playbook/intro 25 | -------------------------------------------------------------------------------- /docs/source/business-networks/resources/bno1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/business-networks/resources/bno1.png -------------------------------------------------------------------------------- /docs/source/business-networks/resources/interop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/business-networks/resources/interop.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/complexity/complexity-commands-coupling.rst: -------------------------------------------------------------------------------- 1 | --------------------- 2 | Coupling Via Commands 3 | --------------------- 4 | 5 | The proposed approach is to tie two or more transitions together across two or more States or instances of the same State by linking their Commands. Diagrammatically: 6 | 7 | .. image:: ../resources/complexity/CMN2_C_Command_coupling_1.png 8 | :width: 60% 9 | :align: center 10 | 11 | The linkages are expressed through the Transaction Level Constraints. 12 | 13 | For the representation, we can’t draw arrows to tie commands together, it would quickly make the model unreadable and restrict the linkages we could represent, especially if linkages could be to many different States. Instead, we reference the linked Command from the Command which is imposing the restriction. 14 | 15 | .. image:: ../resources/complexity/CMN2_C_Command_coupling_2.png 16 | :width: 60% 17 | :align: center 18 | 19 | The interpretation of this diagram is that any transaction that has StateA under ContractA invoking Command X, will not be valid unless there is a StateB under ContractB invoking Command Y also in the transaction. 20 | 21 | This approach leads to two types of linkage: 22 | 23 | 1. Single direction Linkage 24 | 25 | As in the diagram above, the restriction is one way, Command X is not valid without Command Y, but Command Y can be invoked without Command X. An example of this might be a DVP transaction. A bond sales might mandate that cash changes hands, but a cash state would not mandate that it can only be used for settling bonds. 26 | 27 | 2. Two directional linkage 28 | 29 | Where both commands specify that they cannot be invoked without the other one being present in the transaction. 30 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/complexity/complexity-flow-coupling.rst: -------------------------------------------------------------------------------- 1 | ------------------- 2 | Flow Level Coupling 3 | ------------------- 4 | 5 | This is the loosest form of coupling, there is no coupling at the State Machine level, any coupling is purely done by including the States to be coupled in the same Transaction when assembling the Transaction in the flows. 6 | 7 | Note, using Flow Level Coupling does not provide any guarantees of behaviour at the Transaction level. 8 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/complexity/complexity-overview.rst: -------------------------------------------------------------------------------- 1 | =================== 2 | Managing Complexity 3 | =================== 4 | 5 | So far, we have focused on representing CorDapps which have a single State type. However, production CorDapps are likely to have more than one type of Corda States interacting with each other. 6 | 7 | In order to cope with the increased complexity that multiple state types introduce, we can use the concepts of high cohesion and low coupling. From Wikipedia: 8 | 9 | * Cohesion refers to the degree to which the elements inside a module belong together. 10 | 11 | * Coupling is the degree of interdependence between software modules 12 | 13 | We can consider each of the Corda States represented by its own State Machine as a module. Hence, to achieve high cohesion the functions performed by the State should all be related. The challenge is to work out how to couple the modules. 14 | 15 | There are a number of potential couplings: 16 | 17 | .. toctree:: 18 | :maxdepth: 1 19 | 20 | complexity-flow-coupling.rst 21 | complexity-commands-coupling.rst 22 | complexity-stateref-coupling.rst 23 | complexity-linearid-coupling.rst 24 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/complexity/complexity-stateref-coupling.rst: -------------------------------------------------------------------------------- 1 | ------------------------------------------ 2 | Coupling to a State Instance via StateRefs 3 | ------------------------------------------ 4 | 5 | In some cases, a State will need to hold a reference to another specific instance of a state on the ledger. It can do this by including the StateRef in its properties. 6 | 7 | The StateRef consists of the hash of the transaction which created the referenced State and the index of the state in the transaction’s outputs, hence from the StateRef any previously state that has been committed to the ledger can be reference. Note, it doesn’t matter if the state is consumed or unconsumed. 8 | 9 | If the requestor doesn’t have the state in its vault, a flow will need to be implemented to get the state from a party who does have the state. 10 | 11 | This pattern may be useful when a piece of reference data, controlled by another entity needs to be tagged on to the state. 12 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/high-level-architecture/arch-corda-network.rst: -------------------------------------------------------------------------------- 1 | ------------------------ 2 | High Level Corda Network 3 | ------------------------ 4 | The High Corda Network view is designed to show all the participants relevant to a CorDapp running on the Corda Network. 5 | 6 | 7 | .. image:: ../resources/arch/CMN2_HLA_Corda_network.png 8 | :width: 100% 9 | :align: center 10 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/high-level-architecture/arch-high_level_process.rst: -------------------------------------------------------------------------------- 1 | ------------------------------- 2 | High Level Process Architecture 3 | ------------------------------- 4 | The High Level Process Architecture view is designed to show all processes required to support a CorDapp operating in a Corda Business Network 5 | 6 | 7 | 8 | .. image:: ../resources/arch/CMN2_HLA_High_level_process.png 9 | :width: 80% 10 | :align: center 11 | 12 | Points to note: 13 | 14 | * Not all processes will have a technical component 15 | * Not all processes will be necessary for a Minimum Viable Product (MVP) 16 | * The processes are arranged in a hierarchical drill down 17 | * The CorDApp Core Processes will be specific to the particular CorDapp being designed 18 | * The BNO Processes are a suggested set of processes that a BNO might need to run 19 | * To show further detail for each white box, use the BPMN view 20 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/high-level-architecture/arch-overview.rst: -------------------------------------------------------------------------------- 1 | ============================= 2 | High Level Architecture Views 3 | ============================= 4 | 5 | 6 | These view give suggested ways to map out the high level architecture of a CorDapp or Corda Business Network 7 | 8 | 9 | .. toctree:: 10 | :maxdepth: 1 11 | 12 | arch-high_level_process.rst 13 | arch-corda-network.rst 14 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/overview/overview-aims.rst: -------------------------------------------------------------------------------- 1 | -------------------------------- 2 | Aims of CorDap Design Language 3 | -------------------------------- 4 | 5 | In summary, CorDapp Design Language should: 6 | 7 | 1. Allow CorDapp designs to be represented in an accurate, clear and concise way to aid common understanding and reasoning over the design. 8 | 9 | 2. Describe and enable reasoning about key aspects of CorDapp design: 10 | 11 | * Shared data and state 12 | * Shared processing logic 13 | * Permissioning (via digital signatures) 14 | * Privacy (Visibility of data to different participants) 15 | * Security 16 | 17 | 18 | 19 | 3. Draw a clear distinction between Ledger Layer and Orchestration Layer functionality. 20 | 21 | 4. Cope with increase complexity, importantly the design language must not scale in complexity faster than the underlying application that the Model is representing. 22 | 23 | 5. Degrade gracefully and accurately. Not all aspects of the notations should be compulsory, but where details are left off the remaining diagram should remain accurate and self consistent for the level of detail chosen. 24 | 25 | 6. Minimised new representation techniques by reusing and extending existing architecture and design techniques. 26 | 27 | 7. Allows standardised representation of reusable design patterns, including techniques for managing complexity. 28 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/overview/overview-complexity.rst: -------------------------------------------------------------------------------- 1 | ---------------------------- 2 | Managing Complexity with CDL 3 | ---------------------------- 4 | 5 | The Managing Complexity in CDL section considers how to scale complexity in a CorDapp by applying the concepts of high cohesion / low coupling to CorDapp designs. 6 | 7 | It proposes splitting the design into modules where individual Corda State types provide related functionality (high cohesion) which are then (loosely) coupled together by one of four mechanisms: 8 | 9 | 1) Flow level coupling 10 | 2) Commands coupling 11 | 3) Coupling to a State instance via StateRefs 12 | 4) Coupling to a state’s evolution via LinearId 13 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/overview/overview-overview.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | Overview of CDL 3 | =============== 4 | 5 | From working with several of R3’s members and partners, a common challenge is how to write down a CorDapp design. A CorDapp has a lot of interacting parts: States, Contracts, Flows, Transactions, API’s, Participants, Signers. It’s difficult to capture, and hence reason, about the behaviour of the whole CorDapp. 6 | 7 | There is a risk that if inappropriate representation techniques are used, important dimensions of the design could be obscured leading to sub-optimal design decisions. Working on a design when you can’t quite write it down can also cause poor communication and inefficiencies within teams, this can lead to frustration and we want people to be happy using Corda. 8 | 9 | Corda Design Language (CDL) is a bespoke design Language used to accurately represent and reason about CorDapp designs. 10 | 11 | The overview has the following sections: 12 | 13 | .. toctree:: 14 | :maxdepth: 1 15 | 16 | overview-whycdl.rst 17 | overview-aims.rst 18 | overview-views.rst 19 | overview-privacy.rst 20 | overview-complexity.rst 21 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/overview/overview-privacy.rst: -------------------------------------------------------------------------------- 1 | ======================== 2 | Analysing Privacy in CDL 3 | ======================== 4 | 5 | The Analysing Privacy in CDL section considers how to represent and reason about Privacy in CorDapps and Corda Networks. 6 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/privacy/privacy-expressing-requirements.rst: -------------------------------------------------------------------------------- 1 | ------------------------------- 2 | Expressing Privacy Requirements 3 | ------------------------------- 4 | 5 | In order to reason about privacy, we need to be able to express which parties should be able to see which data. 6 | 7 | We can do this using a simple mapping between the Actors in a design and the aggregate data set for the Cordapp. taking the example of a syndicated loan, the privacy map might look a bit like this: 8 | 9 | 10 | .. image:: ../resources/privacy/CMN2_P_privacy_map.png 11 | :width: 80% 12 | :align: center 13 | 14 | 15 | Privacy maps can get a little more complicated when we have to consider the visibility of Actors involved in not only this transaction but prior transactions which gave rise to the input states for this transaction. For example, in the Previous Delivery vs Payment example, the Privacy map might look like this: 16 | 17 | 18 | .. image:: ../resources/privacy/CMN2_P_privacy_map_bond_cash.png 19 | :width: 90% 20 | :align: center 21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/privacy/privacy-overview.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | Analysing Privacy 3 | ================= 4 | 5 | Privacy is key to safe CorDapp design. CDL provides an approach to analysing the privacy characteristics of a CorDApp. 6 | 7 | 8 | .. toctree:: 9 | :maxdepth: 1 10 | 11 | privacy-why-model.rst 12 | privacy-analysing.rst 13 | privacy-expressing-requirements.rst 14 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/privacy/privacy-why-model.rst: -------------------------------------------------------------------------------- 1 | ----------------- 2 | Why Model Privacy 3 | ----------------- 4 | 5 | Privacy is one of the major selling points of Corda. Much is made of it's peer to peer nature and the fact that transactions are not broadcast to the whole of the Network. But there is an important subtlety here: for a transaction to be valid, parties needs assurance of the provenance of it's input states, this often involves receiving transactions from the historic chain of states leading to the current transaction. Corda has built in functionality to resolve these historic transactions via the ResolveTransactionFlow. However, care needs to be taken when designing CorDapps to ensure that resolution of a transaction doesn't lead to parties obtaining historic information which they should not get visibility of, for example, the transactions of their competitors. 6 | 7 | There are design patterns to preserve privacy such as Confidential Identities and Chain-snipping, and in the future SGX has much to offer, but these need to be actively designed into CorDapps. A CorDapp designer needs to be confident in the privacy characteristics of the application. In order to be able to reason about privacy we need a mechanism for analysing Privacy in the context of Corda. The CMN privacy overlays aims to meet this need. 8 | 9 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/arch/CMN2_HLA_Corda_network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/arch/CMN2_HLA_Corda_network.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/arch/CMN2_HLA_High_level_process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/arch/CMN2_HLA_High_level_process.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/complexity/CMN2_C_Command_coupling_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/complexity/CMN2_C_Command_coupling_1.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/complexity/CMN2_C_Command_coupling_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/complexity/CMN2_C_Command_coupling_2.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/complexity/CMN2_C_Linearid-coupling-attachment-state.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/complexity/CMN2_C_Linearid-coupling-attachment-state.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/complexity/CMN2_C_Linearid_coupling_state_instance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/complexity/CMN2_C_Linearid_coupling_state_instance.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Agreement_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Agreement_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Attachment_reference_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Attachment_reference_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Attachment_state_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Attachment_state_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_BPMN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_BPMN.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_BPMN_high_level.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_BPMN_high_level.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Cash_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Cash_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Cordapp_split.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Cordapp_split.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Coupling_commands_dig1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Coupling_commands_dig1.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Coupling_commands_dig2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Coupling_commands_dig2.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Coupling_full_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Coupling_full_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Full_sequence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Full_sequence.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Instance_view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Instance_view.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Instance_view_arrows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Instance_view_arrows.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Multiplicity_constraints.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Multiplicity_constraints.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Reduced_sequence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Reduced_sequence.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Reduced_sequence_with_arrows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Reduced_sequence_with_arrows.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Required_signers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Required_signers.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Transaction_constraints.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Transaction_constraints.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Transaction_equivalent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Transaction_equivalent.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Transaction_instance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Transaction_instance.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Transaction_instance_with_arrows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Transaction_instance_with_arrows.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_Visibility_constraint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_Visibility_constraint.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/old/CMN_refined_box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/old/CMN_refined_box.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/overview/CMN2_O_BPMN_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/overview/CMN2_O_BPMN_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/overview/CMN2_O_FS_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/overview/CMN2_O_FS_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/overview/CMN2_O_Layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/overview/CMN2_O_Layers.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/overview/CMN2_O_SE_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/overview/CMN2_O_SE_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/overview/CMN2_O_SI_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/overview/CMN2_O_SI_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/overview/CMN2_O_SM_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/overview/CMN2_O_SM_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/overview/CMN2_O_State.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/overview/CMN2_O_State.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/overview/CMN2_O_TI_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/overview/CMN2_O_TI_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/privacy/CMN2_P_Example_all_parties.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/privacy/CMN2_P_Example_all_parties.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/privacy/CMN2_P_Example_partyD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/privacy/CMN2_P_Example_partyD.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/privacy/CMN2_P_Example_state_evolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/privacy/CMN2_P_Example_state_evolution.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/privacy/CMN2_P_Example_state_machines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/privacy/CMN2_P_Example_state_machines.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/privacy/CMN2_P_privacy_map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/privacy/CMN2_P_privacy_map.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/privacy/CMN2_P_privacy_map.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/privacy/CMN2_P_privacy_map.xlsx -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/privacy/CMN2_P_privacy_map_bond_cash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/privacy/CMN2_P_privacy_map_bond_cash.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/privacy/~$CMN2_P_privacy_map.xlsx: -------------------------------------------------------------------------------- 1 | Matthew Bradbury Matthew Bradbury -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CDL_SE_Branching_transition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CDL_SE_Branching_transition.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CDL_SE_Reference_state.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CDL_SE_Reference_state.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_BPMN_Bpmn_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_BPMN_Bpmn_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_BPMN_High_level.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_BPMN_High_level.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_Degraded_state.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_Degraded_state.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_FS_Long.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_FS_Long.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_FS_Plantuml_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_FS_Plantuml_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_FS_Short.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_FS_Short.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_SE_State_evolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_SE_State_evolution.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_SE_Transaction_box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_SE_Transaction_box.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_SI_State_instance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_SI_State_instance.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_SM_Cash_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_SM_Cash_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_SM_Full_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_SM_Full_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_SM_Multiplicity_constraints.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_SM_Multiplicity_constraints.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_SM_Signing_constraints_box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_SM_Signing_constraints_box.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_SM_Signing_constraints_inline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_SM_Signing_constraints_inline.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_SM_Simplified_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_SM_Simplified_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_SM_State_level_constraints.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_SM_State_level_constraints.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_SM_Transaction_equivalent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_SM_Transaction_equivalent.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_SM_Transaction_level_constraints.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_SM_Transaction_level_constraints.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_SM_Visibility_constraints.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_SM_Visibility_constraints.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_State.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_State.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/resources/views/CMN2_TI_Transaction_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/corda-modelling-notation/resources/views/CMN2_TI_Transaction_example.png -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/todo.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | Change Transaction Instance view - to match State Evolution - or delete it ??? 4 | 5 | 3. Add analysis sections 6 | 7 | 4. Add ledger time step diagram 8 | 9 | 5. Add high level flows diagram 10 | 11 | 5. Rework mapping to the code 12 | 13 | 6. Add worked example (from Alice's project) 14 | 15 | 7. add cordapp frame work spreadsheet. 16 | 17 | 8. add extra flaw in Token design pattern 18 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/views/views-flow-sequence.rst: -------------------------------------------------------------------------------- 1 | ============================= 2 | Flow Sequence (Orchestration) 3 | ============================= 4 | 5 | For representing flows you can use standard PlantUml style sequence diagrams, for example: 6 | 7 | .. image:: ../resources/views/CMN2_FS_Plantuml_example.png 8 | :width: 60% 9 | :align: center 10 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/views/views-overview.rst: -------------------------------------------------------------------------------- 1 | ========= 2 | CDL Views 3 | ========= 4 | 5 | CDL provides a number of views representing different aspects of a CorDapp design: 6 | 7 | .. toctree:: 8 | :maxdepth: 1 9 | 10 | views-common-concepts.rst 11 | views-state-machine.rst 12 | views-state-evolution.rst 13 | views-state-instance.rst 14 | views-bpmn.rst 15 | views-transaction-instance.rst 16 | views-flow-sequence.rst 17 | -------------------------------------------------------------------------------- /docs/source/corda-modelling-notation/views/views-transaction-instance.rst: -------------------------------------------------------------------------------- 1 | ==================================== 2 | Transaction Instance (Orchestration) 3 | ==================================== 4 | 5 | To specify the required Transaction corresponding to a business event, we use the Transaction Instance view. This consists of writing down the specific Transaction that needs to occur for the particular business event. 6 | 7 | .. image:: ../resources/views/CMN2_TI_Transaction_example.png 8 | :width: 80% 9 | :align: center 10 | 11 | 12 | 1. Inputs: 13 | 14 | Shows all the input States including the relevant properties and participants. Note, these are instances of States so the actual participants and properties should be shown. 15 | 16 | 2. Transaction Parameters: 17 | 18 | Shows the Commands, Actual Signatures, any Attachments, the valid Time-window for notarising the transaction and the participants which consist of the union of the participants in the states. 19 | 20 | Note, any extra participants which the transaction will be distributed to via the flows are not shown here as they don’t form part of the transaction. 21 | 22 | 3. Outputs: 23 | 24 | Shows all the output States including relevant properties and participants. Note, these are instances of States so the actual participants and properties should be shown. 25 | -------------------------------------------------------------------------------- /docs/source/deployment/intro.rst: -------------------------------------------------------------------------------- 1 | Deployment options 2 | ====================== 3 | 4 | These are guidelines for deploying Corda Enterprise and the Corda Enterprise Firewall for use in the Corda Network from different perspectives. 5 | 6 | Currently the recommendation is to follow the on-premises deployment guide for production use. 7 | 8 | The Kubernetes deployment option is there to provide you with an idea of utilising Kubernetes strengths in deploying to cloud environments. 9 | 10 | .. toctree:: 11 | :maxdepth: 1 12 | :titlesonly: 13 | 14 | onprem/intro 15 | kubernetes/intro 16 | -------------------------------------------------------------------------------- /docs/source/deployment/kubernetes/considerations.rst: -------------------------------------------------------------------------------- 1 | Considerations 2 | ============== 3 | 4 | The following section on Kubernetes deployment for a Corda Node is considered **experimental** and should not be used in a production environment until sufficient testing has been done. 5 | 6 | The deployment can be used for setting up test environments and gaining familiarity around orchestrating a deployment of a Corda Node along with a Corda Firewall. 7 | 8 | The current version of the Kubernetes deployment only has support for Microsoft Azure cloud service built in, but with some customisation it should be portable to any other cloud environment as well. 9 | -------------------------------------------------------------------------------- /docs/source/deployment/kubernetes/intro.rst: -------------------------------------------------------------------------------- 1 | Corda Kubernetes Deployment 2 | =========================== 3 | 4 | .. line-block:: 5 | Kubernetes shines in orchestrating complex connection scenarios between multiple components and allowing these components to self-heal and recover from errors. 6 | The Corda Node is quite a complex system to deploy when it is deployed with Corda Firewall and potentially utilising HSM for storing private key material. 7 | This Kubernetes deployment is created to show you how to set up the different components in a Kubernetes cluster while still catering to best security practices. 8 | 9 | Having said that, this deployment is still in its early stages and should be considered **experimental**. 10 | 11 | 12 | .. toctree:: 13 | :maxdepth: 1 14 | 15 | considerations 16 | architecture-overview 17 | prerequisites 18 | corda-kubernetes-deployment 19 | -------------------------------------------------------------------------------- /docs/source/deployment/kubernetes/resources/KubernetesDeploymentArchitecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/kubernetes/resources/KubernetesDeploymentArchitecture.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/additional-info.rst: -------------------------------------------------------------------------------- 1 | Additional information 2 | ====================== 3 | Here you will find background and supplemental information 4 | 5 | 6 | .. toctree:: 7 | :maxdepth: 1 8 | 9 | concepts-background-information 10 | flagdays 11 | -------------------------------------------------------------------------------- /docs/source/deployment/onprem/corda-network-access-details.rst: -------------------------------------------------------------------------------- 1 | Important Corda Network Details 2 | =============================== 3 | 4 | The details of joining the Corda Network, be it UAT or Production, are shared individually once agreements are set. 5 | Information about the Corda Network Foundation is found here https://corda.network/. 6 | 7 | There are currently 3 environments offered: 8 | 9 | `Testnet 10 | `_ 11 | 12 | `UAT 13 | `_ 14 | 15 | `Corda Network 16 | `_ 17 | 18 | -------------------------------------------------------------------------------- /docs/source/deployment/onprem/intro.rst: -------------------------------------------------------------------------------- 1 | On-Premises Deployment 2 | ====================== 3 | These are guidelines for deploying Corda Enterprise and the Corda Enterprise Firewall for use in the Corda Network from an on-premises perspective. While this document focuses on those on-premises deployment details, you may read more about joining the Corda Network here https://corda.network/. 4 | Corda uniquely enables P2P Corda Networking within security constraints of corporate networking architectures. Corda restricts access to Corda Nodes 5 | from other Corda Nodes by way of valid identity certificates that are known in a Corda Network Map that is shared among accepted Nodes. 6 | 7 | 8 | .. toctree:: 9 | :maxdepth: 5 10 | :titlesonly: 11 | 12 | bank-deploy-overview 13 | corda-node-architecture-components 14 | prerequisites-sizing 15 | node-firewall-deployment 16 | node-registration 17 | start-components 18 | monitoring 19 | corda-network-access-details 20 | additional-info 21 | kill-flow 22 | corda-health-checker 23 | -------------------------------------------------------------------------------- /docs/source/deployment/onprem/monitoring.rst: -------------------------------------------------------------------------------- 1 | Monitoring 2 | ========== 3 | 4 | Corda components such as Node, Bridge & Float write system messages to log files similar to many other platforms. These log files can be consumed and managed by commercially available data analysis platforms. 5 | 6 | There is a detailed section on monitoring and available options here : https://docs.corda.r3.com/design/monitoring-management/design.html?highlight=monitoring 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/CordaFirewallConfigAlign.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/CordaFirewallConfigAlign.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/access.conf: -------------------------------------------------------------------------------- 1 | 1552502594.525 70615 10.1.0.30 TCP_TUNNEL/200 30087 CONNECT netmap.uat.corda.network:443 - HIER_DIRECT/51.140.164.141 - 2 | -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/bridge.conf: -------------------------------------------------------------------------------- 1 | // 2 | // R3 Proprietary and Confidential 3 | // 4 | // Copyright (c) 2018 R3 Limited. All rights reserved. 5 | // 6 | // The intellectual and technical concepts contained herein are proprietary to R3 and itssuppliers and are protected by trade secret law. 7 | // 8 | // Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited. 9 | bridgeMode = BridgeInner 10 | outboundConfig : { 11 | artemisBrokerAddress = "hostname-where-corda-node-is-running:11005" 12 | // alternateArtemisBrokerAddresses = [ "backup-hostname-where-corda-node-is-running:11005" ] 13 | } 14 | bridgeInnerConfig : { 15 | floatAddresses = ["hostname-where-float-is-running:12005"] 16 | // floatAddresses = ["hostname-where-float-is-running:12005", "backup-hostname-where-float-is-running:12005"] 17 | expectedCertificateSubject = "CN=Float Local,O=Local Only,L=London,C=GB" 18 | customSSLConfiguration : { 19 | keyStorePassword = "bridgepass" 20 | trustStorePassword = "trustpass" 21 | sslKeystore = "./bridgecerts/bridge.jks" 22 | trustStoreFile = "./bridgecerts/trust.jks" 23 | crlCheckSoftFail = true 24 | } 25 | } 26 | networkParametersPath = network-parameters 27 | -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/config.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/cordadir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/cordadir.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/cordarch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/cordarch.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/firewallpki.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/firewallpki.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/float.conf: -------------------------------------------------------------------------------- 1 | // 2 | // R3 Proprietary and Confidential 3 | // 4 | // Copyright (c) 2018 R3 Limited. All rights reserved. 5 | // 6 | // The intellectual and technical concepts contained herein are proprietary to R3 and its suppliers and are protected by trade secret law. 7 | // 8 | // Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited. 9 | bridgeMode = FloatOuter 10 | inboundConfig : { 11 | listeningAddress = "hostname-where-float-is-running:10005" 12 | } 13 | floatOuterConfig : { 14 | floatAddress = "hostname-where-float-is-running:12005" 15 | expectedCertificateSubject = "CN=Bridge Local,O=Local Only,L=London,C=GB" 16 | customSSLConfiguration : { 17 | keyStorePassword = "floatpass" 18 | trustStorePassword = "trustpass" 19 | sslKeystore = "./floatcerts/float.jks" 20 | trustStoreFile = "./floatcerts/trust.jks" 21 | crlCheckSoftFail = true 22 | } 23 | } 24 | networkParametersPath = network-parameters 25 | -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/ha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/ha.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/node.conf: -------------------------------------------------------------------------------- 1 | Azure SQL/SQL SERVER 2 | 3 | "dataSourceProperties" : { 4 | 5 | "dataSource" : { 6 | 7 | "url" : "jdbc:sqlserver://SQLSERVER:1433;database=DATABASE;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;", 8 | 9 | "user" : "USER" 10 | 11 | "password" : "PASSWORD" 12 | 13 | }, 14 | 15 | "dataSourceClassName" : "com.microsoft.sqlserver.jdbc.SQLServerDataSource" 16 | 17 | } 18 | 19 | postGres RDBMS 20 | 21 | "dataSourceProperties" : { 22 | 23 | "dataSource" : { 24 | 25 | "url" : "jdbc:postgresql://SERVERNAME:5432/DATABASENAME", 26 | 27 | "user" : "user", 28 | 29 | "password" : "password" 30 | 31 | }, 32 | 33 | "dataSourceClassName" : "org.postgresql.ds.PGSimpleDataSource" 34 | 35 | }, 36 | 37 | Oracle RDBMS 38 | 39 | "dataSourceProperties" : { 40 | 41 | "dataSourceClassName" : "oracle.jdbc.pool.OracleDataSource", 42 | 43 | "dataSource" : { 44 | 45 | "url" : "jdbc:oracle:thin:@SERVERNAME:1521/DATABASENAME", 46 | 47 | "user" : "user", 48 | 49 | "password" : "password" 50 | 51 | } 52 | -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/nodebridgefloat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/nodebridgefloat.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/nodebridgefloat_nbrs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/nodebridgefloat_nbrs.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/nodereg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/nodereg.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/nodestart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/nodestart.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/nonha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/nonha.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/overview.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/pki-keys.conf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | keytool -genkeypair -keyalg EC -keysize 256 -alias floatroot -validity 1000 -dname "CN=Float Root,O=Local Only,L=London,C=GB" -ext bc:ca:true,pathlen:1 -keystore floatca.jks -storepass capass -keypass cakeypass 5 | sleep 3 6 | keytool -genkeypair -keyalg EC -keysize 256 -alias bridgecert -validity 1000 -dname "CN=Bridge Local,O=Local Only,L=London,C=GB" -ext bc:ca:false -keystore bridge.jks -storepass bridgepass -keypass bridgepass 7 | sleep 3 8 | keytool -genkeypair -keyalg EC -keysize 256 -alias floatcert -validity 1000 -dname "CN=Float Local,O=Local Only,L=London,C=GB" -ext bc:ca:false -keystore float.jks -storepass floatpass -keypass floatpass 9 | sleep 3 10 | keytool -exportcert -rfc -alias floatroot -keystore floatca.jks -storepass capass -keypass cakeypass > root.pem 11 | sleep 3 12 | keytool -importcert -noprompt -file root.pem -alias root -keystore trust.jks -storepass trustpass 13 | sleep 3 14 | keytool -certreq -alias bridgecert -keystore bridge.jks -storepass bridgepass -keypass bridgepass |keytool -gencert -ext ku:c=dig,keyEncipherment -ext: eku:true=serverAuth,clientAuth -rfc -keystore floatca.jks -alias floatroot -storepass capass -keypass cakeypass > bridge.pem 15 | sleep 3 16 | cat root.pem bridge.pem >> bridgechain.pem 17 | sleep 3 18 | keytool -importcert -noprompt -file bridgechain.pem -alias bridgecert -keystore bridge.jks -storepass bridgepass -keypass bridgepass 19 | sleep 3 20 | keytool -certreq -alias floatcert -keystore float.jks -storepass floatpass -keypass floatpass |keytool -gencert -ext ku:c=dig,keyEncipherment -ext: eku:true=serverAuth,clientAuth -rfc -keystore floatca.jks -alias floatroot -storepass capass -keypass cakeypass > float.pem 21 | sleep 3 22 | cat root.pem float.pem >> floatchain.pem 23 | sleep 3 24 | keytool -importcert -noprompt -file floatchain.pem -alias floatcert -keystore float.jks -storepass floatpass -keypass floatpass 25 | 26 | -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/platform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/platform.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/registration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/registration.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/socks.conf: -------------------------------------------------------------------------------- 1 | socksProxyConfig { 2 | version = SOCKS5 3 | proxyAddress = "PROXYSERVER:1080" 4 | userName = "user" 5 | password = "password" 6 | } 7 | 8 | -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/squidconfig.conf: -------------------------------------------------------------------------------- 1 | acl SSL_ports port 443 2 | acl Safe_ports port 8080 3 | acl CONNECT method CONNECT 4 | http_access allow all 5 | http_port 8080 6 | refresh_pattern ^ftp: 1440 20% 10080 7 | refresh_pattern ^gopher: 1440 0% 1440 8 | refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 9 | refresh_pattern (Release|Packages(.gz)*)$ 0 20% 2880 10 | refresh_pattern . 0 20% 4320 11 | debug_options ALL,3 12 | -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/squidstatus.conf: -------------------------------------------------------------------------------- 1 | cordaadmin@corda-firewall-proxies:~$ sudo systemctl status squid 2 | ● squid.service - LSB: Squid HTTP Proxy version 3.x 3 | Loaded: loaded (/etc/init.d/squid; generated) 4 | Active: active (running) since Wed 2019-03-13 18:44:10 UTC; 14min ago 5 | Docs: man:systemd-sysv-generator(8) 6 | Process: 14135 ExecStop=/etc/init.d/squid stop (code=exited, status=0/SUCCESS) 7 | Process: 14197 ExecStart=/etc/init.d/squid start (code=exited, status=0/SUCCESS) 8 | Tasks: 4 (limit: 4915) 9 | CGroup: /system.slice/squid.service 10 | ├─14261 /usr/sbin/squid -YC -f /etc/squid/squid.conf 11 | ├─14263 (squid-1) -YC -f /etc/squid/squid.conf 12 | ├─14265 (logfile-daemon) /var/log/squid/access.log 13 | └─14267 (pinger) 14 | 15 | Mar 13 18:44:10 corda-firewall-proxies systemd[1]: Starting LSB: Squid HTTP Proxy version 3. 16 | Mar 13 18:44:10 corda-firewall-proxies squid[14197]: * Starting Squid HTTP Proxy squid 17 | Mar 13 18:44:10 corda-firewall-proxies squid[14261]: Squid Parent: will start 1 kids 18 | Mar 13 18:44:10 corda-firewall-proxies squid[14197]: ...done. 19 | Mar 13 18:44:10 corda-firewall-proxies systemd[1]: Started LSB: Squid HTTP Proxy version 3.x 20 | Mar 13 18:44:10 corda-firewall-proxies squid[14261]: Squid Parent: (squid-1) process 14263 21 | -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/subzone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/subzone.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/vault-relations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/vault-relations.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/resources/vault.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/deployment/onprem/resources/vault.png -------------------------------------------------------------------------------- /docs/source/deployment/onprem/start-components.rst: -------------------------------------------------------------------------------- 1 | Start Components 2 | ================ 3 | 4 | The components should be started in the following order: 5 | 6 | 1. Float 7 | #. Node 8 | #. Bridge 9 | 10 | Please note that corda-bridgeserver.jar is used by both Bridge and Float. The JAR file assumes its input is bridge.conf however this may be overridden with the --config-file parameter so you can designate whatever config file name you wish to use. 11 | 12 | Starting Float 13 | ~~~~~~~~~~~~~~ 14 | 15 | On the Float VM run: 16 | 17 | /usr/bin/java -Xmx1024m -jar /opt/corda/corda-bridgeserver-3.2.jar --config-file float.conf 18 | 19 | You should see the following output: 20 | 21 | .. sourcecode:: shell 22 | 23 | FloatSupervisorService: active = false 24 | FloatSupervisorService: active = true 25 | 26 | .. 27 | 28 | 29 | Starting Corda Node 30 | ~~~~~~~~~~~~~~~~~~~ 31 | 32 | On the Node VM run: 33 | 34 | /usr/bin/java -Xmx2048m -jar /opt/corda/corda-3.2.jar --config-file node.conf 35 | 36 | .. literalinclude:: resources/nodestart.conf 37 | :language: bash 38 | 39 | 40 | 41 | Starting Bridge 42 | ~~~~~~~~~~~~~~~ 43 | 44 | On the Bridge VM run: 45 | 46 | /usr/bin/java -Xmx1024m -jar /opt/corda/corda-bridgeserver-3.2.jar 47 | 48 | You should see the following output in the Bridge: 49 | 50 | .. sourcecode:: shell 51 | 52 | BridgeSupervisorService: active = false 53 | BridgeSupervisorService: active = true 54 | 55 | .. 56 | 57 | You should see the following output in the Float log: 58 | 59 | .. sourcecode:: shell 60 | 61 | Now listening for incoming connections on VM-Of-Float-Public-IP:Port 62 | 63 | .. 64 | -------------------------------------------------------------------------------- /docs/source/design-patterns/antipatterns/antipatterns-overview.rst: -------------------------------------------------------------------------------- 1 | ===================== 2 | CorDapp Anti-Patterns 3 | ===================== 4 | 5 | 6 | 7 | There a some designs for CorDapps which have been found to have sub-optimal results. 8 | 9 | The Anti-patterns Library is intended to be a used by CorDapps designers and developers to help them not fall into known traps. It will be added to as more Anti-patterns are identified 10 | 11 | Anti-patterns: 12 | 13 | .. toctree:: 14 | :maxdepth: 1 15 | 16 | dual-roles-for-nodes.rst 17 | check-ownership-of-all-input-states.rst 18 | unknown-commands.rst 19 | -------------------------------------------------------------------------------- /docs/source/design-patterns/antipatterns/dual-roles-for-nodes.rst: -------------------------------------------------------------------------------- 1 | ==================== 2 | Dual roles for nodes 3 | ==================== 4 | 5 | 6 | There are at least 4 different node types in Corda, including: 7 | 8 | Regular transacting node 9 | Validating Notary node 10 | Non-Validating Notary node 11 | Oracle node 12 | Note: we might also have nodes who do not own any assets, but should sign as tx "approvers" (i.e., regulators/auditors etc). 13 | 14 | We recommend against having a dual or multiple role (any combination of the above), especially if the same key(s) are used to sign for processes related to different roles. 15 | For instance, if one node acts as an Oracle and a regular node at the same time and it uses the same legal identity key, the following attack vector is possible. 16 | 17 | 1. Oracles sign filtered transactions and they can only see the commands related to their business (i.e., a command including fx-rates). 18 | 19 | 2. If this Oracle-RegularNode entity has assets owned by the same key used for "oraclisation", then a malicious user might know some unconsumed states owned by this key (i.e., through graph tracing or if they've transacted in the past) and use them as input states in the oraclised transaction (and send them to keys controlled by the attacker). 20 | 21 | 3. Then, the Oracle will sign the filtered transaction, in which these "injected" states (owned by the Oracle itself) won't be visible. 22 | 23 | 4. The latter means that the Oracle blindly approved the contents of the transaction and will lose ownership of its assets after the transaction is notarised. 24 | 25 | Note: the above attack (and its variants) can be performed against other role combinations as well. 26 | -------------------------------------------------------------------------------- /docs/source/design-patterns/antipatterns/unknown-commands.rst: -------------------------------------------------------------------------------- 1 | ================ 2 | Unknown Commands 3 | ================ 4 | 5 | Contract.verify does not handle all Commands and does not fail if it encounters an unknown command 6 | 7 | The recommended approach is to handle all possible Commands in contract.verify, and to add an else branch that fails. 8 | 9 | Also, to use the available utility methods like: ``tx.commands.requireSingleCommand``, to make sure there's no ambiguity. However, this will not be suitable if there needs to be multiple Commands in one transaction, in that case use ``tx.commandsOfType()`` where Commands is defined in the Contract. This will isolate the Commands relevant to a particular Contract. 10 | 11 | 12 | This protects against an attack where a node tries to bypass all checks by somehow abusing the Commands. 13 | -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/asset-lock.rst: -------------------------------------------------------------------------------- 1 | ================== 2 | Asset Lock Pattern 3 | ================== 4 | 5 | WIP 6 | 7 | The asset lock pattern purpose is to enable an asset to be locked out of use pending another event happening which allows the asset to be unlocked and transferred to a new Owner. 8 | 9 | The challenge is to set up the lock so that the lock can be released by somebody other than the owner once they have provided some consideration. This is difficult as the asset's own contract rules are likely to state that the current owner needs to sign to transfer ownership. 10 | 11 | It is likely that the asset has to have a rule that says it can be transferred without the owners signature if some form of precondition is proved to have been met. eg a lock state signed by the owner specifying asset that can be transferred, who it is transferred to and the condition for the transfer. 12 | 13 | 4 options mapped out so far. 14 | 15 | .. image:: resources/Asset-Lock-option-1.png 16 | :width: 80% 17 | :align: center 18 | 19 | 20 | .. image:: resources/Asset-Lock-option-2.png 21 | :width: 80% 22 | :align: center 23 | 24 | .. image:: resources/Asset-Lock-option-3.png 25 | :width: 80% 26 | :align: center 27 | 28 | .. image:: resources/Asset-Lock-option-4.png 29 | :width: 80% 30 | :align: center 31 | 32 | for option 4 - doesn't actually lock the asset, so not an asset lock, it only gives the ability for someone other than the owner to move the asset. 33 | 34 | 35 | Note, if need to guarantee that only a specific counterparty can pay the consideration, then the counterparty can pass H(Secret) to the asset owner. when the asset owner creates the asset lock, a pre-condition is that the consideration state must reveal the matching secret. 36 | -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/billing-with-receipts.rst: -------------------------------------------------------------------------------- 1 | =============================== 2 | Billing With ChipOffs/ Receipts 3 | =============================== 4 | 5 | WIP 6 | 7 | ** need to correct Diagram for privacy traceback (like receipts) + update github implementation readme 8 | 9 | ------- 10 | Summary 11 | ------- 12 | 13 | Allows a Business Network Operator (BNO) to Bill for transactions occuring on a Corda network without being a participant on, or receiveing copies of, those transactions. 14 | 15 | ------------ 16 | Key features 17 | ------------ 18 | 19 | - uses the Receipts pattern 20 | 21 | 22 | The 'Billing With Chip Offs' Pattern can be used for billing and metering on Business Networks. The Pattern has a notion of Billing Chips that can be included into Corda transactions which participants need to pay for. Billing Chips never cross a single transaction boundaries (when created, Billing Chips can be consumed in an exactly one transaction) and hence never cause privacy leaks. All Billing Chips are attached to their respective Billing States, that accumulate the total spent amount and can be safely reported back to the BNO without leaking the transaction history which the in Billing Chips have been involved. 23 | 24 | 25 | Diagrams: 26 | 27 | .. image:: resources/Billing-State-evolution-diagram-v3.png 28 | :width: 80% 29 | :align: center 30 | 31 | 32 | .. image:: resources/Billing-state-with-combine-v2.png 33 | :width: 80% 34 | :align: center 35 | -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/business-pattern.rst: -------------------------------------------------------------------------------- 1 | ===================== 2 | Business Deal Pattern 3 | ===================== 4 | 5 | WIP 6 | 7 | Generic 'Business deal' Pattern (all 'on-ledger') combines Asset lock, Receipts/ token-receipts, propose-agree patterns such that: 8 | 9 | - Two parties can agree to a deal, where some arbitrary state transition will take place only if another party makes payment with a payment asset. 10 | - The deal is atomic, if payment is not made, the state transition doesn't take place, recreating the original state. (ie the deal unwinds) 11 | - The payment asset does not leak information about previous transactions it has been used to pay for. (core problem with niaive DVP approach) 12 | - Both partys can consent to the deal, ie possible for a human to decline. (Not possible in Collectsignatures flow) 13 | - Confidential identites protect identity of previous payment asset owners. 14 | 15 | (Illustrated in notes with Asset moving for Cash) 16 | 17 | .. image:: resources/propose-lock-pay-1.jpg 18 | :width: 80% 19 | :align: center 20 | 21 | .. image:: resources/propose-lock-pay-2.jpg 22 | :width: 80% 23 | :align: center 24 | 25 | .. image:: resources/propose-lock-pay-3.jpg 26 | :width: 80% 27 | :align: center 28 | 29 | .. image:: resources/propose-lock-pay-4.jpg 30 | :width: 80% 31 | :align: center 32 | -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/design-principles.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | Design principles 3 | ================= 4 | 5 | 6 | Controls over other Party's go in the Contracts, not the Flows 7 | 8 | Favour small transactions over large transactions 9 | 10 | Minimum participants necessary on a transaction 11 | -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/ref-states.rst: -------------------------------------------------------------------------------- 1 | =========================================== 2 | Reference States as a proof of current data 3 | =========================================== 4 | 5 | WIP 6 | 7 | References states can be used to prove that a state is current, even though that state is not consumed in the transaction. 8 | 9 | For example, say the GBP-USD FX rate is represented by a DailyFXRateState. Every day the previous day's DailyFXRateState is consumed and replaced by a new DailyFXRateState containing the new rate. 10 | 11 | Two counterparties want to perform a USD - GBP FX swap. 12 | 13 | The transaction has: 14 | - 15 USD(owner A) -> 15 USD(owner B) 15 | - 10 GBP(owner B) -> 10GBP(owner A ) 16 | - refstate( dailyFXRateState = 1.5 ) 17 | 18 | The swap Contract rules say that the transaction is not valid unless there s a current DailyFXRateState included in the transaction as a reference state. 19 | 20 | If the transaction references the current (unconsumed) dailyFXRateState, then the transaction will verify. 21 | If the transaction tries to reference yesterday's (consumed) DailyFXRateState the transaction will not verify and the transaction will fail. 22 | 23 | 24 | 25 | Anti pattern: 26 | 27 | Note, one possible application of reference states would be to reference a transferred Cash or asset state as proof of payment to allow a transfer to take place eg transfer some other assets. This is problematic as you have to be careful not to allow the same cash state to be referenced in multiple transactions, ie similar to double spending. 28 | 29 | This can be partially mitigated by agreeing a specific pre-agreed reference to be added to the cash state, however a malicious actor could deliberately set up two transactions with the same required cash reference and commit a double spend. 30 | -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/request-tree.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Request Tree 3 | ============ 4 | 5 | 6 | 7 | WIP 8 | 9 | Add details around state ownerships and modification rights 10 | 11 | 12 | 13 | .. image:: resources/Request-tree.png 14 | :width: 80% 15 | :align: center 16 | -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/resources/Asset-Lock-option-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/WIP/resources/Asset-Lock-option-1.png -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/resources/Asset-Lock-option-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/WIP/resources/Asset-Lock-option-2.png -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/resources/Asset-Lock-option-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/WIP/resources/Asset-Lock-option-3.png -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/resources/Asset-Lock-option-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/WIP/resources/Asset-Lock-option-4.png -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/resources/Billing-State-evolution-diagram-v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/WIP/resources/Billing-State-evolution-diagram-v2.png -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/resources/Billing-State-evolution-diagram-v3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/WIP/resources/Billing-State-evolution-diagram-v3.png -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/resources/Billing-state-with-combine-v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/WIP/resources/Billing-state-with-combine-v2.png -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/resources/Pattern-relationships.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/WIP/resources/Pattern-relationships.png -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/resources/Propose-agree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/WIP/resources/Propose-agree.png -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/resources/Request-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/WIP/resources/Request-tree.png -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/resources/propose-lock-pay-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/WIP/resources/propose-lock-pay-1.jpg -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/resources/propose-lock-pay-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/WIP/resources/propose-lock-pay-2.jpg -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/resources/propose-lock-pay-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/WIP/resources/propose-lock-pay-3.jpg -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/resources/propose-lock-pay-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/WIP/resources/propose-lock-pay-4.jpg -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/WIP/wip-overview.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | ======================================== 4 | Work in Progress CorDapp Design Patterns 5 | ======================================== 6 | 7 | The following Design Patterns library is Work in progress, more patterns will be added as they are developed. 8 | 9 | 10 | .. toctree:: 11 | :maxdepth: 1 12 | 13 | asset-lock 14 | asset-lock-pattern 15 | billing-with-receipts 16 | business-pattern 17 | design-principles 18 | propose-agree 19 | ref-states 20 | request-tree 21 | template 22 | 23 | -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/patterns-overview.rst: -------------------------------------------------------------------------------- 1 | ======================= 2 | CorDapp Design Patterns 3 | ======================= 4 | 5 | 6 | This Design Patterns library is Work in progress, more patterns will be added as they are developed. 7 | 8 | 9 | .. toctree:: 10 | :maxdepth: 1 11 | 12 | receipts.rst 13 | token-receipts.rst 14 | -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/resources/P_Receipts_state_evolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/resources/P_Receipts_state_evolution.png -------------------------------------------------------------------------------- /docs/source/design-patterns/patterns/resources/P_Token_receipts_state_evolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/design-patterns/patterns/resources/P_Token_receipts_state_evolution.png -------------------------------------------------------------------------------- /docs/source/designs/resources/Membership_approval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/designs/resources/Membership_approval.png -------------------------------------------------------------------------------- /docs/source/designs/resources/Membership_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/designs/resources/Membership_request.png -------------------------------------------------------------------------------- /docs/source/designs/resources/Membership_revocation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/designs/resources/Membership_revocation.png -------------------------------------------------------------------------------- /docs/source/designs/resources/Membership_snapshot_distribution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/designs/resources/Membership_snapshot_distribution.png -------------------------------------------------------------------------------- /docs/source/designs/resources/Metadata_amendment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/designs/resources/Metadata_amendment.png -------------------------------------------------------------------------------- /docs/source/designs/resources/ledger_sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/docs/source/designs/resources/ledger_sync.png -------------------------------------------------------------------------------- /docs/source/faq.rst: -------------------------------------------------------------------------------- 1 | Frequently asked questions 2 | ========================== 3 | 4 | What is this site for? 5 | ---------------------- 6 | 7 | This site sets out to explain how to use Corda to solve real problems. It doesn't tell you what Corda is, nor does 8 | it seek to describe how it's built, but instead focuses on how to use it to the best of its capabilities. 9 | 10 | Where did all the content come from? 11 | ------------------------------------ 12 | 13 | All the content was produced to help solve some of the problems posed by real decentralised applications. You can find 14 | a list of contributors at: https://github.com/corda/corda-solutions/blob/master/CONTRIBUTORS.md 15 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | name=Test 2 | group=com.template 3 | version=0.1 4 | kotlin.incremental=false -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/corda/corda-solutions/fdc9d37a3d63acaa11fc836269305a5c31a4be6a/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip 6 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':docs' 2 | include ':bn-apps:ledger-sync:ledger-sync-service' 3 | include ':bn-apps:memberships-management:membership-service' 4 | include ':bn-apps:memberships-management:membership-service-contracts-and-states' 5 | include ':bn-apps:cordapp-updates-distribution:corda-updates-app' 6 | include ':bn-apps:cordapp-updates-distribution:corda-updates-app-states' 7 | include ':bn-apps:cordapp-updates-distribution:corda-updates-core' 8 | include ':bn-apps:cordapp-updates-distribution:corda-updates-test-utils' 9 | include ':bn-apps:cordapp-updates-distribution:corda-updates-transport' 10 | include ':bn-apps:billing:billing-app' 11 | include ':bn-apps:billing:billing-contracts-and-states' 12 | include ':bn-apps:billing:billing-demo' 13 | include ':bn-apps:businessnetworks-utilities' 14 | include ':bn-apps:businessnetworks-test-utilities' 15 | include ':bn-apps:memberships-management:test-utils' 16 | 17 | --------------------------------------------------------------------------------