mirror of
https://github.com/corda/corda.git
synced 2025-06-19 23:53:52 +00:00
Merge commit 'bc330bd9890d41904bbeea6e579f5fc4438872b6' into christians/merge-ENT-2414
This commit is contained in:
@ -82,6 +82,7 @@ dependencies {
|
||||
compile project(':client:rpc')
|
||||
compile project(':tools:shell')
|
||||
|
||||
|
||||
compile "net.corda.plugins:cordform-common:$gradle_plugins_version"
|
||||
|
||||
// Log4J: logging framework (with SLF4J bindings)
|
||||
|
@ -11,6 +11,7 @@
|
||||
package net.corda.node.services.network
|
||||
|
||||
import net.corda.cordform.CordformNode
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.crypto.random63BitValue
|
||||
import net.corda.core.internal.*
|
||||
import net.corda.core.internal.concurrent.transpose
|
||||
@ -19,6 +20,9 @@ import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.core.utilities.seconds
|
||||
import net.corda.node.services.config.configureDevKeyAndTrustStores
|
||||
import net.corda.nodeapi.internal.NODE_INFO_DIRECTORY
|
||||
import net.corda.nodeapi.internal.config.NodeSSLConfiguration
|
||||
import net.corda.nodeapi.internal.network.NETWORK_PARAMS_FILE_NAME
|
||||
import net.corda.nodeapi.internal.network.NETWORK_PARAMS_UPDATE_FILE_NAME
|
||||
import net.corda.nodeapi.internal.network.SignedNetworkParameters
|
||||
@ -252,7 +256,7 @@ class NetworkMapTest(var initFunc: (URL, NetworkMapServer) -> CompatibilityZoneP
|
||||
|
||||
private fun NodeHandle.onlySees(vararg nodes: NodeInfo) {
|
||||
// Make sure the nodes aren't getting the node infos from their additional directories
|
||||
val nodeInfosDir = baseDirectory / CordformNode.NODE_INFO_DIRECTORY
|
||||
val nodeInfosDir = baseDirectory / NODE_INFO_DIRECTORY
|
||||
if (nodeInfosDir.exists()) {
|
||||
assertThat(nodeInfosDir.list()).isEmpty()
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import com.github.benmanes.caffeine.cache.Cache
|
||||
import com.github.benmanes.caffeine.cache.Caffeine
|
||||
import com.google.common.primitives.Ints
|
||||
import net.corda.core.context.AuthServiceId
|
||||
import net.corda.core.internal.buildNamed
|
||||
import net.corda.core.internal.uncheckedCast
|
||||
import net.corda.core.utilities.loggerFor
|
||||
import net.corda.node.internal.DataSourceFactory
|
||||
@ -318,7 +319,7 @@ private class CaffeineCacheManager(val maxSize: Long,
|
||||
return Caffeine.newBuilder()
|
||||
.expireAfterWrite(timeToLiveSeconds, TimeUnit.SECONDS)
|
||||
.maximumSize(maxSize)
|
||||
.build<K, V>()
|
||||
.buildNamed<K, V>("RPCSecurityManagerShiroCache_$name")
|
||||
.toShiroCache()
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ class PersistentIdentityService : SingletonSerializeAsToken(), IdentityServiceIn
|
||||
|
||||
fun createPKMap(): AppendOnlyPersistentMap<SecureHash, PartyAndCertificate, PersistentIdentity, String> {
|
||||
return AppendOnlyPersistentMap(
|
||||
"PersistentIdentityService_partyByKey",
|
||||
toPersistentEntityKey = { it.toString() },
|
||||
fromPersistentEntity = {
|
||||
Pair(
|
||||
@ -61,6 +62,7 @@ class PersistentIdentityService : SingletonSerializeAsToken(), IdentityServiceIn
|
||||
|
||||
fun createX500Map(): AppendOnlyPersistentMap<CordaX500Name, SecureHash, PersistentIdentityNames, String> {
|
||||
return AppendOnlyPersistentMap(
|
||||
"PersistentIdentityService_partyByName",
|
||||
toPersistentEntityKey = { it.toString() },
|
||||
fromPersistentEntity = { Pair(CordaX500Name.parse(it.name), SecureHash.parse(it.publicKeyHash)) },
|
||||
toPersistentEntity = { key: CordaX500Name, value: SecureHash ->
|
||||
|
@ -58,6 +58,7 @@ class PersistentKeyManagementService(val identityService: PersistentIdentityServ
|
||||
private companion object {
|
||||
fun createKeyMap(): AppendOnlyPersistentMap<PublicKey, PrivateKey, PersistentKey, String> {
|
||||
return AppendOnlyPersistentMap(
|
||||
"PersistentKeyManagementService_keys",
|
||||
toPersistentEntityKey = { it.toStringShort() },
|
||||
fromPersistentEntity = {
|
||||
Pair(Crypto.decodePublicKey(it.publicKey),
|
||||
|
@ -42,6 +42,7 @@ class P2PMessageDeduplicator(private val database: CordaPersistence) {
|
||||
|
||||
private fun createProcessedMessages(): AppendOnlyPersistentMap<DeduplicationId, MessageMeta, ProcessedMessage, String> {
|
||||
return AppendOnlyPersistentMap(
|
||||
"P2PMessageDeduplicator_processedMessages",
|
||||
toPersistentEntityKey = { it.toString },
|
||||
fromPersistentEntity = { Pair(DeduplicationId(it.id), MessageMeta(it.insertionTime, it.hash, it.seqNo)) },
|
||||
toPersistentEntity = { key: DeduplicationId, value: MessageMeta ->
|
||||
|
@ -23,6 +23,7 @@ import net.corda.core.context.Trace
|
||||
import net.corda.core.context.Trace.InvocationId
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.internal.LifeCycle
|
||||
import net.corda.core.internal.buildNamed
|
||||
import net.corda.core.messaging.RPCOps
|
||||
import net.corda.core.serialization.SerializationContext
|
||||
import net.corda.core.serialization.SerializationDefaults
|
||||
@ -163,7 +164,7 @@ class RPCServer(
|
||||
log.debug { "Unsubscribing from Observable with id $key because of $cause" }
|
||||
value!!.subscription.unsubscribe()
|
||||
}
|
||||
return Caffeine.newBuilder().removalListener(onObservableRemove).executor(SameThreadExecutor.getExecutor()).build()
|
||||
return Caffeine.newBuilder().removalListener(onObservableRemove).executor(SameThreadExecutor.getExecutor()).buildNamed("RPCServer_observableSubscription")
|
||||
}
|
||||
|
||||
fun start(activeMqServerControl: ActiveMQServerControl) {
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
package net.corda.node.services.network
|
||||
|
||||
import net.corda.cordform.CordformNode
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.internal.*
|
||||
import net.corda.core.node.NodeInfo
|
||||
@ -21,6 +20,7 @@ import net.corda.core.utilities.contextLogger
|
||||
import net.corda.core.utilities.debug
|
||||
import net.corda.core.utilities.seconds
|
||||
import net.corda.node.serialization.amqp.AMQPServerSerializationScheme
|
||||
import net.corda.nodeapi.internal.NODE_INFO_DIRECTORY
|
||||
import net.corda.nodeapi.internal.NodeInfoAndSigned
|
||||
import net.corda.nodeapi.internal.SignedNodeInfo
|
||||
import net.corda.nodeapi.internal.network.NodeInfoFilesCopier
|
||||
@ -74,7 +74,8 @@ class NodeInfoWatcher(private val nodePath: Path,
|
||||
}
|
||||
|
||||
internal data class NodeInfoFromFile(val nodeInfohash: SecureHash, val lastModified: FileTime)
|
||||
private val nodeInfosDir = nodePath / CordformNode.NODE_INFO_DIRECTORY
|
||||
|
||||
private val nodeInfosDir = nodePath / NODE_INFO_DIRECTORY
|
||||
private val nodeInfoFilesMap = HashMap<Path, NodeInfoFromFile>()
|
||||
val processedNodeInfoHashes: Set<SecureHash> get() = nodeInfoFilesMap.values.map { it.nodeInfohash }.toSet()
|
||||
|
||||
@ -84,7 +85,7 @@ class NodeInfoWatcher(private val nodePath: Path,
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all the files contained in [nodePath] / [CordformNode.NODE_INFO_DIRECTORY] and keep watching
|
||||
* Read all the files contained in [nodePath] / [NODE_INFO_DIRECTORY] and keep watching
|
||||
* the folder for further updates.
|
||||
*
|
||||
* We simply list the directory content every 5 seconds, the Java implementation of WatchService has been proven to
|
||||
|
@ -132,7 +132,9 @@ open class PersistentNetworkMapCache(private val database: CordaPersistence,
|
||||
|
||||
override fun getNodesByLegalIdentityKey(identityKey: PublicKey): List<NodeInfo> = nodesByKeyCache[identityKey]!!
|
||||
|
||||
private val nodesByKeyCache = NonInvalidatingCache<PublicKey, List<NodeInfo>>(1024) { key ->
|
||||
private val nodesByKeyCache = NonInvalidatingCache<PublicKey, List<NodeInfo>>(
|
||||
"PersistentNetworkMap_nodesByKey",
|
||||
1024) { key ->
|
||||
database.transaction { queryByIdentityKey(session, key) }
|
||||
}
|
||||
|
||||
@ -150,7 +152,9 @@ open class PersistentNetworkMapCache(private val database: CordaPersistence,
|
||||
return identityByLegalNameCache.get(name)!!.orElse(null)
|
||||
}
|
||||
|
||||
private val identityByLegalNameCache = NonInvalidatingCache<CordaX500Name, Optional<PartyAndCertificate>>(1024) { name ->
|
||||
private val identityByLegalNameCache = NonInvalidatingCache<CordaX500Name, Optional<PartyAndCertificate>>(
|
||||
"PersistentNetworkMap_idByLegalName",
|
||||
1024) { name ->
|
||||
Optional.ofNullable(database.transaction { queryIdentityByLegalName(session, name) })
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,7 @@ class DBTransactionStorage(cacheSizeBytes: Long, private val database: CordaPers
|
||||
fun createTransactionsMap(maxSizeInBytes: Long)
|
||||
: AppendOnlyPersistentMapBase<SecureHash, TxCacheValue, DBTransaction, String> {
|
||||
return WeightBasedAppendOnlyPersistentMap<SecureHash, TxCacheValue, DBTransaction, String>(
|
||||
name = "DBTransactionStorage_transactions",
|
||||
toPersistentEntityKey = { it.toString() },
|
||||
fromPersistentEntity = {
|
||||
Pair(SecureHash.parse(it.txId),
|
||||
|
@ -216,6 +216,7 @@ class NodeAttachmentService(
|
||||
// a problem somewhere else or this needs to be revisited.
|
||||
|
||||
private val attachmentContentCache = NonInvalidatingWeightBasedCache(
|
||||
name = "NodeAttachmentService_attachmentContent",
|
||||
maxWeight = attachmentContentCacheSize,
|
||||
weigher = Weigher<SecureHash, Optional<Pair<Attachment, ByteArray>>> { key, value -> key.size + if (value.isPresent) value.get().second.size else 0 },
|
||||
loadFunction = { Optional.ofNullable(loadAttachmentContent(it)) }
|
||||
@ -236,7 +237,9 @@ class NodeAttachmentService(
|
||||
}
|
||||
}
|
||||
|
||||
private val attachmentCache = NonInvalidatingCache<SecureHash, Optional<Attachment>>(attachmentCacheBound) { key ->
|
||||
private val attachmentCache = NonInvalidatingCache<SecureHash, Optional<Attachment>>(
|
||||
"NodeAttachmentService_attachemnt",
|
||||
attachmentCacheBound) { key ->
|
||||
Optional.ofNullable(createAttachment(key))
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,7 @@ class FlowsDrainingModeOperationsImpl(readPhysicalNodeId: () -> String, private
|
||||
}
|
||||
|
||||
internal val map = PersistentMap(
|
||||
"FlowDrainingMode_nodeProperties",
|
||||
{ key -> key },
|
||||
{ entity -> entity.key to entity.value!! },
|
||||
NodePropertiesPersistentStore::DBNodeProperty,
|
||||
|
@ -112,6 +112,7 @@ class BFTNonValidatingNotaryService(
|
||||
|
||||
private fun createMap(): AppendOnlyPersistentMap<StateRef, SecureHash, CommittedState, PersistentStateRef> {
|
||||
return AppendOnlyPersistentMap(
|
||||
"BFTNonValidatingNotaryService_transactions",
|
||||
toPersistentEntityKey = { PersistentStateRef(it.txhash.toString(), it.index) },
|
||||
fromPersistentEntity = {
|
||||
//TODO null check will become obsolete after making DB/JPA columns not nullable
|
||||
|
@ -87,6 +87,7 @@ class PersistentUniquenessProvider(val clock: Clock) : UniquenessProvider, Singl
|
||||
private val log = contextLogger()
|
||||
fun createMap(): AppendOnlyPersistentMap<StateRef, SecureHash, CommittedState, PersistentStateRef> =
|
||||
AppendOnlyPersistentMap(
|
||||
"PersistentUniquenessProvider_transactions",
|
||||
toPersistentEntityKey = { PersistentStateRef(it.txhash.toString(), it.index) },
|
||||
fromPersistentEntity = {
|
||||
//TODO null check will become obsolete after making DB/JPA columns not nullable
|
||||
|
@ -71,6 +71,7 @@ class RaftUniquenessProvider(
|
||||
private val log = contextLogger()
|
||||
fun createMap(): AppendOnlyPersistentMap<StateRef, Pair<Long, SecureHash>, CommittedState, PersistentStateRef> =
|
||||
AppendOnlyPersistentMap(
|
||||
"RaftUniquenessProvider_transactions",
|
||||
toPersistentEntityKey = { PersistentStateRef(it) },
|
||||
fromPersistentEntity = {
|
||||
val txId = it.id.txId
|
||||
|
@ -38,6 +38,7 @@ class ContractUpgradeServiceImpl : ContractUpgradeService, SingletonSerializeAsT
|
||||
private companion object {
|
||||
fun createContractUpgradesMap(): PersistentMap<String, String, DBContractUpgrade, String> {
|
||||
return PersistentMap(
|
||||
"ContractUpgradeService_upgrades",
|
||||
toPersistentEntityKey = { it },
|
||||
fromPersistentEntity = { Pair(it.stateRef, it.upgradedContractClassName ?: "") },
|
||||
toPersistentEntity = { key: String, value: String ->
|
||||
|
@ -319,6 +319,7 @@ abstract class AppendOnlyPersistentMapBase<K, V, E, out EK>(
|
||||
|
||||
// Open for tests to override
|
||||
open class AppendOnlyPersistentMap<K, V, E, out EK>(
|
||||
name: String,
|
||||
toPersistentEntityKey: (K) -> EK,
|
||||
fromPersistentEntity: (E) -> Pair<K, V>,
|
||||
toPersistentEntity: (key: K, value: V) -> E,
|
||||
@ -331,6 +332,7 @@ open class AppendOnlyPersistentMap<K, V, E, out EK>(
|
||||
persistentEntityClass) {
|
||||
//TODO determine cacheBound based on entity class later or with node config allowing tuning, or using some heuristic based on heap size
|
||||
override val cache = NonInvalidatingCache(
|
||||
name = name,
|
||||
bound = cacheBound,
|
||||
loadFunction = { key: K ->
|
||||
// This gets called if a value is read and the cache has no Transactional for this key yet.
|
||||
@ -363,6 +365,7 @@ open class AppendOnlyPersistentMap<K, V, E, out EK>(
|
||||
|
||||
// Same as above, but with weighted values (e.g. memory footprint sensitive).
|
||||
class WeightBasedAppendOnlyPersistentMap<K, V, E, out EK>(
|
||||
name: String,
|
||||
toPersistentEntityKey: (K) -> EK,
|
||||
fromPersistentEntity: (E) -> Pair<K, V>,
|
||||
toPersistentEntity: (key: K, value: V) -> E,
|
||||
@ -375,6 +378,7 @@ class WeightBasedAppendOnlyPersistentMap<K, V, E, out EK>(
|
||||
toPersistentEntity,
|
||||
persistentEntityClass) {
|
||||
override val cache = NonInvalidatingWeightBasedCache(
|
||||
name,
|
||||
maxWeight = maxWeight,
|
||||
weigher = Weigher { key, value -> weighingFunc(key, value) },
|
||||
loadFunction = { key: K ->
|
||||
|
@ -14,18 +14,19 @@ import com.github.benmanes.caffeine.cache.CacheLoader
|
||||
import com.github.benmanes.caffeine.cache.Caffeine
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache
|
||||
import com.github.benmanes.caffeine.cache.Weigher
|
||||
import net.corda.core.internal.buildNamed
|
||||
|
||||
class NonInvalidatingCache<K, V> private constructor(
|
||||
val cache: LoadingCache<K, V>
|
||||
) : LoadingCache<K, V> by cache {
|
||||
|
||||
constructor(bound: Long, loadFunction: (K) -> V) :
|
||||
this(buildCache(bound, loadFunction))
|
||||
constructor(name: String, bound: Long, loadFunction: (K) -> V) :
|
||||
this(buildCache(name, bound, loadFunction))
|
||||
|
||||
private companion object {
|
||||
private fun <K, V> buildCache(bound: Long, loadFunction: (K) -> V): LoadingCache<K, V> {
|
||||
private fun <K, V> buildCache(name: String, bound: Long, loadFunction: (K) -> V): LoadingCache<K, V> {
|
||||
val builder = Caffeine.newBuilder().maximumSize(bound)
|
||||
return builder.build(NonInvalidatingCacheLoader(loadFunction))
|
||||
return builder.buildNamed(name, NonInvalidatingCacheLoader(loadFunction))
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,13 +43,13 @@ class NonInvalidatingCache<K, V> private constructor(
|
||||
class NonInvalidatingWeightBasedCache<K, V> private constructor(
|
||||
val cache: LoadingCache<K, V>
|
||||
) : LoadingCache<K, V> by cache {
|
||||
constructor (maxWeight: Long, weigher: Weigher<K, V>, loadFunction: (K) -> V) :
|
||||
this(buildCache(maxWeight, weigher, loadFunction))
|
||||
constructor (name: String, maxWeight: Long, weigher: Weigher<K, V>, loadFunction: (K) -> V) :
|
||||
this(buildCache(name, maxWeight, weigher, loadFunction))
|
||||
|
||||
private companion object {
|
||||
private fun <K, V> buildCache(maxWeight: Long, weigher: Weigher<K, V>, loadFunction: (K) -> V): LoadingCache<K, V> {
|
||||
private fun <K, V> buildCache(name: String, maxWeight: Long, weigher: Weigher<K, V>, loadFunction: (K) -> V): LoadingCache<K, V> {
|
||||
val builder = Caffeine.newBuilder().maximumWeight(maxWeight).weigher(weigher)
|
||||
return builder.build(NonInvalidatingCache.NonInvalidatingCacheLoader(loadFunction))
|
||||
return builder.buildNamed(name, NonInvalidatingCache.NonInvalidatingCacheLoader(loadFunction))
|
||||
}
|
||||
}
|
||||
}
|
@ -15,20 +15,21 @@ import com.github.benmanes.caffeine.cache.CacheLoader
|
||||
import com.github.benmanes.caffeine.cache.Caffeine
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache
|
||||
import com.github.benmanes.caffeine.cache.RemovalListener
|
||||
import net.corda.core.internal.buildNamed
|
||||
|
||||
class NonInvalidatingUnboundCache<K, V> private constructor(
|
||||
val cache: LoadingCache<K, V>
|
||||
) : LoadingCache<K, V> by cache {
|
||||
|
||||
constructor(loadFunction: (K) -> V, removalListener: RemovalListener<K, V> = RemovalListener { _, _, _ -> },
|
||||
constructor(name: String, loadFunction: (K) -> V, removalListener: RemovalListener<K, V> = RemovalListener { _, _, _ -> },
|
||||
keysToPreload: () -> Iterable<K> = { emptyList() }) :
|
||||
this(buildCache(loadFunction, removalListener, keysToPreload))
|
||||
this(buildCache(name, loadFunction, removalListener, keysToPreload))
|
||||
|
||||
private companion object {
|
||||
private fun <K, V> buildCache(loadFunction: (K) -> V, removalListener: RemovalListener<K, V>,
|
||||
private fun <K, V> buildCache(name: String, loadFunction: (K) -> V, removalListener: RemovalListener<K, V>,
|
||||
keysToPreload: () -> Iterable<K>): LoadingCache<K, V> {
|
||||
val builder = Caffeine.newBuilder().removalListener(removalListener).executor(SameThreadExecutor.getExecutor())
|
||||
return builder.build(NonInvalidatingCacheLoader(loadFunction)).apply {
|
||||
return builder.buildNamed(name, NonInvalidatingCacheLoader(loadFunction)).apply {
|
||||
getAll(keysToPreload())
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import java.util.*
|
||||
* Implements an unbound caching layer on top of a table accessed via Hibernate mapping.
|
||||
*/
|
||||
class PersistentMap<K : Any, V, E, out EK>(
|
||||
name: String,
|
||||
val toPersistentEntityKey: (K) -> EK,
|
||||
val fromPersistentEntity: (E) -> Pair<K, V>,
|
||||
val toPersistentEntity: (key: K, value: V) -> E,
|
||||
@ -31,6 +32,7 @@ class PersistentMap<K : Any, V, E, out EK>(
|
||||
}
|
||||
|
||||
private val cache = NonInvalidatingUnboundCache(
|
||||
name,
|
||||
loadFunction = { key -> Optional.ofNullable(loadValue(key)) },
|
||||
removalListener = ExplicitRemoval(toPersistentEntityKey, persistentEntityClass)
|
||||
)
|
||||
|
@ -13,7 +13,6 @@ package net.corda.node.services.network
|
||||
import com.google.common.jimfs.Configuration.unix
|
||||
import com.google.common.jimfs.Jimfs
|
||||
import com.nhaarman.mockito_kotlin.*
|
||||
import net.corda.cordform.CordformNode.NODE_INFO_DIRECTORY
|
||||
import net.corda.core.crypto.Crypto
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.sign
|
||||
@ -25,6 +24,7 @@ import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.millis
|
||||
import net.corda.node.services.api.NetworkMapCacheInternal
|
||||
import net.corda.nodeapi.internal.NODE_INFO_DIRECTORY
|
||||
import net.corda.nodeapi.internal.NodeInfoAndSigned
|
||||
import net.corda.nodeapi.internal.network.NETWORK_PARAMS_UPDATE_FILE_NAME
|
||||
import net.corda.nodeapi.internal.network.NodeInfoFilesCopier
|
||||
|
@ -12,11 +12,11 @@ package net.corda.node.services.network
|
||||
|
||||
import com.google.common.jimfs.Configuration
|
||||
import com.google.common.jimfs.Jimfs
|
||||
import net.corda.cordform.CordformNode
|
||||
import net.corda.core.internal.createDirectories
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.core.internal.size
|
||||
import net.corda.core.node.services.KeyManagementService
|
||||
import net.corda.nodeapi.internal.NODE_INFO_DIRECTORY
|
||||
import net.corda.nodeapi.internal.NodeInfoAndSigned
|
||||
import net.corda.nodeapi.internal.network.NodeInfoFilesCopier
|
||||
import net.corda.testing.core.ALICE_NAME
|
||||
@ -61,7 +61,7 @@ class NodeInfoWatcherTest {
|
||||
val identityService = makeTestIdentityService()
|
||||
keyManagementService = MockKeyManagementService(identityService)
|
||||
nodeInfoWatcher = NodeInfoWatcher(tempFolder.root.toPath(), scheduler)
|
||||
nodeInfoPath = tempFolder.root.toPath() / CordformNode.NODE_INFO_DIRECTORY
|
||||
nodeInfoPath = tempFolder.root.toPath() / NODE_INFO_DIRECTORY
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -271,6 +271,7 @@ class AppendOnlyPersistentMapTest(var scenario: Scenario) {
|
||||
)
|
||||
|
||||
class TestMap : AppendOnlyPersistentMap<Long, String, PersistentMapEntry, Long>(
|
||||
"ApoendOnlyPersistentMap_test",
|
||||
toPersistentEntityKey = { it },
|
||||
fromPersistentEntity = { Pair(it.key, it.value) },
|
||||
toPersistentEntity = { key: Long, value: String ->
|
||||
|
@ -16,6 +16,7 @@ class PersistentMapTests {
|
||||
//create a test map using an existing db table
|
||||
private fun createTestMap(): PersistentMap<String, String, ContractUpgradeServiceImpl.DBContractUpgrade, String> {
|
||||
return PersistentMap(
|
||||
"Test_test",
|
||||
toPersistentEntityKey = { it },
|
||||
fromPersistentEntity = { Pair(it.stateRef, it.upgradedContractClassName ?: "") },
|
||||
toPersistentEntity = { key: String, value: String ->
|
||||
|
Reference in New Issue
Block a user