ENT-5275: Replace hardcoded platform versions with descriptive values (#6236)

* ENT-5275: Replace hardcoded platform versions with descriptive values

* PR updates

* missed versions

* missed versions

* fix

* add FIRST_VERSION
This commit is contained in:
Ryan Fowler 2020-05-14 14:43:52 +01:00 committed by GitHub
parent fd272125cf
commit 6dd72ac079
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 43 additions and 22 deletions

View File

@ -7,8 +7,6 @@ import net.corda.core.flows.FlowSession
import net.corda.core.flows.WaitTimeUpdate
import net.corda.core.utilities.UntrustworthyData
const val MIN_PLATFORM_VERSION_FOR_BACKPRESSURE_MESSAGE = 4
/**
* Implementation of TimedFlow that can handle WaitTimeUpdate messages. Any flow talking to the notary should implement this and use
* explicit send and this class's receiveResultOrTiming to receive the response to handle cases where the notary sends a timeout update.

View File

@ -288,7 +288,8 @@ class FetchBatchTransactionsFlow(requests: Set<SecureHash>, otherSide: FlowSessi
/**
* Given a set of hashes either loads from local network parameters storage or requests them from the other peer. Downloaded
* network parameters are saved to local parameters storage automatically. This flow can be used only if the minimumPlatformVersion is >= 4.
* network parameters are saved to local parameters storage automatically. This flow can be used only if the minimumPlatformVersion
* is >= [PlatformVersionSwitches.FETCH_MISSING_NETWORK_PARAMETERS].
* Nodes on lower versions won't respond to this flow.
*/
class FetchNetworkParametersFlow(requests: Set<SecureHash>,

View File

@ -5,5 +5,15 @@ Constants for new features that can only be switched on at specific platform ver
The text constant describes the feature and the numeric specifies the platform version the feature is enabled at.
*/
object PlatformVersionSwitches {
const val FIRST_VERSION = 1
const val BELONGS_TO_CONTRACT_ENFORCEMENT = 4
const val FETCH_MISSING_NETWORK_PARAMETERS = 4
const val MIGRATE_HASH_TO_SIGNATURE_CONSTRAINTS = 4
const val MIGRATE_ATTACHMENT_TO_SIGNATURE_CONSTRAINTS = 4
const val NETWORK_PARAMETERS_COMPONENT_GROUP = 4
const val IGNORE_JOLOKIA_JSON_SIMPLE_IN_CORDAPPS = 4
const val MIN_PLATFORM_VERSION_FOR_BACKPRESSURE_MESSAGE = 4
const val LIMIT_KEYS_IN_SIGNATURE_CONSTRAINTS = 5
const val BATCH_DOWNLOAD_COUNTERPARTY_BACKCHAIN = 6
const val ENABLE_P2P_COMPRESSION = 7
}

View File

@ -48,8 +48,8 @@ class ResolveTransactionsFlow private constructor(
// Fetch missing parameters flow was added in version 4. This check is needed so we don't end up with node V4 sending parameters
// request to node V3 that doesn't know about this protocol.
fetchNetParamsFromCounterpart = counterpartyPlatformVersion >= 4
val batchMode = counterpartyPlatformVersion >= 6
fetchNetParamsFromCounterpart = counterpartyPlatformVersion >= PlatformVersionSwitches.FETCH_MISSING_NETWORK_PARAMETERS
val batchMode = counterpartyPlatformVersion >= PlatformVersionSwitches.BATCH_DOWNLOAD_COUNTERPARTY_BACKCHAIN
logger.debug { "ResolveTransactionsFlow.call(): Otherside Platform Version = '$counterpartyPlatformVersion': Batch mode = $batchMode" }
if (initialTx != null) {

View File

@ -176,7 +176,7 @@ fun FlowLogic<*>.checkParameterHash(networkParametersHash: SecureHash?) {
// Transactions created on Corda 3.x or below do not contain network parameters,
// so no checking is done until the minimum platform version is at least 4.
if (networkParametersHash == null) {
if (serviceHub.networkParameters.minimumPlatformVersion < 4) return
if (serviceHub.networkParameters.minimumPlatformVersion < PlatformVersionSwitches.NETWORK_PARAMETERS_COMPONENT_GROUP) return
else throw IllegalArgumentException("Transaction for notarisation doesn't contain network parameters hash.")
} else {
serviceHub.networkParametersService.lookup(networkParametersHash) ?: throw IllegalArgumentException("Transaction for notarisation contains unknown parameters hash: $networkParametersHash")

View File

@ -329,13 +329,19 @@ abstract class Verifier(val ltx: LedgerTransaction, protected val transactionCla
allStates.map { it.contract to it.constraint }.toSet().forEach { (contract, constraint) ->
if (constraint is SignatureAttachmentConstraint) {
/**
* Support for signature constraints has been added on min. platform version >= 4.
* On minimum platform version >= 5, an explicit check has been introduced on the supported number of leaf keys
* in composite keys of signature constraints in order to harden consensus.
* Support for signature constraints has been added on
* min. platform version >= [PlatformVersionSwitches.MIGRATE_ATTACHMENT_TO_SIGNATURE_CONSTRAINTS].
* On minimum platform version >= [PlatformVersionSwitches.LIMIT_KEYS_IN_SIGNATURE_CONSTRAINTS], an explicit check has
* been introduced on the supported number of leaf keys in composite keys of signature constraints in
* order to harden consensus.
*/
checkMinimumPlatformVersion(ltx.networkParameters?.minimumPlatformVersion ?: 1, 4, "Signature constraints")
checkMinimumPlatformVersion(
ltx.networkParameters?.minimumPlatformVersion ?: PlatformVersionSwitches.FIRST_VERSION,
PlatformVersionSwitches.MIGRATE_ATTACHMENT_TO_SIGNATURE_CONSTRAINTS,
"Signature constraints"
)
val constraintKey = constraint.key
if (ltx.networkParameters?.minimumPlatformVersion ?: 1 >= 5) {
if (ltx.networkParameters?.minimumPlatformVersion ?: 1 >= PlatformVersionSwitches.LIMIT_KEYS_IN_SIGNATURE_CONSTRAINTS) {
if (constraintKey is CompositeKey && constraintKey.leafKeys.size > MAX_NUMBER_OF_KEYS_IN_SIGNATURE_CONSTRAINT) {
throw TransactionVerificationException.InvalidConstraintRejection(ltx.id, contract,
"Signature constraint contains composite key with ${constraintKey.leafKeys.size} leaf keys, " +

View File

@ -8,7 +8,7 @@ import net.corda.core.crypto.TransactionSignature
import net.corda.core.flows.*
import net.corda.core.identity.Party
import net.corda.core.internal.IdempotentFlow
import net.corda.core.internal.MIN_PLATFORM_VERSION_FOR_BACKPRESSURE_MESSAGE
import net.corda.core.internal.PlatformVersionSwitches
import net.corda.core.internal.checkParameterHash
import net.corda.core.utilities.seconds
import net.corda.core.utilities.unwrap
@ -44,7 +44,7 @@ abstract class NotaryServiceFlow(val otherSideSession: FlowSession, val service:
private var transactionId: SecureHash? = null
@Suspendable
private fun counterpartyCanHandleBackPressure() = otherSideSession.getCounterpartyFlowInfo(true).flowVersion >= MIN_PLATFORM_VERSION_FOR_BACKPRESSURE_MESSAGE
private fun counterpartyCanHandleBackPressure() = otherSideSession.getCounterpartyFlowInfo(true).flowVersion >= PlatformVersionSwitches.MIN_PLATFORM_VERSION_FOR_BACKPRESSURE_MESSAGE
@Suspendable
override fun call(): Void? {

View File

@ -1,6 +1,7 @@
package net.corda.core.internal.rules
import net.corda.core.contracts.ContractState
import net.corda.core.internal.PlatformVersionSwitches
import net.corda.core.internal.cordapp.targetPlatformVersion
import net.corda.core.internal.warnOnce
import org.slf4j.LoggerFactory
@ -44,6 +45,6 @@ object StateContractValidationEnforcementRule {
}
}
return targetVersion >= 4
return targetVersion >= PlatformVersionSwitches.BELONGS_TO_CONTRACT_ENFORCEMENT
}
}

View File

@ -147,7 +147,8 @@ class AttachmentsClassLoader(attachments: List<Attachment>,
return when {
path.endsWith("/") -> false // Directories (packages) can overlap.
targetPlatformVersion < 4 && ignoreDirectories.any { path.startsWith(it) } -> false // Ignore jolokia and json-simple for old cordapps.
targetPlatformVersion < PlatformVersionSwitches.IGNORE_JOLOKIA_JSON_SIMPLE_IN_CORDAPPS &&
ignoreDirectories.any { path.startsWith(it) } -> false // Ignore jolokia and json-simple for old cordapps.
path.endsWith(".class") -> true // All class files need to be unique.
!path.startsWith("meta-inf") -> true // All files outside of META-INF need to be unique.
(path == "meta-inf/services/net.corda.core.serialization.serializationwhitelist") -> false // Allow overlapping on the SerializationWhitelist.

View File

@ -516,7 +516,7 @@ open class TransactionBuilder(
services: ServicesForResolution
): Boolean {
return HashAttachmentConstraint.disableHashConstraints
&& services.networkParameters.minimumPlatformVersion >= 4
&& services.networkParameters.minimumPlatformVersion >= PlatformVersionSwitches.MIGRATE_HASH_TO_SIGNATURE_CONSTRAINTS
// `disableHashConstraints == true` therefore it does not matter if there are
// multiple input states with different hash constraints
&& inputStates?.any { it.constraint is HashAttachmentConstraint } == true
@ -534,8 +534,8 @@ open class TransactionBuilder(
attachmentToUse: ContractAttachment,
services: ServicesForResolution): AttachmentConstraint = when {
inputStates != null -> attachmentConstraintsTransition(inputStates.groupBy { it.constraint }.keys, attachmentToUse, services)
attachmentToUse.signerKeys.isNotEmpty() && services.networkParameters.minimumPlatformVersion < 4 -> {
log.warnOnce("Signature constraints not available on network requiring a minimum platform version of 4. Current is: ${services.networkParameters.minimumPlatformVersion}.")
attachmentToUse.signerKeys.isNotEmpty() && services.networkParameters.minimumPlatformVersion < PlatformVersionSwitches.MIGRATE_ATTACHMENT_TO_SIGNATURE_CONSTRAINTS -> {
log.warnOnce("Signature constraints not available on network requiring a minimum platform version of ${PlatformVersionSwitches.MIGRATE_ATTACHMENT_TO_SIGNATURE_CONSTRAINTS}. Current is: ${services.networkParameters.minimumPlatformVersion}.")
if (useWhitelistedByZoneAttachmentConstraint(contractClassName, services.networkParameters)) {
log.warnOnce("Reverting back to using whitelisted zone constraints for contract $contractClassName")
WhitelistedByZoneAttachmentConstraint
@ -583,7 +583,10 @@ open class TransactionBuilder(
throw IllegalArgumentException("Cannot mix SignatureAttachmentConstraints signed by different parties in the same transaction.")
// This ensures a smooth migration from a Whitelist Constraint to a Signature Constraint
constraints.any { it is WhitelistedByZoneAttachmentConstraint } && attachmentToUse.isSigned && services.networkParameters.minimumPlatformVersion >= 4 -> transitionToSignatureConstraint(constraints, attachmentToUse)
constraints.any { it is WhitelistedByZoneAttachmentConstraint } &&
attachmentToUse.isSigned &&
services.networkParameters.minimumPlatformVersion >= PlatformVersionSwitches.MIGRATE_ATTACHMENT_TO_SIGNATURE_CONSTRAINTS ->
transitionToSignatureConstraint(constraints, attachmentToUse)
// This condition is hit when the current node has not installed the latest signed version but has already received states that have been migrated
constraints.any { it is SignatureAttachmentConstraint } && !attachmentToUse.isSigned ->

View File

@ -241,7 +241,7 @@ class JarScanningCordappLoader private constructor(private val cordappJarPaths:
"Version identifier ($versionStr) for attribute $attributeName must be a whole number starting from 1.",
CordappErrors.INVALID_VERSION_IDENTIFIER,
listOf(versionStr, attributeName))
if (version < 1) {
if (version < PlatformVersionSwitches.FIRST_VERSION) {
throw CordappInvalidVersionException(
"Target versionId ($versionStr) for attribute $attributeName must not be smaller than 1.",
CordappErrors.INVALID_VERSION_IDENTIFIER,

View File

@ -6,6 +6,7 @@ import net.corda.core.flows.FlowSession
import net.corda.core.flows.NotarisationPayload
import net.corda.core.flows.NotaryError
import net.corda.core.identity.Party
import net.corda.core.internal.PlatformVersionSwitches
import net.corda.core.internal.notary.NotaryInternalException
import net.corda.core.internal.notary.NotaryServiceFlow
import net.corda.core.internal.notary.SinglePartyNotaryService
@ -47,7 +48,7 @@ class NonValidatingNotaryFlow(otherSideSession: FlowSession, service: SinglePart
checkAllComponentsVisible(ComponentGroupEnum.INPUTS_GROUP)
checkAllComponentsVisible(ComponentGroupEnum.TIMEWINDOW_GROUP)
checkAllComponentsVisible(ComponentGroupEnum.REFERENCES_GROUP)
if (minPlatformVersion >= 4) checkAllComponentsVisible(ComponentGroupEnum.PARAMETERS_GROUP)
if (minPlatformVersion >= PlatformVersionSwitches.NETWORK_PARAMETERS_COMPONENT_GROUP) checkAllComponentsVisible(ComponentGroupEnum.PARAMETERS_GROUP)
}
val notary = tx.notary ?: throw IllegalArgumentException("Transaction does not specify a notary.")
checkNotaryWhitelisted(notary, tx.networkParametersHash)
@ -67,7 +68,7 @@ class NonValidatingNotaryFlow(otherSideSession: FlowSession, service: SinglePart
/** Make sure the transaction notary is part of the network parameter whitelist. */
private fun checkNotaryWhitelisted(notary: Party, attachedParameterHash: SecureHash?) {
if (minPlatformVersion >= 4) {
if (minPlatformVersion >= PlatformVersionSwitches.NETWORK_PARAMETERS_COMPONENT_GROUP) {
// Expecting network parameters to be attached for platform version 4 or later.
if (attachedParameterHash == null) {
throw IllegalArgumentException("Transaction must contain network parameters.")