@@ -34,33 +34,61 @@ import java.util.*
34
34
* Represents the base class for attestation pointer implementations.
35
35
*
36
36
* @param T The underlying [ContractState] type.
37
- * @property stateRef The [StateRef] of the witnessed state being attested.
38
37
* @property stateType The [Class] of the witnessed state being attested.
39
- * @property hash The unique hash of the attestation pointer.
38
+ * @property statePointer The pointer to the witnessed state being attested.
39
+ * @property hash The hash of the attestation pointer.
40
+ *
41
+ * Note that attestation pointer hashes should be unique for static attestation pointers since they point to the
42
+ * attested state's [StateRef], however attestation pointer hashes for linear attestation pointers will not be unique
43
+ * since they point to the attested state's [UniqueIdentifier].
40
44
*/
41
45
@CordaSerializable
42
46
sealed class AttestationPointer <T : ContractState > : SingularResolvable <T >, Hashable {
43
47
abstract val stateType: Class <T >
44
- abstract val stateRef: StateRef
48
+ abstract val statePointer: Any
49
+
50
+ final override val hash: SecureHash
51
+ get() = SecureHash .sha256(" $stateType$statePointer " )
45
52
46
53
/* *
47
- * Determines whether any immutable properties of this object have changed .
54
+ * Determines whether the specified object is equal to the current object .
48
55
*
49
- * @param other The pointer to compare to this one .
50
- * @return Returns true if the immutable properties remain unchanged ; otherwise, false.
56
+ * @param other The object to compare with the current object .
57
+ * @return Returns true if the specified object is equal to the current object ; otherwise, false.
51
58
*/
52
- internal abstract fun immutableEquals (other : AttestationPointer <T >): Boolean
59
+ final override fun equals (other : Any? ): Boolean {
60
+ return this == = other || (other is AttestationPointer <* >
61
+ && other.javaClass == javaClass
62
+ && other.stateType == stateType
63
+ && other.statePointer == statePointer)
64
+ }
53
65
54
66
/* *
55
- * Determines whether this [SingularResolvable] is pointing to the specified [StateAndRef] instance .
67
+ * Serves as the default hash function .
56
68
*
57
- * @param stateAndRef The [StateAndRef] to determine being pointed to.
58
- * @return Returns true if this [SingularResolvable] is pointing to the specified [StateAndRef]; otherwise, false.
69
+ * @return Returns a hash code for the current object.
59
70
*/
60
- override fun isPointingTo (stateAndRef : StateAndRef <T >): Boolean {
61
- return stateAndRef.ref == stateRef
71
+ final override fun hashCode (): Int {
72
+ return Objects .hash(stateType, statePointer)
73
+ }
74
+
75
+ /* *
76
+ * Serves as the default hash function.
77
+ *
78
+ * @return Returns a hash code for the current object.
79
+ */
80
+ final override fun toString (): String {
81
+ return toDataClassString()
62
82
}
63
83
84
+ /* *
85
+ * Determines whether any immutable properties of this object have changed.
86
+ *
87
+ * @param other The pointer to compare to this one.
88
+ * @return Returns true if the immutable properties remain unchanged; otherwise, false.
89
+ */
90
+ internal abstract fun immutableEquals (other : AttestationPointer <T >): Boolean
91
+
64
92
/* *
65
93
* Checks the claim and value class types of the specified state to ensure they match the expected types.
66
94
*
@@ -75,77 +103,46 @@ sealed class AttestationPointer<T : ContractState> : SingularResolvable<T>, Hash
75
103
}
76
104
}
77
105
}
78
-
79
- /* *
80
- * Gets the state linearId if this [AttestationPointer] is a [LinearAttestationPointer]; otherwise, null.
81
- * @return Returns the state linearId if this [AttestationPointer] is a [LinearAttestationPointer]; otherwise, null.
82
- */
83
- internal fun getLinearId (): UniqueIdentifier ? {
84
- return if (this is LinearAttestationPointer <* >) stateLinearId else null
85
- }
86
106
}
87
107
88
108
/* *
89
109
* Represents a linear attestation pointer to a [LinearState].
90
110
*
91
- * @param T The underlying [LinearState] type.
111
+ * The intention of a linear attestation pointer is to evolve with the linear state that they point to. In this case
112
+ * the linear state being witnessed and attested is free to evolve without losing attestation, since the attestation
113
+ * points to the state by it's linear ID. Whilst this behavior is deliberate, it might incur some security concerns;
114
+ * for example, the state being witnessed and attested may evolve to contain erroneous data, however its attestation
115
+ * will remain unchanged until the attestor amends it.
92
116
*
117
+ * To mitigate these security concerns, the intention is that developers will derive a custom attestation and decide
118
+ * on the attestation's validity based on some other factor about the underlying state.
119
+ *
120
+ * @param T The underlying [LinearState] type.
93
121
* @property stateType The [Class] of the witnessed state being attested.
94
- * @property stateRef The [StateRef] of the witnessed state being attested.
95
- * @property stateLinearId The [UniqueIdentifier] of the witnessed state being attested.
96
- * @property hash The unique hash of the attestation pointer.
122
+ * @property statePointer The pointer to the witnessed state being attested.
123
+ * @property hash The hash of the attestation pointer.
97
124
*/
98
125
class LinearAttestationPointer <T : LinearState > internal constructor(
99
126
override val stateType : Class <T >,
100
- override val stateRef : StateRef ,
101
- val stateLinearId : UniqueIdentifier
127
+ override val statePointer : UniqueIdentifier
102
128
) : AttestationPointer<T>() {
103
129
104
- constructor (stateAndRef: StateAndRef <T >) : this (
105
- stateType = stateAndRef.state.data.javaClass,
106
- stateRef = stateAndRef.ref,
107
- stateLinearId = stateAndRef.state.data.linearId
108
- )
130
+ constructor (stateAndRef: StateAndRef <T >) : this (stateAndRef.state.data.javaClass, stateAndRef.state.data.linearId)
109
131
110
132
private val criteria: QueryCriteria = vaultQuery(stateType) {
111
- stateStatus(Vault .StateStatus .ALL )
133
+ stateStatus(Vault .StateStatus .UNCONSUMED )
112
134
relevancyStatus(Vault .RelevancyStatus .ALL )
113
- stateRefs(stateRef)
114
- linearIds(stateLinearId)
115
- }
116
-
117
- override val hash: SecureHash
118
- get() = SecureHash .sha256(" $stateType$stateRef$stateLinearId " )
119
-
120
- /* *
121
- * Determines whether the specified object is equal to the current object.
122
- *
123
- * @param other The object to compare with the current object.
124
- * @return Returns true if the specified object is equal to the current object; otherwise, false.
125
- */
126
- override fun equals (other : Any? ): Boolean {
127
- return this == = other || (other is LinearAttestationPointer <* >
128
- && other.stateType == stateType
129
- && other.stateRef == stateRef
130
- && other.stateLinearId == stateLinearId)
131
- }
132
-
133
- /* *
134
- * Serves as the default hash function.
135
- *
136
- * @return Returns a hash code for the current object.
137
- */
138
- override fun hashCode (): Int {
139
- return Objects .hash(stateType, stateRef, stateLinearId)
135
+ linearIds(statePointer)
140
136
}
141
137
142
138
/* *
143
- * Serves as the default hash function .
139
+ * Determines whether this [SingularResolvable] is pointing to the specified [StateAndRef] instance .
144
140
*
145
- * @return Returns a hash code for the current object.
141
+ * @param stateAndRef The [StateAndRef] to determine being pointed to.
142
+ * @return Returns true if this [SingularResolvable] is pointing to the specified [StateAndRef]; otherwise, false.
146
143
*/
147
- override fun toString ( ): String {
148
- return toDataClassString()
144
+ override fun isPointingTo ( stateAndRef : StateAndRef < T > ): Boolean {
145
+ return statePointer == stateAndRef.state.data.linearId
149
146
}
150
147
151
148
/* *
@@ -194,66 +191,46 @@ class LinearAttestationPointer<T : LinearState> internal constructor(
194
191
override fun immutableEquals (other : AttestationPointer <T >): Boolean {
195
192
return other is LinearAttestationPointer <* >
196
193
&& other.stateType == stateType
197
- && other.stateLinearId == stateLinearId
194
+ && other.statePointer == statePointer
198
195
}
199
196
}
200
197
201
198
/* *
202
199
* Represents a static attestation pointer to a [ContractState].
203
200
*
204
- * @param T The underlying [LinearState] type.
201
+ * The intention of a static attestation pointer is to point specifically to a version of a state by its [StateRef].
202
+ * Any evolution of the state being witnessed and attested therefore renders existing attestations useless since
203
+ * they no longer point to a relevant state on the ledger, and must be amended to point to the latest state version.
204
+ *
205
+ * In most cases, static attestation pointers may be considered safer than linear attestation pointers, since they
206
+ * do not permit state evolution.
205
207
*
208
+ * @param T The underlying [LinearState] type.
206
209
* @property stateType The [Class] of the witnessed state being attested.
207
- * @property stateRef The [StateRef] of the witnessed state being attested.
208
- * @property hash The unique hash of the attestation pointer.
210
+ * @property statePointer The pointer to the witnessed state being attested.
211
+ * @property hash The hash of the attestation pointer.
209
212
*/
210
213
class StaticAttestationPointer <T : ContractState > internal constructor(
211
214
override val stateType : Class <T >,
212
- override val stateRef : StateRef
215
+ override val statePointer : StateRef
213
216
) : AttestationPointer<T>() {
214
217
215
- constructor (stateAndRef: StateAndRef <T >) : this (
216
- stateType = stateAndRef.state.data.javaClass,
217
- stateRef = stateAndRef.ref
218
- )
218
+ constructor (stateAndRef: StateAndRef <T >) : this (stateAndRef.state.data.javaClass, stateAndRef.ref)
219
219
220
220
private val criteria: QueryCriteria = vaultQuery(stateType) {
221
221
stateStatus(Vault .StateStatus .ALL )
222
222
relevancyStatus(Vault .RelevancyStatus .ALL )
223
- stateRefs(stateRef)
224
- }
225
-
226
- override val hash: SecureHash
227
- get() = SecureHash .sha256(" $stateType$stateRef " )
228
-
229
- /* *
230
- * Determines whether the specified object is equal to the current object.
231
- *
232
- * @param other The object to compare with the current object.
233
- * @return Returns true if the specified object is equal to the current object; otherwise, false.
234
- */
235
- override fun equals (other : Any? ): Boolean {
236
- return this == = other || (other is StaticAttestationPointer <* >
237
- && other.stateType == stateType
238
- && other.stateRef == stateRef)
223
+ stateRefs(statePointer)
239
224
}
240
225
241
226
/* *
242
- * Serves as the default hash function.
243
- *
244
- * @return Returns a hash code for the current object.
245
- */
246
- override fun hashCode (): Int {
247
- return Objects .hash(stateType, stateRef)
248
- }
249
-
250
- /* *
251
- * Serves as the default hash function.
227
+ * Determines whether this [SingularResolvable] is pointing to the specified [StateAndRef] instance.
252
228
*
253
- * @return Returns a hash code for the current object.
229
+ * @param stateAndRef The [StateAndRef] to determine being pointed to.
230
+ * @return Returns true if this [SingularResolvable] is pointing to the specified [StateAndRef]; otherwise, false.
254
231
*/
255
- override fun toString ( ): String {
256
- return toDataClassString()
232
+ override fun isPointingTo ( stateAndRef : StateAndRef < T > ): Boolean {
233
+ return statePointer == stateAndRef.ref
257
234
}
258
235
259
236
/* *
0 commit comments