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

This commit is contained in:
josecoll 2019-01-23 13:10:41 +00:00 committed by GitHub
parent 100a6fcb56
commit 82f5a756fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

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)
}
}