mirror of
https://github.com/corda/corda.git
synced 2024-12-19 21:17:58 +00:00
Verifier test: make sure only correct transactions are generated
This commit is contained in:
parent
f59621ce3f
commit
f69273027c
@ -167,7 +167,7 @@ fun <A> Generator.Companion.replicate(number: Int, generator: Generator<A>): Gen
|
||||
}
|
||||
|
||||
|
||||
fun <A> Generator.Companion.replicatePoisson(meanSize: Double, generator: Generator<A>) = Generator<List<A>> {
|
||||
fun <A> Generator.Companion.replicatePoisson(meanSize: Double, generator: Generator<A>, atLeastOne: Boolean = false) = Generator<List<A>> {
|
||||
val chance = (meanSize - 1) / meanSize
|
||||
val result = mutableListOf<A>()
|
||||
var finish = false
|
||||
@ -177,7 +177,9 @@ fun <A> Generator.Companion.replicatePoisson(meanSize: Double, generator: Genera
|
||||
generator.generate(it).map { result.add(it) }
|
||||
} else {
|
||||
finish = true
|
||||
Try.Success(Unit)
|
||||
if (result.isEmpty() && atLeastOne) {
|
||||
generator.generate(it).map { result.add(it) }
|
||||
} else Try.Success(Unit)
|
||||
}
|
||||
}
|
||||
if (res is Try.Failure) {
|
||||
|
@ -67,7 +67,7 @@ class WiredTransactionGenerator : Generator<WireTransaction>(WireTransaction::cl
|
||||
override fun generate(random: SourceOfRandomness, status: GenerationStatus): WireTransaction {
|
||||
val commands = CommandGenerator().generateList(random, status) + listOf(CommandGenerator().generate(random, status))
|
||||
return WireTransaction(
|
||||
inputs = StateRefGenerator().generateList(random, status),
|
||||
inputs = StateRefGenerator().generateList(random, status) + listOf(StateRefGenerator().generate(random, status)),
|
||||
attachments = SecureHashGenerator().generateList(random, status),
|
||||
outputs = TransactionStateGenerator(ContractStateGenerator()).generateList(random, status),
|
||||
commands = commands,
|
||||
|
@ -50,7 +50,7 @@ data class GeneratedLedger(
|
||||
}
|
||||
|
||||
val commandsGenerator: Generator<List<Pair<Command<*>, Party>>> by lazy {
|
||||
Generator.replicatePoisson(4.0, commandGenerator(identities))
|
||||
Generator.replicatePoisson(4.0, commandGenerator(identities), atLeastOne = true)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,10 +87,42 @@ data class GeneratedLedger(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an exit transaction.
|
||||
* Invariants:
|
||||
* * The output list must be empty
|
||||
*/
|
||||
fun exitTransactionGenerator(inputNotary: Party, inputsToChooseFrom: List<StateAndRef<ContractState>>): Generator<Pair<WireTransaction, GeneratedLedger>> {
|
||||
val inputsGen = Generator.sampleBernoulli(inputsToChooseFrom)
|
||||
return inputsGen.combine(attachmentsGenerator, commandsGenerator) { inputs, txAttachments, commands ->
|
||||
val newTransaction = WireTransaction(
|
||||
inputs.map { it.ref },
|
||||
txAttachments.map { it.id },
|
||||
emptyList(),
|
||||
commands.map { it.first },
|
||||
inputNotary,
|
||||
null
|
||||
)
|
||||
|
||||
val availableOutputsMinusConsumed = HashMap(availableOutputs)
|
||||
if (inputs.size == inputsToChooseFrom.size) {
|
||||
availableOutputsMinusConsumed.remove(inputNotary)
|
||||
} else {
|
||||
availableOutputsMinusConsumed[inputNotary] = inputsToChooseFrom - inputs
|
||||
}
|
||||
val newAvailableOutputs = availableOutputsMinusConsumed
|
||||
val newAttachments = attachments + txAttachments
|
||||
val newIdentities = identities + commands.map { it.second }
|
||||
val newLedger = GeneratedLedger(transactions + newTransaction, newAvailableOutputs, newAttachments, newIdentities)
|
||||
Pair(newTransaction, newLedger)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a regular non-issue transaction.
|
||||
* Invariants:
|
||||
* * Input and output notaries must be one and the same.
|
||||
* * There must be at least one input and output state.
|
||||
*/
|
||||
fun regularTransactionGenerator(inputNotary: Party, inputsToChooseFrom: List<StateAndRef<ContractState>>): Generator<Pair<WireTransaction, GeneratedLedger>> {
|
||||
val outputsGen = outputsGenerator.map { outputs ->
|
||||
@ -136,8 +168,9 @@ data class GeneratedLedger(
|
||||
Generator.pickOne(availableOutputs.keys.toList()).flatMap { inputNotary ->
|
||||
val inputsToChooseFrom = availableOutputs[inputNotary]!!
|
||||
Generator.frequency(
|
||||
0.5 to issuanceGenerator,
|
||||
0.5 to regularTransactionGenerator(inputNotary, inputsToChooseFrom)
|
||||
0.3 to issuanceGenerator,
|
||||
0.3 to exitTransactionGenerator(inputNotary, inputsToChooseFrom),
|
||||
0.4 to regularTransactionGenerator(inputNotary, inputsToChooseFrom)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -193,4 +226,4 @@ fun <A> pickOneOrMaybeNew(from: Collection<A>, generator: Generator<A>): Generat
|
||||
}
|
||||
|
||||
val attachmentGenerator: Generator<Attachment> = Generator.bytes(16).map(::GeneratedAttachment)
|
||||
val outputsGenerator = Generator.replicatePoisson(3.0, stateGenerator)
|
||||
val outputsGenerator = Generator.replicatePoisson(3.0, stateGenerator, atLeastOne = true)
|
||||
|
Loading…
Reference in New Issue
Block a user