CORDA-2485 - Add minimum platform version check before attempting a hash -> signature constraints auto migration. (#4623) (#4625)

This commit is contained in:
josecoll 2019-01-23 16:21:08 +00:00 committed by Katelyn Baker
parent 25ad122a50
commit 2bc1e73833

View File

@ -280,32 +280,34 @@ open class TransactionBuilder(
): Pair<Set<AttachmentId>, List<TransactionState<ContractState>>?> {
val inputsAndOutputs = (inputStates ?: emptyList()) + (outputStates ?: emptyList())
// Hash to Signature constraints migration switchover
// Hash to Signature constraints migration switchover (only applicable from version 4 onwards)
// identify if any input-output pairs are transitioning from hash to signature constraints:
// 1. output states contain implicitly selected hash constraint (pre-existing from set of unconsumed states in a nodes vault) or explicitly set SignatureConstraint
// 2. node has signed jar for associated contract class and version
val inputsHashConstraints = inputStates?.filter { it.constraint is HashAttachmentConstraint } ?: emptyList()
val outputHashConstraints = outputStates?.filter { it.constraint is HashAttachmentConstraint } ?: emptyList()
val outputSignatureConstraints = outputStates?.filter { it.constraint is SignatureAttachmentConstraint } ?: emptyList()
if (inputsHashConstraints.isNotEmpty() && (outputHashConstraints.isNotEmpty() || outputSignatureConstraints.isNotEmpty())) {
val attachmentIds = services.attachments.getLatestContractAttachments(contractClassName)
// only switchover if we have both signed and unsigned attachments for the given contract class name
if (attachmentIds.isNotEmpty() && attachmentIds.size == 2) {
val attachmentsToUse = attachmentIds.map {
services.attachments.openAttachment(it)?.let { it as ContractAttachment }
?: throw IllegalArgumentException("Contract attachment $it for $contractClassName is missing.")
if (services.networkParameters.minimumPlatformVersion >= 4) {
val inputsHashConstraints = inputStates?.filter { it.constraint is HashAttachmentConstraint } ?: emptyList()
val outputHashConstraints = outputStates?.filter { it.constraint is HashAttachmentConstraint } ?: emptyList()
val outputSignatureConstraints = outputStates?.filter { it.constraint is SignatureAttachmentConstraint } ?: emptyList()
if (inputsHashConstraints.isNotEmpty() && (outputHashConstraints.isNotEmpty() || outputSignatureConstraints.isNotEmpty())) {
val attachmentIds = services.attachments.getLatestContractAttachments(contractClassName)
// only switchover if we have both signed and unsigned attachments for the given contract class name
if (attachmentIds.isNotEmpty() && attachmentIds.size == 2) {
val attachmentsToUse = attachmentIds.map {
services.attachments.openAttachment(it)?.let { it as ContractAttachment }
?: throw IllegalArgumentException("Contract attachment $it for $contractClassName is missing.")
}
val signedAttachment = attachmentsToUse.filter { it.isSigned }.firstOrNull()
?: throw IllegalArgumentException("Signed contract attachment for $contractClassName is missing.")
val outputConstraints =
if (outputHashConstraints.isNotEmpty()) {
log.warn("Switching output states from hash to signed constraints using signers in signed contract attachment given by ${signedAttachment.id}")
val outputsSignatureConstraints = outputHashConstraints.map { it.copy(constraint = SignatureAttachmentConstraint(signedAttachment.signerKeys.first())) }
outputs.addAll(outputsSignatureConstraints)
outputs.removeAll(outputHashConstraints)
outputsSignatureConstraints
} else outputSignatureConstraints
return Pair(attachmentIds.toSet(), outputConstraints)
}
val signedAttachment = attachmentsToUse.filter { it.isSigned }.firstOrNull()
?: throw IllegalArgumentException("Signed contract attachment for $contractClassName is missing.")
val outputConstraints =
if (outputHashConstraints.isNotEmpty()) {
log.warn("Switching output states from hash to signed constraints using signers in signed contract attachment given by ${signedAttachment.id}")
val outputsSignatureConstraints = outputHashConstraints.map { it.copy(constraint = SignatureAttachmentConstraint(signedAttachment.signerKeys.first())) }
outputs.addAll(outputsSignatureConstraints)
outputs.removeAll(outputHashConstraints)
outputsSignatureConstraints
} else outputSignatureConstraints
return Pair(attachmentIds.toSet(), outputConstraints)
}
}