ENT-1990 SQL Server and Oracle coin selection over-select coins (#891)

This commit is contained in:
szymonsztuka 2018-05-30 11:40:38 +01:00 committed by Michele Sollecito
parent d377f14ac3
commit 621835aea8
3 changed files with 36 additions and 2 deletions

View File

@ -8,6 +8,7 @@ import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
import net.corda.finance.DOLLARS
import net.corda.finance.contracts.asset.Cash
import net.corda.finance.contracts.asset.cash.selection.AbstractCashSelection
import net.corda.finance.contracts.getCashBalance
import net.corda.finance.issuedBy
import net.corda.testing.core.*
@ -51,6 +52,39 @@ class CashSelectionTest : IntegrationTest() {
}
}
@Test
fun `dont return extra coins if the selected amount has been reached`() {
driver(DriverParameters(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.finance"))) {
val node = startNode().getOrThrow() as InProcessImpl
val nodeIdentity = node.services.myInfo.singleIdentity()
//issue $1 coin twice
val issuer = nodeIdentity.ref(1)
repeat(2, {
val coin = 1.DOLLARS.issuedBy(issuer)
val issuance = TransactionBuilder(null as Party?)
issuance.addOutputState(TransactionState(Cash.State(coin, nodeIdentity), Cash.PROGRAM_ID, defaultNotaryIdentity))
issuance.addCommand(Cash.Commands.Issue(), nodeIdentity.owningKey)
val transaction = node.services.signInitialTransaction(issuance, nodeIdentity.owningKey)
node.database.transaction {
node.services.recordTransactions(transaction)
}
})
val exitedAmount = 1.DOLLARS
val builder = TransactionBuilder(notary = null)
val exitStates = node.database.transaction {
AbstractCashSelection
.getInstance { node.services.jdbcSession().metaData }
.unconsumedCashStatesForSpending(node.services, exitedAmount, setOf(issuer.party), builder.notary, builder.lockId, setOf(issuer.reference))
}
val returnedCoinsNumber = 1
assertThat(exitStates.size).isEqualTo(returnedCoinsNumber)
}
}
@Test
fun `select cash states issued by single transaction and give change`() {
driver(DriverParameters(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.finance"))) {

View File

@ -63,7 +63,7 @@ class CashSelectionOracleImpl : AbstractCashSelection(maxRetries = 16, retrySlee
} else { "" }) +
""")
SELECT transaction_id, output_index, pennies, total, lock_id
FROM entry where total <= ? + pennies"""
FROM entry where total < ? + pennies"""
// Use prepared statement for protection against SQL Injection (http://www.h2database.com/html/advanced.html#sql_injection)
connection.prepareStatement(selectJoin).use { statement ->

View File

@ -70,7 +70,7 @@ class CashSelectionSQLServerImpl : AbstractCashSelection(maxRetries = 16, retryS
} else { "" }) +
""")
SELECT row.transaction_id, row.output_index, row.pennies, row.total, row.lock_id
FROM row where row.total <= ? + row.pennies"""
FROM row where row.total < ? + row.pennies"""
// Use prepared statement for protection against SQL Injection
connection.prepareStatement(selectJoin).use { statement ->