mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +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 -> {
|
||||
// The states from the current issuer more than covers this payment.
|
||||
outputStates += deriveState(templateState, Amount(remainingToPay, token), party)
|
||||
remainingFromEachIssuer[0] = Pair(token, Amount(delta, token))
|
||||
remainingFromEachIssuer[remainingFromEachIssuer.lastIndex] = Pair(token, Amount(delta, token))
|
||||
remainingToPay = 0
|
||||
}
|
||||
delta == 0L -> {
|
||||
|
@ -14,6 +14,7 @@ import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||
import org.junit.After
|
||||
import org.junit.Test
|
||||
import java.util.Collections.nCopies
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
class CashSelectionH2ImplTest {
|
||||
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 { 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