ENT-1727 Fix cash selection with PostgreSQL. (#2949)

Change conversion to toStringShort() instead of toBase58String() - as done for H2 Cash Selection.
Fix withIssuerRefs case - iterate via list of IssuerRefs and setBytes instead of setArray of BYTEA.
Add test for Cash Selection with issuerRef.
This commit is contained in:
szymonsztuka 2018-04-11 13:36:29 +01:00 committed by GitHub
parent 54a6fd0e06
commit 2dc2a8dc19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 11 deletions

View File

@ -1,6 +1,7 @@
package net.corda.finance.contracts.asset.cash.selection
import net.corda.core.contracts.Amount
import net.corda.core.crypto.toStringShort
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party
import net.corda.core.utilities.*
@ -44,8 +45,12 @@ class CashSelectionPostgreSQLImpl : AbstractCashSelection() {
" AND vs.notary_name = ?" else "") +
(if (onlyFromIssuerParties.isNotEmpty())
" AND ccs.issuer_key_hash = ANY (?)" else "") +
(if (withIssuerRefs.isNotEmpty())
" AND ccs.issuer_ref = ANY (?)" else "") +
(if (withIssuerRefs.isNotEmpty()) {
val repeats = generateSequence { "?" }
.take(withIssuerRefs.size)
.joinToString(",")
" AND ccs.issuer_ref IN ($repeats)"
} else "") +
""")
nested WHERE nested.total < ?
"""
@ -60,14 +65,12 @@ class CashSelectionPostgreSQLImpl : AbstractCashSelection() {
}
if (onlyFromIssuerParties.isNotEmpty()) {
val issuerKeys = connection.createArrayOf("VARCHAR", onlyFromIssuerParties.map
{ it.owningKey.toBase58String() }.toTypedArray())
{ it.owningKey.toStringShort() }.toTypedArray())
statement.setArray(3 + paramOffset, issuerKeys)
paramOffset += 1
}
if (withIssuerRefs.isNotEmpty()) {
val issuerRefs = connection.createArrayOf("BYTEA", withIssuerRefs.map
{ it.bytes }.toTypedArray())
statement.setArray(3 + paramOffset, issuerRefs)
withIssuerRefs.map { it.bytes }.forEach {
statement.setBytes( 3 + paramOffset, it)
paramOffset += 1
}
statement.setLong(3 + paramOffset, amount.quantity)

View File

@ -9,15 +9,14 @@ import net.corda.core.internal.packageName
import net.corda.core.node.services.*
import net.corda.core.node.services.vault.*
import net.corda.core.node.services.vault.QueryCriteria.*
import net.corda.core.utilities.NonEmptySet
import net.corda.core.utilities.days
import net.corda.core.utilities.seconds
import net.corda.core.utilities.toHexString
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.*
import net.corda.finance.*
import net.corda.finance.contracts.CommercialPaper
import net.corda.finance.contracts.Commodity
import net.corda.finance.contracts.DealState
import net.corda.finance.contracts.asset.Cash
import net.corda.finance.contracts.asset.cash.selection.AbstractCashSelection
import net.corda.finance.schemas.CashSchemaV1
import net.corda.finance.schemas.CashSchemaV1.PersistentCashState
import net.corda.finance.schemas.CommercialPaperSchemaV1
@ -2056,6 +2055,39 @@ class VaultQueryTests {
}
}
@Test
fun `unconsumedCashStatesForSpending_single_issuer_reference`() {
database.transaction {
vaultFiller.fillWithSomeTestCash(1000.DOLLARS, notaryServices, 1, DUMMY_CASH_ISSUER)
}
database.transaction {
val builder = TransactionBuilder()
val issuer = DUMMY_CASH_ISSUER
val exitStates = AbstractCashSelection
.getInstance { services.jdbcSession().metaData }
.unconsumedCashStatesForSpending(services, 300.DOLLARS, setOf(issuer.party),
builder.notary, builder.lockId, setOf(issuer.reference))
assertThat(exitStates).hasSize(1)
assertThat(exitStates[0].state.data.amount.quantity).isEqualTo(100000)
}
}
@Test
fun `unconsumedCashStatesForSpending_single_issuer_reference_not_matching`() {
database.transaction {
vaultFiller.fillWithSomeTestCash(1000.DOLLARS, notaryServices, 1, DUMMY_CASH_ISSUER)
}
database.transaction {
val builder = TransactionBuilder()
val issuer = DUMMY_CASH_ISSUER
val exitStates = AbstractCashSelection
.getInstance { services.jdbcSession().metaData }
.unconsumedCashStatesForSpending(services, 300.DOLLARS, setOf(issuer.party),
builder.notary, builder.lockId, setOf(OpaqueBytes.of(13)))
assertThat(exitStates).hasSize(0)
}
}
/**
* USE CASE demonstrations (outside of mainline Corda)
*