mirror of
https://github.com/corda/corda.git
synced 2024-12-19 04:57:58 +00:00
CORDA-1506: Cash selection logic fails when selection with a change from more that 2 different issuer groups (#3187)
* Expose a flaw in cash selection logic * Minimal test exposing the bug. * Remaining unspent cash overwrites the cash of the first issuer, not the current issuer - the problem emerged when at least three different groups were selected, for 2 different issuers the last one in selection process was always the first remaining one. * Addressing PR comments + more precise test name * Addressing PR comments.
This commit is contained in:
parent
013eb33d7c
commit
fa090eb865
@ -152,7 +152,7 @@ abstract class OnLedgerAsset<T : Any, out C : CommandData, S : FungibleAsset<T>>
|
|||||||
delta > 0 -> {
|
delta > 0 -> {
|
||||||
// The states from the current issuer more than covers this payment.
|
// The states from the current issuer more than covers this payment.
|
||||||
outputStates += deriveState(templateState, Amount(remainingToPay, token), party)
|
outputStates += deriveState(templateState, Amount(remainingToPay, token), party)
|
||||||
remainingFromEachIssuer[0] = Pair(token, Amount(delta, token))
|
remainingFromEachIssuer[remainingFromEachIssuer.lastIndex] = Pair(token, Amount(delta, token))
|
||||||
remainingToPay = 0
|
remainingToPay = 0
|
||||||
}
|
}
|
||||||
delta == 0L -> {
|
delta == 0L -> {
|
||||||
|
@ -14,6 +14,7 @@ import org.assertj.core.api.Assertions.assertThatThrownBy
|
|||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.util.Collections.nCopies
|
import java.util.Collections.nCopies
|
||||||
|
import kotlin.test.assertNotNull
|
||||||
|
|
||||||
class CashSelectionH2ImplTest {
|
class CashSelectionH2ImplTest {
|
||||||
private val mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.finance"))
|
private val mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.finance"))
|
||||||
@ -53,4 +54,19 @@ class CashSelectionH2ImplTest {
|
|||||||
assertThatThrownBy { flow2.getOrThrow() }.isInstanceOf(CashException::class.java)
|
assertThatThrownBy { flow2.getOrThrow() }.isInstanceOf(CashException::class.java)
|
||||||
assertThatThrownBy { flow3.getOrThrow() }.isInstanceOf(CashException::class.java)
|
assertThatThrownBy { flow3.getOrThrow() }.isInstanceOf(CashException::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `select pennies amount from cash states with more than two different issuers and expect change`() {
|
||||||
|
val node = mockNet.createNode()
|
||||||
|
val notary = mockNet.defaultNotaryIdentity
|
||||||
|
|
||||||
|
// Issue some cash
|
||||||
|
node.startFlow(CashIssueFlow(1.POUNDS, OpaqueBytes.of(1), notary)).getOrThrow()
|
||||||
|
node.startFlow(CashIssueFlow(1.POUNDS, OpaqueBytes.of(2), notary)).getOrThrow()
|
||||||
|
node.startFlow(CashIssueFlow(1000.POUNDS, OpaqueBytes.of(3), notary)).getOrThrow()
|
||||||
|
|
||||||
|
// Make a payment
|
||||||
|
val paymentResult = node.startFlow(CashPaymentFlow(999.POUNDS, node.info.legalIdentities[0], false)).getOrThrow()
|
||||||
|
assertNotNull(paymentResult.recipient)
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user