diff --git a/contracts/src/main/kotlin/com/r3corda/contracts/testing/WalletFiller.kt b/contracts/src/main/kotlin/com/r3corda/contracts/testing/WalletFiller.kt index ae6565e585..b062de2f44 100644 --- a/contracts/src/main/kotlin/com/r3corda/contracts/testing/WalletFiller.kt +++ b/contracts/src/main/kotlin/com/r3corda/contracts/testing/WalletFiller.kt @@ -13,8 +13,6 @@ import com.r3corda.core.node.ServiceHub import com.r3corda.core.node.services.Wallet import com.r3corda.core.serialization.OpaqueBytes import com.r3corda.core.testing.DUMMY_NOTARY -import com.r3corda.core.testing.DUMMY_NOTARY_KEY -import java.security.KeyPair import java.security.PublicKey import java.util.* @@ -61,22 +59,29 @@ fun ServiceHub.fillWithSomeTestCash(howMuch: Amount, } private fun calculateRandomlySizedAmounts(howMuch: Amount, min: Int, max: Int, rng: Random): LongArray { - val numStates = min + Math.floor(rng.nextDouble() * (max - min)).toInt() - val amounts = LongArray(numStates) - val baseSize = howMuch.quantity / numStates + val numSlots = min + Math.floor(rng.nextDouble() * (max - min)).toInt() + val baseSize = howMuch.quantity / numSlots check(baseSize > 0) { baseSize } - var filledSoFar = 0L - for (i in 0..numStates - 1) { - if (i < numStates - 1) { - // Adjust the amount a bit up or down, to give more realistic amounts (not all identical). - amounts[i] = baseSize + (baseSize / 2 * (rng.nextDouble() - 0.5)).toLong() - filledSoFar += amounts[i] + + val amounts = LongArray(numSlots) { baseSize } + var distanceFromGoal = 0L + // If we want 10 slots then max adjust is 0.1, so even if all random numbers come out to the largest downward + // adjustment possible, the last slot ends at zero. With 20 slots, max adjust is 0.05 etc. + val maxAdjust = 1.0 / numSlots + for (i in amounts.indices) { + if (i != amounts.lastIndex) { + val adjustBy = rng.nextDouble() * maxAdjust - (maxAdjust / 2) + val adjustment = (1 + adjustBy) + val adjustTo = (amounts[i] * adjustment).toLong() + amounts[i] = adjustTo + distanceFromGoal += baseSize - adjustTo } else { - // Handle inexact rounding. - amounts[i] = howMuch.quantity - filledSoFar + amounts[i] += distanceFromGoal } - check(amounts[i] >= 0) { "${amounts[i]} : $filledSoFar : $howMuch" } } - check(amounts.sum() == howMuch.quantity) + + // The desired amount may not have divided equally to start with, so adjust the first value to make up. + amounts[0] += howMuch.quantity - amounts.sum() + return amounts } \ No newline at end of file diff --git a/node/src/test/kotlin/com/r3corda/node/services/WalletWithCashTest.kt b/node/src/test/kotlin/com/r3corda/node/services/WalletWithCashTest.kt index af374e5bfa..53232f2ce9 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/WalletWithCashTest.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/WalletWithCashTest.kt @@ -5,7 +5,6 @@ import com.r3corda.contracts.asset.DUMMY_CASH_ISSUER import com.r3corda.contracts.asset.cashBalances import com.r3corda.contracts.testing.fillWithSomeTestCash import com.r3corda.core.contracts.* -import com.r3corda.core.crypto.SecureHash import com.r3corda.core.node.services.WalletService import com.r3corda.core.node.services.testing.MockServices import com.r3corda.core.node.services.testing.makeTestDataSourceProperties @@ -60,11 +59,11 @@ class WalletWithCashTest { assertEquals(3, w.states.toList().size) val state = w.states.toList()[0].state.data as Cash.State - assertEquals(29.01.DOLLARS `issued by` DUMMY_CASH_ISSUER, state.amount) + assertEquals(30.45.DOLLARS `issued by` DUMMY_CASH_ISSUER, state.amount) assertEquals(services.key.public, state.owner) - assertEquals(35.38.DOLLARS `issued by` DUMMY_CASH_ISSUER, (w.states.toList()[2].state.data as Cash.State).amount) - assertEquals(35.61.DOLLARS `issued by` DUMMY_CASH_ISSUER, (w.states.toList()[1].state.data as Cash.State).amount) + assertEquals(34.70.DOLLARS `issued by` DUMMY_CASH_ISSUER, (w.states.toList()[2].state.data as Cash.State).amount) + assertEquals(34.85.DOLLARS `issued by` DUMMY_CASH_ISSUER, (w.states.toList()[1].state.data as Cash.State).amount) } @Test