diff --git a/LICENSE b/180Dashboard/LICENSE similarity index 100% rename from LICENSE rename to 180Dashboard/LICENSE diff --git a/180Dashboard/src/store/consumer/actions.js b/180Dashboard/src/store/consumer/actions.js index 945da7d..6610d5c 100644 --- a/180Dashboard/src/store/consumer/actions.js +++ b/180Dashboard/src/store/consumer/actions.js @@ -1,9 +1,6 @@ export async function createAggregationRequest(dispatch, apiUrl, payload) { const requestOptions = { method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, body: JSON.stringify(payload) }; try { @@ -25,10 +22,7 @@ export async function createAggregationRequest(dispatch, apiUrl, payload) { export async function fetchEncryptedDataOutput(dispatch, apiUrl, payload) { const requestOptions = { - method: 'GET', - headers: { - 'Content-Type': 'application/json' - } + method: 'GET' }; let userInfo = JSON.parse(localStorage.getItem('user')); @@ -52,9 +46,6 @@ export async function fetchEncryptedDataOutput(dispatch, apiUrl, payload) { export async function fetchDecryptedDataOutput(dispatch, apiUrl, payload) { const requestOptions = { method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, body: JSON.stringify(payload) }; diff --git a/180Dashboard/src/store/provider/actions.js b/180Dashboard/src/store/provider/actions.js index 6eb0bbb..8d6afe2 100644 --- a/180Dashboard/src/store/provider/actions.js +++ b/180Dashboard/src/store/provider/actions.js @@ -23,10 +23,7 @@ export async function upload(dispatch, apiUrl, payload) { export async function fetchEncryptedRewardsData(dispatch, apiUrl, payload) { const requestOptions = { - method: 'GET', - headers: { - 'Content-Type': 'application/json' - } + method: 'GET' }; let userInfo = JSON.parse(localStorage.getItem('user')); @@ -50,9 +47,6 @@ export async function fetchEncryptedRewardsData(dispatch, apiUrl, payload) { export async function fetchDecryptedRewardsData(dispatch, apiUrl, payload, dateCreated) { const requestOptions = { method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, body: JSON.stringify(payload) }; diff --git a/180Dashboard/src/userInfo.yml b/180Dashboard/src/userInfo.yml index adc5ced..dd60c2c 100644 --- a/180Dashboard/src/userInfo.yml +++ b/180Dashboard/src/userInfo.yml @@ -23,9 +23,9 @@ rewards: uniqueness: 20 updateFrequency: 30 dataTypes: - - value: fixedIncomeDemandData + - value: testSchema2 label: Fixed Income Demand Data - - value: riskMetricsData + - value: testSchema1 label: Risk Metrics Data - value: esgData label: ESG Data diff --git a/180Dashboard/src/views/app/consumer/Dashboard/Dashboard.jsx b/180Dashboard/src/views/app/consumer/Dashboard/Dashboard.jsx index 038a55f..5ce86ce 100644 --- a/180Dashboard/src/views/app/consumer/Dashboard/Dashboard.jsx +++ b/180Dashboard/src/views/app/consumer/Dashboard/Dashboard.jsx @@ -69,8 +69,8 @@ const Dashboard = (props) => { "options": { "trackProgress": true }, - "dataType": values.dataType.value, - "description": values.description + "dataType": values.dataType.value + //"description": values.description }; let response = await createAggregationRequest(dispatch, props.apiUrl, params); diff --git a/README.md b/README.md index dbdc399..9198c47 100644 --- a/README.md +++ b/README.md @@ -1,91 +1,164 @@ -# 180Protocol POC +# 180Protocol -180Protocol is a next generation collaborative computing framework that helps unlock value in private data. Businesses -can utilize 180Protocol to create coalitions - private networks on R3 Corda - to share their private structured data assets. -Coalitions are composed of corda nodes that can act as Data Providers and Data Consumers, and a coalition host. +### Introduction +180Protocol is an open-source software toolkit for data sharing. 180Protocol represents the next evolution of data +sharing infrastructure, an infrastructure that ensures a secure, rewarding, and efficient data sharing experience. + +180Protocol targets enterprise use cases and is uniquely positioned to improve the value and mobility of sensitive and +confidential business data. The software introduces distributed network design to the problem of enterprise data sharing, +solving for the legacy barriers that have limited data mobility and value. We make data available where it needs to be, +without moving it and transforming it along they way. + +Enterprises/Developers can utilize 180Protocol to create coalitions - private networks on R3 Corda - to share their +private structured data assets. Coalitions are composed of corda nodes that can act as Data Providers and Data Consumers, +and a coalition host. * Data Providers - nodes that have pre-approved structured private data assets that they want to share and be rewarded for -* Data Consumer - nodes that have a need to consume data outputs +* Data Consumer - nodes that have a need to consume unique and commercially valuable data outputs * Coalition Host - node that runs the trusted enclave and arbitrates communication between providers and consumers 180Protocol comprises the following components: -1. **Protocol broker** - a set of corda flows that manage communication between data consumers and data providers -in a 180protocol coalition. The broker connects with the enclave based aggregator to enable consumers and providers to -share data and be rewarded for it. - -2. **Protocol aggregator** - a enclave based data transformation interface that can take flexible data input, data output, -and provenance definitions. Furthermore, a data transformation algorithm can be configured to map inputs to outputs. -The Aggregator includes a proprietary rewards engine that can be configured to reward data providers in a coalition for -their private data inputs. Since the aggregator runs inside a trusted enclave, with a pre verified attestation, providers -data inputs are rewarded unbiasedly. Furthermore, consumers get data outputs based on a known transformation algorithm. +1. **Aggregator SDK** - an enclave based data transformation interface that can take flexible data input, data output, +and provenance definitions. Furthermore, a data transformation algorithm can be configured to map inputs to an output. +In future releases, the Aggregator will include a proprietary rewards engine that can be configured to reward data providers +in a coalition for their private data inputs. Since the aggregator runs inside a trusted enclave, with a pre verified attestation, +providers data inputs are rewarded unbiasedly. Furthermore, consumers get data outputs based on a known transformation algorithm. -4. **180Dashboard** - a React based front end application that allows Data Providers and Data Consumers to keep track of +2. **180Dashboard** - a React based front end application that allows Data Providers and Data Consumers to keep track of shared data, view data aggregation history and keep track of rewards for each data aggregation. +3. **Codaptor** - a middleware that connects to the Corda RPC and generates OpenAPI bindings automatically for any CordApp + The above components can be used by application developers to create decentralized applications that enable private structured data to be shared, transformed and rewarded for in a secure way. -The 180ProtocolPoc is representative application built on the 180Protocol framework and can be utilized by developers +This repository contains a representative application built on the 180Protocol framework and can be utilized by developers as a blueprint to start building more complex applications. We encourage application developers and businesses to build -on 180Protocol and provide feedback so we can introduce better features over time. +on 180Protocol and provide feedback so we can introduce better features over time. + +Please read more detailed design and API specifications on our [Wiki](https://180protocol.gitbook.io/product-docs/) + +### Roadmap +This is the alpha release of 180Protocol and is experimental in nature. +There are improvements we plan to release in the coming weeks including - -**Contact: [management@180protocol.com](mailto:management@180protocol.com)** +1. We have tested the enclave based computations in the Enclave 'Mock' mode. We are testing deployment using an [MS Azure](https://azure.microsoft.com/en-gb/solutions/confidential-compute/) +cloud enclave +2. Introducing a regression based rewards engine that can be utilized within the Aggregator SDK +3. The Aggregator SDK workflows are consumer driven only. All providers in the network are required to share data when +requested by the consumer. We intend to introduce further variations of the Aggregation Flows that account for varied +commercial use cases +4. Supporting multiple enclave communication frameworks beyond R3 Conclave. We are currently testing compatibility with +[EGO](https://www.ego.dev/) +5. Introducing a variety of example use cases across industry verticals +6. Integrating the Aggregator SDK with a public blockchain to enable data providers to monetize their rewards using a token +economy + + +**Contact:** +* Commercial queries: [management@180protocol.com](mailto:management@180protocol.com) +* Developer Discord: [180Protocol Discord](https://discord.com/invite/vvA8sRbs) +* Community channels: [www.180protocol.com](https://www.180protocol.com/) ### How to run the 180Protocol POC The protocol poc comprises the 180Dashboard and pocCordApp modules. The 180 Dashboard is the React based front end and the -pocCordApp is the sample backend. +protocolAggregator is the sample backend. + +To build protocolAggregator: + +1. Run the `./gradlew build` command from within the protocolAggregator folder +2. Run `./gradlew deployNodes` command to generate nodes folder inside build folder. +3. Modify the `/protocolAggregator/build/nodes/runnodes` file generated by the `deployNodes` and replace the run commands +to include the `run-migration-scripts` and `--allow-hibernate-to-manage-app-schema` flags. Please read [here](https://docs.r3.com/en/platform/corda/4.7/open-source/tutorial-cordapp.html#deploying-the-cordapp-locally) + +Read the `protocolAggregator/README.md` for details around extension. -To build pocCordApp: +Change + + `if [ -z "$JAVA_HOME" ] && which osascript >/dev/null; then + /usr/libexec/java_home --exec java -jar runnodes.jar "$@" + else + "${JAVA_HOME:+$JAVA_HOME/bin/}java" -jar runnodes.jar "$@" + fi` + +to + + `if [ -z "$JAVA_HOME" ] && which osascript >/dev/null; then + /usr/libexec/java_home --exec java -jar corda.jar run-migration-scripts --core-schemas "$@" + /usr/libexec/java_home --exec java -jar corda.jar --allow-hibernate-to-manage-app-schema "$@" + else + "${JAVA_HOME:+$JAVA_HOME/bin/}java" -jar corda.jar run-migration-scripts --core-schemas "$@" + "${JAVA_HOME:+$JAVA_HOME/bin/}java" -jar corda.jar --allow-hibernate-to-manage-app-schema "$@" + fi` -1. Run the `./gradlew build` command from within the pocCordApp folder -2. Run `./gradlew deployNodes` command to generate nodes folder inside build folder. To run the sample 180ProtocolPOC Coalition network using Docker: -1. Run below command from the project root path to start 180Dashboard service & pocCordApp +1. Each data provider and consumer data can be viewed on the dashboard using their login credentials (corda node hostname as user and + port number as the password). Modify the file `180Dashboard/src/userInfo.yml` - + Ex, for provider A use + `nodes: + providerA: + username: providerA + password: test + port: 9500 + role: provider + name: O=Host,L=London,C=GB` + +2. Run below command from the project root path to start 180Dashboard service & protocolAggregator service using docker compose `docker-compose -f ./compose-corda-network.yml -f ./compose-codaptor.yml up` -2. The 180Dashboard can be accessed at `http://localhost:3000` on a browser -3. Each data provider data can be viewed on the dashboard using their login credentials (corda node hostname as user and -port number as the password) - -Ex, for provider A use -`username: partya-node -password: 9500` +3. The 180Dashboard can be accessed at `http://localhost:3000` on a browser + +And there you go! + +#### System requirements +The docker based network configuration is composed of several services (corda nodes, codaptor and react) and +thus requires significant memory and processing power. Hence, we recommend at least 16 GB RAM to support smooth running +of the entire coalition network on docker for end to end testing. Alternatively, for testing the back end, the react front end +can be not utilized. -#### Configuring 180Protocol Dashboard users info and rewards weights +#### Configuring 180Protocol Dashboard We provide a yaml file to configure the number of nodes in the coalition - providers or consumers - who have access to the 180Dashboard. Users can be configured in `userInfo.yml` provided under the `180Dashboard/src` directory. These -users must be in accordance with the Corda network setup configured under the `pocCordApp/build.gradle`. +users must be in accordance with the Corda network setup configured under the `protocolAggregator/build.gradle`. The corda network gradle config allows specifying the party name for each Corda node. This party name must also be specified under the userInfo.yml file. The node role (provider or consumer) can also be specified in the userInfo.yml. Further, the port number under userInfo.yml must be the same as that specified `compose-codaptor.yml` file. This is to ensure that the dashboard can query the correct OpenAPI endpoint for the said node. -Finally, the rewards weights used by the Rewards Engine must be configured for the dashboard to display correctly. +Finally, the rewards weights used by the Rewards Engine must be configured for the dashboard to display correctly (These +are representative for now and don't affect the back end) #### Adding a new node to the 180Protocol network To add a new node for the 180Protocol POC, configurations need to be added to the 180Dashboard, the Codaptor OpenAPI and the corda network configurations - -1. Corda Network: add the new node config under the `deployNodes` task of the `pocCordApp/build.gradle` file, e.x. - +1. Corda Network: add the new node config under the `deployNodes` task of the `protocolAggregator/build.gradle` file, e.x. - ``` node { - name "O=PartyB,L=New York,C=US" - p2pAddress "partyb-node:10008" - rpcSettings { - address("0.0.0.0:10009") - adminAddress("0.0.0.0:10049") - } - rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]] - } + name "O=Host,L=London,C=GB" + p2pAddress "host-node:10004" + rpcSettings { + address("0.0.0.0:10005") + adminAddress("0.0.0.0:10045") + } + cordapp (project(':workflows')) { + config '''\ + participantRole = COALITION_HOST + '''.stripIndent() + } + runSchemaMigration = true + rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]] + } ``` In the above, the name corresponds to the node name under the `180Dashboard/src/userInfo.yml`. Run the `deployNodes` @@ -112,4 +185,15 @@ For further details around Codaptor configurations see: [Codaptor](https://githu ``` Here the `username`, `password` are arbitrary but `port` and `role` need to follow the dependencies described in the steps above - +### Licenses + +Please take note of the license obligations you are bound under by downloading the source code. The repository contains +two folders, under different licenses - + +1. 180Dashboard - released under the Apache2.0 License +2. protocolAggregator - released under the GNU AGPL3.0 license + +Additionally, protocolAggregator has a dependency on R3 Conclave, which requires developers to download the Conclave API. +Please take a look at the R3 Conclave license considerations for further information. + +We have tried to emulate MongoDB's philosophy in this regard. Please [read further](https://www.mongodb.com/blog/post/the-agpl) \ No newline at end of file diff --git a/compose-codaptor.yml b/compose-codaptor.yml index ae85674..1fb1913 100644 --- a/compose-codaptor.yml +++ b/compose-codaptor.yml @@ -3,11 +3,11 @@ version: '2' services: codaptora: - image: b180tech/cordaptor:0.2.0-corda4.5-SNAPSHOT + image: b180tech/cordaptor:0.3.0-corda4.7-SNAPSHOT hostname: codaptora mem_limit: 512m environment: - - CORDA_RPC_NODE_ADDRESS=partya-node:10006 # using hostname known within the Docker network + - CORDA_RPC_NODE_ADDRESS=host-node:10005 # using hostname known within the Docker network - CORDA_RPC_USERNAME=user1 # this must match build.gradle - CORDA_RPC_PASSWORD=test # this must match build.gradle # we must override Cordaptor's default of binding to the loopback interface, @@ -18,15 +18,16 @@ services: - CORDAPTOR_API_EXTERNAL_ADDRESS=localhost:9500 # this must be consistent with the ports directive below ports: - "9500:8500" + - "9008:8008" volumes: # Corda RPC requires CorDapp JARs to be available in the classpath - - ./pocCordApp/build/nodes/PartyA/cordapps:/cordaptor/cordapps + - ./protocolAggregator/build/nodes/Host/cordapps:/cordaptor/cordapps codaptorb: - image: b180tech/cordaptor:0.2.0-corda4.5-SNAPSHOT + image: b180tech/cordaptor:0.3.0-corda4.7-SNAPSHOT hostname: codaptorb mem_limit: 512m environment: - - CORDA_RPC_NODE_ADDRESS=partyb-node:10009 # using hostname known within the Docker network + - CORDA_RPC_NODE_ADDRESS=providerb-node:10007 # using hostname known within the Docker network - CORDA_RPC_USERNAME=user1 # this must match build.gradle - CORDA_RPC_PASSWORD=test # this must match build.gradle # we must override Cordaptor's default of binding to the loopback interface, @@ -34,12 +35,33 @@ services: - CORDAPTOR_API_LISTEN_ADDRESS=0.0.0.0:8500 # this is necessary to allow Cordaptor to generate URLs (e.g. for OpenAPI bindings or Location headers) # using URL resolvable outside the Docker network - - CORDAPTOR_API_EXTERNAL_ADDRESS=localhost:9400 # this must be consistent with the ports directive below + - CORDAPTOR_API_EXTERNAL_ADDRESS=localhost:7500 # this must be consistent with the ports directive below ports: - - "9400:8500" + - "7500:8500" + - "7008:8008" volumes: # Corda RPC requires CorDapp JARs to be available in the classpath - - ./pocCordApp/build/nodes/PartyB/cordapps:/cordaptor/cordapps + - ./protocolAggregator/build/nodes/ProviderB/cordapps:/cordaptor/cordapps + codaptorc: + image: b180tech/cordaptor:0.3.0-corda4.7-SNAPSHOT + hostname: codaptorc + mem_limit: 512m + environment: + - CORDA_RPC_NODE_ADDRESS=consumerc-node:10009 # using hostname known within the Docker network + - CORDA_RPC_USERNAME=user1 # this must match build.gradle + - CORDA_RPC_PASSWORD=test # this must match build.gradle + # we must override Cordaptor's default of binding to the loopback interface, + # because we want its port to be visible on the Docker network + - CORDAPTOR_API_LISTEN_ADDRESS=0.0.0.0:8500 + # this is necessary to allow Cordaptor to generate URLs (e.g. for OpenAPI bindings or Location headers) + # using URL resolvable outside the Docker network + - CORDAPTOR_API_EXTERNAL_ADDRESS=localhost:6500 # this must be consistent with the ports directive below + ports: + - "6500:8500" + - "6008:8008" + volumes: + # Corda RPC requires CorDapp JARs to be available in the classpath + - ./protocolAggregator/build/nodes/ConsumerC/cordapps:/cordaptor/cordapps web: build: context: . diff --git a/compose-corda-network.yml b/compose-corda-network.yml index 8f25d6a..c6a9a0c 100644 --- a/compose-corda-network.yml +++ b/compose-corda-network.yml @@ -3,7 +3,7 @@ version: '2' services: notary-node: - image: corda/corda-zulu-java1.8-4.5:latest + image: corda/corda-zulu-java1.8-4.7:latest # hostnames need to be the same as in build.gradle, because they are baked into nodeInfo files hostname: notary-node mem_limit: 1g @@ -11,57 +11,90 @@ services: - 10002 # p2p port - 10003 # Corda RPC port, map to a host port using ports directive if Corda shell access is required volumes: - - ./pocCordApp/build/nodes/Notary/certificates:/opt/corda/certificates - - ./pocCordApp/build/nodes/Notary/cordapps:/opt/corda/cordapps - - ./pocCordApp/build/nodes/Notary/etc:/etc/corda - - ./pocCordApp/build/nodes/Notary/network-parameters:/opt/corda/network-parameters - - ./pocCordApp/build/nodes/Notary/logs:/opt/corda/logs - - ./pocCordApp/build/nodes/Notary/drivers:/opt/corda/drivers - - ./pocCordApp/build/nodes/Notary/persistence:/opt/corda/persistence - - ./pocCordApp/build/nodes/Notary/additional-node-infos:/opt/corda/additional-node-infos + - ./protocolAggregator/build/nodes/Notary/certificates:/opt/corda/certificates + - ./protocolAggregator/build/nodes/runnodes:/opt/corda/runnodes + - ./protocolAggregator/build/nodes/Notary/corda.jar:/opt/corda/corda.jar + - ./protocolAggregator/build/nodes/Notary/cordapps:/opt/corda/cordapps + - ./protocolAggregator/build/nodes/Notary/etc:/etc/corda + - ./protocolAggregator/build/nodes/Notary/network-parameters:/opt/corda/network-parameters + - ./protocolAggregator/build/nodes/Notary/logs:/opt/corda/logs + - ./protocolAggregator/build/nodes/Notary/drivers:/opt/corda/drivers + - ./protocolAggregator/build/nodes/Notary/persistence:/opt/corda/persistence + - ./protocolAggregator/build/nodes/Notary/additional-node-infos:/opt/corda/additional-node-infos # the following makes deployNode dir layout compatible with the expectations of the docker image - - ./pocCordApp/build/nodes/Notary/persistence.mv.db:/opt/corda/persistence/persistence.mv.db - - ./pocCordApp/build/nodes/Notary/persistence.trace.db:/opt/corda/persistence/persistence.trace.db - - ./pocCordApp/build/nodes/Notary/node.conf:/etc/corda/node.conf - partyb-node: - image: corda/corda-zulu-java1.8-4.5:latest + - ./protocolAggregator/build/nodes/Notary/persistence.mv.db:/opt/corda/persistence/persistence.mv.db + - ./protocolAggregator/build/nodes/Notary/persistence.trace.db:/opt/corda/persistence/persistence.trace.db + - ./protocolAggregator/build/nodes/Notary/node.conf:/opt/corda/node.conf + command: /opt/corda/runnodes + host-node: + image: corda/corda-zulu-java1.8-4.7:latest # hostnames need to be the same as in build.gradle, because they are baked into nodeInfo files - hostname: partyb-node + hostname: host-node mem_limit: 1g expose: - - 10008 # p2p port - - 10009 # Corda RPC port, map to a host port using ports directive if Corda shell access is required + - 10004 # p2p port + - 10005 # Corda RPC port, map to a host port using ports directive if Corda shell access is required volumes: - - ./pocCordApp/build/nodes/PartyB/certificates:/opt/corda/certificates - - ./pocCordApp/build/nodes/PartyB/cordapps:/opt/corda/cordapps - - ./pocCordApp/build/nodes/PartyB/etc:/etc/corda - - ./pocCordApp/build/nodes/PartyB/network-parameters:/opt/corda/network-parameters - - ./pocCordApp/build/nodes/PartyB/logs:/opt/corda/logs - - ./pocCordApp/build/nodes/PartyB/drivers:/opt/corda/drivers - - ./pocCordApp/build/nodes/PartyB/persistence:/opt/corda/persistence - - ./pocCordApp/build/nodes/PartyB/additional-node-infos:/opt/corda/additional-node-infos + - ./protocolAggregator/build/nodes/Host/certificates:/opt/corda/certificates + - ./protocolAggregator/build/nodes/runnodes:/opt/corda/runnodes + - ./protocolAggregator/build/nodes/Host/corda.jar:/opt/corda/corda.jar + - ./protocolAggregator/build/nodes/Host/cordapps:/opt/corda/cordapps + - ./protocolAggregator/build/nodes/Host/etc:/etc/corda + - ./protocolAggregator/build/nodes/Host/network-parameters:/opt/corda/network-parameters + - ./protocolAggregator/build/nodes/Host/logs:/opt/corda/logs + - ./protocolAggregator/build/nodes/Host/drivers:/opt/corda/drivers + - ./protocolAggregator/build/nodes/Host/persistence:/opt/corda/persistence + - ./protocolAggregator/build/nodes/Host/additional-node-infos:/opt/corda/additional-node-infos # the following makes deployNode dir layout compatible with the expectations of the docker image - - ./pocCordApp/build/nodes/PartyB/persistence.mv.db:/opt/corda/persistence/persistence.mv.db - - ./pocCordApp/build/nodes/PartyB/persistence.trace.db:/opt/corda/persistence/persistence.trace.db - - ./pocCordApp/build/nodes/PartyB/node.conf:/etc/corda/node.conf - partya-node: - image: corda/corda-zulu-java1.8-4.5:latest + - ./protocolAggregator/build/nodes/Host/persistence.mv.db:/opt/corda/persistence/persistence.mv.db + - ./protocolAggregator/build/nodes/Host/persistence.trace.db:/opt/corda/persistence/persistence.trace.db + - ./protocolAggregator/build/nodes/Host/node.conf:/opt/corda/node.conf + command: /opt/corda/runnodes + providerb-node: + image: corda/corda-zulu-java1.8-4.7:latest # hostnames need to be the same as in build.gradle, because they are baked into nodeInfo files - hostname: partya-node + hostname: providerb-node mem_limit: 1g expose: - - 10005 # p2p port - - 10006 # Corda RPC port, map to a host port using ports directive if Corda shell access is required + - 10006 # p2p port + - 10007 # Corda RPC port, map to a host port using ports directive if Corda shell access is required + volumes: + - ./protocolAggregator/build/nodes/ProviderB/certificates:/opt/corda/certificates + - ./protocolAggregator/build/nodes/runnodes:/opt/corda/runnodes + - ./protocolAggregator/build/nodes/ProviderB/corda.jar:/opt/corda/corda.jar + - ./protocolAggregator/build/nodes/ProviderB/cordapps:/opt/corda/cordapps + - ./protocolAggregator/build/nodes/ProviderB/etc:/etc/corda + - ./protocolAggregator/build/nodes/ProviderB/network-parameters:/opt/corda/network-parameters + - ./protocolAggregator/build/nodes/ProviderB/logs:/opt/corda/logs + - ./protocolAggregator/build/nodes/ProviderB/drivers:/opt/corda/drivers + - ./protocolAggregator/build/nodes/ProviderB/persistence:/opt/corda/persistence + - ./protocolAggregator/build/nodes/ProviderB/additional-node-infos:/opt/corda/additional-node-infos + # the following makes deployNode dir layout compatible with the expectations of the docker image + - ./protocolAggregator/build/nodes/ProviderB/persistence.mv.db:/opt/corda/persistence/persistence.mv.db + - ./protocolAggregator/build/nodes/ProviderB/persistence.trace.db:/opt/corda/persistence/persistence.trace.db + - ./protocolAggregator/build/nodes/ProviderB/node.conf:/opt/corda/node.conf + command: /opt/corda/runnodes + consumerc-node: + image: corda/corda-zulu-java1.8-4.7:latest + # hostnames need to be the same as in build.gradle, because they are baked into nodeInfo files + hostname: consumerc-node + mem_limit: 1g + expose: + - 10008 # p2p port + - 10009 # Corda RPC port, map to a host port using ports directive if Corda shell access is required volumes: - - ./pocCordApp/build/nodes/PartyA/certificates:/opt/corda/certificates - - ./pocCordApp/build/nodes/PartyA/cordapps:/opt/corda/cordapps - - ./pocCordApp/build/nodes/PartyA/etc:/etc/corda - - ./pocCordApp/build/nodes/PartyA/network-parameters:/opt/corda/network-parameters - - ./pocCordApp/build/nodes/PartyA/logs:/opt/corda/logs - - ./pocCordApp/build/nodes/PartyA/drivers:/opt/corda/drivers - - ./pocCordApp/build/nodes/PartyA/persistence:/opt/corda/persistence - - ./pocCordApp/build/nodes/PartyA/additional-node-infos:/opt/corda/additional-node-infos + - ./protocolAggregator/build/nodes/ConsumerC/certificates:/opt/corda/certificates + - ./protocolAggregator/build/nodes/runnodes:/opt/corda/runnodes + - ./protocolAggregator/build/nodes/ConsumerC/corda.jar:/opt/corda/corda.jar + - ./protocolAggregator/build/nodes/ConsumerC/cordapps:/opt/corda/cordapps + - ./protocolAggregator/build/nodes/ConsumerC/etc:/etc/corda + - ./protocolAggregator/build/nodes/ConsumerC/network-parameters:/opt/corda/network-parameters + - ./protocolAggregator/build/nodes/ConsumerC/logs:/opt/corda/logs + - ./protocolAggregator/build/nodes/ConsumerC/drivers:/opt/corda/drivers + - ./protocolAggregator/build/nodes/ConsumerC/persistence:/opt/corda/persistence + - ./protocolAggregator/build/nodes/ConsumerC/additional-node-infos:/opt/corda/additional-node-infos # the following makes deployNode dir layout compatible with the expectations of the docker image - - ./pocCordApp/build/nodes/PartyA/persistence.mv.db:/opt/corda/persistence/persistence.mv.db - - ./pocCordApp/build/nodes/PartyA/persistence.trace.db:/opt/corda/persistence/persistence.trace.db - - ./pocCordApp/build/nodes/PartyA/node.conf:/etc/corda/node.conf \ No newline at end of file + - ./protocolAggregator/build/nodes/ConsumerC/persistence.mv.db:/opt/corda/persistence/persistence.mv.db + - ./protocolAggregator/build/nodes/ConsumerC/persistence.trace.db:/opt/corda/persistence/persistence.trace.db + - ./protocolAggregator/build/nodes/ConsumerC/node.conf:/opt/corda/node.conf + command: /opt/corda/runnodes diff --git a/pocCordApp/LICENCE b/pocCordApp/LICENCE deleted file mode 100644 index 3ff572d..0000000 --- a/pocCordApp/LICENCE +++ /dev/null @@ -1,13 +0,0 @@ - Copyright 2016, R3 Limited. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/pocCordApp/TRADEMARK b/pocCordApp/TRADEMARK deleted file mode 100644 index aa7e20f..0000000 --- a/pocCordApp/TRADEMARK +++ /dev/null @@ -1,4 +0,0 @@ -Corda and the Corda logo are trademarks of R3CEV LLC and its affiliates. All rights reserved. - -For R3CEV LLC's trademark and logo usage information, please consult our Trademark Usage Policy at -https://www.r3.com/trademark-policy/. diff --git a/pocCordApp/build.gradle b/pocCordApp/build.gradle deleted file mode 100644 index fde44c5..0000000 --- a/pocCordApp/build.gradle +++ /dev/null @@ -1,156 +0,0 @@ -buildscript { //properties that you need to build the project - - Properties constants = new Properties() - file("$projectDir/./constants.properties").withInputStream { constants.load(it) } - - ext { - corda_release_group = constants.getProperty("cordaReleaseGroup") - corda_core_release_group = constants.getProperty("cordaCoreReleaseGroup") - corda_release_version = constants.getProperty("cordaVersion") - corda_core_release_version = constants.getProperty("cordaCoreVersion") - corda_gradle_plugins_version = constants.getProperty("gradlePluginsVersion") - kotlin_version = constants.getProperty("kotlinVersion") - junit_version = constants.getProperty("junitVersion") - quasar_version = constants.getProperty("quasarVersion") - log4j_version = constants.getProperty("log4jVersion") - slf4j_version = constants.getProperty("slf4jVersion") - corda_platform_version = constants.getProperty("platformVersion").toInteger() - //springboot - spring_boot_version = '2.0.2.RELEASE' - spring_boot_gradle_plugin_version = '2.0.2.RELEASE' - } - - repositories { - mavenLocal() - mavenCentral() - jcenter() - maven { url 'https://software.r3.com/artifactory/corda-releases' } - } - - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath "net.corda.plugins:cordapp:$corda_gradle_plugins_version" - classpath "net.corda.plugins:cordformation:$corda_gradle_plugins_version" - classpath "net.corda.plugins:quasar-utils:$corda_gradle_plugins_version" - classpath "org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_gradle_plugin_version" - } -} - -allprojects { //Properties that you need to compile your project (The application) - apply from: "${rootProject.projectDir}/repositories.gradle" - apply plugin: 'kotlin' - - repositories { - mavenLocal() - jcenter() - mavenCentral() - maven { url 'https://software.r3.com/artifactory/corda' } - maven { url 'https://jitpack.io' } - } - - tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) { - kotlinOptions { - languageVersion = "1.2" - apiVersion = "1.2" - jvmTarget = "1.8" - javaParameters = true // Useful for reflection. - } - } - - jar { - // This makes the JAR's SHA-256 hash repeatable. - preserveFileTimestamps = false - reproducibleFileOrder = true - } -} - -apply plugin: 'net.corda.plugins.cordapp' -apply plugin: 'net.corda.plugins.cordformation' -apply plugin: 'net.corda.plugins.quasar-utils' - -sourceSets { - main { - resources { - srcDir rootProject.file("config/dev") - } - } -} - -//Module dependencis -dependencies { - // Corda dependencies. - cordaCompile "$corda_core_release_group:corda-core:$corda_core_release_version" - cordaRuntime "$corda_release_group:corda-node-api:$corda_release_version" - cordaRuntime "$corda_release_group:corda:$corda_release_version" - - // CorDapp dependencies. - cordapp project(":workflows") - cordapp project(":contracts") - - cordaCompile "org.apache.logging.log4j:log4j-slf4j-impl:${log4j_version}" - cordaCompile "org.apache.logging.log4j:log4j-web:${log4j_version}" - cordaCompile "org.slf4j:jul-to-slf4j:$slf4j_version" -} - -//Task to build the jar for ganache. -task ganache { - subprojects { - if (it.project.name != "clients") { - dependsOn jar - doLast { - copy { - from "${buildDir}/libs" - into "${rootDir}/build/libs" - } - } - } - } -} - -//Task to deploy the nodes in order to bootstrap a network -task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) { - - /* This property will load the CorDapps to each of the node by default, including the Notary. You can find them - * in the cordapps folder of the node at build/nodes/Notary/cordapps. However, the notary doesn't really understand - * the notion of cordapps. In production, Notary does not need cordapps as well. This is just a short cut to load - * the Corda network bootstrapper. - */ - nodeDefaults { - projectCordapp { - deploy = false - } - cordapp project(':contracts') - cordapp project(':workflows') - // runSchemaMigration = true //This configuration is for any CorDapps with custom schema, We will leave this as true to avoid - //problems for developers who are not familiar with Corda. If you are not using custom schemas, you can change - //it to false for quicker project compiling time. - } - node { - name "O=Notary,L=London,C=GB" - notary = [validating : false] - p2pAddress "notary-node:10002" - rpcSettings { - address("0.0.0.0:10003") - adminAddress("0.0.0.0:10043") - } - } - node { - name "O=PartyA,L=London,C=GB" - p2pAddress "partya-node:10005" - rpcSettings { - address("0.0.0.0:10006") - adminAddress("0.0.0.0:10046") - } - rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]] - } - node { - name "O=PartyB,L=New York,C=US" - p2pAddress "partyb-node:10008" - rpcSettings { - address("0.0.0.0:10009") - adminAddress("0.0.0.0:10049") - } - rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]] - } - -} diff --git a/pocCordApp/clients/build.gradle b/pocCordApp/clients/build.gradle deleted file mode 100644 index 17d20a7..0000000 --- a/pocCordApp/clients/build.gradle +++ /dev/null @@ -1,55 +0,0 @@ -apply plugin: 'org.springframework.boot' - -sourceSets { - main { - resources { - srcDir rootProject.file("config/dev") - } - } -} - -dependencies { - // Corda dependencies. - compile "$corda_release_group:corda-rpc:$corda_release_version" - compile "net.corda:corda-jackson:$corda_release_version" - - // CorDapp dependencies. - compile project(":contracts") - compile project(":workflows") - compile("org.springframework.boot:spring-boot-starter-websocket:$spring_boot_version") { - exclude group: "org.springframework.boot", module: "spring-boot-starter-logging" - } - compile "org.apache.logging.log4j:log4j-slf4j-impl:${log4j_version}" - compile "org.apache.logging.log4j:log4j-web:${log4j_version}" - compile "org.slf4j:jul-to-slf4j:$slf4j_version" -} - - -springBoot { - mainClassName = "net.corda.samples.example.webserver.ServerKt" -} - -/* The Client is the communication channel between the external and the node. This task will help you immediately - * execute your rpc methods in the main method of the client.kt. You can somewhat see this as a quick test of making - * RPC calls to your nodes. - */ -task runTestClient(type: JavaExec, dependsOn: assemble) { - classpath = sourceSets.main.runtimeClasspath - main = 'net.corda.samples.example.ClientKt' - args 'localhost:10006', 'user1', 'test' -} - -/* This task will start the springboot server that connects to your node (via RPC connection). All of the http requests - * are in the Controller file. You can leave the Server.kt and NodeRPCConnection.kt file untouched for your use. - */ -task runPartyAServer(type: JavaExec, dependsOn: assemble) { - classpath = sourceSets.main.runtimeClasspath - main = 'net.corda.samples.example.webserver.ServerKt' - args '--server.port=50005', '--config.rpc.host=localhost', '--config.rpc.port=10006', '--config.rpc.username=user1', '--config.rpc.password=test' -} - -task runPartyBServer(type: JavaExec, dependsOn: assemble) { - classpath = sourceSets.main.runtimeClasspath - main = 'net.corda.samples.example.webserver.ServerKt' - args '--server.port=50006', '--config.rpc.host=localhost', '--config.rpc.port=10009', '--config.rpc.username=user1', '--config.rpc.password=test' -} diff --git a/pocCordApp/clients/src/main/kotlin/net/corda/samples/example/Client.kt b/pocCordApp/clients/src/main/kotlin/net/corda/samples/example/Client.kt deleted file mode 100644 index f6f4fc0..0000000 --- a/pocCordApp/clients/src/main/kotlin/net/corda/samples/example/Client.kt +++ /dev/null @@ -1,43 +0,0 @@ -package net.corda.samples.example - -import net.corda.client.rpc.CordaRPCClient -import net.corda.core.utilities.NetworkHostAndPort.Companion.parse -import net.corda.core.utilities.loggerFor - -/** - * Connects to a Corda node via RPC and performs RPC operations on the node. - * - * The RPC connection is configured using command line arguments. - */ -fun main(args: Array) = Client().main(args) - -private class Client { - companion object { - val logger = loggerFor() - } - - fun main(args: Array) { - // Create an RPC connection to the node. - require(args.size == 3) { "Usage: Client " } - val nodeAddress = parse(args[0]) - val rpcUsername = args[1] - val rpcPassword = args[2] - val client = CordaRPCClient(nodeAddress) - val clientConnection = client.start(rpcUsername, rpcPassword) - val proxy = clientConnection.proxy - - // Interact with the node. - // Example #1, here we print the nodes on the network. - val nodes = proxy.networkMapSnapshot() - println("\n-- Here is the networkMap snapshot --") - logger.info("{}", nodes) - - // Example #2, here we print the PartyA's node info - val me = proxy.nodeInfo().legalIdentities.first().name - println("\n-- Here is the node info of the node that the client connected to --") - logger.info("{}", me) - - //Close the client connection - clientConnection.close() - } -} \ No newline at end of file diff --git a/pocCordApp/clients/src/main/kotlin/net/corda/samples/example/webserver/Controller.kt b/pocCordApp/clients/src/main/kotlin/net/corda/samples/example/webserver/Controller.kt deleted file mode 100644 index 78b08f8..0000000 --- a/pocCordApp/clients/src/main/kotlin/net/corda/samples/example/webserver/Controller.kt +++ /dev/null @@ -1,122 +0,0 @@ -package net.corda.samples.example.webserver - -import com.fasterxml.jackson.databind.ObjectMapper -import net.corda.client.jackson.JacksonSupport.createNonRpcMapper -import net.corda.core.contracts.StateAndRef -import net.corda.core.identity.CordaX500Name -import net.corda.core.messaging.startTrackedFlow -import net.corda.core.messaging.vaultQueryBy -import net.corda.core.utilities.getOrThrow -import net.corda.samples.example.flows.ExampleFlow.Initiator -import net.corda.samples.example.states.IOUState -import org.slf4j.LoggerFactory -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration -import org.springframework.http.HttpStatus -import org.springframework.http.MediaType -import org.springframework.http.ResponseEntity -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PostMapping -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController -import javax.servlet.http.HttpServletRequest -import net.corda.client.jackson.JacksonSupport -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter - -val SERVICE_NAMES = listOf("Notary", "Network Map Service") - -/** - * Define your API endpoints here. - */ -@RestController -@RequestMapping("/") // The paths for HTTP requests are relative to this base path. -class Controller(rpc: NodeRPCConnection) { - - - companion object { - private val logger = LoggerFactory.getLogger(RestController::class.java) - } - @Bean - open fun mappingJackson2HttpMessageConverter(@Autowired rpcConnection: NodeRPCConnection): MappingJackson2HttpMessageConverter { - val mapper = JacksonSupport.createDefaultMapper(rpcConnection.proxy) - val converter = MappingJackson2HttpMessageConverter() - converter.objectMapper = mapper - return converter - } - - - private val myLegalName = rpc.proxy.nodeInfo().legalIdentities.first().name - private val proxy = rpc.proxy - - /** - * Returns the node's name. - */ - @GetMapping(value = ["me"], produces = [MediaType.APPLICATION_JSON_VALUE]) - fun whoami() = mapOf("me" to myLegalName) - - /** - * Returns all parties registered with the network map service. These names can be used to look up identities using - * the identity service. - */ - @GetMapping(value = ["peers"], produces = [MediaType.APPLICATION_JSON_VALUE]) - fun getPeers(): Map> { - val nodeInfo = proxy.networkMapSnapshot() - return mapOf("peers" to nodeInfo - .map { it.legalIdentities.first().name } - //filter out myself, notary and eventual network map started by driver - .filter { it.organisation !in (SERVICE_NAMES + myLegalName.organisation) }) - } - - /** - * Displays all IOU states that exist in the node's vault. - */ - @GetMapping(value = ["ious"], produces = [MediaType.APPLICATION_JSON_VALUE]) - fun getIOUs() : ResponseEntity>> { - return ResponseEntity.ok(proxy.vaultQueryBy().states) - } - - /** - * Initiates a flow to agree an IOU between two parties. - * - * Once the flow finishes it will have written the IOU to ledger. Both the lender and the borrower will be able to - * see it when calling /spring/api/ious on their respective nodes. - * - * This end-point takes a Party name parameter as part of the path. If the serving node can't find the other party - * in its network map cache, it will return an HTTP bad request. - * - * The flow is invoked asynchronously. It returns a future when the flow's call() method returns. - */ - - @PostMapping(value = ["create-iou"], produces = [MediaType.TEXT_PLAIN_VALUE], headers = ["Content-Type=application/x-www-form-urlencoded"]) - fun createIOU(request: HttpServletRequest): ResponseEntity { - val iouValue = request.getParameter("iouValue").toInt() - val partyName = request.getParameter("partyName") - if(partyName == null){ - return ResponseEntity.badRequest().body("Query parameter 'partyName' must not be null.\n") - } - if (iouValue <= 0 ) { - return ResponseEntity.badRequest().body("Query parameter 'iouValue' must be non-negative.\n") - } - val partyX500Name = CordaX500Name.parse(partyName) - val otherParty = proxy.wellKnownPartyFromX500Name(partyX500Name) ?: return ResponseEntity.badRequest().body("Party named $partyName cannot be found.\n") - - return try { - val signedTx = proxy.startTrackedFlow(::Initiator, iouValue, otherParty).returnValue.getOrThrow() - ResponseEntity.status(HttpStatus.CREATED).body("Transaction id ${signedTx.id} committed to ledger.\n") - - } catch (ex: Throwable) { - logger.error(ex.message, ex) - ResponseEntity.badRequest().body(ex.message!!) - } - } - - /** - * Displays all IOU states that only this node has been involved in. - */ - @GetMapping(value = ["my-ious"], produces = [MediaType.APPLICATION_JSON_VALUE]) - fun getMyIOUs(): ResponseEntity>> { - val myious = proxy.vaultQueryBy().states.filter { it.state.data.lender.equals(proxy.nodeInfo().legalIdentities.first()) } - return ResponseEntity.ok(myious) - } -} diff --git a/pocCordApp/clients/src/main/kotlin/net/corda/samples/example/webserver/NodeRPCConnection.kt b/pocCordApp/clients/src/main/kotlin/net/corda/samples/example/webserver/NodeRPCConnection.kt deleted file mode 100644 index a4a8250..0000000 --- a/pocCordApp/clients/src/main/kotlin/net/corda/samples/example/webserver/NodeRPCConnection.kt +++ /dev/null @@ -1,52 +0,0 @@ -package net.corda.samples.example.webserver - -import net.corda.client.rpc.CordaRPCClient -import net.corda.client.rpc.CordaRPCConnection -import net.corda.core.messaging.CordaRPCOps -import net.corda.core.utilities.NetworkHostAndPort -import org.springframework.beans.factory.annotation.Value -import org.springframework.stereotype.Component -import javax.annotation.PostConstruct -import javax.annotation.PreDestroy - -private const val CORDA_USER_NAME = "config.rpc.username" -private const val CORDA_USER_PASSWORD = "config.rpc.password" -private const val CORDA_NODE_HOST = "config.rpc.host" -private const val CORDA_RPC_PORT = "config.rpc.port" - -/** - * Wraps an RPC connection to a Corda node. - * - * The RPC connection is configured using command line arguments. - * - * @param host The host of the node we are connecting to. - * @param rpcPort The RPC port of the node we are connecting to. - * @param username The username for logging into the RPC client. - * @param password The password for logging into the RPC client. - * @property proxy The RPC proxy. - */ -@Component -open class NodeRPCConnection( - @Value("\${$CORDA_NODE_HOST}") private val host: String, - @Value("\${$CORDA_USER_NAME}") private val username: String, - @Value("\${$CORDA_USER_PASSWORD}") private val password: String, - @Value("\${$CORDA_RPC_PORT}") private val rpcPort: Int): AutoCloseable { - - lateinit var rpcConnection: CordaRPCConnection - private set - lateinit var proxy: CordaRPCOps - private set - - @PostConstruct - fun initialiseNodeRPCConnection() { - val rpcAddress = NetworkHostAndPort(host, rpcPort) - val rpcClient = CordaRPCClient(rpcAddress) - val rpcConnection = rpcClient.start(username, password) - proxy = rpcConnection.proxy - } - - @PreDestroy - override fun close() { - rpcConnection.notifyServerAndClose() - } -} \ No newline at end of file diff --git a/pocCordApp/clients/src/main/kotlin/net/corda/samples/example/webserver/Server.kt b/pocCordApp/clients/src/main/kotlin/net/corda/samples/example/webserver/Server.kt deleted file mode 100644 index a8c0ee2..0000000 --- a/pocCordApp/clients/src/main/kotlin/net/corda/samples/example/webserver/Server.kt +++ /dev/null @@ -1,22 +0,0 @@ -package net.corda.samples.example.webserver - -import org.springframework.boot.Banner -import org.springframework.boot.SpringApplication -import org.springframework.boot.WebApplicationType.SERVLET -import org.springframework.boot.autoconfigure.SpringBootApplication - -/** - * Our Spring Boot application. - */ -@SpringBootApplication -private open class Server - -/** - * Starts our Spring Boot application. - */ -fun main(args: Array) { - val app = SpringApplication(Server::class.java) - app.setBannerMode(Banner.Mode.OFF) - app.webApplicationType = SERVLET - app.run(*args) -} diff --git a/pocCordApp/clients/src/main/resources/static/app.js b/pocCordApp/clients/src/main/resources/static/app.js deleted file mode 100644 index c58d2de..0000000 --- a/pocCordApp/clients/src/main/resources/static/app.js +++ /dev/null @@ -1,3 +0,0 @@ -"use strict"; - -// Define your client-side logic here. \ No newline at end of file diff --git a/pocCordApp/clients/src/main/resources/static/index.html b/pocCordApp/clients/src/main/resources/static/index.html deleted file mode 100644 index ab27dbf..0000000 --- a/pocCordApp/clients/src/main/resources/static/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - Example front-end. - - -
- Corda -

CorDapp Template (Kotlin Version)

-

Learn more about how to build CorDapps at sample-kotlin

-
- - \ No newline at end of file diff --git a/pocCordApp/config/dev/log4j2.xml b/pocCordApp/config/dev/log4j2.xml deleted file mode 100644 index 34ba4d4..0000000 --- a/pocCordApp/config/dev/log4j2.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - logs - node-${hostName} - ${log-path}/archive - - - - - - - - - %highlight{%level{length=1} %d{HH:mm:ss} %T %c{1}.%M - %msg%n}{INFO=white,WARN=red,FATAL=bright red blink} - > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pocCordApp/config/test/log4j2.xml b/pocCordApp/config/test/log4j2.xml deleted file mode 100644 index cd9926c..0000000 --- a/pocCordApp/config/test/log4j2.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - [%-5level] %d{HH:mm:ss.SSS} [%t] %c{1}.%M - %msg%n - > - - - - - - - - - - - - diff --git a/pocCordApp/constants.properties b/pocCordApp/constants.properties deleted file mode 100644 index ac31f03..0000000 --- a/pocCordApp/constants.properties +++ /dev/null @@ -1,12 +0,0 @@ -cordaReleaseGroup=net.corda -cordaCoreReleaseGroup=net.corda -cordaVersion=4.5 -cordaCoreVersion=4.5 -gradlePluginsVersion=5.0.10 -kotlinVersion=1.2.71 -junitVersion=4.12 -quasarVersion=0.7.10 -log4jVersion=2.11.2 -platformVersion=5 -slf4jVersion=1.7.25 -nettyVersion=4.1.22.Final diff --git a/pocCordApp/contracts/build.gradle b/pocCordApp/contracts/build.gradle deleted file mode 100644 index 45e6118..0000000 --- a/pocCordApp/contracts/build.gradle +++ /dev/null @@ -1,19 +0,0 @@ -apply plugin: 'net.corda.plugins.cordapp' - -cordapp { - targetPlatformVersion corda_platform_version - minimumPlatformVersion corda_platform_version - contract { - name "Example-Cordapp Contracts" - vendor "Corda Open Source" - licence "Apache License, Version 2.0" - versionId 1 - } -} - -dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - // Corda dependencies. - cordaCompile "$corda_core_release_group:corda-core:$corda_core_release_version" - testCompile "$corda_release_group:corda-node-driver:$corda_release_version" -} diff --git a/pocCordApp/contracts/src/main/kotlin/net/corda/samples/example/contracts/IOUContract.kt b/pocCordApp/contracts/src/main/kotlin/net/corda/samples/example/contracts/IOUContract.kt deleted file mode 100644 index b786800..0000000 --- a/pocCordApp/contracts/src/main/kotlin/net/corda/samples/example/contracts/IOUContract.kt +++ /dev/null @@ -1,53 +0,0 @@ -package net.corda.samples.example.contracts - -import net.corda.samples.example.states.IOUState -import net.corda.core.contracts.CommandData -import net.corda.core.contracts.Contract -import net.corda.core.contracts.requireSingleCommand -import net.corda.core.contracts.requireThat -import net.corda.core.transactions.LedgerTransaction - -/** - * A implementation of a basic smart contract in Corda. - * - * This contract enforces rules regarding the creation of a valid [IOUState], which in turn encapsulates an [IOUState]. - * - * For a new [IOUState] to be issued onto the ledger, a transaction is required which takes: - * - Zero input states. - * - One output state: the new [IOUState]. - * - An Create() command with the public keys of both the lender and the borrower. - * - * All contracts must sub-class the [Contract] interface. - */ -class IOUContract : Contract { - companion object { - @JvmStatic - val ID = "net.corda.samples.example.contracts.IOUContract" - } - - /** - * The verify() function of all the states' contracts must not throw an exception for a transaction to be - * considered valid. - */ - override fun verify(tx: LedgerTransaction) { - val command = tx.commands.requireSingleCommand() - requireThat { - // Generic constraints around the IOU transaction. - "No inputs should be consumed when issuing an IOU." using (tx.inputs.isEmpty()) - "Only one output state should be created." using (tx.outputs.size == 1) - val out = tx.outputsOfType().single() - "The lender and the borrower cannot be the same entity." using (out.lender != out.borrower) - "All of the participants must be signers." using (command.signers.containsAll(out.participants.map { it.owningKey })) - - // IOU-specific constraints. - "The IOU's value must be non-negative." using (out.value > 0) - } - } - - /** - * This contract only implements one command, Create. - */ - interface Commands : CommandData { - class Create : Commands - } -} diff --git a/pocCordApp/contracts/src/main/kotlin/net/corda/samples/example/schema/IOUSchema.kt b/pocCordApp/contracts/src/main/kotlin/net/corda/samples/example/schema/IOUSchema.kt deleted file mode 100644 index 9628449..0000000 --- a/pocCordApp/contracts/src/main/kotlin/net/corda/samples/example/schema/IOUSchema.kt +++ /dev/null @@ -1,48 +0,0 @@ -package net.corda.samples.example.schema - -import net.corda.core.schemas.MappedSchema -import net.corda.core.schemas.PersistentState -import java.util.* -import javax.persistence.Column -import javax.persistence.Entity -import javax.persistence.Table -//4.6 changes -import org.hibernate.annotations.Type - - -/** - * The family of schemas for IOUState. - */ -object IOUSchema - -/** - * An IOUState schema. - */ -object IOUSchemaV1 : MappedSchema( - schemaFamily = IOUSchema.javaClass, - version = 1, - mappedTypes = listOf(PersistentIOU::class.java)) { - - override val migrationResource: String? - get() = "iou.changelog-master"; - - @Entity - @Table(name = "iou_states") - class PersistentIOU( - @Column(name = "lender") - var lenderName: String, - - @Column(name = "borrower") - var borrowerName: String, - - @Column(name = "value") - var value: Int, - - @Column(name = "linear_id") - @Type(type = "uuid-char") - var linearId: UUID - ) : PersistentState() { - // Default constructor required by hibernate. - constructor(): this("", "", 0, UUID.randomUUID()) - } -} \ No newline at end of file diff --git a/pocCordApp/contracts/src/main/kotlin/net/corda/samples/example/states/IOUState.kt b/pocCordApp/contracts/src/main/kotlin/net/corda/samples/example/states/IOUState.kt deleted file mode 100644 index bb7620f..0000000 --- a/pocCordApp/contracts/src/main/kotlin/net/corda/samples/example/states/IOUState.kt +++ /dev/null @@ -1,46 +0,0 @@ -package net.corda.samples.example.states - -import net.corda.samples.example.contracts.IOUContract -import net.corda.samples.example.schema.IOUSchemaV1 -import net.corda.core.contracts.BelongsToContract -import net.corda.core.contracts.ContractState -import net.corda.core.contracts.LinearState -import net.corda.core.contracts.UniqueIdentifier -import net.corda.core.identity.AbstractParty -import net.corda.core.identity.Party -import net.corda.core.schemas.MappedSchema -import net.corda.core.schemas.PersistentState -import net.corda.core.schemas.QueryableState - -/** - * The state object recording IOU agreements between two parties. - * - * A state must implement [ContractState] or one of its descendants. - * - * @param value the value of the IOU. - * @param lender the party issuing the IOU. - * @param borrower the party receiving and approving the IOU. - */ -@BelongsToContract(IOUContract::class) -data class IOUState(val value: Int, - val lender: Party, - val borrower: Party, - override val linearId: UniqueIdentifier = UniqueIdentifier()): - LinearState, QueryableState { - /** The public keys of the involved parties. */ - override val participants: List get() = listOf(lender, borrower) - - override fun generateMappedObject(schema: MappedSchema): PersistentState { - return when (schema) { - is IOUSchemaV1 -> IOUSchemaV1.PersistentIOU( - this.lender.name.toString(), - this.borrower.name.toString(), - this.value, - this.linearId.id - ) - else -> throw IllegalArgumentException("Unrecognised schema $schema") - } - } - - override fun supportedSchemas(): Iterable = listOf(IOUSchemaV1) -} diff --git a/pocCordApp/contracts/src/test/kotlin/net/corda/samples/example/contracts/ContractTests.kt b/pocCordApp/contracts/src/test/kotlin/net/corda/samples/example/contracts/ContractTests.kt deleted file mode 100644 index c0b8d6e..0000000 --- a/pocCordApp/contracts/src/test/kotlin/net/corda/samples/example/contracts/ContractTests.kt +++ /dev/null @@ -1,95 +0,0 @@ -package net.corda.samples.example.contracts - -import net.corda.core.identity.CordaX500Name -import net.corda.samples.example.states.IOUState -import net.corda.testing.core.TestIdentity -import net.corda.testing.node.MockServices -import net.corda.testing.node.ledger -import org.junit.Test - -class ContractTests { - private val ledgerServices = MockServices() - private val megaCorp = TestIdentity(CordaX500Name("MegaCorp", "London", "GB")) - private val miniCorp = TestIdentity(CordaX500Name("MiniCorp", "New York", "US")) - private val iouValue = 1 - - @Test - fun `transaction must include Create command`() { - ledgerServices.ledger { - transaction { - output(IOUContract.ID, IOUState(iouValue, miniCorp.party, megaCorp.party)) - fails() - command(listOf(megaCorp.publicKey, miniCorp.publicKey), IOUContract.Commands.Create()) - verifies() - } - } - } - - @Test - fun `transaction must have no inputs`() { - ledgerServices.ledger { - transaction { - input(IOUContract.ID, IOUState(iouValue, miniCorp.party, megaCorp.party)) - output(IOUContract.ID, IOUState(iouValue, miniCorp.party, megaCorp.party)) - command(listOf(megaCorp.publicKey, miniCorp.publicKey), IOUContract.Commands.Create()) - `fails with`("No inputs should be consumed when issuing an IOU.") - } - } - } - - @Test - fun `transaction must have one output`() { - ledgerServices.ledger { - transaction { - output(IOUContract.ID, IOUState(iouValue, miniCorp.party, megaCorp.party)) - output(IOUContract.ID, IOUState(iouValue, miniCorp.party, megaCorp.party)) - command(listOf(megaCorp.publicKey, miniCorp.publicKey), IOUContract.Commands.Create()) - `fails with`("Only one output state should be created.") - } - } - } - - @Test - fun `lender must sign transaction`() { - ledgerServices.ledger { - transaction { - output(IOUContract.ID, IOUState(iouValue, miniCorp.party, megaCorp.party)) - command(miniCorp.publicKey, IOUContract.Commands.Create()) - `fails with`("All of the participants must be signers.") - } - } - } - - @Test - fun `borrower must sign transaction`() { - ledgerServices.ledger { - transaction { - output(IOUContract.ID, IOUState(iouValue, miniCorp.party, megaCorp.party)) - command(megaCorp.publicKey, IOUContract.Commands.Create()) - `fails with`("All of the participants must be signers.") - } - } - } - - @Test - fun `lender is not borrower`() { - ledgerServices.ledger { - transaction { - output(IOUContract.ID, IOUState(iouValue, megaCorp.party, megaCorp.party)) - command(listOf(megaCorp.publicKey, miniCorp.publicKey), IOUContract.Commands.Create()) - `fails with`("The lender and the borrower cannot be the same entity.") - } - } - } - - @Test - fun `cannot create negative-value IOUs`() { - ledgerServices.ledger { - transaction { - output(IOUContract.ID, IOUState(-1, miniCorp.party, megaCorp.party)) - command(listOf(megaCorp.publicKey, miniCorp.publicKey), IOUContract.Commands.Create()) - `fails with`("The IOU's value must be non-negative.") - } - } - } -} \ No newline at end of file diff --git a/pocCordApp/contracts/src/test/kotlin/net/corda/samples/example/contracts/StateTests.kt b/pocCordApp/contracts/src/test/kotlin/net/corda/samples/example/contracts/StateTests.kt deleted file mode 100644 index 1947b50..0000000 --- a/pocCordApp/contracts/src/test/kotlin/net/corda/samples/example/contracts/StateTests.kt +++ /dev/null @@ -1,16 +0,0 @@ -package net.corda.samples.example.contracts - -import net.corda.samples.example.states.IOUState -import net.corda.testing.node.MockServices -import org.junit.Test - -class StateTests { - private val ledgerServices = MockServices() - @Test - @Throws(NoSuchFieldException::class) - fun hasAmountFieldOfCorrectType() { - // Does the message field exist? - IOUState::class.java.getDeclaredField("value") - assert(IOUState::class.java.getDeclaredField("value").getType() == Int::class.javaPrimitiveType) - } -} \ No newline at end of file diff --git a/pocCordApp/gradle.properties b/pocCordApp/gradle.properties deleted file mode 100644 index 7a11822..0000000 --- a/pocCordApp/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=Example Cordapp -group=com.example -version=1.0 -kotlin.incremental=false \ No newline at end of file diff --git a/pocCordApp/gradle/wrapper/gradle-wrapper.jar b/pocCordApp/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 99340b4..0000000 Binary files a/pocCordApp/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/pocCordApp/gradlew b/pocCordApp/gradlew deleted file mode 100644 index cccdd3d..0000000 --- a/pocCordApp/gradlew +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env sh - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/pocCordApp/gradlew.bat b/pocCordApp/gradlew.bat deleted file mode 100644 index f955316..0000000 --- a/pocCordApp/gradlew.bat +++ /dev/null @@ -1,84 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/pocCordApp/repositories.gradle b/pocCordApp/repositories.gradle deleted file mode 100644 index 206b9c6..0000000 --- a/pocCordApp/repositories.gradle +++ /dev/null @@ -1,8 +0,0 @@ -repositories { - mavenLocal() - mavenCentral() - jcenter() - maven { url 'https://jitpack.io' } - maven { url 'https://software.r3.com/artifactory/corda' } - maven { url 'https://repo.gradle.org/gradle/libs-releases' } -} diff --git a/pocCordApp/settings.gradle b/pocCordApp/settings.gradle deleted file mode 100644 index 2514aca..0000000 --- a/pocCordApp/settings.gradle +++ /dev/null @@ -1,3 +0,0 @@ -include 'workflows' -include 'contracts' -include 'clients' \ No newline at end of file diff --git a/pocCordApp/workflows/build.gradle b/pocCordApp/workflows/build.gradle deleted file mode 100644 index 980b9c2..0000000 --- a/pocCordApp/workflows/build.gradle +++ /dev/null @@ -1,57 +0,0 @@ -apply plugin: 'net.corda.plugins.cordapp' -apply plugin: 'net.corda.plugins.quasar-utils' - -cordapp { - targetPlatformVersion corda_platform_version - minimumPlatformVersion corda_platform_version - workflow { - name "Example-Cordapp Flows" - vendor "Corda Open Source" - licence "Apache License, Version 2.0" - versionId 1 - } -} - -sourceSets { - main { - resources { - srcDir rootProject.file("config/dev") - } - } - test { - resources { - srcDir rootProject.file("config/test") - } - } - integrationTest { - kotlin { - compileClasspath += main.output + test.output - runtimeClasspath += main.output + test.output - srcDir file('src/integrationTest/kotlin') - } - } -} - -configurations { - integrationTestCompile.extendsFrom testCompile - integrationTestRuntime.extendsFrom testRuntime -} - -dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" - testCompile "junit:junit:$junit_version" - - // Corda dependencies. - cordaCompile "$corda_core_release_group:corda-core:$corda_core_release_version" - cordaRuntime "$corda_release_group:corda:$corda_release_version" - testCompile "$corda_release_group:corda-node-driver:$corda_release_version" - - // CorDapp dependencies. - cordapp project(":contracts") -} - -task integrationTest(type: Test, dependsOn: []) { - testClassesDirs = sourceSets.integrationTest.output.classesDirs - classpath = sourceSets.integrationTest.runtimeClasspath -} \ No newline at end of file diff --git a/pocCordApp/workflows/src/integrationTest/kotlin/net/corda/samples/example/DriverBasedTest.kt b/pocCordApp/workflows/src/integrationTest/kotlin/net/corda/samples/example/DriverBasedTest.kt deleted file mode 100644 index 1f366c0..0000000 --- a/pocCordApp/workflows/src/integrationTest/kotlin/net/corda/samples/example/DriverBasedTest.kt +++ /dev/null @@ -1,47 +0,0 @@ -package net.corda.samples.example - -import net.corda.core.identity.CordaX500Name -import net.corda.core.utilities.getOrThrow -import net.corda.testing.core.TestIdentity -import net.corda.testing.driver.DriverDSL -import net.corda.testing.driver.DriverParameters -import net.corda.testing.driver.NodeHandle -import net.corda.testing.driver.driver -import org.junit.Test -import java.util.concurrent.Future -import kotlin.test.assertEquals - -class DriverBasedTest { - private val bankA = TestIdentity(CordaX500Name("BankA", "", "GB")) - private val bankB = TestIdentity(CordaX500Name("BankB", "", "US")) - - @Test - fun `node test`() = withDriver { - // Start a pair of nodes and wait for them both to be ready. - val (partyAHandle, partyBHandle) = startNodes(bankA, bankB) - - // From each node, make an RPC call to retrieve another node's name from the network map, to verify that the - // nodes have started and can communicate. - - // This is a very basic test: in practice tests would be starting flows, and verifying the states in the vault - // and other important metrics to ensure that your CorDapp is working as intended. - assertEquals(bankB.name, partyAHandle.resolveName(bankB.name)) - assertEquals(bankA.name, partyBHandle.resolveName(bankA.name)) - } - - // Runs a test inside the Driver DSL, which provides useful functions for starting nodes, etc. - private fun withDriver(test: DriverDSL.() -> Unit) = driver( - DriverParameters(isDebug = true, startNodesInProcess = true) - ) { test() } - - // Makes an RPC call to retrieve another node's name from the network map. - private fun NodeHandle.resolveName(name: CordaX500Name) = rpc.wellKnownPartyFromX500Name(name)!!.name - - // Resolves a list of futures to a list of the promised values. - private fun List>.waitForAll(): List = map { it.getOrThrow() } - - // Starts multiple nodes simultaneously, then waits for them all to be ready. - private fun DriverDSL.startNodes(vararg identities: TestIdentity) = identities - .map { startNode(providedName = it.name) } - .waitForAll() -} \ No newline at end of file diff --git a/pocCordApp/workflows/src/main/kotlin/net/corda/samples/example/flows/ExampleFlow.kt b/pocCordApp/workflows/src/main/kotlin/net/corda/samples/example/flows/ExampleFlow.kt deleted file mode 100644 index 0f9a2a7..0000000 --- a/pocCordApp/workflows/src/main/kotlin/net/corda/samples/example/flows/ExampleFlow.kt +++ /dev/null @@ -1,126 +0,0 @@ -package net.corda.samples.example.flows - -import co.paralleluniverse.fibers.Suspendable -import net.corda.samples.example.flows.ExampleFlow.Acceptor -import net.corda.samples.example.flows.ExampleFlow.Initiator -import net.corda.core.contracts.Command -import net.corda.core.contracts.requireThat -import net.corda.core.flows.* -import net.corda.core.identity.Party -import net.corda.core.transactions.SignedTransaction -import net.corda.core.transactions.TransactionBuilder -import net.corda.core.utilities.ProgressTracker -import net.corda.core.utilities.ProgressTracker.Step -import net.corda.samples.example.contracts.IOUContract -import net.corda.samples.example.states.IOUState - - -/** - * This flow allows two parties (the [Initiator] and the [Acceptor]) to come to an agreement about the IOU encapsulated - * within an [IOUState]. - * - * In our simple example, the [Acceptor] always accepts a valid IOU. - * - * These flows have deliberately been implemented by using only the call() method for ease of understanding. In - * practice we would recommend splitting up the various stages of the flow into sub-routines. - * - * All methods called within the [FlowLogic] sub-class need to be annotated with the @Suspendable annotation. - */ -object ExampleFlow { - @InitiatingFlow - @StartableByRPC - class Initiator(val iouValue: Int, - val otherParty: Party) : FlowLogic() { - /** - * The progress tracker checkpoints each stage of the flow and outputs the specified messages when each - * checkpoint is reached in the code. See the 'progressTracker.currentStep' expressions within the call() function. - */ - companion object { - object GENERATING_TRANSACTION : Step("Generating transaction based on new IOU.") - object VERIFYING_TRANSACTION : Step("Verifying contract constraints.") - object SIGNING_TRANSACTION : Step("Signing transaction with our private key.") - object GATHERING_SIGS : Step("Gathering the counterparty's signature.") { - override fun childProgressTracker() = CollectSignaturesFlow.tracker() - } - - object FINALISING_TRANSACTION : Step("Obtaining notary signature and recording transaction.") { - override fun childProgressTracker() = FinalityFlow.tracker() - } - - fun tracker() = ProgressTracker( - GENERATING_TRANSACTION, - VERIFYING_TRANSACTION, - SIGNING_TRANSACTION, - GATHERING_SIGS, - FINALISING_TRANSACTION - ) - } - - override val progressTracker = tracker() - - /** - * The flow logic is encapsulated within the call() method. - */ - @Suspendable - override fun call(): SignedTransaction { - - // Obtain a reference from a notary we wish to use. - /** - * METHOD 1: Take first notary on network, WARNING: use for test, non-prod environments, and single-notary networks only!* - * METHOD 2: Explicit selection of notary by CordaX500Name - argument can by coded in flow or parsed from config (Preferred) - * - * * - For production you always want to use Method 2 as it guarantees the expected notary is returned. - */ - val notary = serviceHub.networkMapCache.notaryIdentities.single() // METHOD 1 - // val notary = serviceHub.networkMapCache.getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB")) // METHOD 2 - - // Stage 1. - progressTracker.currentStep = GENERATING_TRANSACTION - // Generate an unsigned transaction. - val iouState = IOUState(iouValue, serviceHub.myInfo.legalIdentities.first(), otherParty) - val txCommand = Command(IOUContract.Commands.Create(), iouState.participants.map { it.owningKey }) - val txBuilder = TransactionBuilder(notary) - .addOutputState(iouState, IOUContract.ID) - .addCommand(txCommand) - - // Stage 2. - progressTracker.currentStep = VERIFYING_TRANSACTION - // Verify that the transaction is valid. - txBuilder.verify(serviceHub) - - // Stage 3. - progressTracker.currentStep = SIGNING_TRANSACTION - // Sign the transaction. - val partSignedTx = serviceHub.signInitialTransaction(txBuilder) - - // Stage 4. - progressTracker.currentStep = GATHERING_SIGS - // Send the state to the counterparty, and receive it back with their signature. - val otherPartySession = initiateFlow(otherParty) - val fullySignedTx = subFlow(CollectSignaturesFlow(partSignedTx, setOf(otherPartySession), GATHERING_SIGS.childProgressTracker())) - - // Stage 5. - progressTracker.currentStep = FINALISING_TRANSACTION - // Notarise and record the transaction in both parties' vaults. - return subFlow(FinalityFlow(fullySignedTx, setOf(otherPartySession), FINALISING_TRANSACTION.childProgressTracker())) - } - } - - @InitiatedBy(Initiator::class) - class Acceptor(val otherPartySession: FlowSession) : FlowLogic() { - @Suspendable - override fun call(): SignedTransaction { - val signTransactionFlow = object : SignTransactionFlow(otherPartySession) { - override fun checkTransaction(stx: SignedTransaction) = requireThat { - val output = stx.tx.outputs.single().data - "This must be an IOU transaction." using (output is IOUState) - val iou = output as IOUState - "I won't accept IOUs with a value over 100." using (iou.value <= 100) - } - } - val txId = subFlow(signTransactionFlow).id - - return subFlow(ReceiveFinalityFlow(otherPartySession, expectedTxId = txId)) - } - } -} diff --git a/pocCordApp/workflows/src/main/resources/migration/iou.changelog-master.xml b/pocCordApp/workflows/src/main/resources/migration/iou.changelog-master.xml deleted file mode 100644 index 32b4d1d..0000000 --- a/pocCordApp/workflows/src/main/resources/migration/iou.changelog-master.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - \ No newline at end of file diff --git a/pocCordApp/workflows/src/main/resources/migration/iou.changelog-v1.xml b/pocCordApp/workflows/src/main/resources/migration/iou.changelog-v1.xml deleted file mode 100644 index 660d7b3..0000000 --- a/pocCordApp/workflows/src/main/resources/migration/iou.changelog-v1.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/pocCordApp/workflows/src/test/kotlin/net/corda/samples/example/FlowTests.kt b/pocCordApp/workflows/src/test/kotlin/net/corda/samples/example/FlowTests.kt deleted file mode 100644 index f8e6281..0000000 --- a/pocCordApp/workflows/src/test/kotlin/net/corda/samples/example/FlowTests.kt +++ /dev/null @@ -1,126 +0,0 @@ -package net.corda.samples.example - -import net.corda.core.contracts.TransactionVerificationException -import net.corda.core.node.services.queryBy -import net.corda.core.utilities.getOrThrow -import net.corda.samples.example.flows.ExampleFlow -import net.corda.samples.example.states.IOUState -import net.corda.testing.core.singleIdentity -import net.corda.testing.node.MockNetwork -import net.corda.testing.node.MockNetworkParameters -import net.corda.testing.node.StartedMockNode -import net.corda.testing.node.TestCordapp -import org.junit.After -import org.junit.Before -import org.junit.Test -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith - -class IOUFlowTests { - private lateinit var network: MockNetwork - private lateinit var a: StartedMockNode - private lateinit var b: StartedMockNode - - @Before - fun setup() { - network = MockNetwork(MockNetworkParameters(cordappsForAllNodes = listOf( - TestCordapp.findCordapp("net.corda.samples.example.contracts"), - TestCordapp.findCordapp("net.corda.samples.example.flows") - ))) - a = network.createPartyNode() - b = network.createPartyNode() - // For real nodes this happens automatically, but we have to manually register the flow for tests. - listOf(a, b).forEach { it.registerInitiatedFlow(ExampleFlow.Acceptor::class.java) } - network.runNetwork() - } - - @After - fun tearDown() { - network.stopNodes() - } - - @Test - fun `flow rejects invalid IOUs`() { - val flow = ExampleFlow.Initiator(-1, b.info.singleIdentity()) - val future = a.startFlow(flow) - network.runNetwork() - - // The IOUContract specifies that IOUs cannot have negative values. - assertFailsWith { future.getOrThrow() } - } - - @Test - fun `SignedTransaction returned by the flow is signed by the initiator`() { - val flow = ExampleFlow.Initiator(1, b.info.singleIdentity()) - val future = a.startFlow(flow) - network.runNetwork() - - val signedTx = future.getOrThrow() - signedTx.verifySignaturesExcept(b.info.singleIdentity().owningKey) - } - - @Test - fun `SignedTransaction returned by the flow is signed by the acceptor`() { - val flow = ExampleFlow.Initiator(1, b.info.singleIdentity()) - val future = a.startFlow(flow) - network.runNetwork() - - val signedTx = future.getOrThrow() - signedTx.verifySignaturesExcept(a.info.singleIdentity().owningKey) - } - - @Test - fun `flow records a transaction in both parties' transaction storages`() { - val flow = ExampleFlow.Initiator(1, b.info.singleIdentity()) - val future = a.startFlow(flow) - network.runNetwork() - val signedTx = future.getOrThrow() - - // We check the recorded transaction in both transaction storages. - for (node in listOf(a, b)) { - assertEquals(signedTx, node.services.validatedTransactions.getTransaction(signedTx.id)) - } - } - - @Test - fun `recorded transaction has no inputs and a single output, the input IOU`() { - val iouValue = 1 - val flow = ExampleFlow.Initiator(iouValue, b.info.singleIdentity()) - val future = a.startFlow(flow) - network.runNetwork() - val signedTx = future.getOrThrow() - - // We check the recorded transaction in both vaults. - for (node in listOf(a, b)) { - val recordedTx = node.services.validatedTransactions.getTransaction(signedTx.id) - val txOutputs = recordedTx!!.tx.outputs - assert(txOutputs.size == 1) - - val recordedState = txOutputs[0].data as IOUState - assertEquals(recordedState.value, iouValue) - assertEquals(recordedState.lender, a.info.singleIdentity()) - assertEquals(recordedState.borrower, b.info.singleIdentity()) - } - } - - @Test - fun `flow records the correct IOU in both parties' vaults`() { - val iouValue = 1 - val flow = ExampleFlow.Initiator(1, b.info.singleIdentity()) - val future = a.startFlow(flow) - network.runNetwork() - future.getOrThrow() - - // We check the recorded IOU in both vaults. - for (node in listOf(a, b)) { - node.transaction { - val ious = node.services.vaultService.queryBy().states - assertEquals(1, ious.size) - val recordedState = ious.single().state.data - assertEquals(recordedState.value, iouValue) - assertEquals(recordedState.lender, a.info.singleIdentity()) - assertEquals(recordedState.borrower, b.info.singleIdentity()) - } - } - } -} \ No newline at end of file diff --git a/protocolAggregator/gradle.properties b/protocolAggregator/gradle.properties index cf1ecd3..9b58604 100644 --- a/protocolAggregator/gradle.properties +++ b/protocolAggregator/gradle.properties @@ -1,9 +1,9 @@ # #Fri Jun 25 14:40:09 GMT 2021 conclaveVersion=1.2 -version=1.0 +version=0.1.0 name=ProtocolBrokerEnclave -conclaveRepo=../repo +conclaveRepo=../../conclave-sdk-1.2/repo group=com.180protocol org.gradle.jvmargs=-Xmx4096m diff --git a/pocCordApp/gradle/wrapper/gradle-wrapper.properties b/protocolAggregator/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from pocCordApp/gradle/wrapper/gradle-wrapper.properties rename to protocolAggregator/gradle/wrapper/gradle-wrapper.properties diff --git a/protocolAggregator/workflows/build.gradle b/protocolAggregator/workflows/build.gradle index 05884b1..16c10fa 100644 --- a/protocolAggregator/workflows/build.gradle +++ b/protocolAggregator/workflows/build.gradle @@ -8,7 +8,7 @@ cordapp { workflow { name "180 Protocol Broker Flows" vendor "180Protocol Pte Ltd" - licence "Apache License, Version 2.0" + licence "GNU AFFERO GENERAL PUBLIC LICENSE, Version 3.0" versionId 1 } signing {