Skip to content

Commit 2d61cf3

Browse files
Preparation for major version 4.0.0 release.
1 parent 76885d7 commit 2d61cf3

File tree

16 files changed

+262
-58
lines changed

16 files changed

+262
-58
lines changed

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=onixlabs-corda-identity-framework
22
group=io.onixlabs
3-
version=4.0.0-rc4
3+
version=4.0.0-rc5
44
onixlabs.development.jarsign.keystore=../lib/onixlabs.development.pkcs12
55
onixlabs.development.jarsign.password=5891f47942424d2acbe108691fdb5ba258712fca7e4762be4327241ebf3dbfa3

onixlabs-corda-identity-framework-contract/src/main/kotlin/io/onixlabs/corda/identityframework/contract/Extensions.Attestation.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ inline fun <reified T : ContractState, reified U : Attestation<T>> StateAndRef<U
5353
status: AttestationStatus,
5454
stateAndRef: StateAndRef<T>,
5555
metadata: Map<String, String> = emptyMap()
56-
): U = amendAttestation(status, stateAndRef.toStaticAttestationPointer(), metadata)
56+
): U = amendAttestation(status, stateAndRef.toStaticAttestationPointer(state.data.pointer.identifier), metadata)
5757

5858
/**
5959
* Amends an attestation of a [LinearState].
@@ -69,7 +69,7 @@ inline fun <reified T : LinearState, reified U : Attestation<T>> StateAndRef<U>.
6969
status: AttestationStatus,
7070
stateAndRef: StateAndRef<T>,
7171
metadata: Map<String, String> = emptyMap()
72-
): U = amendAttestation(status, stateAndRef.toLinearAttestationPointer(), metadata)
72+
): U = amendAttestation(status, stateAndRef.toLinearAttestationPointer(state.data.pointer.identifier), metadata)
7373

7474
/**
7575
* Accepts an attestation.
@@ -97,7 +97,7 @@ inline fun <T : ContractState, reified U : Attestation<T>> StateAndRef<U>.accept
9797
inline fun <T : ContractState, reified U : Attestation<T>> StateAndRef<U>.acceptStaticAttestation(
9898
stateAndRef: StateAndRef<T>,
9999
metadata: Map<String, String> = emptyMap()
100-
): U = amendAttestation(AttestationStatus.ACCEPTED, stateAndRef.toStaticAttestationPointer(), metadata)
100+
): U = amendAttestation(AttestationStatus.ACCEPTED, stateAndRef.toStaticAttestationPointer(state.data.pointer.identifier), metadata)
101101

102102
/**
103103
* Accepts an attestation of a [LinearState].
@@ -111,7 +111,7 @@ inline fun <T : ContractState, reified U : Attestation<T>> StateAndRef<U>.accept
111111
inline fun <T : LinearState, reified U : Attestation<T>> StateAndRef<U>.acceptLinearAttestation(
112112
stateAndRef: StateAndRef<T>,
113113
metadata: Map<String, String> = emptyMap()
114-
): U = amendAttestation(AttestationStatus.ACCEPTED, stateAndRef.toLinearAttestationPointer(), metadata)
114+
): U = amendAttestation(AttestationStatus.ACCEPTED, stateAndRef.toLinearAttestationPointer(state.data.pointer.identifier), metadata)
115115

116116
/**
117117
* Rejects an attestation.
@@ -139,7 +139,7 @@ inline fun <T : ContractState, reified U : Attestation<T>> StateAndRef<U>.reject
139139
inline fun <T : ContractState, reified U : Attestation<T>> StateAndRef<U>.rejectStaticAttestation(
140140
stateAndRef: StateAndRef<T>,
141141
metadata: Map<String, String> = emptyMap()
142-
): U = amendAttestation(AttestationStatus.REJECTED, stateAndRef.toStaticAttestationPointer(), metadata)
142+
): U = amendAttestation(AttestationStatus.REJECTED, stateAndRef.toStaticAttestationPointer(state.data.pointer.identifier), metadata)
143143

144144
/**
145145
* Rejects an attestation of a [LinearState].
@@ -153,4 +153,4 @@ inline fun <T : ContractState, reified U : Attestation<T>> StateAndRef<U>.reject
153153
inline fun <T : LinearState, reified U : Attestation<T>> StateAndRef<U>.rejectLinearAttestation(
154154
stateAndRef: StateAndRef<T>,
155155
metadata: Map<String, String> = emptyMap()
156-
): U = amendAttestation(AttestationStatus.REJECTED, stateAndRef.toLinearAttestationPointer(), metadata)
156+
): U = amendAttestation(AttestationStatus.REJECTED, stateAndRef.toLinearAttestationPointer(state.data.pointer.identifier), metadata)

onixlabs-corda-identity-framework-contract/src/main/kotlin/io/onixlabs/corda/identityframework/contract/Extensions.StateAndRef.kt

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,22 @@ import net.corda.core.identity.AbstractParty
3030
* Creates a static attestation pointer from a [StateAndRef].
3131
*
3232
* @param T The underlying [ContractState] type.
33+
* @param identifier Provides an additional, external identifier which can be used to track states across state transitions.
3334
* @return Returns a static attestation pointer for the specified [StateAndRef].
3435
*/
35-
fun <T : ContractState> StateAndRef<T>.toStaticAttestationPointer(): StaticAttestationPointer<T> {
36-
return StaticAttestationPointer(this)
36+
fun <T : ContractState> StateAndRef<T>.toStaticAttestationPointer(identifier: String? = null): StaticAttestationPointer<T> {
37+
return StaticAttestationPointer(this, identifier)
3738
}
3839

3940
/**
4041
* Creates a linear attestation pointer from a [StateAndRef].
4142
*
4243
* @param T The underlying [LinearState] type.
44+
* @param identifier Provides an additional, external identifier which can be used to track states across state transitions.
4345
* @return Returns a linear attestation pointer for the specified [StateAndRef].
4446
*/
45-
fun <T : LinearState> StateAndRef<T>.toLinearAttestationPointer(): LinearAttestationPointer<T> {
46-
return LinearAttestationPointer(this)
47+
fun <T : LinearState> StateAndRef<T>.toLinearAttestationPointer(identifier: String? = state.data.linearId.toString()): LinearAttestationPointer<T> {
48+
return LinearAttestationPointer(this, identifier)
4749
}
4850

4951
/**
@@ -54,17 +56,19 @@ fun <T : LinearState> StateAndRef<T>.toLinearAttestationPointer(): LinearAttesta
5456
* @param status The status of the attestation.
5557
* @param metadata Additional information about the attestation.
5658
* @param linearId The unique identifier of the attestation.
59+
* @param identifier Provides an additional, external identifier which can be used to track states across state transitions.
5760
* @return Returns an attestation for the specified [StateAndRef].
5861
*/
5962
fun <T : ContractState> StateAndRef<T>.createStaticAttestation(
6063
attestor: AbstractParty,
6164
status: AttestationStatus,
6265
metadata: Map<String, String> = emptyMap(),
63-
linearId: UniqueIdentifier = UniqueIdentifier()
66+
linearId: UniqueIdentifier = UniqueIdentifier(),
67+
identifier: String? = null
6468
): Attestation<T> = Attestation(
6569
attestor,
6670
state.data.participants.toSet(),
67-
toStaticAttestationPointer(),
71+
toStaticAttestationPointer(identifier),
6872
status,
6973
metadata,
7074
linearId,
@@ -78,13 +82,15 @@ fun <T : ContractState> StateAndRef<T>.createStaticAttestation(
7882
* @param attestor The attestor of the witnessed state.
7983
* @param metadata Additional information about the attestation.
8084
* @param linearId The unique identifier of the attestation.
85+
* @param identifier Provides an additional, external identifier which can be used to track states across state transitions.
8186
* @return Returns an accepted attestation for the specified [StateAndRef].
8287
*/
8388
fun <T : ContractState> StateAndRef<T>.createAcceptedStaticAttestation(
8489
attestor: AbstractParty,
8590
metadata: Map<String, String> = emptyMap(),
86-
linearId: UniqueIdentifier = UniqueIdentifier()
87-
): Attestation<T> = createStaticAttestation(attestor, AttestationStatus.ACCEPTED, metadata, linearId)
91+
linearId: UniqueIdentifier = UniqueIdentifier(),
92+
identifier: String? = null
93+
): Attestation<T> = createStaticAttestation(attestor, AttestationStatus.ACCEPTED, metadata, linearId, identifier)
8894

8995
/**
9096
* Creates a rejected attestation from the specified [StateAndRef].
@@ -93,13 +99,15 @@ fun <T : ContractState> StateAndRef<T>.createAcceptedStaticAttestation(
9399
* @param attestor The attestor of the witnessed state.
94100
* @param metadata Additional information about the attestation.
95101
* @param linearId The unique identifier of the attestation.
102+
* @param identifier Provides an additional, external identifier which can be used to track states across state transitions.
96103
* @return Returns an rejected attestation for the specified [StateAndRef].
97104
*/
98105
fun <T : ContractState> StateAndRef<T>.createRejectedStaticAttestation(
99106
attestor: AbstractParty,
100107
metadata: Map<String, String> = emptyMap(),
101-
linearId: UniqueIdentifier = UniqueIdentifier()
102-
): Attestation<T> = createStaticAttestation(attestor, AttestationStatus.REJECTED, metadata, linearId)
108+
linearId: UniqueIdentifier = UniqueIdentifier(),
109+
identifier: String? = null
110+
): Attestation<T> = createStaticAttestation(attestor, AttestationStatus.REJECTED, metadata, linearId, identifier)
103111

104112
/**
105113
* Creates an attestation from the specified [StateAndRef].
@@ -109,17 +117,19 @@ fun <T : ContractState> StateAndRef<T>.createRejectedStaticAttestation(
109117
* @param status The status of the attestation.
110118
* @param metadata Additional information about the attestation.
111119
* @param linearId The unique identifier of the attestation.
120+
* @param identifier Provides an additional, external identifier which can be used to track states across state transitions.
112121
* @return Returns an attestation for the specified [StateAndRef].
113122
*/
114123
fun <T : LinearState> StateAndRef<T>.createLinearAttestation(
115124
attestor: AbstractParty,
116125
status: AttestationStatus,
117126
metadata: Map<String, String> = emptyMap(),
118-
linearId: UniqueIdentifier = UniqueIdentifier()
127+
linearId: UniqueIdentifier = UniqueIdentifier(),
128+
identifier: String? = state.data.linearId.toString()
119129
): Attestation<T> = Attestation(
120130
attestor,
121131
state.data.participants.toSet(),
122-
toLinearAttestationPointer(),
132+
toLinearAttestationPointer(identifier),
123133
status,
124134
metadata,
125135
linearId,
@@ -133,13 +143,15 @@ fun <T : LinearState> StateAndRef<T>.createLinearAttestation(
133143
* @param attestor The attestor of the witnessed state.
134144
* @param metadata Additional information about the attestation.
135145
* @param linearId The unique identifier of the attestation.
146+
* @param identifier Provides an additional, external identifier which can be used to track states across state transitions.
136147
* @return Returns an accepted attestation for the specified [StateAndRef].
137148
*/
138149
fun <T : LinearState> StateAndRef<T>.createAcceptedLinearAttestation(
139150
attestor: AbstractParty,
140151
metadata: Map<String, String> = emptyMap(),
141-
linearId: UniqueIdentifier = UniqueIdentifier()
142-
): Attestation<T> = createLinearAttestation(attestor, AttestationStatus.ACCEPTED, metadata, linearId)
152+
linearId: UniqueIdentifier = UniqueIdentifier(),
153+
identifier: String? = state.data.linearId.toString()
154+
): Attestation<T> = createLinearAttestation(attestor, AttestationStatus.ACCEPTED, metadata, linearId, identifier)
143155

144156
/**
145157
* Creates a rejected attestation from the specified [StateAndRef].
@@ -148,10 +160,12 @@ fun <T : LinearState> StateAndRef<T>.createAcceptedLinearAttestation(
148160
* @param attestor The attestor of the witnessed state.
149161
* @param metadata Additional information about the attestation.
150162
* @param linearId The unique identifier of the attestation.
163+
* @param identifier Provides an additional, external identifier which can be used to track states across state transitions.
151164
* @return Returns an rejected attestation for the specified [StateAndRef].
152165
*/
153166
fun <T : LinearState> StateAndRef<T>.createRejectedLinearAttestation(
154167
attestor: AbstractParty,
155168
metadata: Map<String, String> = emptyMap(),
156-
linearId: UniqueIdentifier = UniqueIdentifier()
157-
): Attestation<T> = createLinearAttestation(attestor, AttestationStatus.REJECTED, metadata, linearId)
169+
linearId: UniqueIdentifier = UniqueIdentifier(),
170+
identifier: String? = state.data.linearId.toString()
171+
): Attestation<T> = createLinearAttestation(attestor, AttestationStatus.REJECTED, metadata, linearId, identifier)

onixlabs-corda-identity-framework-contract/src/main/kotlin/io/onixlabs/corda/identityframework/contract/attestations/AttestationContract.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ package io.onixlabs.corda.identityframework.contract.attestations
1818

1919
import io.onixlabs.corda.core.contract.ContractID
2020
import io.onixlabs.corda.core.contract.isPointingTo
21-
import net.corda.core.contracts.*
21+
import net.corda.core.contracts.CommandData
22+
import net.corda.core.contracts.Contract
23+
import net.corda.core.contracts.requireSingleCommand
24+
import net.corda.core.contracts.requireThat
2225
import net.corda.core.transactions.LedgerTransaction
2326
import java.security.PublicKey
2427

@@ -75,7 +78,7 @@ open class AttestationContract : Contract {
7578
"On attestation amending, only one attestation state must be created."
7679

7780
internal const val CONTRACT_RULE_CHANGES =
78-
"On attestation amending, the attestor, linear ID, pointer class and pointer linear ID must not change."
81+
"On attestation amending, the attestor, linear ID, pointer class and pointer identifier must not change."
7982

8083
internal const val CONTRACT_RULE_STATE_REF =
8184
"On attestation amending, the created attestation state must point to the consumed attestation state."

onixlabs-corda-identity-framework-contract/src/main/kotlin/io/onixlabs/corda/identityframework/contract/attestations/AttestationPointer.kt

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import java.util.*
3737
* @param T The underlying [ContractState] type.
3838
* @property stateType The [Class] of the witnessed state being attested.
3939
* @property statePointer The pointer to the witnessed state being attested.
40+
* @property identifier Provides an additional, external identifier which can be used to track states across state transitions.
4041
* @property hash The hash of the attestation pointer.
4142
*
4243
* Note that attestation pointer hashes should be unique for static attestation pointers since they point to the
@@ -47,9 +48,10 @@ import java.util.*
4748
sealed class AttestationPointer<T : ContractState> : SingularResolvable<T>, Hashable {
4849
abstract val stateType: Class<T>
4950
abstract val statePointer: Any
51+
abstract val identifier: String?
5052

5153
final override val hash: SecureHash
52-
get() = SecureHash.sha256("$stateType$statePointer")
54+
get() = SecureHash.sha256("$stateType$statePointer$identifier")
5355

5456
/**
5557
* Determines whether the specified object is equal to the current object.
@@ -121,14 +123,20 @@ sealed class AttestationPointer<T : ContractState> : SingularResolvable<T>, Hash
121123
* @param T The underlying [LinearState] type.
122124
* @property stateType The [Class] of the witnessed state being attested.
123125
* @property statePointer The pointer to the witnessed state being attested.
126+
* @property identifier Provides an additional, external identifier which can be used to track states across state transitions.
124127
* @property hash The hash of the attestation pointer.
125128
*/
126129
class LinearAttestationPointer<T : LinearState> internal constructor(
127130
override val stateType: Class<T>,
128-
override val statePointer: UniqueIdentifier
131+
override val statePointer: UniqueIdentifier,
132+
override val identifier: String?
129133
) : AttestationPointer<T>() {
130134

131-
constructor(stateAndRef: StateAndRef<T>) : this(stateAndRef.state.data.javaClass, stateAndRef.state.data.linearId)
135+
constructor(stateAndRef: StateAndRef<T>, identifier: String?) : this(
136+
stateType = stateAndRef.state.data.javaClass,
137+
statePointer = stateAndRef.state.data.linearId,
138+
identifier = identifier
139+
)
132140

133141
private val criteria: QueryCriteria = vaultQuery(stateType) {
134142
stateStatus(Vault.StateStatus.UNCONSUMED)
@@ -193,6 +201,7 @@ class LinearAttestationPointer<T : LinearState> internal constructor(
193201
return other is LinearAttestationPointer<*>
194202
&& other.stateType == stateType
195203
&& other.statePointer == statePointer
204+
&& other.identifier == identifier
196205
}
197206
}
198207

@@ -209,14 +218,20 @@ class LinearAttestationPointer<T : LinearState> internal constructor(
209218
* @param T The underlying [LinearState] type.
210219
* @property stateType The [Class] of the witnessed state being attested.
211220
* @property statePointer The pointer to the witnessed state being attested.
221+
* @property identifier Provides an additional, external identifier which can be used to track states across state transitions.
212222
* @property hash The hash of the attestation pointer.
213223
*/
214224
class StaticAttestationPointer<T : ContractState> internal constructor(
215225
override val stateType: Class<T>,
216-
override val statePointer: StateRef
226+
override val statePointer: StateRef,
227+
override val identifier: String?
217228
) : AttestationPointer<T>() {
218229

219-
constructor(stateAndRef: StateAndRef<T>) : this(stateAndRef.state.data.javaClass, stateAndRef.ref)
230+
constructor(stateAndRef: StateAndRef<T>, identifier: String?) : this(
231+
stateType = stateAndRef.state.data.javaClass,
232+
statePointer = stateAndRef.ref,
233+
identifier = identifier
234+
)
220235

221236
private val criteria: QueryCriteria = vaultQuery(stateType) {
222237
stateStatus(Vault.StateStatus.ALL)
@@ -280,5 +295,6 @@ class StaticAttestationPointer<T : ContractState> internal constructor(
280295
override fun immutableEquals(other: AttestationPointer<T>): Boolean {
281296
return other is StaticAttestationPointer<*>
282297
&& other.stateType == stateType
298+
&& other.identifier == identifier
283299
}
284300
}

onixlabs-corda-identity-framework-contract/src/main/kotlin/io/onixlabs/corda/identityframework/contract/attestations/AttestationSchema.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ object AttestationSchema {
5454
@Column(name = "pointer_state_type", nullable = false)
5555
val pointerStateType: String = "",
5656

57+
@Column(name = "pointer_identifier", nullable = true)
58+
val pointerIdentifier: String? = null,
59+
5760
@Column(name = "pointer_hash", nullable = false)
5861
val pointerHash: String = "",
5962

@@ -78,6 +81,7 @@ object AttestationSchema {
7881
attestorAccountExternalId = attestation.attestor.accountLinearId?.externalId,
7982
pointer = attestation.pointer.statePointer.toString(),
8083
pointerStateType = attestation.pointer.stateType.canonicalName,
84+
pointerIdentifier = attestation.pointer.identifier,
8185
pointerHash = attestation.pointer.hash.toString(),
8286
status = attestation.status,
8387
previousStateRef = attestation.previousStateRef?.toString(),

onixlabs-corda-identity-framework-contract/src/main/resources/migration/attestation-schema.changelog-master.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
55
<include file="migration/attestation-schema.changelog-v1.xml"/>
66
<include file="migration/attestation-schema.changelog-v2.xml"/>
7+
<include file="migration/attestation-schema.changelog-v3.xml"/>
78
</databaseChangeLog>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
2+
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
5+
<changeSet author="ONIXLabs" id="update-v3-onixlabs_attestation_states">
6+
<addColumn tableName="onixlabs_attestation_states">
7+
<column name="pointer_identifier" type="nvarchar(1024)"/>
8+
</addColumn>
9+
</changeSet>
10+
</databaseChangeLog>

onixlabs-corda-identity-framework-contract/src/test/kotlin/io/onixlabs/corda/identityframework/contract/ContractTest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ abstract class ContractTest {
7272

7373
fun <T : LinearState> StateAndRef<Attestation<T>>.withInvalidPointer(): Attestation<T> {
7474
return with(state.data) {
75-
val invalidPointer = LinearAttestationPointer(pointer.stateType, UniqueIdentifier())
75+
val invalidLinearId = UniqueIdentifier()
76+
val invalidPointer = LinearAttestationPointer(pointer.stateType, invalidLinearId, invalidLinearId.toString())
7677
Attestation(attestor, attestees, invalidPointer, status, metadata, linearId, null)
7778
}
7879
}

onixlabs-corda-identity-framework-contract/src/test/kotlin/io/onixlabs/corda/identityframework/contract/attestations/AttestationContractAmendCommandTests.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class AttestationContractAmendCommandTests : ContractTest() {
7272
}
7373

7474
@Test
75-
fun `On attestation amending, the attestor, linear ID, pointer class and pointer linear ID must not change (wrong attestor)`() {
75+
fun `On attestation amending, the attestor, linear ID, pointer class and pointer identifier must not change (wrong attestor)`() {
7676
services.ledger {
7777
transaction {
7878
val issuedClaim1 = issue(CLAIM_1)
@@ -87,7 +87,7 @@ class AttestationContractAmendCommandTests : ContractTest() {
8787
}
8888

8989
@Test
90-
fun `On attestation amending, the attestor, linear ID, pointer class and pointer linear ID must not change (wrong pointer)`() {
90+
fun `On attestation amending, the attestor, linear ID, pointer class and pointer identifier must not change (wrong pointer)`() {
9191
services.ledger {
9292
transaction {
9393
val issuedClaim1 = issue(CLAIM_1)

0 commit comments

Comments
 (0)