Removal of transaction contract state as BLOB in VaultStates table. (#2034)

* Removal of transaction contract state as BLOB in VaultStates table.
Transaction contract state now resolved using StateLoader (from DBTransactionStorage).

Fixed broken JUnits.

* Changes to address review comments by RP

Address logic error.

* Fixed failing JUnit (CashExitFlowTests.exit zero cash).

* Fix VaultQueryTests to respect transaction visibility boundaries.

* Adopt consistent use of "session" using DatabaseTransactionManager.

* Removed redundant transaction demarcation boundaries in Vault Query tests.
This commit is contained in:
josecoll 2017-11-15 19:28:04 +00:00 committed by GitHub
parent b423fea537
commit 5bdbd2457a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 300 additions and 414 deletions

View File

@ -31,6 +31,16 @@ interface StateLoader {
*/
@Throws(TransactionResolutionException::class)
fun loadState(stateRef: StateRef): TransactionState<*>
/**
* Given a [Set] of [StateRef]'s loads the referenced transaction and looks up the specified output [ContractState].
*
* @throws TransactionResolutionException if [stateRef] points to a non-existent transaction.
*/
// TODO: future implementation to use a Vault state ref -> contract state BLOB table and perform single query bulk load
// as the existing transaction store will become encrypted at some point
@Throws(TransactionResolutionException::class)
fun loadStates(stateRefs: Set<StateRef>): Set<StateAndRef<ContractState>>
}
/**

View File

@ -131,17 +131,19 @@ abstract class AbstractCashSelection {
stateAndRefs.clear()
var totalPennies = 0L
val stateRefs = mutableSetOf<StateRef>()
while (rs.next()) {
val txHash = SecureHash.parse(rs.getString(1))
val index = rs.getInt(2)
val stateRef = StateRef(txHash, index)
val state = rs.getBlob(3).deserialize<TransactionState<Cash.State>>(context = SerializationDefaults.STORAGE_CONTEXT)
val pennies = rs.getLong(4)
totalPennies = rs.getLong(5)
val rowLockId = rs.getString(6)
stateAndRefs.add(StateAndRef(state, stateRef))
log.trace { "ROW: $rowLockId ($lockId): $stateRef : $pennies ($totalPennies)" }
val pennies = rs.getLong(3)
totalPennies = rs.getLong(4)
val rowLockId = rs.getString(5)
stateRefs.add(StateRef(txHash, index))
log.trace { "ROW: $rowLockId ($lockId): ${StateRef(txHash, index)} : $pennies ($totalPennies)" }
}
if (stateRefs.isNotEmpty())
// TODO: future implementation to retrieve contract states from a Vault BLOB store
stateAndRefs.addAll(services.loadStates(stateRefs) as Collection<StateAndRef<Cash.State>>)
if (stateAndRefs.isNotEmpty() && totalPennies >= amount.quantity) {
// we should have a minimum number of states to satisfy our selection `amount` criteria

View File

@ -35,7 +35,7 @@ class CashSelectionH2Impl : AbstractCashSelection() {
connection.createStatement().execute("CALL SET(@t, 0);")
val selectJoin = """
SELECT vs.transaction_id, vs.output_index, vs.contract_state, ccs.pennies, SET(@t, ifnull(@t,0)+ccs.pennies) total_pennies, vs.lock_id
SELECT vs.transaction_id, vs.output_index, ccs.pennies, SET(@t, ifnull(@t,0)+ccs.pennies) total_pennies, vs.lock_id
FROM vault_states AS vs, contract_cash_states AS ccs
WHERE vs.transaction_id = ccs.transaction_id AND vs.output_index = ccs.output_index
AND vs.state_status = 0

View File

@ -32,10 +32,10 @@ class CashSelectionPostgreSQLImpl : AbstractCashSelection() {
// 3) Currently (version 9.6), FOR UPDATE cannot be specified with window functions
override fun executeQuery(connection: Connection, amount: Amount<Currency>, lockId: UUID, notary: Party?,
onlyFromIssuerParties: Set<AbstractParty>, withIssuerRefs: Set<OpaqueBytes>) : ResultSet {
val selectJoin = """SELECT nested.transaction_id, nested.output_index, nested.contract_state, nested.pennies,
val selectJoin = """SELECT nested.transaction_id, nested.output_index, nested.pennies,
nested.total+nested.pennies as total_pennies, nested.lock_id
FROM
(SELECT vs.transaction_id, vs.output_index, vs.contract_state, ccs.pennies,
(SELECT vs.transaction_id, vs.output_index, ccs.pennies,
coalesce((SUM(ccs.pennies) OVER (PARTITION BY 1 ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)), 0)
AS total, vs.lock_id
FROM vault_states AS vs, contract_cash_states AS ccs

View File

@ -1,8 +1,6 @@
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.contracts.*
import net.corda.core.flows.FlowLogic
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.node.NodeInfo
@ -37,4 +35,10 @@ class StateLoaderImpl(private val validatedTransactions: TransactionStorage) : S
val stx = validatedTransactions.getTransaction(stateRef.txhash) ?: throw TransactionResolutionException(stateRef.txhash)
return stx.resolveBaseTransaction(this).outputs[stateRef.index]
}
@Throws(TransactionResolutionException::class)
// TODO: future implementation to retrieve contract states from a Vault BLOB store
override fun loadStates(stateRefs: Set<StateRef>): Set<StateAndRef<ContractState>> {
return (stateRefs.map { StateAndRef(loadState(it), it) }).toSet()
}
}

View File

@ -8,16 +8,10 @@ import net.corda.core.internal.*
import net.corda.core.messaging.DataFeed
import net.corda.core.node.StateLoader
import net.corda.core.node.StatesToRecord
import net.corda.core.node.services.KeyManagementService
import net.corda.core.node.services.StatesNotAvailableException
import net.corda.core.node.services.Vault
import net.corda.core.node.services.VaultQueryException
import net.corda.core.node.services.*
import net.corda.core.node.services.vault.*
import net.corda.core.schemas.PersistentStateRef
import net.corda.core.serialization.SerializationDefaults.STORAGE_CONTEXT
import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize
import net.corda.core.transactions.CoreTransaction
import net.corda.core.transactions.NotaryChangeWireTransaction
import net.corda.core.transactions.WireTransaction
@ -89,7 +83,6 @@ class NodeVaultService(
val state = VaultSchemaV1.VaultStates(
notary = stateAndRef.value.state.notary,
contractStateClassName = stateAndRef.value.state.data.javaClass.name,
contractState = stateAndRef.value.state.serialize(context = STORAGE_CONTEXT).bytes,
stateStatus = Vault.StateStatus.UNCONSUMED,
recordedTime = clock.instant())
state.stateRef = PersistentStateRef(stateAndRef.key)
@ -169,7 +162,7 @@ class NodeVaultService(
return Vault.NoUpdate
}
return Vault.Update(consumedStates, ourNewStates.toHashSet())
return Vault.Update(consumedStates.toSet(), ourNewStates.toSet())
}
val netDelta = txns.fold(Vault.NoUpdate) { netDelta, txn -> netDelta + makeUpdate(txn) }
@ -207,28 +200,10 @@ class NodeVaultService(
processAndNotify(netDelta)
}
// TODO: replace this method in favour of a VaultQuery query
private fun loadStates(refs: Collection<StateRef>): HashSet<StateAndRef<ContractState>> {
val states = HashSet<StateAndRef<ContractState>>()
if (refs.isNotEmpty()) {
val session = currentDBSession()
val criteriaBuilder = session.criteriaBuilder
val criteriaQuery = criteriaBuilder.createQuery(VaultSchemaV1.VaultStates::class.java)
val vaultStates = criteriaQuery.from(VaultSchemaV1.VaultStates::class.java)
val statusPredicate = criteriaBuilder.equal(vaultStates.get<Vault.StateStatus>(VaultSchemaV1.VaultStates::stateStatus.name), Vault.StateStatus.UNCONSUMED)
val persistentStateRefs = refs.map(::PersistentStateRef)
val compositeKey = vaultStates.get<PersistentStateRef>(VaultSchemaV1.VaultStates::stateRef.name)
val stateRefsPredicate = criteriaBuilder.and(compositeKey.`in`(persistentStateRefs))
criteriaQuery.where(statusPredicate, stateRefsPredicate)
val results = session.createQuery(criteriaQuery).resultList
results.asSequence().forEach {
val txHash = SecureHash.parse(it.stateRef?.txId!!)
val index = it.stateRef?.index!!
val state = it.contractState.deserialize<TransactionState<ContractState>>(context = STORAGE_CONTEXT)
states.add(StateAndRef(state, StateRef(txHash, index)))
}
}
return states
private fun loadStates(refs: Collection<StateRef>): Collection<StateAndRef<ContractState>> {
return if (refs.isNotEmpty())
queryBy<ContractState>(QueryCriteria.VaultQueryCriteria(stateRefs = refs.toList())).states
else emptySet()
}
private fun processAndNotify(update: Vault.Update<ContractState>) {
@ -428,70 +403,70 @@ class NodeVaultService(
val session = getSession()
session.use {
val criteriaQuery = criteriaBuilder.createQuery(Tuple::class.java)
val queryRootVaultStates = criteriaQuery.from(VaultSchemaV1.VaultStates::class.java)
val criteriaQuery = criteriaBuilder.createQuery(Tuple::class.java)
val queryRootVaultStates = criteriaQuery.from(VaultSchemaV1.VaultStates::class.java)
// TODO: revisit (use single instance of parser for all queries)
val criteriaParser = HibernateQueryCriteriaParser(contractStateType, contractStateTypeMappings, criteriaBuilder, criteriaQuery, queryRootVaultStates)
// TODO: revisit (use single instance of parser for all queries)
val criteriaParser = HibernateQueryCriteriaParser(contractStateType, contractStateTypeMappings, criteriaBuilder, criteriaQuery, queryRootVaultStates)
try {
// parse criteria and build where predicates
criteriaParser.parse(criteria, sorting)
try {
// parse criteria and build where predicates
criteriaParser.parse(criteria, sorting)
// prepare query for execution
val query = session.createQuery(criteriaQuery)
// prepare query for execution
val query = session.createQuery(criteriaQuery)
// 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]")
}
query.firstResult = (paging.pageNumber - 1) * paging.pageSize
query.maxResults = paging.pageSize + 1 // detection too many results
// execution
val results = query.resultList
// 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]")
val statesAndRefs: MutableList<StateAndRef<T>> = mutableListOf()
val statesMeta: MutableList<Vault.StateMetadata> = mutableListOf()
val otherResults: MutableList<Any> = mutableListOf()
results.asSequence()
.forEachIndexed { index, result ->
if (result[0] is VaultSchemaV1.VaultStates) {
if (!paging.isDefault && index == paging.pageSize) // skip last result if paged
return@forEachIndexed
val vaultState = result[0] as VaultSchemaV1.VaultStates
val stateRef = StateRef(SecureHash.parse(vaultState.stateRef!!.txId!!), vaultState.stateRef!!.index!!)
val state = vaultState.contractState.deserialize<TransactionState<T>>(context = STORAGE_CONTEXT)
statesMeta.add(Vault.StateMetadata(stateRef,
vaultState.contractStateClassName,
vaultState.recordedTime,
vaultState.consumedTime,
vaultState.stateStatus,
vaultState.notary,
vaultState.lockId,
vaultState.lockUpdateTime))
statesAndRefs.add(StateAndRef(state, stateRef))
} else {
// TODO: improve typing of returned other results
log.debug { "OtherResults: ${Arrays.toString(result.toArray())}" }
otherResults.addAll(result.toArray().asList())
}
}
return Vault.Page(states = statesAndRefs, statesMetadata = statesMeta, stateTypes = criteriaParser.stateTypes, totalStatesAvailable = totalStates, otherResults = otherResults)
} catch (e: java.lang.Exception) {
log.error(e.message)
throw e.cause ?: e
// 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]")
}
query.firstResult = (paging.pageNumber - 1) * paging.pageSize
query.maxResults = paging.pageSize + 1 // detection too many results
// execution
val results = query.resultList
// 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]")
val statesAndRefs: MutableList<StateAndRef<T>> = mutableListOf()
val statesMeta: MutableList<Vault.StateMetadata> = mutableListOf()
val otherResults: MutableList<Any> = mutableListOf()
val stateRefs = mutableSetOf<StateRef>()
results.asSequence()
.forEachIndexed { index, result ->
if (result[0] is VaultSchemaV1.VaultStates) {
if (!paging.isDefault && index == paging.pageSize) // skip last result if paged
return@forEachIndexed
val vaultState = result[0] as VaultSchemaV1.VaultStates
val stateRef = StateRef(SecureHash.parse(vaultState.stateRef!!.txId!!), vaultState.stateRef!!.index!!)
stateRefs.add(stateRef)
statesMeta.add(Vault.StateMetadata(stateRef,
vaultState.contractStateClassName,
vaultState.recordedTime,
vaultState.consumedTime,
vaultState.stateStatus,
vaultState.notary,
vaultState.lockId,
vaultState.lockUpdateTime))
} else {
// TODO: improve typing of returned other results
log.debug { "OtherResults: ${Arrays.toString(result.toArray())}" }
otherResults.addAll(result.toArray().asList())
}
}
if (stateRefs.isNotEmpty())
statesAndRefs.addAll(stateLoader.loadStates(stateRefs) as Collection<StateAndRef<T>>)
return Vault.Page(states = statesAndRefs, statesMetadata = statesMeta, stateTypes = criteriaParser.stateTypes, totalStatesAvailable = totalStates, otherResults = otherResults)
} catch (e: java.lang.Exception) {
log.error(e.message)
throw e.cause ?: e
}
}
@ -504,11 +479,7 @@ class NodeVaultService(
}
}
private fun getSession(): Session {
return sessionFactory.withOptions().
connection(DatabaseTransactionManager.current().connection).
openSession()
}
private fun getSession() = DatabaseTransactionManager.currentOrNew().session
/**
* Derive list from existing vault states and then incrementally update using vault observables
@ -518,22 +489,21 @@ class NodeVaultService(
val vaultStates = criteria.from(VaultSchemaV1.VaultStates::class.java)
criteria.select(vaultStates.get("contractStateClassName")).distinct(true)
val session = getSession()
session.use {
val query = session.createQuery(criteria)
val results = query.resultList
val distinctTypes = results.map { it }
val contractInterfaceToConcreteTypes = mutableMapOf<String, MutableSet<String>>()
distinctTypes.forEach { type ->
val concreteType: Class<ContractState> = uncheckedCast(Class.forName(type))
val contractInterfaces = deriveContractInterfaces(concreteType)
contractInterfaces.map {
val contractInterface = contractInterfaceToConcreteTypes.getOrPut(it.name, { mutableSetOf() })
contractInterface.add(concreteType.name)
}
val query = session.createQuery(criteria)
val results = query.resultList
val distinctTypes = results.map { it }
val contractInterfaceToConcreteTypes = mutableMapOf<String, MutableSet<String>>()
distinctTypes.forEach { type ->
val concreteType: Class<ContractState> = uncheckedCast(Class.forName(type))
val contractInterfaces = deriveContractInterfaces(concreteType)
contractInterfaces.map {
val contractInterface = contractInterfaceToConcreteTypes.getOrPut(it.name, { mutableSetOf() })
contractInterface.add(concreteType.name)
}
return contractInterfaceToConcreteTypes
}
return contractInterfaceToConcreteTypes
}
private fun <T : ContractState> deriveContractInterfaces(clazz: Class<T>): Set<Class<T>> {

View File

@ -29,6 +29,9 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
@Table(name = "vault_states",
indexes = arrayOf(Index(name = "state_status_idx", columnList = "state_status")))
class VaultStates(
/** NOTE: serialized transaction state (including contract state) is now resolved from transaction store */
// TODO: create a distinct table to hold serialized state data (once DBTransactionStore is encrypted)
/** refers to the X500Name of the notary a state is attached to */
@Column(name = "notary_name")
var notary: Party,
@ -37,11 +40,6 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
@Column(name = "contract_state_class_name")
var contractStateClassName: String,
/** refers to serialized transaction Contract State */
@Lob
@Column(name = "contract_state")
var contractState: ByteArray,
/** state lifecycle: unconsumed, consumed */
@Column(name = "state_status")
var stateStatus: Vault.StateStatus,

View File

@ -139,7 +139,9 @@ class HibernateConfigurationTest {
// execute query
val queryResults = entityManager.createQuery(criteriaQuery).resultList
val coins = queryResults.map { it.contractState.deserialize<TransactionState<Cash.State>>(context = SerializationDefaults.STORAGE_CONTEXT).data }.sumCash()
val coins = queryResults.map {
(services.loadState(toStateRef(it.stateRef!!)) as TransactionState<Cash.State>).data
}.sumCash()
assertThat(coins.toDecimal() >= BigDecimal("50.00"))
}
@ -657,8 +659,7 @@ class HibernateConfigurationTest {
val queryResults = entityManager.createQuery(criteriaQuery).resultList
queryResults.forEach {
val contractState = it.contractState.deserialize<TransactionState<ContractState>>(context = SerializationDefaults.STORAGE_CONTEXT)
val cashState = contractState.data as Cash.State
val cashState = (services.loadState(toStateRef(it.stateRef!!)) as TransactionState<Cash.State>).data
println("${it.stateRef} with owner: ${cashState.owner.owningKey.toBase58String()}")
}
@ -742,8 +743,7 @@ class HibernateConfigurationTest {
// execute query
val queryResults = entityManager.createQuery(criteriaQuery).resultList
queryResults.forEach {
val contractState = it.contractState.deserialize<TransactionState<ContractState>>(context = SerializationDefaults.STORAGE_CONTEXT)
val cashState = contractState.data as Cash.State
val cashState = (services.loadState(toStateRef(it.stateRef!!)) as TransactionState<Cash.State>).data
println("${it.stateRef} with owner ${cashState.owner.owningKey.toBase58String()} and participants ${cashState.participants.map { it.owningKey.toBase58String() }}")
}
@ -880,4 +880,8 @@ class HibernateConfigurationTest {
Assert.assertEquals(cashStates.count(), count)
}
}
private fun toStateRef(pStateRef: PersistentStateRef): StateRef {
return StateRef(SecureHash.parse(pStateRef.txId!!), pStateRef.index!!)
}
}

View File

@ -5,7 +5,7 @@ import net.corda.core.contracts.Amount
import net.corda.core.contracts.Issued
import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.StateRef
import net.corda.core.crypto.generateKeyPair
import net.corda.core.crypto.*
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.Party
@ -517,22 +517,32 @@ class NodeVaultServiceTest {
val amount = Amount(1000, Issued(BOC.ref(1), GBP))
// Issue then move some cash
val issueTx = TransactionBuilder(identity.party).apply {
val builder = TransactionBuilder(identity.party).apply {
Cash().generateIssue(this, amount, anonymousIdentity.party.anonymise(), identity.party)
}.toWireTransaction(bocServices)
}
val issueTx = builder.toWireTransaction(bocServices)
val cashState = StateAndRef(issueTx.outputs.single(), StateRef(issueTx.id, 0))
// ensure transaction contract state is persisted in DBStorage
val signedIssuedTx = services.signInitialTransaction(builder)
services.validatedTransactions.addTransaction(signedIssuedTx)
database.transaction { service.notify(StatesToRecord.ONLY_RELEVANT, issueTx) }
val expectedIssueUpdate = Vault.Update(emptySet(), setOf(cashState), null)
database.transaction {
val moveTx = TransactionBuilder(services.myInfo.chooseIdentity()).apply {
val builder = TransactionBuilder(services.myInfo.chooseIdentity()).apply {
Cash.generateSpend(services, this, Amount(1000, GBP), thirdPartyIdentity)
}.toWireTransaction(services)
}
val moveTx = builder.toWireTransaction(services)
service.notify(StatesToRecord.ONLY_RELEVANT, moveTx)
}
val expectedMoveUpdate = Vault.Update(setOf(cashState), emptySet(), null)
// ensure transaction contract state is persisted in DBStorage
val signedMoveTx = services.signInitialTransaction(builder)
services.validatedTransactions.addTransaction(signedMoveTx)
val observedUpdates = vaultSubscriber.onNextEvents
assertEquals(observedUpdates, listOf(expectedIssueUpdate, expectedMoveUpdate))
}
@ -572,12 +582,20 @@ class NodeVaultServiceTest {
service.notifyAll(StatesToRecord.ONLY_RELEVANT, listOf(issueStx.tx, changeNotaryTx))
}
// ensure transaction contract state is persisted in DBStorage
services.validatedTransactions.addTransaction(SignedTransaction(changeNotaryTx, listOf(NullKeys.NULL_SIGNATURE)))
// Move cash
val moveTx = database.transaction {
val moveTxBuilder = database.transaction {
TransactionBuilder(newNotary).apply {
Cash.generateSpend(services, this, Amount(amount.quantity, GBP), anonymousIdentity, thirdPartyIdentity.party.anonymise())
}.toWireTransaction(services)
}
}
val moveTx = moveTxBuilder.toWireTransaction(services)
// ensure transaction contract state is persisted in DBStorage
val signedMoveTx = services.signInitialTransaction(moveTxBuilder)
services.validatedTransactions.addTransaction(signedMoveTx)
database.transaction {
service.notify(StatesToRecord.ONLY_RELEVANT, moveTx)
@ -609,6 +627,10 @@ class NodeVaultServiceTest {
vaultService.notify(StatesToRecord.ONLY_RELEVANT, wtx)
}
// ensure transaction contract state is persisted in DBStorage
val signedTxb = services.signInitialTransaction(txb)
services.validatedTransactions.addTransaction(signedTxb)
// Check that it was ignored as irrelevant.
assertEquals(currentCashStates, countCash())

View File

@ -95,18 +95,14 @@ class VaultQueryTests {
}
private fun setUpDb(_database: CordaPersistence, delay: Long = 0) {
_database.transaction {
// create new states
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 10, 10, Random(0L))
val linearStatesXYZ = services.fillWithSomeTestLinearStates(1, "XYZ")
val linearStatesJKL = services.fillWithSomeTestLinearStates(2, "JKL")
services.fillWithSomeTestLinearStates(3, "ABC")
val dealStates = services.fillWithSomeTestDeals(listOf("123", "456", "789"))
// Total unconsumed states = 10 + 1 + 2 + 3 + 3 = 19
sleep(delay)
// consume some states
@ -114,7 +110,6 @@ class VaultQueryTests {
services.consumeLinearStates(linearStatesJKL.states.toList(), DUMMY_NOTARY)
services.consumeDeals(dealStates.states.filter { it.state.data.linearId.externalId == "456" }, DUMMY_NOTARY)
services.consumeCash(50.DOLLARS, notary = DUMMY_NOTARY)
// Total unconsumed states = 4 + 3 + 2 + 1 (new cash change) = 10
// Total consumed states = 6 + 1 + 2 + 1 = 10
}
@ -145,8 +140,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
services.fillWithSomeTestLinearStates(10)
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
}
database.transaction {
// DOCSTART VaultQueryExample1
val result = vaultService.queryBy<ContractState>()
@ -172,8 +166,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
services.fillWithSomeTestLinearStates(10)
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
}
database.transaction {
val criteria = VaultQueryCriteria() // default is UNCONSUMED
val result = vaultService.queryBy<ContractState>(criteria)
@ -189,18 +182,15 @@ class VaultQueryTests {
services.fillWithSomeTestCash(25.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(25.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(25.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
val paging = PageSpecification(DEFAULT_PAGE_NUM, 10)
database.transaction {
val paging = PageSpecification(DEFAULT_PAGE_NUM, 10)
val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
val resultsBeforeConsume = vaultService.queryBy<ContractState>(criteria, paging)
assertThat(resultsBeforeConsume.states).hasSize(4)
assertThat(resultsBeforeConsume.totalStatesAvailable).isEqualTo(4)
}
database.transaction {
services.consumeCash(75.DOLLARS, notary = DUMMY_NOTARY)
}
database.transaction {
val consumedCriteria = VaultQueryCriteria(status = Vault.StateStatus.UNCONSUMED)
val resultsAfterConsume = vaultService.queryBy<ContractState>(consumedCriteria, paging)
assertThat(resultsAfterConsume.states).hasSize(1)
@ -214,8 +204,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
services.fillWithSomeTestLinearStates(10)
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
}
database.transaction {
val result = vaultService.queryBy<Cash.State>()
assertThat(result.states).hasSize(3)
@ -229,8 +218,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
services.fillWithSomeTestLinearStates(10)
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
}
database.transaction {
val criteria = VaultQueryCriteria() // default is UNCONSUMED
val result = vaultService.queryBy<Cash.State>(criteria)
@ -252,8 +240,7 @@ class VaultQueryTests {
val consumedStateRefs = spentStates.consumed.map { it.ref }.toList()
val producedStateRefs = spentStates.produced.map { it.ref }.toList()
stateRefs.addAll(consumedStateRefs.plus(producedStateRefs))
}
database.transaction {
val sortAttribute = SortAttribute.Standard(Sort.CommonStateAttribute.STATE_REF)
val criteria = VaultQueryCriteria()
val results = vaultService.queryBy<Cash.State>(criteria, Sort(setOf(Sort.SortColumn(sortAttribute, Sort.Direction.ASC))))
@ -280,8 +267,7 @@ class VaultQueryTests {
database.transaction {
services.consumeCash(10.DOLLARS, notary = DUMMY_NOTARY).consumed.forEach { consumed += it.ref.txhash }
services.consumeCash(10.DOLLARS, notary = DUMMY_NOTARY).consumed.forEach { consumed += it.ref.txhash }
}
database.transaction {
val sortAttributeTxnId = SortAttribute.Standard(Sort.CommonStateAttribute.STATE_REF_TXN_ID)
val sortAttributeIndex = SortAttribute.Standard(Sort.CommonStateAttribute.STATE_REF_INDEX)
val sortBy = Sort(setOf(Sort.SortColumn(sortAttributeTxnId, Sort.Direction.ASC),
@ -301,13 +287,11 @@ class VaultQueryTests {
@Test
fun `unconsumed states for state refs`() {
val stateRefs =
database.transaction {
services.fillWithSomeTestLinearStates(8)
val issuedStates = services.fillWithSomeTestLinearStates(2)
issuedStates.states.map { it.ref }.toList()
}
database.transaction {
services.fillWithSomeTestLinearStates(8)
val issuedStates = services.fillWithSomeTestLinearStates(2)
val stateRefs = issuedStates.states.map { it.ref }.toList()
// DOCSTART VaultQueryExample2
val sortAttribute = SortAttribute.Standard(Sort.CommonStateAttribute.STATE_REF_TXN_ID)
val criteria = VaultQueryCriteria(stateRefs = listOf(stateRefs.first(), stateRefs.last()))
@ -328,8 +312,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
services.fillWithSomeTestLinearStates(10)
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
}
database.transaction {
// default State.Status is UNCONSUMED
// DOCSTART VaultQueryExample3
val criteria = VaultQueryCriteria(contractStateTypes = setOf(Cash.State::class.java, DealState::class.java))
@ -350,8 +333,7 @@ class VaultQueryTests {
services.consumeLinearStates(linearStates.states.toList(), DUMMY_NOTARY)
services.consumeDeals(dealStates.states.filter { it.state.data.linearId.externalId == "456" }, DUMMY_NOTARY)
services.consumeCash(50.DOLLARS, notary = DUMMY_NOTARY)
}
database.transaction {
val criteria = VaultQueryCriteria(status = Vault.StateStatus.CONSUMED)
val results = vaultService.queryBy<ContractState>(criteria)
assertThat(results.states).hasSize(5)
@ -365,18 +347,15 @@ class VaultQueryTests {
services.fillWithSomeTestCash(25.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(25.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(25.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
val paging = PageSpecification(DEFAULT_PAGE_NUM, 10)
database.transaction {
val paging = PageSpecification(DEFAULT_PAGE_NUM, 10)
val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
val resultsBeforeConsume = vaultService.queryBy<ContractState>(criteria, paging)
assertThat(resultsBeforeConsume.states).hasSize(4)
assertThat(resultsBeforeConsume.totalStatesAvailable).isEqualTo(4)
}
database.transaction {
services.consumeCash(75.DOLLARS, notary = DUMMY_NOTARY)
}
database.transaction {
val consumedCriteria = VaultQueryCriteria(status = Vault.StateStatus.CONSUMED)
val resultsAfterConsume = vaultService.queryBy<ContractState>(consumedCriteria, paging)
assertThat(resultsAfterConsume.states).hasSize(3)
@ -395,8 +374,7 @@ class VaultQueryTests {
services.consumeLinearStates(linearStates.states.toList(), DUMMY_NOTARY)
services.consumeDeals(dealStates.states.filter { it.state.data.linearId.externalId == "456" }, DUMMY_NOTARY)
services.consumeCash(50.DOLLARS, notary = DUMMY_NOTARY) // generates a new change state!
}
database.transaction {
val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
val results = vaultService.queryBy<ContractState>(criteria)
assertThat(results.states).hasSize(17)
@ -407,18 +385,16 @@ class VaultQueryTests {
fun `all states with count`() {
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
val paging = PageSpecification(DEFAULT_PAGE_NUM, 10)
database.transaction {
val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
val paging = PageSpecification(DEFAULT_PAGE_NUM, 10)
val resultsBeforeConsume = vaultService.queryBy<ContractState>(criteria, paging)
assertThat(resultsBeforeConsume.states).hasSize(1)
assertThat(resultsBeforeConsume.totalStatesAvailable).isEqualTo(1)
}
database.transaction {
services.consumeCash(50.DOLLARS, notary = DUMMY_NOTARY) // consumed 100 (spent), produced 50 (change)
}
database.transaction {
val resultsAfterConsume = vaultService.queryBy<ContractState>(criteria, paging)
assertThat(resultsAfterConsume.states).hasSize(2)
assertThat(resultsAfterConsume.totalStatesAvailable).isEqualTo(2)
@ -431,8 +407,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, CASH_NOTARY, 3, 3, Random(0L))
services.fillWithSomeTestLinearStates(10)
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
}
database.transaction {
// DOCSTART VaultQueryExample4
val criteria = VaultQueryCriteria(notary = listOf(CASH_NOTARY))
val results = vaultService.queryBy<ContractState>(criteria)
@ -449,8 +424,7 @@ class VaultQueryTests {
services.fillWithSomeTestLinearStates(2, "TEST", participants = listOf(MEGA_CORP, MINI_CORP))
services.fillWithSomeTestDeals(listOf("456"), participants = listOf(MEGA_CORP, BIG_CORP))
services.fillWithSomeTestDeals(listOf("123", "789"), participants = listOf(BIG_CORP))
}
database.transaction {
val criteria = LinearStateQueryCriteria(participants = listOf(BIG_CORP))
val results = vaultService.queryBy<ContractState>(criteria)
assertThat(results.states).hasSize(3)
@ -465,8 +439,7 @@ class VaultQueryTests {
services.fillWithSomeTestLinearStates(2, "TEST", participants = listOf(MEGA_CORP, MINI_CORP))
services.fillWithSomeTestDeals(listOf("456"), participants = listOf(MEGA_CORP, BIG_CORP))
services.fillWithSomeTestDeals(listOf("123", "789"), participants = listOf(MEGA_CORP))
}
database.transaction {
// DOCSTART VaultQueryExample5
val criteria = LinearStateQueryCriteria(participants = listOf(BIG_CORP, MINI_CORP))
val results = vaultService.queryBy<ContractState>(criteria)
@ -478,17 +451,14 @@ class VaultQueryTests {
@Test
fun `unconsumed states with soft locking`() {
val (lockId1, lockId2) =
database.transaction {
val issuedStates = services.fillWithSomeTestCash(100.DOLLARS, notaryServices, CASH_NOTARY, 10, 10, Random(0L)).states.toList()
vaultService.softLockReserve(UUID.randomUUID(), NonEmptySet.of(issuedStates[1].ref, issuedStates[2].ref, issuedStates[3].ref))
val lockId1 = UUID.randomUUID()
vaultService.softLockReserve(lockId1, NonEmptySet.of(issuedStates[4].ref, issuedStates[5].ref))
val lockId2 = UUID.randomUUID()
vaultService.softLockReserve(lockId2, NonEmptySet.of(issuedStates[6].ref))
Pair(lockId1, lockId2)
}
database.transaction {
val issuedStates = services.fillWithSomeTestCash(100.DOLLARS, notaryServices, CASH_NOTARY, 10, 10, Random(0L)).states.toList()
vaultService.softLockReserve(UUID.randomUUID(), NonEmptySet.of(issuedStates[1].ref, issuedStates[2].ref, issuedStates[3].ref))
val lockId1 = UUID.randomUUID()
vaultService.softLockReserve(lockId1, NonEmptySet.of(issuedStates[4].ref, issuedStates[5].ref))
val lockId2 = UUID.randomUUID()
vaultService.softLockReserve(lockId2, NonEmptySet.of(issuedStates[6].ref))
// excluding soft locked states
val criteriaExclusive = VaultQueryCriteria(softLockingCondition = SoftLockingCondition(SoftLockingType.UNLOCKED_ONLY))
val resultsExclusive = vaultService.queryBy<ContractState>(criteriaExclusive)
@ -528,8 +498,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
val logicalExpression = builder { CashSchemaV1.PersistentCashState::currency.equal(GBP.currencyCode) }
val criteria = VaultCustomQueryCriteria(logicalExpression)
val results = vaultService.queryBy<Cash.State>(criteria)
@ -543,8 +512,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
val logicalExpression = builder { CashSchemaV1.PersistentCashState::currency.notEqual(GBP.currencyCode) }
val criteria = VaultCustomQueryCriteria(logicalExpression)
val results = vaultService.queryBy<Cash.State>(criteria)
@ -558,8 +526,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(1.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(10.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
val logicalExpression = builder { CashSchemaV1.PersistentCashState::pennies.greaterThan(1000L) }
val criteria = VaultCustomQueryCriteria(logicalExpression)
val results = vaultService.queryBy<Cash.State>(criteria)
@ -573,8 +540,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(1.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(10.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
val logicalExpression = builder { CashSchemaV1.PersistentCashState::pennies.greaterThanOrEqual(1000L) }
val criteria = VaultCustomQueryCriteria(logicalExpression)
val results = vaultService.queryBy<Cash.State>(criteria)
@ -588,8 +554,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(1.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(10.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
val logicalExpression = builder { CashSchemaV1.PersistentCashState::pennies.lessThan(1000L) }
val criteria = VaultCustomQueryCriteria(logicalExpression)
val results = vaultService.queryBy<Cash.State>(criteria)
@ -603,8 +568,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(1.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(10.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
val logicalExpression = builder { CashSchemaV1.PersistentCashState::pennies.lessThanOrEqual(1000L) }
val criteria = VaultCustomQueryCriteria(logicalExpression)
val results = vaultService.queryBy<Cash.State>(criteria)
@ -618,8 +582,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(1.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(10.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
val logicalExpression = builder { CashSchemaV1.PersistentCashState::pennies.between(500L, 1500L) }
val criteria = VaultCustomQueryCriteria(logicalExpression)
val results = vaultService.queryBy<Cash.State>(criteria)
@ -633,8 +596,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
val currencies = listOf(CHF.currencyCode, GBP.currencyCode)
val logicalExpression = builder { CashSchemaV1.PersistentCashState::currency.`in`(currencies) }
val criteria = VaultCustomQueryCriteria(logicalExpression)
@ -649,8 +611,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
val currencies = listOf(CHF.currencyCode, GBP.currencyCode)
val logicalExpression = builder { CashSchemaV1.PersistentCashState::currency.notIn(currencies) }
val criteria = VaultCustomQueryCriteria(logicalExpression)
@ -665,8 +626,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
val logicalExpression = builder { CashSchemaV1.PersistentCashState::currency.like("%BP") } // GPB
val criteria = VaultCustomQueryCriteria(logicalExpression)
val results = vaultService.queryBy<Cash.State>(criteria)
@ -680,8 +640,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
val logicalExpression = builder { CashSchemaV1.PersistentCashState::currency.notLike("%BP") } // GPB
val criteria = VaultCustomQueryCriteria(logicalExpression)
val results = vaultService.queryBy<Cash.State>(criteria)
@ -695,8 +654,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
val logicalExpression = builder { CashSchemaV1.PersistentCashState::issuerPartyHash.isNull() }
val criteria = VaultCustomQueryCriteria(logicalExpression)
val results = vaultService.queryBy<Cash.State>(criteria)
@ -710,8 +668,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
val logicalExpression = builder { CashSchemaV1.PersistentCashState::issuerPartyHash.notNull() }
val criteria = VaultCustomQueryCriteria(logicalExpression)
val results = vaultService.queryBy<Cash.State>(criteria)
@ -727,8 +684,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(300.DOLLARS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
services.fillWithSomeTestCash(400.POUNDS, notaryServices, DUMMY_NOTARY, 4, 4, Random(0L))
services.fillWithSomeTestCash(500.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 5, 5, Random(0L))
}
database.transaction {
// DOCSTART VaultQueryExample21
val sum = builder { CashSchemaV1.PersistentCashState::pennies.sum() }
val sumCriteria = VaultCustomQueryCriteria(sum)
@ -769,8 +725,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(300.DOLLARS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
services.fillWithSomeTestCash(400.POUNDS, notaryServices, DUMMY_NOTARY, 4, 4, Random(0L))
services.fillWithSomeTestCash(500.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 5, 5, Random(0L))
}
database.transaction {
// DOCSTART VaultQueryExample22
val sum = builder { CashSchemaV1.PersistentCashState::pennies.sum(groupByColumns = listOf(CashSchemaV1.PersistentCashState::currency)) }
val sumCriteria = VaultCustomQueryCriteria(sum)
@ -821,8 +776,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(200.DOLLARS, notaryServices, DUMMY_NOTARY, 2, 2, Random(0L), issuedBy = BOC.ref(1))
services.fillWithSomeTestCash(300.POUNDS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L), issuedBy = DUMMY_CASH_ISSUER)
services.fillWithSomeTestCash(400.POUNDS, notaryServices, DUMMY_NOTARY, 4, 4, Random(0L), issuedBy = BOC.ref(2))
}
database.transaction {
// DOCSTART VaultQueryExample23
val sum = builder {
CashSchemaV1.PersistentCashState::pennies.sum(groupByColumns = listOf(CashSchemaV1.PersistentCashState::issuerPartyHash,
@ -859,8 +813,7 @@ class VaultQueryTests {
services.fillWithSomeTestLinearStates(2, "JKL")
services.fillWithSomeTestLinearStates(3, "ABC")
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
}
database.transaction {
// count fungible assets
val count = builder { VaultSchemaV1.VaultStates::recordedTime.count() }
val countCriteria = QueryCriteria.VaultCustomQueryCriteria(count)
@ -879,18 +832,16 @@ class VaultQueryTests {
@Test
fun `aggregate functions count by contract type and state status`() {
val (linearStatesJKL, linearStatesXYZ, dealStates) =
database.transaction {
// create new states
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 10, 10, Random(0L))
val linearStatesXYZ = services.fillWithSomeTestLinearStates(1, "XYZ")
val linearStatesJKL = services.fillWithSomeTestLinearStates(2, "JKL")
services.fillWithSomeTestLinearStates(3, "ABC")
val dealStates = services.fillWithSomeTestDeals(listOf("123", "456", "789"))
Triple(linearStatesJKL, linearStatesXYZ, dealStates)
}
val count = builder { VaultSchemaV1.VaultStates::recordedTime.count() }
database.transaction {
// create new states
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 10, 10, Random(0L))
val linearStatesXYZ = services.fillWithSomeTestLinearStates(1, "XYZ")
val linearStatesJKL = services.fillWithSomeTestLinearStates(2, "JKL")
services.fillWithSomeTestLinearStates(3, "ABC")
val dealStates = services.fillWithSomeTestDeals(listOf("123", "456", "789"))
val count = builder { VaultSchemaV1.VaultStates::recordedTime.count() }
// count fungible assets
val countCriteria = QueryCriteria.VaultCustomQueryCriteria(count, Vault.StateStatus.ALL)
val fungibleStateCount = vaultService.queryBy<FungibleAsset<*>>(countCriteria).otherResults.single() as Long
@ -903,18 +854,15 @@ class VaultQueryTests {
// count deal states
val dealStateCount = vaultService.queryBy<DealState>(countCriteria).otherResults.single() as Long
assertThat(dealStateCount).isEqualTo(3L)
}
val cashUpdates =
database.transaction {
// consume some states
services.consumeLinearStates(linearStatesXYZ.states.toList(), DUMMY_NOTARY)
services.consumeLinearStates(linearStatesJKL.states.toList(), DUMMY_NOTARY)
services.consumeDeals(dealStates.states.filter { it.state.data.linearId.externalId == "456" }, DUMMY_NOTARY)
services.consumeCash(50.DOLLARS, notary = DUMMY_NOTARY)
// UNCONSUMED states (default)
}
database.transaction {
// consume some states
services.consumeLinearStates(linearStatesXYZ.states.toList(), DUMMY_NOTARY)
services.consumeLinearStates(linearStatesJKL.states.toList(), DUMMY_NOTARY)
services.consumeDeals(dealStates.states.filter { it.state.data.linearId.externalId == "456" }, DUMMY_NOTARY)
val cashUpdates = services.consumeCash(50.DOLLARS, notary = DUMMY_NOTARY)
// UNCONSUMED states (default)
// count fungible assets
val countCriteriaUnconsumed = QueryCriteria.VaultCustomQueryCriteria(count, Vault.StateStatus.UNCONSUMED)
val fungibleStateCountUnconsumed = vaultService.queryBy<FungibleAsset<*>>(countCriteriaUnconsumed).otherResults.single() as Long
@ -951,8 +899,7 @@ class VaultQueryTests {
fun `unconsumed states recorded between two time intervals`() {
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, CASH_NOTARY, 3, 3, Random(0L))
}
database.transaction {
// DOCSTART VaultQueryExample6
val start = TODAY
val end = TODAY.plus(30, ChronoUnit.DAYS)
@ -982,8 +929,7 @@ class VaultQueryTests {
}
database.transaction {
services.consumeCash(100.DOLLARS, notary = DUMMY_NOTARY)
}
database.transaction {
val asOfDateTime = TODAY
val consumedAfterExpression = TimeCondition(
QueryCriteria.TimeInstantType.CONSUMED, ColumnPredicate.BinaryComparison(BinaryComparisonOperator.GREATER_THAN_OR_EQUAL, asOfDateTime))
@ -1000,8 +946,7 @@ class VaultQueryTests {
fun `all states with paging specification - first page`() {
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 100, 100, Random(0L))
}
database.transaction {
// DOCSTART VaultQueryExample7
val pagingSpec = PageSpecification(DEFAULT_PAGE_NUM, 10)
val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
@ -1017,8 +962,7 @@ class VaultQueryTests {
fun `all states with paging specification - last`() {
database.transaction {
services.fillWithSomeTestCash(95.DOLLARS, notaryServices, DUMMY_NOTARY, 95, 95, Random(0L))
}
database.transaction {
// Last page implies we need to perform a row count for the Query first,
// and then re-query for a given offset defined by (count - pageSize)
val pagingSpec = PageSpecification(10, 10)
@ -1038,8 +982,7 @@ class VaultQueryTests {
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 100, 100, Random(0L))
}
database.transaction {
val pagingSpec = PageSpecification(0, 10)
val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
@ -1055,8 +998,7 @@ class VaultQueryTests {
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 100, 100, Random(0L))
}
database.transaction {
@Suppress("EXPECTED_CONDITION")
val pagingSpec = PageSpecification(DEFAULT_PAGE_NUM, @Suppress("INTEGER_OVERFLOW") MAX_PAGE_SIZE + 1) // overflow = -2147483648
val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
@ -1072,8 +1014,7 @@ class VaultQueryTests {
database.transaction {
services.fillWithSomeTestCash(201.DOLLARS, notaryServices, DUMMY_NOTARY, 201, 201, Random(0L))
}
database.transaction {
val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
vaultService.queryBy<ContractState>(criteria)
}
@ -1114,8 +1055,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
services.fillWithSomeTestCommodity(Amount(100, Commodity.getInstance("FCOJ")!!), notaryServices)
services.fillWithSomeTestLinearStates(10)
}
database.transaction {
val results = vaultService.queryBy<FungibleAsset<*>>()
assertThat(results.states).hasSize(4)
}
@ -1128,12 +1068,10 @@ class VaultQueryTests {
}
database.transaction {
services.consumeCash(50.DOLLARS, notary = DUMMY_NOTARY)
}
database.transaction {
services.fillWithSomeTestCommodity(Amount(100, Commodity.getInstance("FCOJ")!!), notaryServices)
services.fillWithSomeTestLinearStates(10)
}
database.transaction {
val criteria = VaultQueryCriteria(status = Vault.StateStatus.CONSUMED)
val results = vaultService.queryBy<FungibleAsset<*>>(criteria)
assertThat(results.states).hasSize(2)
@ -1145,8 +1083,7 @@ class VaultQueryTests {
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
services.fillWithSomeTestLinearStates(10)
}
database.transaction {
val results = vaultService.queryBy<Cash.State>()
assertThat(results.states).hasSize(3)
}
@ -1159,9 +1096,7 @@ class VaultQueryTests {
}
database.transaction {
services.consumeCash(50.DOLLARS, notary = DUMMY_NOTARY)
}
// should now have x2 CONSUMED + x2 UNCONSUMED (one spent + one change)
database.transaction {
// should now have x2 CONSUMED + x2 UNCONSUMED (one spent + one change)
val results = vaultService.queryBy<Cash.State>(FungibleAssetQueryCriteria())
assertThat(results.statesMetadata).hasSize(2)
assertThat(results.states).hasSize(2)
@ -1175,15 +1110,9 @@ class VaultQueryTests {
}
database.transaction {
services.consumeCash(50.DOLLARS, notary = DUMMY_NOTARY)
}
val linearStates =
database.transaction {
services.fillWithSomeTestLinearStates(10)
}
database.transaction {
val linearStates = services.fillWithSomeTestLinearStates(10)
services.consumeLinearStates(linearStates.states.toList(), DUMMY_NOTARY)
}
database.transaction {
val criteria = VaultQueryCriteria(status = Vault.StateStatus.CONSUMED)
val results = vaultService.queryBy<Cash.State>(criteria)
assertThat(results.states).hasSize(2)
@ -1196,8 +1125,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
services.fillWithSomeTestLinearStates(10)
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
}
database.transaction {
val results = vaultService.queryBy<LinearState>()
assertThat(results.states).hasSize(13)
}
@ -1214,8 +1142,7 @@ class VaultQueryTests {
services.consumeLinearStates(linearStates.states.toList(), DUMMY_NOTARY)
services.consumeDeals(dealStates.states.filter { it.state.data.linearId.externalId == "456" }, DUMMY_NOTARY)
services.consumeCash(50.DOLLARS, notary = DUMMY_NOTARY)
}
database.transaction {
val criteria = VaultQueryCriteria(status = Vault.StateStatus.CONSUMED)
val results = vaultService.queryBy<LinearState>(criteria)
assertThat(results.states).hasSize(3)
@ -1226,11 +1153,9 @@ class VaultQueryTests {
@Test
fun `unconsumed linear heads for linearId without external Id`() {
val issuedStates =
database.transaction {
services.fillWithSomeTestLinearStates(10)
}
database.transaction {
val issuedStates = services.fillWithSomeTestLinearStates(10)
// DOCSTART VaultQueryExample8
val linearIds = issuedStates.states.map { it.state.data.linearId }.toList()
val criteria = LinearStateQueryCriteria(linearId = listOf(linearIds.first(), linearIds.last()))
@ -1242,14 +1167,11 @@ class VaultQueryTests {
@Test
fun `unconsumed linear heads by linearId`() {
val (linearState1, linearState3) =
database.transaction {
val linearState1 = services.fillWithSomeTestLinearStates(1, "ID1")
services.fillWithSomeTestLinearStates(1, "ID2")
val linearState3 = services.fillWithSomeTestLinearStates(1, "ID3")
Pair(linearState1, linearState3)
}
database.transaction {
val linearState1 = services.fillWithSomeTestLinearStates(1, "ID1")
services.fillWithSomeTestLinearStates(1, "ID2")
val linearState3 = services.fillWithSomeTestLinearStates(1, "ID3")
val linearIds = listOf(linearState1.states.first().state.data.linearId, linearState3.states.first().state.data.linearId)
val criteria = LinearStateQueryCriteria(linearId = linearIds)
val results = vaultService.queryBy<LinearState>(criteria)
@ -1259,14 +1181,11 @@ class VaultQueryTests {
@Test
fun `unconsumed linear heads for linearId by external Id`() {
val (linearState1, linearState3) =
database.transaction {
val linearState1 = services.fillWithSomeTestLinearStates(1, "ID1")
services.fillWithSomeTestLinearStates(1, "ID2")
val linearState3 = services.fillWithSomeTestLinearStates(1, "ID3")
Pair(linearState1, linearState3)
}
database.transaction {
val linearState1 = services.fillWithSomeTestLinearStates(1, "ID1")
services.fillWithSomeTestLinearStates(1, "ID2")
val linearState3 = services.fillWithSomeTestLinearStates(1, "ID3")
val externalIds = listOf(linearState1.states.first().state.data.linearId.externalId!!, linearState3.states.first().state.data.linearId.externalId!!)
val criteria = LinearStateQueryCriteria(externalId = externalIds)
val results = vaultService.queryBy<LinearState>(criteria)
@ -1276,16 +1195,14 @@ class VaultQueryTests {
@Test
fun `all linear states for a given linear id`() {
val linearId =
database.transaction {
val txns = services.fillWithSomeTestLinearStates(1, "TEST")
val linearState = txns.states.first()
services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
linearState.state.data.linearId
}
database.transaction {
val txns = services.fillWithSomeTestLinearStates(1, "TEST")
val linearState = txns.states.first()
services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
val linearId = linearState.state.data.linearId
// should now have 1 UNCONSUMED & 3 CONSUMED state refs for Linear State with "TEST"
// DOCSTART VaultQueryExample9
val linearStateCriteria = LinearStateQueryCriteria(linearId = listOf(linearId), status = Vault.StateStatus.ALL)
@ -1298,16 +1215,13 @@ class VaultQueryTests {
@Test
fun `all linear states for a given id sorted by uuid`() {
val linearStates =
database.transaction {
val txns = services.fillWithSomeTestLinearStates(2, "TEST")
val linearStates = txns.states.toList()
services.evolveLinearStates(linearStates, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearStates(linearStates, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearStates(linearStates, DUMMY_NOTARY) // consume current and produce new state reference
linearStates
}
database.transaction {
val txns = services.fillWithSomeTestLinearStates(2, "TEST")
val linearStates = txns.states.toList()
services.evolveLinearStates(linearStates, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearStates(linearStates, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearStates(linearStates, DUMMY_NOTARY) // consume current and produce new state reference
// should now have 1 UNCONSUMED & 3 CONSUMED state refs for Linear State with "TEST"
val linearStateCriteria = LinearStateQueryCriteria(uuid = linearStates.map { it.state.data.linearId.id }, status = Vault.StateStatus.ALL)
val vaultCriteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
@ -1325,8 +1239,7 @@ class VaultQueryTests {
services.fillWithSomeTestLinearStates(1, externalId = "111")
services.fillWithSomeTestLinearStates(2, externalId = "222")
services.fillWithSomeTestLinearStates(3, externalId = "333")
}
database.transaction {
val vaultCriteria = VaultQueryCriteria()
val sorting = Sort(setOf(Sort.SortColumn(SortAttribute.Standard(Sort.LinearStateAttribute.EXTERNAL_ID), Sort.Direction.DESC)))
@ -1338,13 +1251,11 @@ class VaultQueryTests {
@Test
fun `unconsumed deal states sorted`() {
val uid =
database.transaction {
val linearStates = services.fillWithSomeTestLinearStates(10)
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
linearStates.states.first().state.data.linearId.id
}
database.transaction {
val linearStates = services.fillWithSomeTestLinearStates(10)
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
val uid = linearStates.states.first().state.data.linearId.id
val linearStateCriteria = LinearStateQueryCriteria(uuid = listOf(uid))
val dealStateCriteria = LinearStateQueryCriteria(externalId = listOf("123", "456", "789"))
val compositeCriteria = linearStateCriteria or dealStateCriteria
@ -1363,8 +1274,7 @@ class VaultQueryTests {
services.fillWithSomeTestLinearStates(1, linearString = "111")
services.fillWithSomeTestLinearStates(2, linearString = "222")
services.fillWithSomeTestLinearStates(3, linearString = "333")
}
database.transaction {
val vaultCriteria = VaultQueryCriteria()
val sorting = Sort(setOf(Sort.SortColumn(SortAttribute.Custom(DummyLinearStateSchemaV1.PersistentDummyLinearState::class.java, "linearString"), Sort.Direction.DESC)))
@ -1376,16 +1286,15 @@ class VaultQueryTests {
@Test
fun `return consumed linear states for a given linear id`() {
val txns =
database.transaction {
val txns = services.fillWithSomeTestLinearStates(1, "TEST")
val linearState = txns.states.first()
val linearState2 = services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
val linearState3 = services.evolveLinearState(linearState2, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearState(linearState3, DUMMY_NOTARY) // consume current and produce new state reference
txns
}
database.transaction {
val txns = services.fillWithSomeTestLinearStates(1, "TEST")
val linearState = txns.states.first()
val linearState2 =services.evolveLinearState(linearState, DUMMY_NOTARY) // consume current and produce new state reference
val linearState3 = services.evolveLinearState(linearState2, DUMMY_NOTARY) // consume current and produce new state reference
services.evolveLinearState(linearState3, DUMMY_NOTARY) // consume current and produce new state reference
// should now have 1 UNCONSUMED & 3 CONSUMED state refs for Linear State with "TEST"
val linearStateCriteria = LinearStateQueryCriteria(linearId = txns.states.map { it.state.data.linearId }, status = Vault.StateStatus.CONSUMED)
val vaultCriteria = VaultQueryCriteria(status = Vault.StateStatus.CONSUMED)
@ -1402,8 +1311,7 @@ class VaultQueryTests {
fun `unconsumed deals`() {
database.transaction {
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
}
database.transaction {
val results = vaultService.queryBy<DealState>()
assertThat(results.states).hasSize(3)
}
@ -1413,8 +1321,7 @@ class VaultQueryTests {
fun `unconsumed deals for ref`() {
database.transaction {
services.fillWithSomeTestDeals(listOf("123", "456", "789"))
}
database.transaction {
// DOCSTART VaultQueryExample10
val criteria = LinearStateQueryCriteria(externalId = listOf("456", "789"))
val results = vaultService.queryBy<DealState>(criteria)
@ -1430,8 +1337,7 @@ class VaultQueryTests {
services.fillWithSomeTestLinearStates(2, "TEST")
services.fillWithSomeTestDeals(listOf("456"))
services.fillWithSomeTestDeals(listOf("123", "789"))
}
database.transaction {
val all = vaultService.queryBy<DealState>()
all.states.forEach { println(it.state) }
@ -1448,8 +1354,7 @@ class VaultQueryTests {
services.fillWithSomeTestLinearStates(2, "TEST")
services.fillWithSomeTestDeals(listOf("456"), parties)
services.fillWithSomeTestDeals(listOf("123", "789"))
}
database.transaction {
// DOCSTART VaultQueryExample11
val criteria = LinearStateQueryCriteria(participants = parties)
val results = vaultService.queryBy<DealState>(criteria)
@ -1470,8 +1375,6 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = BOC.ref(1))
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = BOC.ref(2))
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = BOC.ref(3))
}
database.transaction {
val criteria = FungibleAssetQueryCriteria(issuer = listOf(BOC),
issuerRef = listOf(BOC.ref(1).reference, BOC.ref(2).reference))
val results = vaultService.queryBy<FungibleAsset<*>>(criteria)
@ -1493,12 +1396,12 @@ class VaultQueryTests {
val chfCashIssuerKey = entropyToKeyPair(BigInteger.valueOf(1003))
val chfCashIssuer = Party(CordaX500Name(organisation = "Swiss Francs Cash Issuer", locality = "Zurich", country = "CH"), chfCashIssuerKey.public).ref(1)
val chfCashIssuerServices = MockServices(cordappPackages, chfCashIssuerKey)
database.transaction {
services.fillWithSomeTestCash(100.POUNDS, gbpCashIssuerServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (gbpCashIssuer))
services.fillWithSomeTestCash(100.DOLLARS, usdCashIssuerServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (usdCashIssuer))
services.fillWithSomeTestCash(100.SWISS_FRANCS, chfCashIssuerServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (chfCashIssuer))
}
database.transaction {
val criteria = FungibleAssetQueryCriteria(issuer = listOf(gbpCashIssuer.party, usdCashIssuer.party))
val results = vaultService.queryBy<FungibleAsset<*>>(criteria)
assertThat(results.states).hasSize(2)
@ -1511,8 +1414,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = BOC.ref(1))
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L),
issuedBy = MEGA_CORP.ref(0), ownedBy = (MINI_CORP))
}
database.transaction {
val criteria = FungibleAssetQueryCriteria(owner = listOf(MEGA_CORP))
val results = vaultService.queryBy<FungibleAsset<*>>(criteria)
assertThat(results.states).hasSize(1) // can only be 1 owner of a node (MEGA_CORP in this MockServices setup)
@ -1527,8 +1429,7 @@ class VaultQueryTests {
issuedBy = MEGA_CORP.ref(0), ownedBy = (MEGA_CORP))
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L),
issuedBy = BOC.ref(0), ownedBy = (MINI_CORP)) // irrelevant to this vault
}
database.transaction {
// DOCSTART VaultQueryExample5.2
val criteria = FungibleAssetQueryCriteria(owner = listOf(MEGA_CORP, BOC))
val results = vaultService.queryBy<ContractState>(criteria)
@ -1546,8 +1447,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
}
database.transaction {
// DOCSTART VaultQueryExample12
val ccyIndex = builder { CashSchemaV1.PersistentCashState::currency.equal(USD.currencyCode) }
val criteria = VaultCustomQueryCriteria(ccyIndex)
@ -1563,8 +1463,7 @@ class VaultQueryTests {
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(200.DOLLARS, notaryServices, DUMMY_NOTARY, 2, 2, Random(0L))
}
database.transaction {
val sum = builder { CashSchemaV1.PersistentCashState::pennies.sum(groupByColumns = listOf(CashSchemaV1.PersistentCashState::currency)) }
val sumCriteria = VaultCustomQueryCriteria(sum)
@ -1588,8 +1487,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(400.POUNDS, notaryServices, DUMMY_NOTARY, 4, 4, Random(0L))
services.fillWithSomeTestCash(500.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 5, 5, Random(0L))
services.fillWithSomeTestCash(600.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 6, 6, Random(0L))
}
database.transaction {
val ccyIndex = builder { CashSchemaV1.PersistentCashState::pennies.sum(groupByColumns = listOf(CashSchemaV1.PersistentCashState::currency)) }
val criteria = VaultCustomQueryCriteria(ccyIndex)
val results = vaultService.queryBy<FungibleAsset<*>>(criteria)
@ -1611,8 +1509,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(25.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(50.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 3, 3, Random(0L))
}
database.transaction {
// DOCSTART VaultQueryExample13
val fungibleAssetCriteria = FungibleAssetQueryCriteria(quantity = builder { greaterThan(2500L) })
val results = vaultService.queryBy<Cash.State>(fungibleAssetCriteria)
@ -1629,8 +1526,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (DUMMY_CASH_ISSUER))
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L), issuedBy = (BOC.ref(1)))
}
database.transaction {
// DOCSTART VaultQueryExample14
val criteria = FungibleAssetQueryCriteria(issuer = listOf(BOC))
val results = vaultService.queryBy<FungibleAsset<*>>(criteria)
@ -1647,8 +1543,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(50.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
val ccyIndex = builder { CashSchemaV1.PersistentCashState::currency.equal(GBP.currencyCode) }
val customCriteria = VaultCustomQueryCriteria(ccyIndex)
val fungibleAssetCriteria = FungibleAssetQueryCriteria(quantity = builder { greaterThan(5000L) })
@ -1686,8 +1581,7 @@ class VaultQueryTests {
notaryServices.addSignature(stx, DUMMY_NOTARY_KEY.public)
}
services.recordTransactions(commercialPaper2)
}
database.transaction {
val ccyIndex = builder { CommercialPaperSchemaV1.PersistentCommercialPaperState::currency.equal(USD.currencyCode) }
val criteria1 = QueryCriteria.VaultCustomQueryCriteria(ccyIndex)
@ -1725,8 +1619,7 @@ class VaultQueryTests {
}
commercialPaper2.verifyRequiredSignatures()
services.recordTransactions(commercialPaper2)
}
database.transaction {
val result = builder {
val ccyIndex = CommercialPaperSchemaV1.PersistentCommercialPaperState::currency.equal(USD.currencyCode)
@ -1753,8 +1646,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.POUNDS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
// CashSchemaV3 NOT registered with NodeSchemaService
val logicalExpression = builder { SampleCashSchemaV3.PersistentCashState::currency.equal(GBP.currencyCode) }
val criteria = VaultCustomQueryCriteria(logicalExpression)
@ -1775,8 +1667,7 @@ class VaultQueryTests {
services.fillWithSomeTestCash(100.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(10.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
services.fillWithSomeTestCash(1.DOLLARS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
}
database.transaction {
// DOCSTART VaultQueryExample20
val generalCriteria = VaultQueryCriteria(Vault.StateStatus.ALL)
@ -1808,8 +1699,6 @@ class VaultQueryTests {
services.fillWithSomeTestLinearStates(1, "TEST")
// 2 unconsumed states with same external ID
}
database.transaction {
val recordedBetweenExpression = TimeCondition(TimeInstantType.RECORDED, builder { between(start, end) })
val basicCriteria = VaultQueryCriteria(timeCondition = recordedBetweenExpression)
@ -1825,8 +1714,7 @@ class VaultQueryTests {
database.transaction {
services.fillWithSomeTestLinearStates(1, "TEST1")
services.fillWithSomeTestLinearStates(1, "TEST2")
}
database.transaction {
// 2 unconsumed states with same external ID
val externalIdCondition = builder { VaultSchemaV1.VaultLinearStates::externalId.equal("TEST2") }
val externalIdCustomCriteria = VaultCustomQueryCriteria(externalIdCondition)
@ -1848,8 +1736,7 @@ class VaultQueryTests {
services.fillWithSomeTestLinearStates(1, "TEST2")
sleep(1000)
services.fillWithSomeTestLinearStates(1, "TEST3")
}
database.transaction {
// 2 unconsumed states with same external ID
val results = builder {
@ -1870,16 +1757,13 @@ class VaultQueryTests {
// specifying Query on Linear state attributes
@Test
fun `unconsumed linear heads for a given external id or uuid`() {
val uuid =
database.transaction {
services.fillWithSomeTestLinearStates(1, "TEST1")
val aState = services.fillWithSomeTestLinearStates(1, "TEST2").states
services.consumeLinearStates(aState.toList(), DUMMY_NOTARY)
services.fillWithSomeTestLinearStates(1, "TEST1").states.first().state.data.linearId.id
// 2 unconsumed states with same external ID, 1 consumed with different external ID
}
database.transaction {
services.fillWithSomeTestLinearStates(1, "TEST1")
val aState = services.fillWithSomeTestLinearStates(1, "TEST2").states
services.consumeLinearStates(aState.toList(), DUMMY_NOTARY)
val uuid = services.fillWithSomeTestLinearStates(1, "TEST1").states.first().state.data.linearId.id
// 2 unconsumed states with same external ID, 1 consumed with different external ID
val results = builder {
val externalIdCondition = VaultSchemaV1.VaultLinearStates::externalId.equal("TEST1")
val externalIdCustomCriteria = VaultCustomQueryCriteria(externalIdCondition)
@ -1902,8 +1786,7 @@ class VaultQueryTests {
services.fillWithSomeTestLinearStates(1, "TEST1", listOf(ALICE))
services.fillWithSomeTestLinearStates(1)
services.fillWithSomeTestLinearStates(1, "TEST3")
}
database.transaction {
val linearStateCriteria = LinearStateQueryCriteria(participants = listOf(ALICE))
val results = vaultService.queryBy<LinearState>(linearStateCriteria)
@ -1922,8 +1805,7 @@ class VaultQueryTests {
services.fillWithSomeTestLinearStates(1, "TEST1", listOf(ALICE, BOB, CHARLIE))
services.fillWithSomeTestLinearStates(1)
services.fillWithSomeTestLinearStates(1, "TEST3")
}
database.transaction {
val linearStateCriteria = LinearStateQueryCriteria(participants = listOf(ALICE, BOB, CHARLIE))
val results = vaultService.queryBy<LinearState>(linearStateCriteria)
@ -1940,8 +1822,6 @@ class VaultQueryTests {
services.fillWithSomeTestLinearStates(1, "TEST3")
// 3 unconsumed states (one without an external ID)
}
database.transaction {
val results = builder {
val externalIdCondition = VaultSchemaV1.VaultLinearStates::externalId.isNull()
val externalIdCustomCriteria = VaultCustomQueryCriteria(externalIdCondition)
@ -1960,8 +1840,6 @@ class VaultQueryTests {
services.fillWithSomeTestLinearStates(1, "TEST3")
// 3 unconsumed states (two with an external ID)
}
database.transaction {
val results = builder {
val externalIdCondition = VaultSchemaV1.VaultLinearStates::externalId.notNull()
val externalIdCustomCriteria = VaultCustomQueryCriteria(externalIdCondition)
@ -1979,9 +1857,7 @@ class VaultQueryTests {
services.fillWithSomeTestCommodity(Amount(100, Commodity.getInstance("FCOJ")!!), notaryServices)
services.fillWithSomeTestLinearStates(1, "ABC")
services.fillWithSomeTestDeals(listOf("123"))
}
database.transaction {
// Base criteria
val baseCriteria = VaultQueryCriteria(notary = listOf(DUMMY_NOTARY),
status = Vault.StateStatus.CONSUMED)