(new YoContract.Commands.Send(), Arrays.asList(me.getOwningKey()));
YoState state = new YoState(me, target);
diff --git a/Features/postgres-cordapp/workflows/src/test/java/net/corda/samples/postgres/flows/FlowTests.java b/Features/postgres-cordapp/workflows/src/test/java/net/corda/samples/postgres/flows/FlowTests.java
index 8265218a..395bc840 100644
--- a/Features/postgres-cordapp/workflows/src/test/java/net/corda/samples/postgres/flows/FlowTests.java
+++ b/Features/postgres-cordapp/workflows/src/test/java/net/corda/samples/postgres/flows/FlowTests.java
@@ -2,11 +2,9 @@
import com.google.common.collect.ImmutableList;
import net.corda.core.concurrent.CordaFuture;
+import net.corda.core.identity.CordaX500Name;
import net.corda.core.transactions.SignedTransaction;
-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 net.corda.testing.node.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -17,7 +15,7 @@ public class FlowTests {
private final MockNetwork network = new MockNetwork(new MockNetworkParameters().withCordappsForAllNodes(ImmutableList.of(
TestCordapp.findCordapp("net.corda.samples.postgres.contracts"),
TestCordapp.findCordapp("net.corda.samples.postgres.flows")
- )));
+ )).withNotarySpecs(ImmutableList.of(new MockNetworkNotarySpec(CordaX500Name.parse("O=Notary,L=London,C=GB")))));
private final StartedMockNode a = network.createNode();
private final StartedMockNode b = network.createNode();
diff --git a/Features/queryablestate-carinsurance/QueryableState.postman_collection.json b/Features/queryablestate-carinsurance/QueryableState.postman_collection.json
new file mode 100644
index 00000000..593eaaf6
--- /dev/null
+++ b/Features/queryablestate-carinsurance/QueryableState.postman_collection.json
@@ -0,0 +1,93 @@
+{
+ "info": {
+ "_postman_id": "381497f6-9903-47b2-9d74-7f1578532895",
+ "name": "Queryable State",
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
+ },
+ "item": [
+ {
+ "name": "Vehicle Insurance",
+ "request": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Content-Type",
+ "name": "Content-Type",
+ "type": "text",
+ "value": "application/json"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\"vehicleInfo\": {\n\t\t\"registrationNumber\": \"MH014343\",\n\t\t\"chasisNumber\": \"C232ND832\",\n\t\t\"make\": \"Hyundai\",\n\t\t\"model\": \"Elantra\",\n\t\t\"variant\": \"SX\",\n\t\t\"color\": \"Black\",\n\t\t\"fuelType\": \"Petrol\"\n\t},\n\t\"policyNumber\": \"8190\",\n\t\"insuredValue\": \"20000\",\n\t\"duration\": 1,\n\t\"premium\": \"3000\"\n}"
+ },
+ "url": {
+ "raw": "http://localhost:8080/vehicleInsurance/Insuree",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8080",
+ "path": [
+ "vehicleInsurance",
+ "Insuree"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Claim",
+ "request": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Content-Type",
+ "name": "Content-Type",
+ "value": "application/json",
+ "type": "text"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\"claimNumber\":\"C001\",\n\t\"claimDescription\": \"Minor Accident, Bumper Damaged\",\n\t\"claimAmount\": 1000\n}"
+ },
+ "url": {
+ "raw": "http://localhost:8080//vehicleInsurance/claim/8190",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8080",
+ "path": [
+ "",
+ "vehicleInsurance",
+ "claim",
+ "8190"
+ ]
+ }
+ },
+ "response": []
+ }
+ ],
+ "event": [
+ {
+ "listen": "prerequest",
+ "script": {
+ "type": "text/javascript",
+ "exec": [
+ ""
+ ]
+ }
+ },
+ {
+ "listen": "test",
+ "script": {
+ "type": "text/javascript",
+ "exec": [
+ ""
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Features/queryablestate-carinsurance/README.md b/Features/queryablestate-carinsurance/README.md
index 0e94c408..f7f39dea 100644
--- a/Features/queryablestate-carinsurance/README.md
+++ b/Features/queryablestate-carinsurance/README.md
@@ -1,6 +1,6 @@
# Car Insurance -- QueryableState
-This CorDapp demonstrates [QueryableState](https://docs.corda.net/docs/corda-os/api-persistence.html) works in Corda. Corda allows developers
+This CorDapp demonstrates [QueryableState](https://docs.r3.com/en/platform/corda/4.10/enterprise/cordapps/api-states.html#the-queryablestate-and-schedulablestate-interfaces) works in Corda. Corda allows developers
to have the ability to expose some or all parts of their states to a custom database
table using an ORM tools. To support this feature the state must implement
`QueryableState`.
@@ -8,7 +8,7 @@ table using an ORM tools. To support this feature the state must implement
In this CorDapp we would use an `Insurance` state and persist its properties in a
custom table in the database. The `Insurance` state among other fields also
contains an `VehicleDetail` object, which is the asset being insured. We have used
-this `VehicleDetail` to demonstrate _One-to-One_ relationship. Similarly we also
+this `VehicleDetail` to demonstrate _One-to-One_ relationship. Similarly, we also
have a list of `Claim` objects in the `Insurance` state which represents claims
made against the insurance. We use them to demonstrate _One-to-Many_ relationship.
@@ -16,31 +16,31 @@ made against the insurance. We use them to demonstrate _One-to-Many_ relationshi
## Concepts
-A spring boot client is provided with the cordapp, which exposes two REST endpoints
-(see `Controller` in the clients module) to trigger the flows.
+A spring boot client is provided with the CorDapp, which exposes two REST endpoints
+(see `Controller` in the clients' module) to trigger the flows.
Use the command `./gradlew bootRun` in the project root folder to run the [Spring Boot
Server](https://spring.io/projects/spring-boot#overview).
### Flows
-There are two flow in this cordapp:
+There are two flow in this CorDapp:
-1. IssueInsurance: It creates the insurance state with the associated vehicle information.
+1. `IssueInsurance`: It creates the insurance state with the associated vehicle information.
-2. InsuranceClaim: It creates the claims against the insurance.
+2. `InsuranceClaim`: It creates the claims against the insurance.
## Usage
## Pre-Requisites
-For development environment setup, please refer to: [Setup Guide](https://docs.corda.net/getting-set-up.html).
+For development environment setup, please refer to: [Setup Guide](https://docs.r3.com/en/platform/corda/4.10/community/getting-set-up.html).
### Running the CorDapp
Open a terminal and go to the project root directory and type: (to deploy the nodes using bootstrapper)
```
-./gradlew clean deployNodes
+./gradlew clean build deployNodes
```
Then type: (to run the nodes)
```
@@ -50,7 +50,8 @@ Then type: (to run the nodes)
### Interacting with the nodes
The Postman collection containing API's calls to the REST endpoints can be imported
-from the link: https://www.getpostman.com/collections/ddc01c13b8ab4b5e853b.
+from [this link](https://www.getpostman.com/collections/ddc01c13b8ab4b5e853b).
+
Use the option Import > Import from Link option in Postman to import the collection.
diff --git a/Features/queryablestate-carinsurance/build.gradle b/Features/queryablestate-carinsurance/build.gradle
index 9cef224f..a2f9fd30 100644
--- a/Features/queryablestate-carinsurance/build.gradle
+++ b/Features/queryablestate-carinsurance/build.gradle
@@ -23,8 +23,8 @@ buildscript {
repositories {
mavenLocal()
mavenCentral()
- jcenter()
- maven { url 'https://software.r3.com/artifactory/corda-releases' }
+
+ maven { url 'https://download.corda.net/maven/corda-releases' }
}
dependencies {
@@ -42,9 +42,9 @@ allprojects {
repositories {
mavenLocal()
- jcenter()
+
mavenCentral()
- maven { url 'https://software.r3.com/artifactory/corda' }
+ maven { url 'https://download.corda.net/maven/corda-dependencies' }
maven { url 'https://jitpack.io' }
}
@@ -84,6 +84,9 @@ dependencies {
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"
+
+ cordaDriver "net.corda:corda-shell:4.10"
+
}
cordapp {
diff --git a/Features/queryablestate-carinsurance/contracts/build.gradle b/Features/queryablestate-carinsurance/contracts/build.gradle
index 12dcbf54..6e7348cc 100644
--- a/Features/queryablestate-carinsurance/contracts/build.gradle
+++ b/Features/queryablestate-carinsurance/contracts/build.gradle
@@ -44,6 +44,6 @@ dependencies {
// Corda dependencies.
cordaCompile "$corda_core_release_group:corda-core:$corda_core_release_version"
cordaRuntime "$corda_release_group:corda:$corda_release_version"
- compileOnly "$corda_release_group:corda-testserver-impl:$corda_release_version"
+
testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
}
diff --git a/Features/queryablestate-carinsurance/contracts/src/test/java/net/corda/samples/carinsurance/states/InsuranceStateTests.java b/Features/queryablestate-carinsurance/contracts/src/test/java/net/corda/samples/carinsurance/states/InsuranceStateTests.java
index 8a78e4a8..c94b494c 100644
--- a/Features/queryablestate-carinsurance/contracts/src/test/java/net/corda/samples/carinsurance/states/InsuranceStateTests.java
+++ b/Features/queryablestate-carinsurance/contracts/src/test/java/net/corda/samples/carinsurance/states/InsuranceStateTests.java
@@ -7,8 +7,9 @@
import java.util.Arrays;
-import static org.jgroups.util.Util.assertEquals;
-import static org.jgroups.util.Util.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.wildfly.common.Assert.assertTrue;
+
public class InsuranceStateTests {
diff --git a/Features/queryablestate-carinsurance/contracts/src/test/java/net/corda/samples/carinsurance/states/VehicleDetailTests.java b/Features/queryablestate-carinsurance/contracts/src/test/java/net/corda/samples/carinsurance/states/VehicleDetailTests.java
index 547a62a8..b03ef72a 100644
--- a/Features/queryablestate-carinsurance/contracts/src/test/java/net/corda/samples/carinsurance/states/VehicleDetailTests.java
+++ b/Features/queryablestate-carinsurance/contracts/src/test/java/net/corda/samples/carinsurance/states/VehicleDetailTests.java
@@ -4,7 +4,7 @@
import net.corda.testing.core.TestIdentity;
import org.junit.Test;
-import static org.jgroups.util.Util.assertEquals;
+import static org.junit.Assert.assertEquals;
public class VehicleDetailTests {
diff --git a/Features/queryablestate-carinsurance/repositories.gradle b/Features/queryablestate-carinsurance/repositories.gradle
index 206b9c68..8be7b630 100644
--- a/Features/queryablestate-carinsurance/repositories.gradle
+++ b/Features/queryablestate-carinsurance/repositories.gradle
@@ -1,8 +1,8 @@
repositories {
mavenLocal()
mavenCentral()
- jcenter()
+
maven { url 'https://jitpack.io' }
- maven { url 'https://software.r3.com/artifactory/corda' }
+ maven { url 'https://download.corda.net/maven/corda-dependencies' }
maven { url 'https://repo.gradle.org/gradle/libs-releases' }
}
diff --git a/Features/queryablestate-carinsurance/workflows/build.gradle b/Features/queryablestate-carinsurance/workflows/build.gradle
index a5fd876b..e53991a3 100644
--- a/Features/queryablestate-carinsurance/workflows/build.gradle
+++ b/Features/queryablestate-carinsurance/workflows/build.gradle
@@ -52,7 +52,7 @@ dependencies {
// Corda dependencies.
cordaCompile "$corda_core_release_group:corda-core:$corda_core_release_version"
cordaRuntime "$corda_release_group:corda:$corda_release_version"
- compileOnly "$corda_release_group:corda-testserver-impl:$corda_release_version"
+
testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
// CorDapp dependencies.
diff --git a/Features/queryablestate-carinsurance/workflows/src/main/java/net/corda/samples/carinsurance/flows/IssueInsuranceFlow.java b/Features/queryablestate-carinsurance/workflows/src/main/java/net/corda/samples/carinsurance/flows/IssueInsuranceFlow.java
index 5815c60c..1ac0c4b7 100644
--- a/Features/queryablestate-carinsurance/workflows/src/main/java/net/corda/samples/carinsurance/flows/IssueInsuranceFlow.java
+++ b/Features/queryablestate-carinsurance/workflows/src/main/java/net/corda/samples/carinsurance/flows/IssueInsuranceFlow.java
@@ -3,6 +3,7 @@
import co.paralleluniverse.fibers.Suspendable;
import com.google.common.collect.ImmutableList;
import net.corda.core.flows.*;
+import net.corda.core.identity.CordaX500Name;
import net.corda.core.identity.Party;
import net.corda.core.transactions.SignedTransaction;
import net.corda.core.transactions.TransactionBuilder;
@@ -39,13 +40,7 @@ public ProgressTracker getProgressTracker() {
public SignedTransaction call() throws FlowException {
// Obtain a reference to 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.
- */
- final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0); // METHOD 1
- // final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB")); // METHOD 2
+ final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB"));
Party insurer = getOurIdentity();
diff --git a/Features/queryablestate-carinsurance/workflows/src/test/java/net/corda/samples/carinsurance/flows/FlowTests.java b/Features/queryablestate-carinsurance/workflows/src/test/java/net/corda/samples/carinsurance/flows/FlowTests.java
index 603cd1b2..c63a8228 100644
--- a/Features/queryablestate-carinsurance/workflows/src/test/java/net/corda/samples/carinsurance/flows/FlowTests.java
+++ b/Features/queryablestate-carinsurance/workflows/src/test/java/net/corda/samples/carinsurance/flows/FlowTests.java
@@ -2,11 +2,9 @@
import com.google.common.collect.ImmutableList;
import net.corda.core.concurrent.CordaFuture;
+import net.corda.core.identity.CordaX500Name;
import net.corda.core.transactions.SignedTransaction;
-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 net.corda.testing.node.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -17,7 +15,8 @@ public class FlowTests {
private final MockNetwork network = new MockNetwork(new MockNetworkParameters(ImmutableList.of(
TestCordapp.findCordapp("net.corda.samples.carinsurance.contracts"),
TestCordapp.findCordapp("net.corda.samples.carinsurance.flows")
- )));
+ )).withNotarySpecs(ImmutableList.of(new MockNetworkNotarySpec(CordaX500Name.parse("O=Notary,L=London,C=GB"))))
+ );
private final StartedMockNode a = network.createNode();
private final StartedMockNode b = network.createNode();
diff --git a/Features/referencestates-sanctionsbody/README.md b/Features/referencestates-sanctionsbody/README.md
index 00c0aa0e..be971b8d 100644
--- a/Features/referencestates-sanctionsbody/README.md
+++ b/Features/referencestates-sanctionsbody/README.md
@@ -10,14 +10,14 @@ This CorDapp allows two nodes to enter into an IOU agreement, but enforces that
## Pre-Requisites
-For development environment setup, please refer to: [Setup Guide](https://docs.corda.net/getting-set-up.html).
+For development environment setup, please refer to: [Setup Guide](https://docs.r3.com/en/platform/corda/4.10/community/getting-set-up.html).
### Running the CorDapp
Open a terminal and go to the project root directory and type: (to deploy the nodes using bootstrapper)
```
-./gradlew clean deployNodes
+./gradlew clean build deployNodes
```
Then type: (to run the nodes)
```
diff --git a/Features/referencestates-sanctionsbody/build.gradle b/Features/referencestates-sanctionsbody/build.gradle
index 3f53db2d..49b1af1c 100644
--- a/Features/referencestates-sanctionsbody/build.gradle
+++ b/Features/referencestates-sanctionsbody/build.gradle
@@ -19,8 +19,8 @@ buildscript {
repositories {
mavenLocal()
mavenCentral()
- jcenter()
- maven { url 'https://software.r3.com/artifactory/corda-releases' }
+
+ maven { url 'https://download.corda.net/maven/corda-releases' }
}
dependencies {
@@ -36,9 +36,9 @@ allprojects { //Properties that you need to compile your project (The applicatio
repositories {
mavenLocal()
- jcenter()
+
mavenCentral()
- maven { url 'https://software.r3.com/artifactory/corda' }
+ maven { url 'https://download.corda.net/maven/corda-dependencies' }
maven { url 'https://jitpack.io' }
}
@@ -79,6 +79,8 @@ dependencies {
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"
+ cordaDriver "net.corda:corda-shell:4.10"
+
}
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
diff --git a/Features/referencestates-sanctionsbody/contracts/src/test/java/net/corda/samples/referencestates/states/SanctionableIOUStateTests.java b/Features/referencestates-sanctionsbody/contracts/src/test/java/net/corda/samples/referencestates/states/SanctionableIOUStateTests.java
index a52b82b7..d3c9467b 100644
--- a/Features/referencestates-sanctionsbody/contracts/src/test/java/net/corda/samples/referencestates/states/SanctionableIOUStateTests.java
+++ b/Features/referencestates-sanctionsbody/contracts/src/test/java/net/corda/samples/referencestates/states/SanctionableIOUStateTests.java
@@ -8,8 +8,8 @@
import net.corda.testing.core.TestIdentity;
import org.junit.Test;
-import static org.jgroups.util.Util.assertEquals;
-import static org.jgroups.util.Util.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.wildfly.common.Assert.assertTrue;
public class SanctionableIOUStateTests {
diff --git a/Features/referencestates-sanctionsbody/contracts/src/test/java/net/corda/samples/referencestates/states/SanctionedEntitiesTests.java b/Features/referencestates-sanctionsbody/contracts/src/test/java/net/corda/samples/referencestates/states/SanctionedEntitiesTests.java
index bb1b708f..d5ad4c58 100644
--- a/Features/referencestates-sanctionsbody/contracts/src/test/java/net/corda/samples/referencestates/states/SanctionedEntitiesTests.java
+++ b/Features/referencestates-sanctionsbody/contracts/src/test/java/net/corda/samples/referencestates/states/SanctionedEntitiesTests.java
@@ -10,7 +10,9 @@
import java.util.Arrays;
import java.util.List;
-import static org.jgroups.util.Util.*;
+import static org.junit.Assert.assertEquals;
+import static org.wildfly.common.Assert.assertFalse;
+import static org.wildfly.common.Assert.assertTrue;
public class SanctionedEntitiesTests {
diff --git a/Features/referencestates-sanctionsbody/repositories.gradle b/Features/referencestates-sanctionsbody/repositories.gradle
index 206b9c68..8be7b630 100644
--- a/Features/referencestates-sanctionsbody/repositories.gradle
+++ b/Features/referencestates-sanctionsbody/repositories.gradle
@@ -1,8 +1,8 @@
repositories {
mavenLocal()
mavenCentral()
- jcenter()
+
maven { url 'https://jitpack.io' }
- maven { url 'https://software.r3.com/artifactory/corda' }
+ maven { url 'https://download.corda.net/maven/corda-dependencies' }
maven { url 'https://repo.gradle.org/gradle/libs-releases' }
}
diff --git a/Features/referencestates-sanctionsbody/workflows/src/main/java/net/corda/samples/referencestates/referencestates/flows/IOUIssueFlow.java b/Features/referencestates-sanctionsbody/workflows/src/main/java/net/corda/samples/referencestates/referencestates/flows/IOUIssueFlow.java
index 26121462..d6b37bde 100644
--- a/Features/referencestates-sanctionsbody/workflows/src/main/java/net/corda/samples/referencestates/referencestates/flows/IOUIssueFlow.java
+++ b/Features/referencestates-sanctionsbody/workflows/src/main/java/net/corda/samples/referencestates/referencestates/flows/IOUIssueFlow.java
@@ -1,6 +1,7 @@
package net.corda.samples.referencestates.referencestates.flows;
import co.paralleluniverse.fibers.Suspendable;
+import net.corda.core.identity.CordaX500Name;
import net.corda.samples.referencestates.contracts.SanctionableIOUContract;
import net.corda.samples.referencestates.states.SanctionableIOUState;
import net.corda.samples.referencestates.states.SanctionedEntities;
@@ -65,14 +66,10 @@ public ProgressTracker childProgressTracker() {
@Suspendable
@Override
public SignedTransaction call() throws FlowException {
+
// Obtain a reference to 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 flows or parsed from config (Preferred)
- *
- * * - For production you always want to use Method 2 as it guarantees the expected notary is returned.
- */
- final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0); // METHOD 1
- // final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB")); // METHOD 2
+ /** Explicit selection of notary by CordaX500Name - argument can by coded in flows or parsed from config (Preferred)*/
+ final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB"));
// Stage 1
progressTracker.setCurrentStep(GENERATING_TRANSACTION);
diff --git a/Features/referencestates-sanctionsbody/workflows/src/main/java/net/corda/samples/referencestates/referencestates/flows/IssueSanctionsListFlow.java b/Features/referencestates-sanctionsbody/workflows/src/main/java/net/corda/samples/referencestates/referencestates/flows/IssueSanctionsListFlow.java
index 21f1692c..10378a93 100644
--- a/Features/referencestates-sanctionsbody/workflows/src/main/java/net/corda/samples/referencestates/referencestates/flows/IssueSanctionsListFlow.java
+++ b/Features/referencestates-sanctionsbody/workflows/src/main/java/net/corda/samples/referencestates/referencestates/flows/IssueSanctionsListFlow.java
@@ -1,6 +1,7 @@
package net.corda.samples.referencestates.referencestates.flows;
import co.paralleluniverse.fibers.Suspendable;
+import net.corda.core.identity.CordaX500Name;
import net.corda.samples.referencestates.contracts.SanctionedEntitiesContract;
import net.corda.samples.referencestates.states.SanctionedEntities;
import net.corda.core.contracts.Command;
@@ -49,13 +50,8 @@ public ProgressTracker childProgressTracker() {
@Override
public StateAndRef call() throws FlowException {
// Obtain a reference to 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 flows or parsed from config (Preferred)
- *
- * * - For production you always want to use Method 2 as it guarantees the expected notary is returned.
- */
- final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0); // METHOD 1
- // final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB")); // METHOD 2
+ /** Explicit selection of notary by CordaX500Name - argument can by coded in flows or parsed from config (Preferred)*/
+ final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB"));
// Stage 1
progressTracker.setCurrentStep(GENERATING_TRANSACTION);
diff --git a/Features/referencestates-sanctionsbody/workflows/src/main/java/net/corda/samples/referencestates/referencestates/flows/UpdateSanctionsListFlow.java b/Features/referencestates-sanctionsbody/workflows/src/main/java/net/corda/samples/referencestates/referencestates/flows/UpdateSanctionsListFlow.java
index c260c5a1..3e8a3ea4 100644
--- a/Features/referencestates-sanctionsbody/workflows/src/main/java/net/corda/samples/referencestates/referencestates/flows/UpdateSanctionsListFlow.java
+++ b/Features/referencestates-sanctionsbody/workflows/src/main/java/net/corda/samples/referencestates/referencestates/flows/UpdateSanctionsListFlow.java
@@ -43,14 +43,7 @@ public ProgressTracker childProgressTracker() {
@Suspendable
@Override
public StateAndRef call() throws FlowException {
- // Obtain a reference to 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 flows or parsed from config (Preferred)
- *
- * * - For production you always want to use Method 2 as it guarantees the expected notary is returned.
- */
- final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0); // METHOD 1
- // final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB")); // METHOD 2
+
StateAndRef oldList = getServiceHub().getVaultService().queryBy(SanctionedEntities.class).getStates().get(0);
SanctionedEntities oldStateData = oldList.getState().getData();
@@ -62,6 +55,8 @@ public StateAndRef call() throws FlowException {
oldStateData.getLinearId()
);
+ Party notary = oldList.getState().getNotary();
+
// Stage 1
progressTracker.setCurrentStep(GENERATING_TRANSACTION);
//Create an unsigned transaction
diff --git a/Features/referencestates-sanctionsbody/workflows/src/test/java/net/corda/samples/referencestates/referencestates/flows/IOUFlowTests.java b/Features/referencestates-sanctionsbody/workflows/src/test/java/net/corda/samples/referencestates/referencestates/flows/IOUFlowTests.java
index 486db80b..8e26e20b 100644
--- a/Features/referencestates-sanctionsbody/workflows/src/test/java/net/corda/samples/referencestates/referencestates/flows/IOUFlowTests.java
+++ b/Features/referencestates-sanctionsbody/workflows/src/test/java/net/corda/samples/referencestates/referencestates/flows/IOUFlowTests.java
@@ -3,6 +3,7 @@
import com.google.common.collect.ImmutableList;
import net.corda.core.contracts.TransactionVerificationException;
import net.corda.core.flows.NotaryException;
+import net.corda.core.identity.CordaX500Name;
import net.corda.core.identity.Party;
import net.corda.core.node.NetworkParameters;
import net.corda.core.transactions.SignedTransaction;
@@ -44,7 +45,7 @@ public void setup() {
ImmutableList.of(new MockNetworkNotarySpec(DUMMY_NOTARY_NAME, false)),
new NetworkParameters(4, emptyList(), 10484760, 10484760 * 50, Instant.now(), 1, emptyMap(), Duration.ofDays(30)),
ImmutableList.of(findCordapp("net.corda.samples.referencestates.contracts"))
- );
+ ).withNotarySpecs(ImmutableList.of(new MockNetworkNotarySpec(CordaX500Name.parse("O=Notary,L=London,C=GB"))));
network = new MockNetwork(param);
diff --git a/Features/referencestates-sanctionsbody/workflows/src/test/java/net/corda/samples/referencestates/referencestates/flows/SanctionsFlowTests.java b/Features/referencestates-sanctionsbody/workflows/src/test/java/net/corda/samples/referencestates/referencestates/flows/SanctionsFlowTests.java
index 0cb2c429..2a6ed823 100644
--- a/Features/referencestates-sanctionsbody/workflows/src/test/java/net/corda/samples/referencestates/referencestates/flows/SanctionsFlowTests.java
+++ b/Features/referencestates-sanctionsbody/workflows/src/test/java/net/corda/samples/referencestates/referencestates/flows/SanctionsFlowTests.java
@@ -2,9 +2,9 @@
import com.google.common.collect.ImmutableList;
import net.corda.core.contracts.StateAndRef;
+import net.corda.core.identity.CordaX500Name;
import net.corda.samples.referencestates.states.SanctionedEntities;
-import net.corda.testing.node.MockNetwork;
-import net.corda.testing.node.StartedMockNode;
+import net.corda.testing.node.*;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -23,8 +23,11 @@ public class SanctionsFlowTests {
@Before
public void setup() {
- network = new MockNetwork(
- ImmutableList.of("net.corda.samples.referencestates.contracts"));
+ network = new MockNetwork(new MockNetworkParameters(ImmutableList.of(
+ TestCordapp.findCordapp("net.corda.samples.referencestates.contracts")
+ )).withNotarySpecs(ImmutableList.of(new MockNetworkNotarySpec(CordaX500Name.parse("O=Notary,L=London,C=GB"))))
+ );
+
a = network.createPartyNode(null);
b = network.createPartyNode(null);
c = network.createPartyNode(null);
diff --git a/Features/schedulablestate-heartbeat/README.md b/Features/schedulablestate-heartbeat/README.md
index de7dba7c..31eaf612 100644
--- a/Features/schedulablestate-heartbeat/README.md
+++ b/Features/schedulablestate-heartbeat/README.md
@@ -21,14 +21,14 @@ In this way, calling the `StartHeartbeatFlow` creates an endless chain of `Heart
## Pre-Requisites
-For development environment setup, please refer to: [Setup Guide](https://docs.corda.net/getting-set-up.html).
+For development environment setup, please refer to: [Setup Guide](https://docs.r3.com/en/platform/corda/4.10/community/getting-set-up.html).
### Running the CorDapp
Open a terminal and go to the project root directory and type: (to deploy the nodes using bootstrapper)
```
-./gradlew clean deployNodes
+./gradlew clean build deployNodes
```
Then type: (to run the nodes)
```
@@ -38,7 +38,7 @@ Then type: (to run the nodes)
### Interacting with the nodes:
-Go to the [CRaSH](https://docs.corda.net/docs/corda-os/shell.html) shell for PartyA, and run the `StartHeatbeatFlow`:
+Go to the interactive node shell for PartyA, and run the `StartHeatbeatFlow`:
start StartHeartbeatFlow
diff --git a/Features/schedulablestate-heartbeat/build.gradle b/Features/schedulablestate-heartbeat/build.gradle
index eff91a21..f1f0c4f7 100644
--- a/Features/schedulablestate-heartbeat/build.gradle
+++ b/Features/schedulablestate-heartbeat/build.gradle
@@ -19,8 +19,8 @@ buildscript {
repositories {
mavenLocal()
mavenCentral()
- jcenter()
- maven { url 'https://software.r3.com/artifactory/corda-releases' }
+
+ maven { url 'https://download.corda.net/maven/corda-releases' }
}
dependencies {
@@ -36,12 +36,12 @@ allprojects {
repositories {
mavenLocal()
- jcenter()
+
mavenCentral()
- maven { url 'https://software.r3.com/artifactory/corda' }
+ maven { url 'https://download.corda.net/maven/corda-dependencies' }
maven { url 'https://jitpack.io' }
//SDK lib
- maven { url 'https://software.r3.com/artifactory/corda-lib' }
+ maven { url 'https://download.corda.net/maven/corda-lib' }
//Gradle Plugins
maven { url 'https://repo.gradle.org/gradle/libs-releases' }
}
@@ -83,6 +83,8 @@ dependencies {
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"
+ cordaDriver "net.corda:corda-shell:4.10"
+
}
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
diff --git a/Features/schedulablestate-heartbeat/contracts/src/test/java/net/corda/samples/heartbeat/states/StateTests.java b/Features/schedulablestate-heartbeat/contracts/src/test/java/net/corda/samples/heartbeat/states/StateTests.java
index 07b8826e..4f530b2d 100644
--- a/Features/schedulablestate-heartbeat/contracts/src/test/java/net/corda/samples/heartbeat/states/StateTests.java
+++ b/Features/schedulablestate-heartbeat/contracts/src/test/java/net/corda/samples/heartbeat/states/StateTests.java
@@ -6,8 +6,8 @@
import net.corda.testing.core.TestIdentity;
import org.junit.Test;
-import static org.jgroups.util.Util.assertFalse;
-import static org.jgroups.util.Util.assertTrue;
+import static org.wildfly.common.Assert.assertFalse;
+import static org.wildfly.common.Assert.assertTrue;
public class StateTests {
diff --git a/Features/schedulablestate-heartbeat/workflows/src/main/java/net/corda/samples/heartbeat/flows/HeartbeatFlow.java b/Features/schedulablestate-heartbeat/workflows/src/main/java/net/corda/samples/heartbeat/flows/HeartbeatFlow.java
index 18707b1f..ab5f90a4 100644
--- a/Features/schedulablestate-heartbeat/workflows/src/main/java/net/corda/samples/heartbeat/flows/HeartbeatFlow.java
+++ b/Features/schedulablestate-heartbeat/workflows/src/main/java/net/corda/samples/heartbeat/flows/HeartbeatFlow.java
@@ -1,6 +1,7 @@
package net.corda.samples.heartbeat.flows;
import co.paralleluniverse.fibers.Suspendable;
+import net.corda.core.identity.CordaX500Name;
import net.corda.samples.heartbeat.contracts.HeartContract;
import net.corda.samples.heartbeat.states.HeartState;
import net.corda.core.contracts.*;
@@ -58,13 +59,7 @@ public String call() throws FlowException {
CommandData beatCmd = new HeartContract.Commands.Beat();
// Obtain a reference to 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.
- */
- final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0); // METHOD 1
- // final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB")); // METHOD 2
+ final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB"));
TransactionBuilder txBuilder = new TransactionBuilder(notary)
.addInputState(input)
diff --git a/Features/schedulablestate-heartbeat/workflows/src/main/java/net/corda/samples/heartbeat/flows/StartHeartbeatFlow.java b/Features/schedulablestate-heartbeat/workflows/src/main/java/net/corda/samples/heartbeat/flows/StartHeartbeatFlow.java
index 230a0229..7c64507e 100644
--- a/Features/schedulablestate-heartbeat/workflows/src/main/java/net/corda/samples/heartbeat/flows/StartHeartbeatFlow.java
+++ b/Features/schedulablestate-heartbeat/workflows/src/main/java/net/corda/samples/heartbeat/flows/StartHeartbeatFlow.java
@@ -1,6 +1,7 @@
package net.corda.samples.heartbeat.flows;
import co.paralleluniverse.fibers.Suspendable;
+import net.corda.core.identity.CordaX500Name;
import net.corda.samples.heartbeat.contracts.HeartContract;
import net.corda.samples.heartbeat.states.HeartState;
import net.corda.core.contracts.CommandData;
@@ -56,13 +57,7 @@ public Void call() throws FlowException {
CommandData cmd = new HeartContract.Commands.Beat();
// Obtain a reference to 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.
- */
- final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0); // METHOD 1
- // final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB")); // METHOD 2
+ final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB"));
TransactionBuilder txBuilder = new TransactionBuilder(notary)
.addOutputState(output, HeartContract.contractID)
diff --git a/Features/schedulablestate-heartbeat/workflows/src/test/java/net/corda/samples/heartbeat/flows/FlowTests.java b/Features/schedulablestate-heartbeat/workflows/src/test/java/net/corda/samples/heartbeat/flows/FlowTests.java
index 27c7a162..a3dc50bc 100644
--- a/Features/schedulablestate-heartbeat/workflows/src/test/java/net/corda/samples/heartbeat/flows/FlowTests.java
+++ b/Features/schedulablestate-heartbeat/workflows/src/test/java/net/corda/samples/heartbeat/flows/FlowTests.java
@@ -1,11 +1,9 @@
package net.corda.samples.heartbeat.flows;
import com.google.common.collect.ImmutableList;
+import net.corda.core.identity.CordaX500Name;
import net.corda.core.transactions.SignedTransaction;
-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 net.corda.testing.node.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -28,7 +26,9 @@ public void setup() {
TestCordapp.findCordapp("net.corda.samples.heartbeat.flows"),
TestCordapp.findCordapp("net.corda.samples.heartbeat.contracts")
)
- ));
+ )
+ .withNotarySpecs(ImmutableList.of(new MockNetworkNotarySpec(CordaX500Name.parse("O=Notary,L=London,C=GB"))))
+ );
node = network.createNode();
}
diff --git a/Features/state-reissuance/.ci/Jenkinsfile b/Features/state-reissuance/.ci/Jenkinsfile
new file mode 100644
index 00000000..7421cafe
--- /dev/null
+++ b/Features/state-reissuance/.ci/Jenkinsfile
@@ -0,0 +1,37 @@
+#!groovy
+/**
+ * Jenkins pipeline to build the java CorDapp template
+ */
+
+/**
+ * Kill already started job.
+ * Assume new commit takes precedence and results from previousunfinished builds are not required.
+ * This feature doesn't play well with disableConcurrentBuilds() option
+ */
+@Library('corda-shared-build-pipeline-steps')
+import static com.r3.build.BuildControl.killAllExistingBuildsForJob
+killAllExistingBuildsForJob(env.JOB_NAME, env.BUILD_NUMBER.toInteger())
+
+pipeline {
+ agent {
+ label 'eight-cores'
+ }
+ options {
+ ansiColor('xterm')
+ timestamps()
+ timeout(3*60) // 3 hours
+ buildDiscarder(logRotator(daysToKeepStr: '7', artifactDaysToKeepStr: '7'))
+ }
+ stages {
+ stage('Build') {
+ steps {
+ sh './gradlew --no-daemon -s clean build test deployNodes'
+ }
+ }
+ }
+ post {
+ cleanup {
+ deleteDir()
+ }
+ }
+}
diff --git a/Features/state-reissuance/.settings/org.eclipse.jdt.core.prefs b/Features/state-reissuance/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..ac86f90c
--- /dev/null
+++ b/Features/state-reissuance/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1 @@
+org.eclipse.jdt.core.compiler.codegen.methodParameters=generate
\ No newline at end of file
diff --git a/Features/state-reissuance/LICENCE b/Features/state-reissuance/LICENCE
new file mode 100644
index 00000000..3ff572d1
--- /dev/null
+++ b/Features/state-reissuance/LICENCE
@@ -0,0 +1,13 @@
+ 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/Features/state-reissuance/README.md b/Features/state-reissuance/README.md
new file mode 100644
index 00000000..f73c31d2
--- /dev/null
+++ b/Features/state-reissuance/README.md
@@ -0,0 +1,102 @@
+
+
+
+
+# State Reissuance Sample CorDapp
+
+This CorDapp serves as a sample for state reissuance feature of Corda. This feature enables developers to break long
+transaction backchains by reissuing a state with a guaranteed state replacement. This is particularly useful in situations
+when a party doesn't want to share state history with other parties for privacy or performance concerns.
+
+This samples demonstrates the feature with the help of a linear state, represented by a land title issued on Corda ledger.
+The land title can be transferred multiple times and when the transaction backchain becomes long, the land title could be
+reissued and the transaction backchain could be pruned.
+
+# Pre-Requisites
+
+For development environment setup, please refer to: [Setup Guide](https://docs.r3.com/en/platform/corda/4.10/community/getting-set-up.html).
+
+# Usage
+
+## Running the CorDapp
+
+Open a terminal and go to the project root directory and type: (to deploy the nodes using bootstrapper)
+
+ ./gradlew clean build deployNodes
+
+Then type: (to run the nodes)
+
+ ./build/nodes/runnodes
+
+## Interacting with the CorDapp
+
+PartyA issues a land title to PartyB, Go to PartyA's terminal and run the below command
+
+ start IssueLandTitleFlow owner: PartyB, dimensions: 40X50, area: 1200sqft
+
+Verify the land title has been issued correctly by querying the ledgers of PartyA and PartyB using the below command.
+PartyA should be issuer and PartyB should be the owner of the land title.
+
+ run vaultQuery contractStateType: net.corda.samples.statereissuance.states.LandTitleState
+
+Once land title has been issued to PartyB, they could transfer it to PartyC. Go to PartyB's terminal and run the below command
+
+ start TransferLandTitleFlow owner: PartyC, plotIdentifier:
+
+You could find the `plot-identifier` from the result of the vaultQuery command used earlier to query the ledgers.
+
+
+Verify the land title has been correctly transferred to PartyC by querying the ledgers of PartyA and PartyC using the below command
+
+ run vaultQuery contractStateType: net.corda.samples.statereissuance.states.LandTitleState
+
+Note that PartyB is no more able to see the land title, since they are no longer a party to the state as they have transferred
+the title to PartyC. It is currently only visible to PartyA and PartyC.
+
+Consider that PartyC now wants to reissue the title to get rid of the backchain. They need to request a reissuance to the issuer.
+Go to PartyC's terminal and run the below command
+
+ start RequestReissueLandStateFlow issuer: PartyA, plotIdentifier:
+
+Now a reissuance request is created on the ledgers of PartyA and PartyC, when can be verified using the below command
+
+ run vaultQuery contractStateType: com.r3.corda.lib.reissuance.states.ReissuanceRequest
+
+The issuer could either accept or reject the reissuance request. Let's consider the case where the issuer accepts the
+reissuance request. To accept the request goto PartyA's (issuer) terminal and run the below command
+
+ start AcceptLandReissuanceFlow issuer: PartyA, stateRef: {index: , txhash: }
+
+The `` and `` are of the transaction which created the state to the reissued. They can be found
+in the `ReissuanceRequest` queried earlier.
+
+
+On successful completion of the above flow, a duplicate land title would be issued, however it would be currently
+locked, and it could not be spent. In order to spend it, the older state which was requested to be reissued must be exited
+and that would allow the new reissued state to be unlocked and spend.
+
+To exit the older land title run the below command from PartyC's terminal.
+
+ start ExitLandTitleFlow stateRef: {index: , txhash: }
+
+Once the previous land title is exited, unlock the reissued land title using the below command from PartyC's terminal
+
+ start UnlockReissuedLandStateFlow reissuedRef: {index: , txhash: }, reissuanceLockRef: {index: , txhash: }, exitTrnxId:
+
+The `reissuedRef` is the stateRef of the reissued state.
+ 
+
+ And the `reissuanceLockRef` is the stateRef of the reissuance lock generated, which can queried using `run vaultQuery contractStateType: com.r3.corda.lib.reissuance.states.ReissuanceLock`
+ 
+ And the `exitTrnxId` is the transaction hash of the transaction used to exit the older state.
+ 
+
+Note that the lock uses the encumbrance feature of Corda. You can check out the sample on encumbrance [here](https://github.com/corda/samples-java/tree/master/Features/encumbrance-avatar)
+
+Now with all the information input into the function call, the reissue process is completed and the reissued state can be spent freely.
+
+
+
+You can see the encumbrance field is restored to `null` again, meaning the state is free to be transacted again.
+
+
diff --git a/Features/state-reissuance/TRADEMARK b/Features/state-reissuance/TRADEMARK
new file mode 100644
index 00000000..d2e056b5
--- /dev/null
+++ b/Features/state-reissuance/TRADEMARK
@@ -0,0 +1,4 @@
+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/.
\ No newline at end of file
diff --git a/Features/state-reissuance/build.gradle b/Features/state-reissuance/build.gradle
new file mode 100644
index 00000000..23ed2f31
--- /dev/null
+++ b/Features/state-reissuance/build.gradle
@@ -0,0 +1,180 @@
+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")
+ reissuance_release_group = 'com.r3.corda.lib.reissuance'
+ reissuance_release_version = '1.0-GA'
+ confidential_id_release_group = 'com.r3.corda.lib.ci'
+ confidential_id_release_version = '1.0'
+ tokens_release_version = '1.2'
+ tokens_release_group = 'com.r3.corda.lib.tokens'
+ 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()
+ maven { url 'https://download.corda.net/maven/corda-releases' }
+ maven { url 'https://download.corda.net/maven/corda-lib' }
+ }
+
+ dependencies {
+ 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.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_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: 'java'
+ apply plugin: 'kotlin'
+
+ repositories {
+ mavenLocal()
+ mavenCentral()
+ maven { url 'https://download.corda.net/maven/corda-dependencies' }
+ maven { url 'https://download.corda.net/maven/corda-lib' }
+ maven { url 'https://jitpack.io' }
+
+ }
+
+ tasks.withType(JavaCompile) {
+ options.compilerArgs << "-parameters" // Required by Corda's serialisation framework.
+ }
+
+ 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
+ duplicatesStrategy = DuplicatesStrategy.EXCLUDE
+ }
+}
+
+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"
+ cordaCompile "$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")
+ cordapp "$reissuance_release_group:reissuance-cordapp-contracts:$reissuance_release_version"
+ cordapp "$reissuance_release_group:reissuance-cordapp-workflows:$reissuance_release_version"
+
+ // Token SDK dependencies.
+ cordapp "$tokens_release_group:tokens-contracts:$tokens_release_version"
+ cordapp "$tokens_release_group:tokens-workflows:$tokens_release_version"
+
+ // CI dependencies.
+ cordapp "$confidential_id_release_group:ci-workflows:$confidential_id_release_version"
+
+ 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"
+ cordaDriver "net.corda:corda-shell:4.10"
+
+}
+
+
+//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')
+ cordapp "$reissuance_release_group:reissuance-cordapp-contracts:$reissuance_release_version"
+ cordapp "$reissuance_release_group:reissuance-cordapp-workflows:$reissuance_release_version"
+ cordapp "$tokens_release_group:tokens-contracts:$tokens_release_version"
+ cordapp "$tokens_release_group:tokens-workflows:$tokens_release_version"
+
+ cordapp "$confidential_id_release_group:ci-workflows:$confidential_id_release_version"
+ 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]
+ p2pPort 10002
+ rpcSettings {
+ address("localhost:10003")
+ adminAddress("localhost:10043")
+ }
+ }
+ node {
+ name "O=PartyA,L=London,C=GB"
+ p2pPort 10005
+ rpcSettings {
+ address("localhost:10006")
+ adminAddress("localhost:10046")
+ }
+ rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
+ }
+ node {
+ name "O=PartyB,L=New York,C=US"
+ p2pPort 10008
+ rpcSettings {
+ address("localhost:10009")
+ adminAddress("localhost:10049")
+ }
+ rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
+ }
+
+ node {
+ name "O=PartyC,L=New York,C=US"
+ p2pPort 10011
+ rpcSettings {
+ address("localhost:10012")
+ adminAddress("localhost:10052")
+ }
+ rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
+ }
+}
diff --git a/Features/state-reissuance/config/dev/log4j2.xml b/Features/state-reissuance/config/dev/log4j2.xml
new file mode 100644
index 00000000..34ba4d45
--- /dev/null
+++ b/Features/state-reissuance/config/dev/log4j2.xml
@@ -0,0 +1,59 @@
+
+
+
+
+ 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/Features/state-reissuance/config/test/log4j2.xml b/Features/state-reissuance/config/test/log4j2.xml
new file mode 100644
index 00000000..cd9926ca
--- /dev/null
+++ b/Features/state-reissuance/config/test/log4j2.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ [%-5level] %d{HH:mm:ss.SSS} [%t] %c{1}.%M - %msg%n
+ >
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Features/state-reissuance/contracts/build.gradle b/Features/state-reissuance/contracts/build.gradle
new file mode 100644
index 00000000..8c18caad
--- /dev/null
+++ b/Features/state-reissuance/contracts/build.gradle
@@ -0,0 +1,35 @@
+apply plugin: 'net.corda.plugins.cordapp'
+apply plugin: 'net.corda.plugins.cordformation'
+
+cordapp {
+ targetPlatformVersion corda_platform_version
+ minimumPlatformVersion corda_platform_version
+ contract {
+ name "State Re-Issuance Contracts"
+ vendor "Corda Open Source"
+ licence "Apache License, Version 2.0"
+ versionId 1
+ }
+}
+
+sourceSets {
+ main{
+ java {
+ srcDir 'src/main/java'
+ java.outputDir = file('bin/main')
+ }
+ }
+ test{
+ java{
+ srcDir 'src/test/java'
+ java.outputDir = file('bin/test')
+ }
+ }
+}
+
+dependencies {
+ // 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"
+}
\ No newline at end of file
diff --git a/Features/state-reissuance/contracts/src/main/java/net/corda/samples/statereissuance/contracts/LandTitleContract.java b/Features/state-reissuance/contracts/src/main/java/net/corda/samples/statereissuance/contracts/LandTitleContract.java
new file mode 100644
index 00000000..1219e5df
--- /dev/null
+++ b/Features/state-reissuance/contracts/src/main/java/net/corda/samples/statereissuance/contracts/LandTitleContract.java
@@ -0,0 +1,73 @@
+package net.corda.samples.statereissuance.contracts;
+
+import net.corda.core.contracts.Command;
+import net.corda.samples.statereissuance.states.LandTitleState;
+import net.corda.core.contracts.CommandData;
+import net.corda.core.contracts.Contract;
+import net.corda.core.transactions.LedgerTransaction;
+
+import static net.corda.core.contracts.ContractsDSL.requireThat;
+
+// ************
+// * Contract *
+// ************
+public class LandTitleContract implements Contract {
+
+ // A transaction is valid if the verify() function of the contract of all the transaction's input and output states
+ // does not throw an exception.
+ @Override
+ public void verify(LedgerTransaction tx) {
+ if(tx.getCommands().size() == 0){
+ throw new IllegalArgumentException("One command Expected");
+ }
+
+ Command command = tx.getCommand(0);
+ if(command.getValue() instanceof Commands.Issue)
+ verifyIssue(tx);
+
+ else if(command.getValue() instanceof Commands.Transfer)
+ verifyTransfer(tx);
+
+ else if (command.getValue() instanceof Commands.Exit)
+ verifyExit(tx);
+ }
+
+ private void verifyIssue(LedgerTransaction tx){
+ // Land Title Issue Contract Verification Logic goes here
+ if(tx.getOutputStates().size() != 1) throw new IllegalArgumentException("One Output Expected");
+
+ Command command = tx.getCommand(0);
+ if(!(command.getSigners().contains(((LandTitleState)tx.getOutput(0)).getIssuer().getOwningKey())))
+ throw new IllegalArgumentException("Issuer Signature Required");
+ }
+
+ private void verifyTransfer(LedgerTransaction tx){
+ // Land Title Transfer Contract Verification Logic goes here
+ Command command = tx.getCommand(0);
+ LandTitleState landTitleState = (LandTitleState) tx.getInput(0);
+ if (!(command.getSigners().contains(landTitleState.getIssuer().getOwningKey())) &&
+ (landTitleState.getOwner() != null
+ && command.getSigners().contains(landTitleState.getOwner().getOwningKey())))
+ throw new IllegalArgumentException("Issuer and Owner must Sign");
+ }
+
+ private void verifyExit(LedgerTransaction tx){
+ // Land Title Exit Contract Verification Logic goes here
+
+ if(tx.getOutputStates().size() != 0) throw new IllegalArgumentException("Zero Output Expected");
+ if(tx.getInputStates().size() != 1) throw new IllegalArgumentException("One Input Expected");
+
+ Command command = tx.getCommand(0);
+ if(!(command.getSigners().contains(((LandTitleState)tx.getInput(0)).getIssuer().getOwningKey())))
+ throw new IllegalArgumentException("Issuer Signature Required");
+ }
+
+
+ // Used to indicate the transaction's intent.
+ public interface Commands extends CommandData {
+ class Issue implements Commands {}
+ class Transfer implements Commands {}
+ class Exit implements Commands {}
+ class Reissue implements Commands {}
+ }
+}
\ No newline at end of file
diff --git a/Features/state-reissuance/contracts/src/main/java/net/corda/samples/statereissuance/states/LandTitleState.java b/Features/state-reissuance/contracts/src/main/java/net/corda/samples/statereissuance/states/LandTitleState.java
new file mode 100644
index 00000000..2434d1e6
--- /dev/null
+++ b/Features/state-reissuance/contracts/src/main/java/net/corda/samples/statereissuance/states/LandTitleState.java
@@ -0,0 +1,82 @@
+package net.corda.samples.statereissuance.states;
+
+import net.corda.core.contracts.LinearState;
+import net.corda.core.contracts.UniqueIdentifier;
+import net.corda.samples.statereissuance.contracts.LandTitleContract;
+import net.corda.core.contracts.BelongsToContract;
+import net.corda.core.contracts.ContractState;
+import net.corda.core.identity.AbstractParty;
+import net.corda.core.identity.Party;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+// *********
+// * State *
+// *********
+@BelongsToContract(LandTitleContract.class)
+public class LandTitleState implements LinearState {
+
+ /* This is the unique identifier of the property */
+ private UniqueIdentifier plotIdentifier;
+ private String dimensions;
+ private String area;
+
+ private Party owner;
+ private Party issuer;
+
+ /* Constructor of our Corda state */
+ public LandTitleState(UniqueIdentifier plotIdentifier, String dimensions, String area, Party owner, Party issuer) {
+ this.plotIdentifier = plotIdentifier;
+ this.dimensions = dimensions;
+ this.area = area;
+ this.owner = owner;
+ this.issuer = issuer;
+ }
+
+ //Getters
+
+ public Party getOwner() {
+ return owner;
+ }
+
+ public Party getIssuer() {
+ return issuer;
+ }
+
+ public String getDimensions() {
+ return dimensions;
+ }
+
+ public String getArea() {
+ return area;
+ }
+
+ /* This method will indicate who are the participants and required signers when
+ * this state is used in a transaction. */
+ @NotNull
+ @Override
+ public List getParticipants() {
+ return Arrays.asList(issuer, owner);
+ }
+
+ @NotNull
+ @Override
+ public UniqueIdentifier getLinearId() {
+ return plotIdentifier;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ return plotIdentifier.equals(((LandTitleState) o).plotIdentifier);
+ }
+
+ @Override
+ public int hashCode() {
+ return plotIdentifier.hashCode();
+ }
+}
\ No newline at end of file
diff --git a/Features/state-reissuance/contracts/src/test/java/net/corda/samples/statereissuance/contracts/ContractTests.java b/Features/state-reissuance/contracts/src/test/java/net/corda/samples/statereissuance/contracts/ContractTests.java
new file mode 100644
index 00000000..77e7e50a
--- /dev/null
+++ b/Features/state-reissuance/contracts/src/test/java/net/corda/samples/statereissuance/contracts/ContractTests.java
@@ -0,0 +1,20 @@
+package net.corda.samples.statereissuance.contracts;
+
+import net.corda.samples.statereissuance.states.LandTitleState;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.testing.core.TestIdentity;
+import net.corda.testing.node.MockServices;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static net.corda.testing.node.NodeTestUtils.ledger;
+
+
+public class ContractTests {
+ private final MockServices ledgerServices = new MockServices(Arrays.asList("net.corda.samples.statereissuance"));
+ TestIdentity alice = new TestIdentity(new CordaX500Name("Alice", "TestLand", "US"));
+ TestIdentity bob = new TestIdentity(new CordaX500Name("Alice", "TestLand", "US"));
+
+
+}
\ No newline at end of file
diff --git a/Features/state-reissuance/contracts/src/test/java/net/corda/samples/statereissuance/contracts/StateTests.java b/Features/state-reissuance/contracts/src/test/java/net/corda/samples/statereissuance/contracts/StateTests.java
new file mode 100644
index 00000000..e8f5113b
--- /dev/null
+++ b/Features/state-reissuance/contracts/src/test/java/net/corda/samples/statereissuance/contracts/StateTests.java
@@ -0,0 +1,10 @@
+package net.corda.samples.statereissuance.contracts;
+
+import net.corda.samples.statereissuance.states.LandTitleState;
+import org.junit.Test;
+
+public class StateTests {
+
+ //Mock State test check for if the state has correct parameters type
+
+}
\ No newline at end of file
diff --git a/Features/state-reissuance/gradle.properties b/Features/state-reissuance/gradle.properties
new file mode 100644
index 00000000..1f0a9254
--- /dev/null
+++ b/Features/state-reissuance/gradle.properties
@@ -0,0 +1,3 @@
+name=Test
+group=com.statereissuance
+version=0.1
\ No newline at end of file
diff --git a/Features/state-reissuance/gradle/wrapper/gradle-wrapper.jar b/Features/state-reissuance/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..99340b4a
Binary files /dev/null and b/Features/state-reissuance/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Features/state-reissuance/gradle/wrapper/gradle-wrapper.properties b/Features/state-reissuance/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..0188225a
--- /dev/null
+++ b/Features/state-reissuance/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,7 @@
+#Fri Aug 25 12:50:39 BST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
+
diff --git a/Features/state-reissuance/gradlew b/Features/state-reissuance/gradlew
new file mode 100755
index 00000000..cccdd3d5
--- /dev/null
+++ b/Features/state-reissuance/gradlew
@@ -0,0 +1,172 @@
+#!/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/Features/state-reissuance/gradlew.bat b/Features/state-reissuance/gradlew.bat
new file mode 100644
index 00000000..f9553162
--- /dev/null
+++ b/Features/state-reissuance/gradlew.bat
@@ -0,0 +1,84 @@
+@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/Features/state-reissuance/image/1.jpeg b/Features/state-reissuance/image/1.jpeg
new file mode 100644
index 00000000..e905727a
Binary files /dev/null and b/Features/state-reissuance/image/1.jpeg differ
diff --git a/Features/state-reissuance/image/2.jpeg b/Features/state-reissuance/image/2.jpeg
new file mode 100644
index 00000000..bc28719e
Binary files /dev/null and b/Features/state-reissuance/image/2.jpeg differ
diff --git a/Features/state-reissuance/image/3.jpeg b/Features/state-reissuance/image/3.jpeg
new file mode 100644
index 00000000..21df8109
Binary files /dev/null and b/Features/state-reissuance/image/3.jpeg differ
diff --git a/Features/state-reissuance/image/4.jpeg b/Features/state-reissuance/image/4.jpeg
new file mode 100644
index 00000000..fe79a03a
Binary files /dev/null and b/Features/state-reissuance/image/4.jpeg differ
diff --git a/Features/state-reissuance/image/5.jpeg b/Features/state-reissuance/image/5.jpeg
new file mode 100644
index 00000000..3ecd6895
Binary files /dev/null and b/Features/state-reissuance/image/5.jpeg differ
diff --git a/Features/state-reissuance/image/6.jpeg b/Features/state-reissuance/image/6.jpeg
new file mode 100644
index 00000000..ec48f5fe
Binary files /dev/null and b/Features/state-reissuance/image/6.jpeg differ
diff --git a/Features/state-reissuance/image/7.jpeg b/Features/state-reissuance/image/7.jpeg
new file mode 100644
index 00000000..277c0be9
Binary files /dev/null and b/Features/state-reissuance/image/7.jpeg differ
diff --git a/Features/state-reissuance/repositories.gradle b/Features/state-reissuance/repositories.gradle
new file mode 100644
index 00000000..9797c0ea
--- /dev/null
+++ b/Features/state-reissuance/repositories.gradle
@@ -0,0 +1,7 @@
+repositories {
+ mavenLocal()
+ mavenCentral()
+ maven { url 'https://jitpack.io' }
+ maven { url 'https://download.corda.net/maven/corda-dependencies' }
+ maven { url 'https://repo.gradle.org/gradle/libs-releases' }
+}
diff --git a/Features/state-reissuance/settings.gradle b/Features/state-reissuance/settings.gradle
new file mode 100644
index 00000000..b4446eaf
--- /dev/null
+++ b/Features/state-reissuance/settings.gradle
@@ -0,0 +1,2 @@
+include 'workflows'
+include 'contracts'
\ No newline at end of file
diff --git a/Features/state-reissuance/workflows/build.gradle b/Features/state-reissuance/workflows/build.gradle
new file mode 100644
index 00000000..bc6879c8
--- /dev/null
+++ b/Features/state-reissuance/workflows/build.gradle
@@ -0,0 +1,66 @@
+apply plugin: 'net.corda.plugins.cordapp'
+apply plugin: 'net.corda.plugins.cordformation'
+apply plugin: 'net.corda.plugins.quasar-utils'
+
+cordapp {
+ targetPlatformVersion corda_platform_version
+ minimumPlatformVersion corda_platform_version
+ workflow {
+ name "State Re-Issuance Flows"
+ vendor "Corda Open Source"
+ licence "Apache License, Version 2.0"
+ versionId 1
+ }
+}
+
+sourceSets {
+ main {
+ java {
+ srcDir 'src/main/java'
+ java.outputDir = file('bin/main')
+ }
+ resources {
+ srcDir rootProject.file("config/dev")
+ }
+ }
+ test {
+ java {
+ srcDir 'src/test/java'
+ java.outputDir = file('bin/main')
+ }
+ resources {
+ srcDir rootProject.file("config/test")
+ }
+ }
+ integrationTest {
+ java {
+ compileClasspath += main.output + test.output
+ runtimeClasspath += main.output + test.output
+ srcDir file('src/integrationTest/java')
+ }
+ }
+}
+
+configurations {
+ integrationTestCompile.extendsFrom testCompile
+ integrationTestRuntime.extendsFrom testRuntime
+}
+
+dependencies {
+ 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")
+ cordapp "$reissuance_release_group:reissuance-cordapp-contracts:$reissuance_release_version"
+ cordapp "$reissuance_release_group:reissuance-cordapp-workflows:$reissuance_release_version"
+}
+
+task integrationTest(type: Test, dependsOn: []) {
+ testClassesDirs = sourceSets.integrationTest.output.classesDirs
+ classpath = sourceSets.integrationTest.runtimeClasspath
+}
\ No newline at end of file
diff --git a/Features/state-reissuance/workflows/src/integrationTest/java/net/corda/samples/statereissuance/DriverBasedTest.java b/Features/state-reissuance/workflows/src/integrationTest/java/net/corda/samples/statereissuance/DriverBasedTest.java
new file mode 100644
index 00000000..4173231d
--- /dev/null
+++ b/Features/state-reissuance/workflows/src/integrationTest/java/net/corda/samples/statereissuance/DriverBasedTest.java
@@ -0,0 +1,48 @@
+package net.corda.samples.statereissuance;
+
+import com.google.common.collect.ImmutableList;
+import net.corda.core.concurrent.CordaFuture;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.testing.core.TestIdentity;
+import net.corda.testing.driver.DriverParameters;
+import net.corda.testing.driver.NodeHandle;
+import net.corda.testing.driver.NodeParameters;
+import org.junit.Test;
+
+import java.util.List;
+
+import static net.corda.testing.driver.Driver.driver;
+import static org.junit.Assert.assertEquals;
+
+public class DriverBasedTest {
+ private final TestIdentity bankA = new TestIdentity(new CordaX500Name("BankA", "", "GB"));
+ private final TestIdentity bankB = new TestIdentity(new CordaX500Name("BankB", "", "US"));
+
+ @Test
+ public void nodeTest() {
+ driver(new DriverParameters().withIsDebug(true).withStartNodesInProcess(true), dsl -> {
+ // Start a pair of nodes and wait for them both to be ready.
+ List> handleFutures = ImmutableList.of(
+ dsl.startNode(new NodeParameters().withProvidedName(bankA.getName())),
+ dsl.startNode(new NodeParameters().withProvidedName(bankB.getName()))
+ );
+
+ try {
+ NodeHandle partyAHandle = handleFutures.get(0).get();
+ NodeHandle partyBHandle = handleFutures.get(1).get();
+
+ // 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(partyAHandle.getRpc().wellKnownPartyFromX500Name(bankB.getName()).getName(), bankB.getName());
+ assertEquals(partyBHandle.getRpc().wellKnownPartyFromX500Name(bankA.getName()).getName(), bankA.getName());
+ } catch (Exception e) {
+ throw new RuntimeException("Caught exception during test: ", e);
+ }
+
+ return null;
+ });
+ }
+}
\ No newline at end of file
diff --git a/Features/state-reissuance/workflows/src/main/java/net/corda/samples/statereissuance/flows/ExitLandTitleFlow.java b/Features/state-reissuance/workflows/src/main/java/net/corda/samples/statereissuance/flows/ExitLandTitleFlow.java
new file mode 100644
index 00000000..6e08b56b
--- /dev/null
+++ b/Features/state-reissuance/workflows/src/main/java/net/corda/samples/statereissuance/flows/ExitLandTitleFlow.java
@@ -0,0 +1,81 @@
+package net.corda.samples.statereissuance.flows;
+
+import co.paralleluniverse.fibers.Suspendable;
+import net.corda.core.contracts.StateAndRef;
+import net.corda.core.contracts.StateRef;
+import net.corda.core.flows.*;
+import net.corda.core.transactions.SignedTransaction;
+import net.corda.core.transactions.TransactionBuilder;
+import net.corda.samples.statereissuance.contracts.LandTitleContract;
+import net.corda.samples.statereissuance.states.LandTitleState;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class ExitLandTitleFlow {
+
+ @InitiatingFlow
+ @StartableByRPC
+ public static class Initiator extends FlowLogic {
+
+ private StateRef stateRef;
+
+ public Initiator(StateRef stateRef) {
+ this.stateRef = stateRef;
+ }
+
+ @Override
+ @Suspendable
+ public SignedTransaction call() throws FlowException {
+ List> landTitleStateAndRefs = getServiceHub().getVaultService()
+ .queryBy(LandTitleState.class).getStates();
+
+ StateAndRef inputStateAndRef = landTitleStateAndRefs.stream()
+ .filter(landTitleStateStateAndRef -> landTitleStateStateAndRef.getRef().equals(stateRef))
+ .findAny().orElseThrow(() -> new IllegalArgumentException("Land Title Not Found"));
+
+ LandTitleState input = inputStateAndRef.getState().getData();
+
+ TransactionBuilder builder = new TransactionBuilder(inputStateAndRef.getState().getNotary())
+ .addInputState(inputStateAndRef)
+ .addCommand(new LandTitleContract.Commands.Exit(), Arrays.asList(getOurIdentity().getOwningKey(),
+ input.getIssuer().getOwningKey()));
+
+ builder.verify(getServiceHub());
+ final SignedTransaction ptx = getServiceHub().signInitialTransaction(builder);
+
+ FlowSession issuerSession = initiateFlow(input.getIssuer());
+
+ SignedTransaction stx = subFlow(new CollectSignaturesFlow(ptx, Collections.singletonList(issuerSession)));
+ return subFlow(new FinalityFlow(stx, Collections.singletonList(issuerSession)));
+ }
+ }
+
+ @InitiatedBy(Initiator.class)
+ public static class Responder extends FlowLogic{
+
+ private FlowSession counterpartySession;
+
+ public Responder(FlowSession counterpartySession) {
+ this.counterpartySession = counterpartySession;
+ }
+
+ @Override
+ @Suspendable
+ public Void call() throws FlowException {
+
+ subFlow(new SignTransactionFlow(counterpartySession) {
+ @Suspendable
+ @Override
+ protected void checkTransaction(SignedTransaction stx) throws FlowException {
+
+ }
+ });
+
+ //Stored the transaction into data base.
+ subFlow(new ReceiveFinalityFlow(counterpartySession));
+ return null;
+ }
+ }
+}
diff --git a/Features/state-reissuance/workflows/src/main/java/net/corda/samples/statereissuance/flows/IssueLandTitleFlow.java b/Features/state-reissuance/workflows/src/main/java/net/corda/samples/statereissuance/flows/IssueLandTitleFlow.java
new file mode 100644
index 00000000..2ce669e9
--- /dev/null
+++ b/Features/state-reissuance/workflows/src/main/java/net/corda/samples/statereissuance/flows/IssueLandTitleFlow.java
@@ -0,0 +1,77 @@
+package net.corda.samples.statereissuance.flows;
+
+import co.paralleluniverse.fibers.Suspendable;
+import net.corda.core.contracts.UniqueIdentifier;
+import net.corda.core.flows.*;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.core.identity.Party;
+import net.corda.core.transactions.SignedTransaction;
+import net.corda.core.transactions.TransactionBuilder;
+import net.corda.samples.statereissuance.contracts.LandTitleContract;
+import net.corda.samples.statereissuance.states.LandTitleState;
+
+import java.util.Arrays;
+
+public class IssueLandTitleFlow {
+
+ @InitiatingFlow
+ @StartableByRPC
+ public static class Initiator extends FlowLogic{
+
+ //private variables
+ private Party owner;
+ private String dimensions;
+ private String area;
+
+
+ //public constructor
+ public Initiator(Party owner,String dimensions, String area) {
+ this.owner = owner;
+ this.dimensions = dimensions;
+ this.area = area;
+ }
+
+ @Override
+ @Suspendable
+ public SignedTransaction call() throws FlowException {
+
+ // Get a reference to the notary service on our network and our key pair.
+ /** Explicit selection of notary by CordaX500Name - argument can by coded in flows or parsed from config (Preferred)*/
+ final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB"));
+ Party issuer = getOurIdentity();
+
+ LandTitleState landTitleState = new LandTitleState(new UniqueIdentifier(), dimensions, area, owner, issuer);
+
+ final TransactionBuilder builder = new TransactionBuilder(notary)
+ .addOutputState(landTitleState)
+ .addCommand(new LandTitleContract.Commands.Issue(), Arrays.asList(issuer.getOwningKey()));
+
+ // Verify and sign it with our KeyPair.
+ builder.verify(getServiceHub());
+ final SignedTransaction ptx = getServiceHub().signInitialTransaction(builder);
+
+ // Assuming no exceptions, we can now finalise the transaction
+ return subFlow(new FinalityFlow(ptx, Arrays.asList(initiateFlow(owner))));
+ }
+ }
+
+ @InitiatedBy(Initiator.class)
+ public static class Responder extends FlowLogic{
+ //private variable
+ private FlowSession counterpartySession;
+
+ //Constructor
+ public Responder(FlowSession counterpartySession) {
+ this.counterpartySession = counterpartySession;
+ }
+
+ @Suspendable
+ @Override
+ public Void call() throws FlowException {
+ //Stored the transaction into data base.
+ subFlow(new ReceiveFinalityFlow(counterpartySession));
+ return null;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Features/state-reissuance/workflows/src/main/java/net/corda/samples/statereissuance/flows/TransferLandTitleFlow.java b/Features/state-reissuance/workflows/src/main/java/net/corda/samples/statereissuance/flows/TransferLandTitleFlow.java
new file mode 100644
index 00000000..4b472e58
--- /dev/null
+++ b/Features/state-reissuance/workflows/src/main/java/net/corda/samples/statereissuance/flows/TransferLandTitleFlow.java
@@ -0,0 +1,98 @@
+package net.corda.samples.statereissuance.flows;
+
+import co.paralleluniverse.fibers.Suspendable;
+import net.corda.core.contracts.StateAndRef;
+import net.corda.core.contracts.UniqueIdentifier;
+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.samples.statereissuance.contracts.LandTitleContract;
+import net.corda.samples.statereissuance.states.LandTitleState;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class TransferLandTitleFlow {
+
+ @InitiatingFlow
+ @StartableByRPC
+ public static class Initiator extends FlowLogic {
+
+ private UniqueIdentifier plotIdentifier;
+ private Party owner;
+
+ public Initiator(UniqueIdentifier plotIdentifier, Party owner) {
+ this.plotIdentifier = plotIdentifier;
+ this.owner = owner;
+ }
+
+ @Override
+ @Suspendable
+ public SignedTransaction call() throws FlowException {
+
+ List> landTitleStateAndRefs = getServiceHub().getVaultService()
+ .queryBy(LandTitleState.class).getStates();
+
+ StateAndRef inputStateAndRef = landTitleStateAndRefs.stream().filter(landTitleStateStateAndRef -> {
+ LandTitleState loanBidState = landTitleStateStateAndRef.getState().getData();
+ return loanBidState.getLinearId().equals(plotIdentifier);
+ }).findAny().orElseThrow(() -> new IllegalArgumentException("Land Title Not Found"));
+
+ LandTitleState inputState = inputStateAndRef.getState().getData();
+ LandTitleState outputState = new LandTitleState(inputState.getLinearId(), inputState.getDimensions(),
+ inputState.getArea(), owner, inputState.getIssuer());
+
+ TransactionBuilder transactionBuilder = new TransactionBuilder(inputStateAndRef.getState().getNotary())
+ .addInputState(inputStateAndRef)
+ .addOutputState(outputState)
+ .addCommand(new LandTitleContract.Commands.Transfer(), Arrays.asList(
+ inputState.getIssuer().getOwningKey(),
+ inputState.getOwner().getOwningKey()
+ ));
+
+ transactionBuilder.verify(getServiceHub());
+ final SignedTransaction ptx = getServiceHub().signInitialTransaction(transactionBuilder);
+
+ FlowSession issuerSession = initiateFlow(inputState.getIssuer());
+ issuerSession.send(true);
+ FlowSession newOwnerSession = initiateFlow(owner);
+ newOwnerSession.send(false);
+
+ SignedTransaction stx = subFlow(new CollectSignaturesFlow(ptx, Arrays.asList(issuerSession)));
+ return subFlow(new FinalityFlow(stx, Arrays.asList(issuerSession, newOwnerSession)));
+ }
+ }
+
+
+ @InitiatedBy(Initiator.class)
+ public static class Responder extends FlowLogic{
+ //private variable
+ private FlowSession counterpartySession;
+
+ //Constructor
+ public Responder(FlowSession counterpartySession) {
+ this.counterpartySession = counterpartySession;
+ }
+
+ @Suspendable
+ @Override
+ public Void call() throws FlowException {
+
+ boolean signRequired = counterpartySession.receive(Boolean.class).unwrap(it -> it);
+ if(signRequired) {
+ subFlow(new SignTransactionFlow(counterpartySession) {
+ @Suspendable
+ @Override
+ protected void checkTransaction(SignedTransaction stx) throws FlowException {
+
+ }
+ });
+ }
+
+ //Stored the transaction into data base.
+ subFlow(new ReceiveFinalityFlow(counterpartySession));
+ return null;
+ }
+ }
+}
diff --git a/Features/state-reissuance/workflows/src/main/java/net/corda/samples/statereissuance/flows/reissuance/AcceptLandReissuanceFlow.java b/Features/state-reissuance/workflows/src/main/java/net/corda/samples/statereissuance/flows/reissuance/AcceptLandReissuanceFlow.java
new file mode 100644
index 00000000..a92df046
--- /dev/null
+++ b/Features/state-reissuance/workflows/src/main/java/net/corda/samples/statereissuance/flows/reissuance/AcceptLandReissuanceFlow.java
@@ -0,0 +1,47 @@
+package net.corda.samples.statereissuance.flows.reissuance;
+
+import co.paralleluniverse.fibers.Suspendable;
+import com.r3.corda.lib.reissuance.flows.ReissueStates;
+import com.r3.corda.lib.reissuance.states.ReissuanceRequest;
+import net.corda.core.contracts.StateAndRef;
+import net.corda.core.contracts.StateRef;
+import net.corda.core.crypto.SecureHash;
+import net.corda.core.flows.FlowException;
+import net.corda.core.flows.FlowLogic;
+import net.corda.core.flows.InitiatingFlow;
+import net.corda.core.flows.StartableByRPC;
+import net.corda.core.identity.Party;
+import net.corda.samples.statereissuance.flows.ExitLandTitleFlow;
+
+import java.util.Arrays;
+import java.util.List;
+
+@InitiatingFlow
+@StartableByRPC
+public class AcceptLandReissuanceFlow extends FlowLogic {
+
+ private StateRef stateRef;
+ private Party issuer;
+
+ public AcceptLandReissuanceFlow(StateRef stateRef, Party issuer) {
+ this.stateRef = stateRef;
+ this.issuer = issuer;
+ }
+
+ @Override
+ @Suspendable
+ public SecureHash call() throws FlowException {
+
+ List> reissueRequestStateAndRefs = getServiceHub().getVaultService()
+ .queryBy(ReissuanceRequest.class).getStates();
+
+ StateAndRef