mirror of
https://github.com/corda/corda.git
synced 2025-06-19 15:43:52 +00:00
CORDA-4125: Backport AttachmentClassLoader updates to 4.4 to enable ENT-6152 backport (#6878)
* CORDA-3755: Switched attachments map to a WeakHashMap (#6214) * Bump OS release version 4.6 * CORDA-3755: Switched attachments map to a WeakHashMap * CORDA-3755: Added explicit strong references to map key. * CORDA-3755: Keeping detekt happy. * CORDA-3755: Test a gc in verify. * CORDA-3755: Making detekt happy. * CORDA-3755: Suppress warnings for weak reference test. * CORDA-3755: Fixing build failure with attachments. * CORDA-3755: Rewrite based on Ricks input - now handles attachment already existing in map! * CORDA-3755: Refactor WeakReference behaviour into AttachmentsHolderImpl and provide alternate version of this class for core-deterministic. * CORDA-3755: Added more tests for WeakHashMap. * CORDA-3755: Ignore the tests using System.gc keep for local testing only * CORDA-3755: Adding comment to explain the ignored tests. * Make AttachmentsHolderImpl package-private inside core-deterministic, just like it is inside core. * CORDA-3755: Update assertions following review comments. * CORDA-3755: Removing import * CORDA-3755: Removed unused var. * CORDA-3755: Reverting files that somehow got changed in rebase. Co-authored-by: nargas-ritu <ritu.gupta@r3.com> Co-authored-by: Chris Rankin <chris.rankin@r3.com> * CORDA-3769: Switched attachments class loader cache to use caffeine (#6326) * CORDA-3769: Switched attachments class loader cache to use caffeine with original implementation used by determinstic core. * CORDA-3769: Removed default ctor arguments. * CORDA-3769: Switched mapping function to Function type to avoid synthetic method being generated. * CORDA-3769: Now using a cache created from NamedCacheFactory for the attachments class loader cache. * CORDA-3769: Making detekt happy. * CORDA-3769: The finality tests now check for UntrustedAttachmentsException which will actually happen in reality. * CORDA-3769: Refactored after review comments. * CORDA-3769: Removed the AttachmentsClassLoaderSimpleCacheImpl as DJVM does not need it. Also updated due to review comments. * CORDA-3769: Removed the generic parameters from AttachmentsClassLoader. * CORDA-3769: Removed unused imports. * CORDA-3769: Updates from review comments. * CORDA-3769: Updated following review comments. MigrationServicesForResolution now uses cache factory. Ctor updated for AttachmentsClassLoaderSimpleCacheImpl. * CORDA-3769: Reduced max class loader cache size * CORDA-3769: Fixed the attachments class loader cache size to a fixed default * CORDA-3769: Switched attachments class loader size to be reduced by fixed value. * CORDA-4125: Parameter has been added to a private ctor. Co-authored-by: nargas-ritu <ritu.gupta@r3.com> Co-authored-by: Chris Rankin <chris.rankin@r3.com>
This commit is contained in:
@ -57,6 +57,8 @@ import net.corda.core.schemas.MappedSchema
|
||||
import net.corda.core.serialization.SerializationWhitelist
|
||||
import net.corda.core.serialization.SerializeAsToken
|
||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||
import net.corda.core.serialization.internal.AttachmentsClassLoaderCache
|
||||
import net.corda.core.serialization.internal.AttachmentsClassLoaderCacheImpl
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.core.utilities.days
|
||||
@ -315,6 +317,7 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
||||
} else {
|
||||
BasicVerifierFactoryService()
|
||||
}
|
||||
private val attachmentsClassLoaderCache: AttachmentsClassLoaderCache = AttachmentsClassLoaderCacheImpl(cacheFactory).tokenize()
|
||||
val contractUpgradeService = ContractUpgradeServiceImpl(cacheFactory).tokenize()
|
||||
val auditService = DummyAuditService().tokenize()
|
||||
@Suppress("LeakingThis")
|
||||
@ -1144,6 +1147,8 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
||||
private lateinit var _myInfo: NodeInfo
|
||||
override val myInfo: NodeInfo get() = _myInfo
|
||||
|
||||
override val attachmentsClassLoaderCache: AttachmentsClassLoaderCache get() = this@AbstractNode.attachmentsClassLoaderCache
|
||||
|
||||
private lateinit var _networkParameters: NetworkParameters
|
||||
override val networkParameters: NetworkParameters get() = _networkParameters
|
||||
|
||||
|
@ -37,6 +37,7 @@ class MigrationNamedCacheFactory(private val metricRegistry: MetricRegistry?,
|
||||
"NodeAttachmentService_contractAttachmentVersions" -> caffeine.maximumSize(defaultCacheSize)
|
||||
"NodeParametersStorage_networkParametersByHash" -> caffeine.maximumSize(defaultCacheSize)
|
||||
"NodeAttachmentTrustCalculator_trustedKeysCache" -> caffeine.maximumSize(defaultCacheSize)
|
||||
"AttachmentsClassLoader_cache" -> caffeine.maximumSize(defaultCacheSize)
|
||||
else -> throw IllegalArgumentException("Unexpected cache name $name.")
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ import net.corda.core.node.services.NetworkParametersService
|
||||
import net.corda.core.node.services.TransactionStorage
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.serialization.internal.AttachmentsClassLoaderBuilder
|
||||
import net.corda.core.serialization.internal.AttachmentsClassLoaderCache
|
||||
import net.corda.core.serialization.internal.AttachmentsClassLoaderCacheImpl
|
||||
import net.corda.core.transactions.ContractUpgradeLedgerTransaction
|
||||
import net.corda.core.transactions.NotaryChangeLedgerTransaction
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
@ -62,6 +64,8 @@ class MigrationServicesForResolution(
|
||||
cacheFactory
|
||||
)
|
||||
|
||||
private val attachmentsClassLoaderCache: AttachmentsClassLoaderCache = AttachmentsClassLoaderCacheImpl(cacheFactory)
|
||||
|
||||
private fun defaultNetworkParameters(): NetworkParameters {
|
||||
logger.warn("Using a dummy set of network parameters for migration.")
|
||||
val clock = Clock.systemUTC()
|
||||
@ -124,7 +128,8 @@ class MigrationServicesForResolution(
|
||||
networkParameters,
|
||||
tx.id,
|
||||
attachmentTrustCalculator::calculate,
|
||||
cordappLoader.appClassLoader) {
|
||||
cordappLoader.appClassLoader,
|
||||
attachmentsClassLoaderCache) {
|
||||
deserialiseComponentGroup(tx.componentGroups, TransactionState::class, ComponentGroupEnum.OUTPUTS_GROUP, forceDeserialize = true)
|
||||
}
|
||||
states.filterIndexed {index, _ -> stateIndices.contains(index)}.toList()
|
||||
|
@ -63,6 +63,7 @@ open class DefaultNamedCacheFactory protected constructor(private val metricRegi
|
||||
name == "NodeParametersStorage_networkParametersByHash" -> caffeine.maximumSize(defaultCacheSize)
|
||||
name == "PublicKeyToOwningIdentityCache_cache" -> caffeine.maximumSize(defaultCacheSize)
|
||||
name == "NodeAttachmentTrustCalculator_trustedKeysCache" -> caffeine.maximumSize(defaultCacheSize)
|
||||
name == "AttachmentsClassLoader_cache" -> caffeine.maximumSize(defaultAttachmentsClassLoaderCacheSize)
|
||||
else -> throw IllegalArgumentException("Unexpected cache name $name. Did you add a new cache?")
|
||||
}
|
||||
}
|
||||
@ -85,4 +86,6 @@ open class DefaultNamedCacheFactory protected constructor(private val metricRegi
|
||||
}
|
||||
|
||||
open protected val defaultCacheSize = 1024L
|
||||
}
|
||||
private val defaultAttachmentsClassLoaderCacheSize = defaultCacheSize / CACHE_SIZE_DENOMINATOR
|
||||
}
|
||||
private const val CACHE_SIZE_DENOMINATOR = 4L
|
@ -50,13 +50,13 @@ class FinalityHandlerTest {
|
||||
getOrThrow()
|
||||
}
|
||||
|
||||
bob.assertFlowSentForObservationDueToConstraintError(finalityHandlerId)
|
||||
bob.assertFlowSentForObservationDueToUntrustedAttachmentsException(finalityHandlerId)
|
||||
assertThat(bob.getTransaction(stx.id)).isNull()
|
||||
|
||||
bob = mockNet.restartNode(bob)
|
||||
// Since we've not done anything to fix the orignal error, we expect the finality handler to be sent to the hospital
|
||||
// again on restart
|
||||
bob.assertFlowSentForObservationDueToConstraintError(finalityHandlerId)
|
||||
bob.assertFlowSentForObservationDueToUntrustedAttachmentsException(finalityHandlerId)
|
||||
assertThat(bob.getTransaction(stx.id)).isNull()
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ class FinalityHandlerTest {
|
||||
.ofType(R::class.java)
|
||||
}
|
||||
|
||||
private fun TestStartedNode.assertFlowSentForObservationDueToConstraintError(runId: StateMachineRunId) {
|
||||
private fun TestStartedNode.assertFlowSentForObservationDueToUntrustedAttachmentsException(runId: StateMachineRunId) {
|
||||
val observation = medicalRecordsOfType<MedicalRecord.Flow>()
|
||||
.filter { it.flowId == runId }
|
||||
.toBlocking()
|
||||
@ -104,7 +104,7 @@ class FinalityHandlerTest {
|
||||
assertThat(observation.outcome).isEqualTo(Outcome.OVERNIGHT_OBSERVATION)
|
||||
assertThat(observation.by).contains(FinalityDoctor)
|
||||
val error = observation.errors.single()
|
||||
assertThat(error).isInstanceOf(TransactionVerificationException.ContractConstraintRejection::class.java)
|
||||
assertThat(error).isInstanceOf(TransactionVerificationException.UntrustedAttachmentsException::class.java)
|
||||
}
|
||||
|
||||
private fun TestStartedNode.getTransaction(id: SecureHash): SignedTransaction? {
|
||||
|
Reference in New Issue
Block a user