mirror of
https://github.com/corda/corda.git
synced 2025-06-17 22:58:19 +00:00
CORDA-599 Fix circular dependency between vault and SH (#1630)
Fix circular dependency between the 2 vault objects and SH.
This commit is contained in:
committed by
Mike Hearn
parent
0c2289de8c
commit
f83f1b7010
@ -19,6 +19,10 @@ import net.corda.core.internal.concurrent.flatMap
|
||||
import net.corda.core.internal.concurrent.openFuture
|
||||
import net.corda.core.internal.toX509CertHolder
|
||||
import net.corda.core.internal.uncheckedCast
|
||||
import net.corda.core.messaging.CordaRPCOps
|
||||
import net.corda.core.messaging.RPCOps
|
||||
import net.corda.core.messaging.SingleMessageRecipient
|
||||
import net.corda.core.node.*
|
||||
import net.corda.core.messaging.*
|
||||
import net.corda.core.node.AppServiceHub
|
||||
import net.corda.core.node.NodeInfo
|
||||
@ -453,7 +457,8 @@ abstract class AbstractNode(config: NodeConfiguration,
|
||||
private fun makeServices(schemaService: SchemaService): MutableList<Any> {
|
||||
checkpointStorage = DBCheckpointStorage()
|
||||
cordappProvider = CordappProviderImpl(cordappLoader)
|
||||
_services = ServiceHubInternalImpl(schemaService)
|
||||
val transactionStorage = makeTransactionStorage()
|
||||
_services = ServiceHubInternalImpl(schemaService, transactionStorage, StateLoaderImpl(transactionStorage))
|
||||
attachments = NodeAttachmentService(services.monitoringService.metrics)
|
||||
cordappProvider.start(attachments)
|
||||
legalIdentity = obtainIdentity(notaryConfig = null)
|
||||
@ -752,15 +757,18 @@ abstract class AbstractNode(config: NodeConfiguration,
|
||||
|
||||
protected open fun generateKeyPair() = cryptoGenerateKeyPair()
|
||||
|
||||
private inner class ServiceHubInternalImpl(override val schemaService: SchemaService) : ServiceHubInternal, SingletonSerializeAsToken() {
|
||||
private inner class ServiceHubInternalImpl(
|
||||
override val schemaService: SchemaService,
|
||||
override val validatedTransactions: WritableTransactionStorage,
|
||||
private val stateLoader: StateLoader
|
||||
) : SingletonSerializeAsToken(), ServiceHubInternal, StateLoader by stateLoader {
|
||||
override val rpcFlows = ArrayList<Class<out FlowLogic<*>>>()
|
||||
override val stateMachineRecordedTransactionMapping = DBTransactionMappingStorage()
|
||||
override val auditService = DummyAuditService()
|
||||
override val monitoringService = MonitoringService(MetricRegistry())
|
||||
override val validatedTransactions = makeTransactionStorage()
|
||||
override val transactionVerifierService by lazy { makeTransactionVerifierService() }
|
||||
override val networkMapCache by lazy { PersistentNetworkMapCache(this) }
|
||||
override val vaultService by lazy { NodeVaultService(this, database.hibernateConfig) }
|
||||
override val vaultService by lazy { NodeVaultService(platformClock, keyManagementService, stateLoader, this@AbstractNode.database.hibernateConfig) }
|
||||
override val contractUpgradeService by lazy { ContractUpgradeServiceImpl() }
|
||||
|
||||
// Place the long term identity key in the KMS. Eventually, this is likely going to be separated again because
|
||||
|
@ -1,8 +1,13 @@
|
||||
package net.corda.node.internal
|
||||
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TransactionResolutionException
|
||||
import net.corda.core.contracts.TransactionState
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.messaging.CordaRPCOps
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.node.StateLoader
|
||||
import net.corda.core.node.services.TransactionStorage
|
||||
import net.corda.node.services.api.CheckpointStorage
|
||||
import net.corda.node.services.api.ServiceHubInternal
|
||||
import net.corda.node.services.messaging.MessagingService
|
||||
@ -25,3 +30,13 @@ interface StartedNode<out N : AbstractNode> {
|
||||
fun dispose() = internals.stop()
|
||||
fun <T : FlowLogic<*>> registerInitiatedFlow(initiatedFlowClass: Class<T>) = internals.registerInitiatedFlow(initiatedFlowClass)
|
||||
}
|
||||
|
||||
class StateLoaderImpl(private val validatedTransactions: TransactionStorage) : StateLoader {
|
||||
@Throws(TransactionResolutionException::class)
|
||||
override fun loadState(stateRef: StateRef): TransactionState<*> {
|
||||
val stx = validatedTransactions.getTransaction(stateRef.txhash) ?: throw TransactionResolutionException(stateRef.txhash)
|
||||
return if (stx.isNotaryChangeTransaction()) {
|
||||
stx.resolveNotaryChangeTransaction(this).outputs[stateRef.index]
|
||||
} else stx.tx.outputs[stateRef.index]
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ import net.corda.node.services.config.NodeConfiguration
|
||||
import net.corda.node.services.messaging.MessagingService
|
||||
import net.corda.node.services.statemachine.FlowLogicRefFactoryImpl
|
||||
import net.corda.node.services.statemachine.FlowStateMachineImpl
|
||||
import net.corda.node.services.vault.NodeVaultService
|
||||
import net.corda.node.utilities.CordaPersistence
|
||||
|
||||
interface NetworkMapCacheInternal : NetworkMapCache {
|
||||
@ -73,6 +72,7 @@ interface ServiceHubInternal : ServiceHub {
|
||||
private val log = loggerFor<ServiceHubInternal>()
|
||||
}
|
||||
|
||||
override val vaultService: VaultServiceInternal
|
||||
/**
|
||||
* A map of hash->tx where tx has been signature/contract validated and the states are known to be correct.
|
||||
* The signatures aren't technically needed after that point, but we keep them around so that we can relay
|
||||
@ -104,7 +104,7 @@ interface ServiceHubInternal : ServiceHub {
|
||||
|
||||
if (notifyVault) {
|
||||
val toNotify = recordedTransactions.map { if (it.isNotaryChangeTransaction()) it.notaryChangeTx else it.tx }
|
||||
(vaultService as NodeVaultService).notifyAll(toNotify)
|
||||
vaultService.notifyAll(toNotify)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,19 @@
|
||||
package net.corda.node.services.api
|
||||
|
||||
import net.corda.core.node.services.VaultService
|
||||
import net.corda.core.transactions.CoreTransaction
|
||||
import net.corda.core.transactions.NotaryChangeWireTransaction
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
|
||||
interface VaultServiceInternal : VaultService {
|
||||
/**
|
||||
* Splits the provided [txns] into batches of [WireTransaction] and [NotaryChangeWireTransaction].
|
||||
* This is required because the batches get aggregated into single updates, and we want to be able to
|
||||
* indicate whether an update consists entirely of regular or notary change transactions, which may require
|
||||
* different processing logic.
|
||||
*/
|
||||
fun notifyAll(txns: Iterable<CoreTransaction>)
|
||||
|
||||
/** Same as notifyAll but with a single transaction. */
|
||||
fun notify(tx: CoreTransaction) = notifyAll(listOf(tx))
|
||||
}
|
@ -4,16 +4,16 @@ import co.paralleluniverse.fibers.Suspendable
|
||||
import co.paralleluniverse.strands.Strand
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.internal.ThreadBox
|
||||
import net.corda.core.internal.VisibleForTesting
|
||||
import net.corda.core.internal.bufferUntilSubscribed
|
||||
import net.corda.core.internal.tee
|
||||
import net.corda.core.messaging.DataFeed
|
||||
import net.corda.core.node.ServiceHub
|
||||
import net.corda.core.internal.*
|
||||
import net.corda.core.node.StateLoader
|
||||
import net.corda.core.node.services.*
|
||||
import net.corda.core.node.services.StatesNotAvailableException
|
||||
import net.corda.core.node.services.Vault
|
||||
import net.corda.core.node.services.vault.QueryCriteria
|
||||
import net.corda.core.node.services.vault.Sort
|
||||
import net.corda.core.node.services.vault.SortAttribute
|
||||
import net.corda.core.messaging.DataFeed
|
||||
import net.corda.core.node.services.VaultQueryException
|
||||
import net.corda.core.node.services.VaultService
|
||||
import net.corda.core.node.services.vault.*
|
||||
import net.corda.core.schemas.PersistentStateRef
|
||||
import net.corda.core.serialization.SerializationDefaults.STORAGE_CONTEXT
|
||||
@ -24,6 +24,7 @@ import net.corda.core.transactions.CoreTransaction
|
||||
import net.corda.core.transactions.NotaryChangeWireTransaction
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
import net.corda.core.utilities.*
|
||||
import net.corda.node.services.api.VaultServiceInternal
|
||||
import net.corda.node.services.persistence.HibernateConfiguration
|
||||
import net.corda.node.services.statemachine.FlowStateMachineImpl
|
||||
import net.corda.node.utilities.DatabaseTransactionManager
|
||||
@ -33,6 +34,7 @@ import org.hibernate.Session
|
||||
import rx.Observable
|
||||
import rx.subjects.PublishSubject
|
||||
import java.security.PublicKey
|
||||
import java.time.Clock
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
import javax.persistence.Tuple
|
||||
@ -47,7 +49,7 @@ import javax.persistence.Tuple
|
||||
* TODO: keep an audit trail with time stamps of previously unconsumed states "as of" a particular point in time.
|
||||
* TODO: have transaction storage do some caching.
|
||||
*/
|
||||
class NodeVaultService(private val services: ServiceHub, private val hibernateConfig: HibernateConfiguration) : SingletonSerializeAsToken(), VaultService {
|
||||
class NodeVaultService(private val clock: Clock, private val keyManagementService: KeyManagementService, private val stateLoader: StateLoader, private val hibernateConfig: HibernateConfiguration) : SingletonSerializeAsToken(), VaultServiceInternal {
|
||||
|
||||
private companion object {
|
||||
val log = loggerFor<NodeVaultService>()
|
||||
@ -78,7 +80,7 @@ class NodeVaultService(private val services: ServiceHub, private val hibernateCo
|
||||
contractStateClassName = stateAndRef.value.state.data.javaClass.name,
|
||||
contractState = stateAndRef.value.state.serialize(context = STORAGE_CONTEXT).bytes,
|
||||
stateStatus = Vault.StateStatus.UNCONSUMED,
|
||||
recordedTime = services.clock.instant())
|
||||
recordedTime = clock.instant())
|
||||
state.stateRef = PersistentStateRef(stateAndRef.key)
|
||||
session.save(state)
|
||||
}
|
||||
@ -86,11 +88,11 @@ class NodeVaultService(private val services: ServiceHub, private val hibernateCo
|
||||
val state = session.get<VaultSchemaV1.VaultStates>(VaultSchemaV1.VaultStates::class.java, PersistentStateRef(stateRef))
|
||||
state?.run {
|
||||
stateStatus = Vault.StateStatus.CONSUMED
|
||||
consumedTime = services.clock.instant()
|
||||
consumedTime = clock.instant()
|
||||
// remove lock (if held)
|
||||
if (lockId != null) {
|
||||
lockId = null
|
||||
lockUpdateTime = services.clock.instant()
|
||||
lockUpdateTime = clock.instant()
|
||||
log.trace("Releasing soft lock on consumed state: $stateRef")
|
||||
}
|
||||
session.save(state)
|
||||
@ -106,13 +108,7 @@ class NodeVaultService(private val services: ServiceHub, private val hibernateCo
|
||||
override val updates: Observable<Vault.Update<ContractState>>
|
||||
get() = mutex.locked { _updatesInDbTx }
|
||||
|
||||
/**
|
||||
* Splits the provided [txns] into batches of [WireTransaction] and [NotaryChangeWireTransaction].
|
||||
* This is required because the batches get aggregated into single updates, and we want to be able to
|
||||
* indicate whether an update consists entirely of regular or notary change transactions, which may require
|
||||
* different processing logic.
|
||||
*/
|
||||
fun notifyAll(txns: Iterable<CoreTransaction>) {
|
||||
override fun notifyAll(txns: Iterable<CoreTransaction>) {
|
||||
// It'd be easier to just group by type, but then we'd lose ordering.
|
||||
val regularTxns = mutableListOf<WireTransaction>()
|
||||
val notaryChangeTxns = mutableListOf<NotaryChangeWireTransaction>()
|
||||
@ -140,12 +136,9 @@ class NodeVaultService(private val services: ServiceHub, private val hibernateCo
|
||||
if (notaryChangeTxns.isNotEmpty()) notifyNotaryChange(notaryChangeTxns.toList())
|
||||
}
|
||||
|
||||
/** Same as notifyAll but with a single transaction. */
|
||||
fun notify(tx: CoreTransaction) = notifyAll(listOf(tx))
|
||||
|
||||
private fun notifyRegular(txns: Iterable<WireTransaction>) {
|
||||
fun makeUpdate(tx: WireTransaction): Vault.Update<ContractState> {
|
||||
val myKeys = services.keyManagementService.filterMyKeys(tx.outputs.flatMap { it.data.participants.map { it.owningKey } })
|
||||
val myKeys = keyManagementService.filterMyKeys(tx.outputs.flatMap { it.data.participants.map { it.owningKey } })
|
||||
val ourNewStates = tx.outputs.
|
||||
filter { isRelevant(it.data, myKeys.toSet()) }.
|
||||
map { tx.outRef<ContractState>(it.data) }
|
||||
@ -171,8 +164,8 @@ class NodeVaultService(private val services: ServiceHub, private val hibernateCo
|
||||
// We need to resolve the full transaction here because outputs are calculated from inputs
|
||||
// We also can't do filtering beforehand, since output encumbrance pointers get recalculated based on
|
||||
// input positions
|
||||
val ltx = tx.resolve(services, emptyList())
|
||||
val myKeys = services.keyManagementService.filterMyKeys(ltx.outputs.flatMap { it.data.participants.map { it.owningKey } })
|
||||
val ltx = tx.resolve(stateLoader, emptyList())
|
||||
val myKeys = keyManagementService.filterMyKeys(ltx.outputs.flatMap { it.data.participants.map { it.owningKey } })
|
||||
val (consumedStateAndRefs, producedStates) = ltx.inputs.
|
||||
zip(ltx.outputs).
|
||||
filter { (_, output) -> isRelevant(output.data, myKeys.toSet()) }.
|
||||
@ -246,7 +239,7 @@ class NodeVaultService(private val services: ServiceHub, private val hibernateCo
|
||||
|
||||
@Throws(StatesNotAvailableException::class)
|
||||
override fun softLockReserve(lockId: UUID, stateRefs: NonEmptySet<StateRef>) {
|
||||
val softLockTimestamp = services.clock.instant()
|
||||
val softLockTimestamp = clock.instant()
|
||||
try {
|
||||
val session = DatabaseTransactionManager.current().session
|
||||
val criteriaBuilder = session.criteriaBuilder
|
||||
@ -292,7 +285,7 @@ class NodeVaultService(private val services: ServiceHub, private val hibernateCo
|
||||
}
|
||||
|
||||
override fun softLockRelease(lockId: UUID, stateRefs: NonEmptySet<StateRef>?) {
|
||||
val softLockTimestamp = services.clock.instant()
|
||||
val softLockTimestamp = clock.instant()
|
||||
val session = DatabaseTransactionManager.current().session
|
||||
val criteriaBuilder = session.criteriaBuilder
|
||||
if (stateRefs == null) {
|
||||
@ -440,8 +433,8 @@ class NodeVaultService(private val services: ServiceHub, private val hibernateCo
|
||||
// pagination checks
|
||||
if (!paging.isDefault) {
|
||||
// pagination
|
||||
if (paging.pageNumber < DEFAULT_PAGE_NUM) throw VaultQueryException("Page specification: invalid page number ${paging.pageNumber} [page numbers start from ${DEFAULT_PAGE_NUM}]")
|
||||
if (paging.pageSize < 1) throw VaultQueryException("Page specification: invalid page size ${paging.pageSize} [must be a value between 1 and ${MAX_PAGE_SIZE}]")
|
||||
if (paging.pageNumber < DEFAULT_PAGE_NUM) throw VaultQueryException("Page specification: invalid page number ${paging.pageNumber} [page numbers start from $DEFAULT_PAGE_NUM]")
|
||||
if (paging.pageSize < 1) throw VaultQueryException("Page specification: invalid page size ${paging.pageSize} [must be a value between 1 and $MAX_PAGE_SIZE]")
|
||||
}
|
||||
|
||||
query.firstResult = (paging.pageNumber - 1) * paging.pageSize
|
||||
@ -452,7 +445,7 @@ class NodeVaultService(private val services: ServiceHub, private val hibernateCo
|
||||
|
||||
// final pagination check (fail-fast on too many results when no pagination specified)
|
||||
if (paging.isDefault && results.size > DEFAULT_PAGE_SIZE)
|
||||
throw VaultQueryException("Please specify a `PageSpecification` as there are more results [${results.size}] than the default page size [${DEFAULT_PAGE_SIZE}]")
|
||||
throw VaultQueryException("Please specify a `PageSpecification` as there are more results [${results.size}] than the default page size [$DEFAULT_PAGE_SIZE]")
|
||||
|
||||
val statesAndRefs: MutableList<StateAndRef<T>> = mutableListOf()
|
||||
val statesMeta: MutableList<Vault.StateMetadata> = mutableListOf()
|
||||
@ -495,8 +488,7 @@ class NodeVaultService(private val services: ServiceHub, private val hibernateCo
|
||||
override fun <T : ContractState> _trackBy(criteria: QueryCriteria, paging: PageSpecification, sorting: Sort, contractStateType: Class<out T>): DataFeed<Vault.Page<T>, Vault.Update<T>> {
|
||||
return mutex.locked {
|
||||
val snapshotResults = _queryBy(criteria, paging, sorting, contractStateType)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val updates = _updatesPublisher.bufferUntilSubscribed().filter { it.containsType(contractStateType, snapshotResults.stateTypes) } as Observable<Vault.Update<T>>
|
||||
val updates: Observable<Vault.Update<T>> = uncheckedCast(_updatesPublisher.bufferUntilSubscribed().filter { it.containsType(contractStateType, snapshotResults.stateTypes) })
|
||||
DataFeed(snapshotResults, updates)
|
||||
}
|
||||
}
|
||||
@ -522,8 +514,7 @@ class NodeVaultService(private val services: ServiceHub, private val hibernateCo
|
||||
|
||||
val contractInterfaceToConcreteTypes = mutableMapOf<String, MutableSet<String>>()
|
||||
distinctTypes.forEach { type ->
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val concreteType = Class.forName(type) as Class<ContractState>
|
||||
val concreteType: Class<ContractState> = uncheckedCast(Class.forName(type))
|
||||
val contractInterfaces = deriveContractInterfaces(concreteType)
|
||||
contractInterfaces.map {
|
||||
val contractInterface = contractInterfaceToConcreteTypes.getOrPut(it.name, { mutableSetOf() })
|
||||
@ -537,10 +528,9 @@ class NodeVaultService(private val services: ServiceHub, private val hibernateCo
|
||||
private fun <T : ContractState> deriveContractInterfaces(clazz: Class<T>): Set<Class<T>> {
|
||||
val myInterfaces: MutableSet<Class<T>> = mutableSetOf()
|
||||
clazz.interfaces.forEach {
|
||||
if (!it.equals(ContractState::class.java)) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
myInterfaces.add(it as Class<T>)
|
||||
myInterfaces.addAll(deriveContractInterfaces(it))
|
||||
if (it != ContractState::class.java) {
|
||||
myInterfaces.add(uncheckedCast(it))
|
||||
myInterfaces.addAll(deriveContractInterfaces(uncheckedCast(it)))
|
||||
}
|
||||
}
|
||||
return myInterfaces
|
||||
|
@ -9,12 +9,12 @@ import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.ServiceHub
|
||||
import net.corda.core.node.services.VaultService
|
||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.days
|
||||
import net.corda.node.internal.cordapp.CordappLoader
|
||||
import net.corda.node.internal.cordapp.CordappProviderImpl
|
||||
import net.corda.node.services.api.VaultServiceInternal
|
||||
import net.corda.node.services.identity.InMemoryIdentityService
|
||||
import net.corda.node.services.persistence.DBCheckpointStorage
|
||||
import net.corda.node.services.statemachine.FlowLogicRefFactoryImpl
|
||||
@ -96,7 +96,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
|
||||
overrideClock = testClock,
|
||||
keyManagement = kms,
|
||||
network = mockMessagingService), TestReference {
|
||||
override val vaultService: VaultService = NodeVaultService(this, database.hibernateConfig)
|
||||
override val vaultService: VaultServiceInternal = NodeVaultService(testClock, kms, stateLoader, database.hibernateConfig)
|
||||
override val testReference = this@NodeSchedulerServiceTest
|
||||
override val cordappProvider: CordappProviderImpl = CordappProviderImpl(CordappLoader.createWithTestPackages()).start(attachments)
|
||||
}
|
||||
|
@ -6,18 +6,14 @@ import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.SignatureMetadata
|
||||
import net.corda.core.crypto.TransactionSignature
|
||||
import net.corda.core.node.services.VaultService
|
||||
import net.corda.core.schemas.MappedSchema
|
||||
import net.corda.core.toFuture
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
import net.corda.finance.schemas.CashSchemaV1
|
||||
import net.corda.finance.schemas.SampleCashSchemaV2
|
||||
import net.corda.finance.schemas.SampleCashSchemaV3
|
||||
import net.corda.node.services.api.VaultServiceInternal
|
||||
import net.corda.node.services.schema.HibernateObserver
|
||||
import net.corda.node.services.schema.NodeSchemaService
|
||||
import net.corda.node.services.transactions.PersistentUniquenessProvider
|
||||
import net.corda.node.services.vault.NodeVaultService
|
||||
import net.corda.node.services.vault.VaultSchemaV1
|
||||
import net.corda.node.utilities.CordaPersistence
|
||||
import net.corda.node.utilities.configureDatabase
|
||||
import net.corda.testing.*
|
||||
@ -46,8 +42,8 @@ class DBTransactionStorageTests : TestDependencyInjectionBase() {
|
||||
database.transaction {
|
||||
|
||||
services = object : MockServices(BOB_KEY) {
|
||||
override val vaultService: VaultService get() {
|
||||
val vaultService = NodeVaultService(this, database.hibernateConfig)
|
||||
override val vaultService: VaultServiceInternal get() {
|
||||
val vaultService = NodeVaultService(clock, keyManagementService, stateLoader, database.hibernateConfig)
|
||||
hibernatePersister = HibernateObserver(vaultService.rawUpdates, database.hibernateConfig)
|
||||
return vaultService
|
||||
}
|
||||
@ -57,7 +53,7 @@ class DBTransactionStorageTests : TestDependencyInjectionBase() {
|
||||
validatedTransactions.addTransaction(stx)
|
||||
}
|
||||
// Refactored to use notifyAll() as we have no other unit test for that method with multiple transactions.
|
||||
(vaultService as NodeVaultService).notifyAll(txs.map { it.tx })
|
||||
vaultService.notifyAll(txs.map { it.tx })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ import net.corda.finance.schemas.SampleCashSchemaV3
|
||||
import net.corda.finance.utils.sumCash
|
||||
import net.corda.node.services.schema.HibernateObserver
|
||||
import net.corda.node.services.schema.NodeSchemaService
|
||||
import net.corda.node.services.vault.NodeVaultService
|
||||
import net.corda.node.services.vault.VaultSchemaV1
|
||||
import net.corda.node.utilities.CordaPersistence
|
||||
import net.corda.node.utilities.configureDatabase
|
||||
@ -82,14 +81,13 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
|
||||
database.transaction {
|
||||
hibernateConfig = database.hibernateConfig
|
||||
services = object : MockServices(BOB_KEY, BOC_KEY, DUMMY_NOTARY_KEY) {
|
||||
override val vaultService: VaultService = makeVaultService(database.hibernateConfig)
|
||||
|
||||
override val vaultService = makeVaultService(database.hibernateConfig)
|
||||
override fun recordTransactions(notifyVault: Boolean, txs: Iterable<SignedTransaction>) {
|
||||
for (stx in txs) {
|
||||
validatedTransactions.addTransaction(stx)
|
||||
}
|
||||
// Refactored to use notifyAll() as we have no other unit test for that method with multiple transactions.
|
||||
(vaultService as NodeVaultService).notifyAll(txs.map { it.tx })
|
||||
vaultService.notifyAll(txs.map { it.tx })
|
||||
}
|
||||
override fun jdbcSession() = database.createSession()
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ import kotlin.test.assertTrue
|
||||
class NodeVaultServiceTest : TestDependencyInjectionBase() {
|
||||
lateinit var services: MockServices
|
||||
lateinit var issuerServices: MockServices
|
||||
val vaultService: VaultService get() = services.vaultService
|
||||
val vaultService get() = services.vaultService as NodeVaultService
|
||||
lateinit var database: CordaPersistence
|
||||
|
||||
@Before
|
||||
@ -98,7 +98,7 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() {
|
||||
|
||||
val originalVault = vaultService
|
||||
val services2 = object : MockServices() {
|
||||
override val vaultService: NodeVaultService get() = originalVault as NodeVaultService
|
||||
override val vaultService: NodeVaultService get() = originalVault
|
||||
override fun recordTransactions(notifyVault: Boolean, txs: Iterable<SignedTransaction>) {
|
||||
for (stx in txs) {
|
||||
validatedTransactions.addTransaction(stx)
|
||||
@ -473,7 +473,7 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() {
|
||||
|
||||
@Test
|
||||
fun `is ownable state relevant`() {
|
||||
val service = (services.vaultService as NodeVaultService)
|
||||
val service = vaultService
|
||||
val amount = Amount(1000, Issued(BOC.ref(1), GBP))
|
||||
val wellKnownCash = Cash.State(amount, services.myInfo.chooseIdentity())
|
||||
val myKeys = services.keyManagementService.filterMyKeys(listOf(wellKnownCash.owner.owningKey))
|
||||
@ -494,7 +494,7 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() {
|
||||
|
||||
@Test
|
||||
fun `correct updates are generated for general transactions`() {
|
||||
val service = (services.vaultService as NodeVaultService)
|
||||
val service = vaultService
|
||||
val vaultSubscriber = TestSubscriber<Vault.Update<*>>().apply {
|
||||
service.updates.subscribe(this)
|
||||
}
|
||||
@ -527,7 +527,7 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() {
|
||||
|
||||
@Test
|
||||
fun `correct updates are generated when changing notaries`() {
|
||||
val service = (services.vaultService as NodeVaultService)
|
||||
val service = vaultService
|
||||
val notary = services.myInfo.chooseIdentity()
|
||||
|
||||
val vaultSubscriber = TestSubscriber<Vault.Update<*>>().apply {
|
||||
|
Reference in New Issue
Block a user