Merge pull request #840 from corda/merges/may-14-15-21

Merges May 14 15:21
This commit is contained in:
Michele Sollecito 2018-05-15 15:54:47 +07:00 committed by GitHub
commit 454899bc77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
459 changed files with 1777 additions and 1511 deletions

View File

@ -9,7 +9,7 @@ omissions, and create a pull request, or email <james@r3.com>, if you wish to
see changes to this list. see changes to this list.
* acetheultimate * acetheultimate
* Adrian Flethcehr (TD) * Adrian Fletcher (TD)
* agoldvarg * agoldvarg
* Alberto Arri (R3) * Alberto Arri (R3)
* amiracam * amiracam
@ -108,7 +108,7 @@ see changes to this list.
* Lars Stage Thomsen (Danske Bank) * Lars Stage Thomsen (Danske Bank)
* Lee Braine (Barclays) * Lee Braine (Barclays)
* Lucas Salmen (Itau) * Lucas Salmen (Itau)
* Maksymillian Pawlak (R3) * Maksymilian Pawlak (R3)
* Marek Scocovsky (ABSA) * Marek Scocovsky (ABSA)
* marekdapps * marekdapps
* Mark Lauer (Westpac) * Mark Lauer (Westpac)
@ -175,7 +175,8 @@ see changes to this list.
* tomconte * tomconte
* Tommy Lillehagen (R3) * Tommy Lillehagen (R3)
* tomtau * tomtau
* Tudor Malene (R3) * Tudor Malene (R3)
* Tushar Singh Bora
* varunkm * varunkm
* verymahler * verymahler
* Viktor Kolomeyko (R3) * Viktor Kolomeyko (R3)

View File

@ -340,14 +340,14 @@ object JacksonSupport {
mapper.wellKnownPartyFromX500Name(principal) ?: throw JsonParseException(parser, "Could not find a Party with name $principal") mapper.wellKnownPartyFromX500Name(principal) ?: throw JsonParseException(parser, "Could not find a Party with name $principal")
} else { } else {
val nameMatches = mapper.partiesFromName(parser.text) val nameMatches = mapper.partiesFromName(parser.text)
if (nameMatches.isEmpty()) { when {
val publicKey = parser.readValueAs<PublicKey>() nameMatches.isEmpty() -> {
mapper.partyFromKey(publicKey) val publicKey = parser.readValueAs<PublicKey>()
?: throw JsonParseException(parser, "Could not find a Party with key ${publicKey.toStringShort()}") mapper.partyFromKey(publicKey)
} else if (nameMatches.size == 1) { ?: throw JsonParseException(parser, "Could not find a Party with key ${publicKey.toStringShort()}")
nameMatches.first() }
} else { nameMatches.size == 1 -> nameMatches.first()
throw JsonParseException(parser, "Ambiguous name match '${parser.text}': could be any of " + else -> throw JsonParseException(parser, "Ambiguous name match '${parser.text}': could be any of " +
nameMatches.map { it.name }.joinToString(" ... or ... ")) nameMatches.map { it.name }.joinToString(" ... or ... "))
} }
} }

View File

@ -230,7 +230,7 @@ open class StringToMethodCallParser<in T : Any> @JvmOverloads constructor(
val paramNames = methodParamNames[name]!! val paramNames = methodParamNames[name]!!
val typeNames = args.parameters.map { it.type.simpleName } val typeNames = args.parameters.map { it.type.simpleName }
val paramTypes = paramNames.zip(typeNames) val paramTypes = paramNames.zip(typeNames)
paramTypes.map { "${it.first}: ${it.second}" }.joinToString(", ") paramTypes.joinToString(", ") { "${it.first}: ${it.second}" }
} }
Pair(name, argStr) Pair(name, argStr)
}.toMap() }.toMap()

View File

@ -13,7 +13,6 @@ package net.corda.client.jackson
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertArrayEquals
import org.junit.Test import org.junit.Test
import kotlin.reflect.full.primaryConstructor
import kotlin.test.assertEquals import kotlin.test.assertEquals
class StringToMethodCallParserTest { class StringToMethodCallParserTest {

View File

@ -121,13 +121,13 @@ class NodeMonitorModelTest : IntegrationTest() {
sequence( sequence(
// TODO : Add test for remove when driver DSL support individual node shutdown. // TODO : Add test for remove when driver DSL support individual node shutdown.
expect { output: NetworkMapCache.MapChange -> expect { output: NetworkMapCache.MapChange ->
require(output.node.legalIdentities.any { it.name == ALICE_NAME }) { "Expecting : ${ALICE_NAME}, Actual : ${output.node.legalIdentities.map(Party::name)}" } require(output.node.legalIdentities.any { it.name == ALICE_NAME }) { "Expecting : $ALICE_NAME, Actual : ${output.node.legalIdentities.map(Party::name)}" }
}, },
expect { output: NetworkMapCache.MapChange -> expect { output: NetworkMapCache.MapChange ->
require(output.node.legalIdentities.any { it.name == BOB_NAME }) { "Expecting : ${BOB_NAME}, Actual : ${output.node.legalIdentities.map(Party::name)}" } require(output.node.legalIdentities.any { it.name == BOB_NAME }) { "Expecting : $BOB_NAME, Actual : ${output.node.legalIdentities.map(Party::name)}" }
}, },
expect { output: NetworkMapCache.MapChange -> expect { output: NetworkMapCache.MapChange ->
require(output.node.legalIdentities.any { it.name == CHARLIE_NAME }) { "Expecting : ${CHARLIE_NAME}, Actual : ${output.node.legalIdentities.map(Party::name)}" } require(output.node.legalIdentities.any { it.name == CHARLIE_NAME }) { "Expecting : $CHARLIE_NAME, Actual : ${output.node.legalIdentities.map(Party::name)}" }
} }
) )
} }

View File

@ -39,24 +39,23 @@ class ContractStateModel {
private val cashStatesDiff: Observable<Diff<Cash.State>> = contractStatesDiff.map { private val cashStatesDiff: Observable<Diff<Cash.State>> = contractStatesDiff.map {
Diff(it.added.filterCashStateAndRefs(), it.removed.filterCashStateAndRefs()) Diff(it.added.filterCashStateAndRefs(), it.removed.filterCashStateAndRefs())
} }
val cashStates: ObservableList<StateAndRef<Cash.State>> = cashStatesDiff.fold(FXCollections.observableArrayList()) { list: MutableList<StateAndRef<Cash.State>>, statesDiff -> val cashStates: ObservableList<StateAndRef<Cash.State>> = cashStatesDiff.fold(FXCollections.observableArrayList()) { list: MutableList<StateAndRef<Cash.State>>, (added, removed) ->
list.removeIf { it in statesDiff.removed } list.removeIf { it in removed }
list.addAll(statesDiff.added) list.addAll(added)
}.distinctBy { it.ref } }.distinctBy { it.ref }
val cash = cashStates.map { it.state.data.amount } val cash = cashStates.map { it.state.data.amount }
companion object { companion object {
private fun Collection<StateAndRef<ContractState>>.filterCashStateAndRefs(): List<StateAndRef<Cash.State>> { private fun Collection<StateAndRef<ContractState>>.filterCashStateAndRefs(): List<StateAndRef<Cash.State>> {
return this.map { stateAndRef -> return this.mapNotNull { stateAndRef ->
if (stateAndRef.state.data is Cash.State) { if (stateAndRef.state.data is Cash.State) {
// Kotlin doesn't unify here for some reason // Kotlin doesn't unify here for some reason
uncheckedCast<StateAndRef<ContractState>, StateAndRef<Cash.State>>(stateAndRef) uncheckedCast<StateAndRef<ContractState>, StateAndRef<Cash.State>>(stateAndRef)
} else { } else {
null null
} }
}.filterNotNull() }
} }
} }
} }

View File

@ -10,16 +10,7 @@
package net.corda.client.jfx.model package net.corda.client.jfx.model
import javafx.beans.property.ObjectProperty
import javafx.beans.value.ObservableValue
import javafx.beans.value.WritableValue
import javafx.collections.ObservableList
import net.corda.core.internal.uncheckedCast import net.corda.core.internal.uncheckedCast
import org.reactfx.EventSink
import org.reactfx.EventStream
import rx.Observable
import rx.Observer
import rx.subjects.Subject
import java.util.* import java.util.*
import kotlin.reflect.KClass import kotlin.reflect.KClass
@ -84,7 +75,7 @@ object Models {
fun <M : Any> initModel(klass: KClass<M>) = modelStore.getOrPut(klass) { klass.java.newInstance() } fun <M : Any> initModel(klass: KClass<M>) = modelStore.getOrPut(klass) { klass.java.newInstance() }
fun <M : Any> get(klass: KClass<M>, origin: KClass<*>): M { fun <M : Any> get(klass: KClass<M>, origin: KClass<*>): M {
dependencyGraph.getOrPut(origin) { mutableSetOf<KClass<*>>() }.add(klass) dependencyGraph.getOrPut(origin) { mutableSetOf() }.add(klass)
val model = initModel(klass) val model = initModel(klass)
if (model.javaClass != klass.java) { if (model.javaClass != klass.java) {
throw IllegalStateException("Model stored as ${klass.qualifiedName} has type ${model.javaClass}") throw IllegalStateException("Model stored as ${klass.qualifiedName} has type ${model.javaClass}")

View File

@ -21,7 +21,6 @@ import org.reactfx.EventStream
import rx.Observable import rx.Observable
import rx.Observer import rx.Observer
import rx.subjects.Subject import rx.subjects.Subject
import kotlin.reflect.KClass
inline fun <reified M : Any, T> observable(noinline observableProperty: (M) -> Observable<T>) = inline fun <reified M : Any, T> observable(noinline observableProperty: (M) -> Observable<T>) =
TrackedDelegate.ObservableDelegate(M::class, observableProperty) TrackedDelegate.ObservableDelegate(M::class, observableProperty)

View File

@ -32,7 +32,7 @@ class NetworkIdentityModel {
else -> false else -> false
} }
} }
if(update is MapChange.Modified || update is MapChange.Added){ if (update is MapChange.Modified || update is MapChange.Added) {
list.addAll(update.node) list.addAll(update.node)
} }
} }

View File

@ -95,8 +95,8 @@ class TransactionDataModel {
private val transactions by observable(NodeMonitorModel::transactions) private val transactions by observable(NodeMonitorModel::transactions)
private val collectedTransactions = transactions.recordInSequence().distinctBy { it.id } private val collectedTransactions = transactions.recordInSequence().distinctBy { it.id }
private val vaultUpdates by observable(NodeMonitorModel::vaultUpdates) private val vaultUpdates by observable(NodeMonitorModel::vaultUpdates)
private val stateMap = vaultUpdates.fold(FXCollections.observableHashMap<StateRef, StateAndRef<ContractState>>()) { map, update -> private val stateMap = vaultUpdates.fold(FXCollections.observableHashMap<StateRef, StateAndRef<ContractState>>()) { map, (consumed, produced) ->
val states = update.consumed + update.produced val states = consumed + produced
states.forEach { map[it.ref] = it } states.forEach { map[it.ref] = it }
} }

View File

@ -80,21 +80,25 @@ class AggregatedList<A, E : Any, K : Any>(
override fun sourceChanged(c: ListChangeListener.Change<out E>) { override fun sourceChanged(c: ListChangeListener.Change<out E>) {
beginChange() beginChange()
while (c.next()) { while (c.next()) {
if (c.wasPermutated()) { when {
// Permutation should not change aggregation c.wasPermutated() -> {
} else if (c.wasUpdated()) { // Permutation should not change aggregation
// Update should not change aggregation
} else {
for (removedSourceItem in c.removed) {
val removedPair = removeItem(removedSourceItem)
if (removedPair != null) {
nextRemove(removedPair.first, removedPair.second.value)
}
} }
for (addedItem in c.addedSubList) { c.wasUpdated() -> {
val insertIndex = addItem(addedItem) // Update should not change aggregation
if (insertIndex != null) { }
nextAdd(insertIndex, insertIndex + 1) else -> {
for (removedSourceItem in c.removed) {
val removedPair = removeItem(removedSourceItem)
if (removedPair != null) {
nextRemove(removedPair.first, removedPair.second.value)
}
}
for (addedItem in c.addedSubList) {
val insertIndex = addItem(addedItem)
if (insertIndex != null) {
nextAdd(insertIndex, insertIndex + 1)
}
} }
} }
} }

View File

@ -16,6 +16,7 @@ import javafx.collections.ObservableList
import net.corda.client.jfx.model.ExchangeRate import net.corda.client.jfx.model.ExchangeRate
import net.corda.core.contracts.Amount import net.corda.core.contracts.Amount
import org.fxmisc.easybind.EasyBind import org.fxmisc.easybind.EasyBind
import org.fxmisc.easybind.monadic.MonadicBinding
import java.util.* import java.util.*
import java.util.stream.Collectors import java.util.stream.Collectors
@ -23,7 +24,7 @@ import java.util.stream.Collectors
* Utility bindings for the [Amount] type, similar in spirit to [Bindings] * Utility bindings for the [Amount] type, similar in spirit to [Bindings]
*/ */
object AmountBindings { object AmountBindings {
fun <T : Any> sum(amounts: ObservableList<Amount<T>>, token: T) = EasyBind.map( fun <T : Any> sum(amounts: ObservableList<Amount<T>>, token: T): MonadicBinding<Amount<T>> = EasyBind.map(
Bindings.createLongBinding({ Bindings.createLongBinding({
amounts.stream().collect(Collectors.summingLong { amounts.stream().collect(Collectors.summingLong {
require(it.token == token) require(it.token == token)

View File

@ -31,35 +31,39 @@ class AssociatedList<K, out A, B>(
init { init {
sourceList.forEach { sourceList.forEach {
val key = toKey(it) val key = toKey(it)
backingMap.set(key, Pair(assemble(key, it), Unit)) backingMap[key] = Pair(assemble(key, it), Unit)
} }
sourceList.addListener { change: ListChangeListener.Change<out A> -> sourceList.addListener { change: ListChangeListener.Change<out A> ->
while (change.next()) { while (change.next()) {
if (change.wasPermutated()) { when {
} else if (change.wasUpdated()) { change.wasPermutated() -> {
} else {
val removedSourceMap = change.removed.associateBy(toKey)
val addedSourceMap = change.addedSubList.associateBy(toKey)
val removedMap = HashMap<K, B>()
val addedMap = HashMap<K, B>()
removedSourceMap.forEach {
val removed = backingMap.remove(it.key)?.first
removed ?: throw IllegalStateException("Removed list does not associate")
removedMap.put(it.key, removed)
} }
addedSourceMap.forEach { change.wasUpdated() -> {
val oldValue = backingMap.get(it.key) }
val newValue = if (oldValue == null) { else -> {
assemble(it.key, it.value) val removedSourceMap = change.removed.associateBy(toKey)
} else { val addedSourceMap = change.addedSubList.associateBy(toKey)
throw IllegalStateException("Several elements associated with same key") val removedMap = HashMap<K, B>()
val addedMap = HashMap<K, B>()
removedSourceMap.forEach {
val removed = backingMap.remove(it.key)?.first
removed ?: throw IllegalStateException("Removed list does not associate")
removedMap.put(it.key, removed)
}
addedSourceMap.forEach {
val oldValue = backingMap.get(it.key)
val newValue = if (oldValue == null) {
assemble(it.key, it.value)
} else {
throw IllegalStateException("Several elements associated with same key")
}
backingMap.put(it.key, Pair(newValue, Unit))
addedMap.put(it.key, newValue)
}
val keys = removedMap.keys + addedMap.keys
keys.forEach { key ->
fireChange(createMapChange(key, removedMap.get(key), addedMap.get(key)))
} }
backingMap.put(it.key, Pair(newValue, Unit))
addedMap.put(it.key, newValue)
}
val keys = removedMap.keys + addedMap.keys
keys.forEach { key ->
fireChange(createMapChange(key, removedMap.get(key), addedMap.get(key)))
} }
} }
} }

View File

@ -37,9 +37,7 @@ class ChosenList<E>(
private var currentList = chosenListObservable.value private var currentList = chosenListObservable.value
private val listener = object : ListChangeListener<E> { private val listener = ListChangeListener<E> { change -> fireChange(change) }
override fun onChanged(change: ListChangeListener.Change<out E>) = fireChange(change)
}
init { init {
chosenListObservable.addListener { _: Observable -> rechoose() } chosenListObservable.addListener { _: Observable -> rechoose() }
@ -49,7 +47,7 @@ class ChosenList<E>(
endChange() endChange()
} }
override fun get(index: Int) = currentList.get(index) override fun get(index: Int): E = currentList[index]
override val size: Int get() = currentList.size override val size: Int get() = currentList.size
private fun rechoose() { private fun rechoose() {

View File

@ -62,10 +62,10 @@ class ConcatenatedList<A>(sourceList: ObservableList<ObservableList<A>>) : Trans
} }
private fun startingOffsetOf(listIndex: Int): Int { private fun startingOffsetOf(listIndex: Int): Int {
if (listIndex == 0) { return if (listIndex == 0) {
return 0 0
} else { } else {
return nestedIndexOffsets[listIndex - 1] nestedIndexOffsets[listIndex - 1]
} }
} }
@ -84,11 +84,11 @@ class ConcatenatedList<A>(sourceList: ObservableList<ObservableList<A>>) : Trans
// firstTouched is the result list index of the beginning of the permutation. // firstTouched is the result list index of the beginning of the permutation.
val firstTouched = startingOffset + change.from val firstTouched = startingOffset + change.from
// We first set the non-permuted indices. // We first set the non-permuted indices.
for (i in 0..firstTouched - 1) { for (i in 0 until firstTouched) {
permutation[i] = i permutation[i] = i
} }
// Then the permuted ones. // Then the permuted ones.
for (i in firstTouched..startingOffset + change.to - 1) { for (i in firstTouched until startingOffset + change.to) {
permutation[startingOffset + i] = change.getPermutation(i) permutation[startingOffset + i] = change.getPermutation(i)
} }
nextPermutation(firstTouched, startingOffset + change.to, permutation) nextPermutation(firstTouched, startingOffset + change.to, permutation)
@ -97,7 +97,7 @@ class ConcatenatedList<A>(sourceList: ObservableList<ObservableList<A>>) : Trans
// by the startingOffsetOf the nested list. // by the startingOffsetOf the nested list.
val listIndex = indexMap[wrapped]!!.first val listIndex = indexMap[wrapped]!!.first
val startingOffset = startingOffsetOf(listIndex) val startingOffset = startingOffsetOf(listIndex)
for (i in change.from..change.to - 1) { for (i in change.from until change.to) {
nextUpdate(startingOffset + i) nextUpdate(startingOffset + i)
} }
} else { } else {
@ -154,7 +154,7 @@ class ConcatenatedList<A>(sourceList: ObservableList<ObservableList<A>>) : Trans
val newSubNestedIndexOffsets = IntArray(change.to - change.from) val newSubNestedIndexOffsets = IntArray(change.to - change.from)
val firstTouched = if (change.from == 0) 0 else nestedIndexOffsets[change.from - 1] val firstTouched = if (change.from == 0) 0 else nestedIndexOffsets[change.from - 1]
var currentOffset = firstTouched var currentOffset = firstTouched
for (i in 0..change.to - change.from - 1) { for (i in 0 until change.to - change.from) {
currentOffset += source[change.from + i].size currentOffset += source[change.from + i].size
newSubNestedIndexOffsets[i] = currentOffset newSubNestedIndexOffsets[i] = currentOffset
} }
@ -162,24 +162,24 @@ class ConcatenatedList<A>(sourceList: ObservableList<ObservableList<A>>) : Trans
val concatenatedPermutation = IntArray(newSubNestedIndexOffsets.last()) val concatenatedPermutation = IntArray(newSubNestedIndexOffsets.last())
// Set the non-permuted part // Set the non-permuted part
var offset = 0 var offset = 0
for (i in 0..change.from - 1) { for (i in 0 until change.from) {
val nestedList = source[i] val nestedList = source[i]
for (j in offset..offset + nestedList.size - 1) { for (j in offset until offset + nestedList.size) {
concatenatedPermutation[j] = j concatenatedPermutation[j] = j
} }
offset += nestedList.size offset += nestedList.size
} }
// Now the permuted part // Now the permuted part
for (i in 0..newSubNestedIndexOffsets.size - 1) { for (i in 0 until newSubNestedIndexOffsets.size) {
val startingOffset = startingOffsetOf(change.from + i) val startingOffset = startingOffsetOf(change.from + i)
val permutedListIndex = change.getPermutation(change.from + i) val permutedListIndex = change.getPermutation(change.from + i)
val permutedOffset = (if (permutedListIndex == 0) 0 else newSubNestedIndexOffsets[permutedListIndex - 1]) val permutedOffset = (if (permutedListIndex == 0) 0 else newSubNestedIndexOffsets[permutedListIndex - 1])
for (j in 0..source[permutedListIndex].size - 1) { for (j in 0 until source[permutedListIndex].size) {
concatenatedPermutation[startingOffset + j] = permutedOffset + j concatenatedPermutation[startingOffset + j] = permutedOffset + j
} }
} }
// Record permuted offsets // Record permuted offsets
for (i in 0..newSubNestedIndexOffsets.size - 1) { for (i in 0 until newSubNestedIndexOffsets.size) {
nestedIndexOffsets[change.from + i] = newSubNestedIndexOffsets[i] nestedIndexOffsets[change.from + i] = newSubNestedIndexOffsets[i]
} }
nextPermutation(firstTouched, newSubNestedIndexOffsets.last(), concatenatedPermutation) nextPermutation(firstTouched, newSubNestedIndexOffsets.last(), concatenatedPermutation)
@ -248,7 +248,7 @@ class ConcatenatedList<A>(sourceList: ObservableList<ObservableList<A>>) : Trans
if (firstInvalidatedPosition < source.size) { if (firstInvalidatedPosition < source.size) {
val firstInvalid = firstInvalidatedPosition val firstInvalid = firstInvalidatedPosition
var offset = if (firstInvalid == 0) 0 else nestedIndexOffsets[firstInvalid - 1] var offset = if (firstInvalid == 0) 0 else nestedIndexOffsets[firstInvalid - 1]
for (i in firstInvalid..source.size - 1) { for (i in firstInvalid until source.size) {
offset += source[i].size offset += source[i].size
if (i < nestedIndexOffsets.size) { if (i < nestedIndexOffsets.size) {
nestedIndexOffsets[i] = offset nestedIndexOffsets[i] = offset
@ -266,10 +266,10 @@ class ConcatenatedList<A>(sourceList: ObservableList<ObservableList<A>>) : Trans
override val size: Int override val size: Int
get() { get() {
recalculateOffsets() recalculateOffsets()
if (nestedIndexOffsets.size > 0) { return if (nestedIndexOffsets.size > 0) {
return nestedIndexOffsets.last() nestedIndexOffsets.last()
} else { } else {
return 0 0
} }
} }
@ -283,17 +283,17 @@ class ConcatenatedList<A>(sourceList: ObservableList<ObservableList<A>>) : Trans
comparison = { offset -> compareValues(offset, index) } comparison = { offset -> compareValues(offset, index) }
) )
if (listIndex >= 0) { return if (listIndex >= 0) {
var nonEmptyListIndex = listIndex + 1 var nonEmptyListIndex = listIndex + 1
while (source[nonEmptyListIndex].isEmpty()) { while (source[nonEmptyListIndex].isEmpty()) {
nonEmptyListIndex++ nonEmptyListIndex++
} }
return source[nonEmptyListIndex][0] source[nonEmptyListIndex][0]
} else { } else {
// The element is in the range of this list // The element is in the range of this list
val rangeListIndex = -listIndex - 1 val rangeListIndex = -listIndex - 1
val subListOffset = index - startingOffsetOf(rangeListIndex) val subListOffset = index - startingOffsetOf(rangeListIndex)
return source[rangeListIndex][subListOffset] source[rangeListIndex][subListOffset]
} }
} }

View File

@ -65,7 +65,7 @@ class FlattenedList<A>(val sourceList: ObservableList<out ObservableValue<out A>
val from = c.from val from = c.from
val to = c.to val to = c.to
val permutation = IntArray(to, { c.getPermutation(it) }) val permutation = IntArray(to, { c.getPermutation(it) })
indexMap.replaceAll { _, pair -> Pair(permutation[pair.first], pair.second) } indexMap.replaceAll { _, (first, second) -> Pair(permutation[first], second) }
nextPermutation(from, to, permutation) nextPermutation(from, to, permutation)
} else if (c.wasUpdated()) { } else if (c.wasUpdated()) {
throw UnsupportedOperationException("FlattenedList doesn't support Update changes") throw UnsupportedOperationException("FlattenedList doesn't support Update changes")
@ -119,7 +119,7 @@ class FlattenedList<A>(val sourceList: ObservableList<out ObservableValue<out A>
assert(sourceList.size == indexMap.size) assert(sourceList.size == indexMap.size)
} }
override fun get(index: Int) = sourceList.get(index).value override fun get(index: Int): A = sourceList[index].value
override fun getSourceIndex(index: Int) = index override fun getSourceIndex(index: Int) = index

View File

@ -26,8 +26,8 @@ class LeftOuterJoinedMap<K : Any, A, B, C>(
) : ReadOnlyBackedObservableMapBase<K, C, SimpleObjectProperty<B?>>() { ) : ReadOnlyBackedObservableMapBase<K, C, SimpleObjectProperty<B?>>() {
init { init {
leftTable.forEach { entry -> leftTable.forEach { entry ->
val rightValueProperty = SimpleObjectProperty(rightTable.get(entry.key)) val rightValueProperty = SimpleObjectProperty(rightTable[entry.key])
backingMap.set(entry.key, Pair(assemble(entry.key, entry.value, rightValueProperty), rightValueProperty)) backingMap[entry.key] = Pair(assemble(entry.key, entry.value, rightValueProperty), rightValueProperty)
} }
leftTable.addListener { change: MapChangeListener.Change<out K, out A> -> leftTable.addListener { change: MapChangeListener.Change<out K, out A> ->
@ -39,10 +39,10 @@ class LeftOuterJoinedMap<K : Any, A, B, C>(
} }
if (change.wasAdded()) { if (change.wasAdded()) {
val rightValue = rightTable.get(change.key) val rightValue = rightTable[change.key]
val rightValueProperty = SimpleObjectProperty(rightValue) val rightValueProperty = SimpleObjectProperty(rightValue)
val newValue = assemble(change.key, change.valueAdded, rightValueProperty) val newValue = assemble(change.key, change.valueAdded, rightValueProperty)
backingMap.set(change.key, Pair(newValue, rightValueProperty)) backingMap[change.key] = Pair(newValue, rightValueProperty)
addedValue = newValue addedValue = newValue
} }
@ -50,11 +50,11 @@ class LeftOuterJoinedMap<K : Any, A, B, C>(
} }
rightTable.addListener { change: MapChangeListener.Change<out K, out B> -> rightTable.addListener { change: MapChangeListener.Change<out K, out B> ->
if (change.wasRemoved() && !change.wasAdded()) { if (change.wasRemoved() && !change.wasAdded()) {
backingMap.get(change.key)?.second?.set(null) backingMap[change.key]?.second?.set(null)
} }
if (change.wasAdded()) { if (change.wasAdded()) {
backingMap.get(change.key)?.second?.set(change.valueAdded) backingMap[change.key]?.second?.set(change.valueAdded)
} }
} }
} }

View File

@ -15,7 +15,6 @@ import javafx.collections.ObservableList
import javafx.collections.transformation.TransformationList import javafx.collections.transformation.TransformationList
import java.util.* import java.util.*
/** /**
* This is a variant of [EasyBind.map] where the mapped list is backed, therefore the mapping function will only be run * This is a variant of [EasyBind.map] where the mapped list is backed, therefore the mapping function will only be run
* when an element is inserted or updated. * when an element is inserted or updated.

View File

@ -40,7 +40,7 @@ private fun onError(th: Throwable) {
*/ */
fun <A, B> Observable<A>.foldToObservableValue(initial: B, folderFun: (A, B) -> B): ObservableValue<B> { fun <A, B> Observable<A>.foldToObservableValue(initial: B, folderFun: (A, B) -> B): ObservableValue<B> {
val result = SimpleObjectProperty<B>(initial) val result = SimpleObjectProperty<B>(initial)
subscribe ({ subscribe({
Platform.runLater { Platform.runLater {
result.set(folderFun(it, result.get())) result.set(folderFun(it, result.get()))
} }

View File

@ -52,10 +52,10 @@ fun <A, B> ObservableValue<out A>.map(function: (A) -> B): ObservableValue<B> =
* re-run the function. * re-run the function.
*/ */
fun <A, B> ObservableList<out A>.map(cached: Boolean = true, function: (A) -> B): ObservableList<B> { fun <A, B> ObservableList<out A>.map(cached: Boolean = true, function: (A) -> B): ObservableList<B> {
if (cached) { return if (cached) {
return MappedList(this, function) MappedList(this, function)
} else { } else {
return EasyBind.map(this, function) EasyBind.map(this, function)
} }
} }
@ -130,11 +130,7 @@ fun <A> ObservableList<out A>.filter(predicate: ObservableValue<(A) -> Boolean>)
*/ */
fun <A> ObservableList<out A?>.filterNotNull(): ObservableList<A> { fun <A> ObservableList<out A?>.filterNotNull(): ObservableList<A> {
//TODO This is a tactical work round for an issue with SAM conversion (https://youtrack.jetbrains.com/issue/ALL-1552) so that the M10 explorer works. //TODO This is a tactical work round for an issue with SAM conversion (https://youtrack.jetbrains.com/issue/ALL-1552) so that the M10 explorer works.
return uncheckedCast(uncheckedCast<Any, ObservableList<A?>>(this).filtered(object : Predicate<A?> { return uncheckedCast(uncheckedCast<Any, ObservableList<A?>>(this).filtered { t -> t != null })
override fun test(t: A?): Boolean {
return t != null
}
}))
} }
/** /**
@ -257,8 +253,8 @@ fun <A : Any, B : Any, C, K : Any> ObservableList<A>.leftOuterJoin(
assemble: (A, ObservableList<B>) -> C assemble: (A, ObservableList<B>) -> C
): ObservableList<C> { ): ObservableList<C> {
val joinedMap = leftOuterJoin(rightTable, leftToJoinKey, rightToJoinKey) val joinedMap = leftOuterJoin(rightTable, leftToJoinKey, rightToJoinKey)
return joinedMap.getObservableValues().map { pair -> return joinedMap.getObservableValues().map { (first, second) ->
pair.first.map { assemble(it, pair.second) } first.map { assemble(it, second) }
}.concatenate() }.concatenate()
} }
@ -281,11 +277,9 @@ fun <A : Any, B : Any, K : Any> ObservableList<A>.leftOuterJoin(
): ObservableMap<K, Pair<ObservableList<A>, ObservableList<B>>> { ): ObservableMap<K, Pair<ObservableList<A>, ObservableList<B>>> {
val leftTableMap = associateByAggregation(leftToJoinKey) val leftTableMap = associateByAggregation(leftToJoinKey)
val rightTableMap = rightTable.associateByAggregation(rightToJoinKey) val rightTableMap = rightTable.associateByAggregation(rightToJoinKey)
val joinedMap: ObservableMap<K, Pair<ObservableList<A>, ObservableList<B>>> = return LeftOuterJoinedMap(leftTableMap, rightTableMap) { _, left, rightValue ->
LeftOuterJoinedMap(leftTableMap, rightTableMap) { _, left, rightValue -> Pair(left, ChosenList(rightValue.map { it ?: FXCollections.emptyObservableList() }, "ChosenList from leftOuterJoin"))
Pair(left, ChosenList(rightValue.map { it ?: FXCollections.emptyObservableList() }, "ChosenList from leftOuterJoin")) }
}
return joinedMap
} }
fun <A> ObservableList<A>.getValueAt(index: Int): ObservableValue<A?> { fun <A> ObservableList<A>.getValueAt(index: Int): ObservableValue<A?> {

View File

@ -56,7 +56,7 @@ open class ReadOnlyBackedObservableMapBase<K, A, B> : ObservableMap<K, A> {
override fun containsValue(value: A) = backingMap.any { it.value.first == value } override fun containsValue(value: A) = backingMap.any { it.value.first == value }
override fun get(key: K) = backingMap.get(key)?.first override fun get(key: K) = backingMap[key]?.first
override fun isEmpty() = backingMap.isEmpty() override fun isEmpty() = backingMap.isEmpty()

View File

@ -43,14 +43,14 @@ class ReplayedList<A>(sourceList: ObservableList<A>) : TransformationList<A, A>(
} }
nextPermutation(from, to, permutation) nextPermutation(from, to, permutation)
} else if (c.wasUpdated()) { } else if (c.wasUpdated()) {
for (i in c.from..c.to - 1) { for (i in c.from until c.to) {
replayedList[i] = c.list[i] replayedList[i] = c.list[i]
nextUpdate(i) nextUpdate(i)
} }
} else { } else {
if (c.wasRemoved()) { if (c.wasRemoved()) {
val removePosition = c.from val removePosition = c.from
for (i in 0..c.removedSize - 1) { for (i in 0 until c.removedSize) {
replayedList.removeAt(removePosition) replayedList.removeAt(removePosition)
} }
nextRemove(c.from, c.removed) nextRemove(c.from, c.removed)
@ -58,7 +58,7 @@ class ReplayedList<A>(sourceList: ObservableList<A>) : TransformationList<A, A>(
if (c.wasAdded()) { if (c.wasAdded()) {
val addStart = c.from val addStart = c.from
val addEnd = c.to val addEnd = c.to
for (i in addStart..addEnd - 1) { for (i in addStart until addEnd) {
replayedList.add(i, c.list[i]) replayedList.add(i, c.list[i])
} }
nextAdd(addStart, addEnd) nextAdd(addStart, addEnd)

View File

@ -29,9 +29,10 @@ class ExchangeRateModelTest {
private fun assertEquals(one: Amount<Currency>, another: Amount<Currency>) { private fun assertEquals(one: Amount<Currency>, another: Amount<Currency>) {
assertEquals(one.token, another.token) assertEquals(one.token, another.token)
assertTrue("$one != $another", {(one.toDecimal() - another.toDecimal()).abs() < BigDecimal(0.01) }) assertTrue("$one != $another", { (one.toDecimal() - another.toDecimal()).abs() < BigDecimal(0.01) })
} }
} }
@Test @Test
fun `perform fx testing`() { fun `perform fx testing`() {
val tenSwissies = Amount(10, BigDecimal.ONE, CHF) val tenSwissies = Amount(10, BigDecimal.ONE, CHF)

View File

@ -19,9 +19,9 @@ import kotlin.test.fail
class AggregatedListTest { class AggregatedListTest {
lateinit var sourceList: ObservableList<Int> private lateinit var sourceList: ObservableList<Int>
lateinit var aggregatedList: ObservableList<Pair<Int, ObservableList<Int>>> private lateinit var aggregatedList: ObservableList<Pair<Int, ObservableList<Int>>>
lateinit var replayedList: ObservableList<Pair<Int, ObservableList<Int>>> private lateinit var replayedList: ObservableList<Pair<Int, ObservableList<Int>>>
@Before @Before
fun setup() { fun setup() {

View File

@ -34,14 +34,13 @@ class ConcatenatedListTest {
fun <A> ConcatenatedList<A>.checkInvariants() { fun <A> ConcatenatedList<A>.checkInvariants() {
assertEquals(nestedIndexOffsets.size, source.size) assertEquals(nestedIndexOffsets.size, source.size)
var currentOffset = 0 var currentOffset = 0
for (i in 0..source.size - 1) { for (i in 0 until source.size) {
currentOffset += source[i].size currentOffset += source[i].size
assertEquals(nestedIndexOffsets[i], currentOffset) assertEquals(nestedIndexOffsets[i], currentOffset)
} }
assertEquals(indexMap.size, source.size) assertEquals(indexMap.size, source.size)
for (entry in indexMap) { for ((wrapped, pair) in indexMap) {
val (wrapped, pair) = entry
val index = pair.first val index = pair.first
val foundListIndices = ArrayList<Int>() val foundListIndices = ArrayList<Int>()
source.forEachIndexed { i, list -> source.forEachIndexed { i, list ->
@ -134,11 +133,7 @@ class ConcatenatedListTest {
assertEquals(replayedList[2], "b") assertEquals(replayedList[2], "b")
assertEquals(replayedList[3], "c") assertEquals(replayedList[3], "c")
sourceList.sortWith(object : Comparator<ObservableList<String>> { sourceList.sortWith(Comparator<ObservableList<String>> { p0, p1 -> p0.size - p1.size })
override fun compare(p0: ObservableList<String>, p1: ObservableList<String>): Int {
return p0.size - p1.size
}
})
concatenatedList.checkInvariants() concatenatedList.checkInvariants()
assertEquals(replayedList.size, 4) assertEquals(replayedList.size, 4)
assertEquals(replayedList[0], "hello") assertEquals(replayedList[0], "hello")
@ -147,11 +142,7 @@ class ConcatenatedListTest {
assertEquals(replayedList[3], "b") assertEquals(replayedList[3], "b")
sourceList.add(0, FXCollections.observableArrayList("d", "e", "f")) sourceList.add(0, FXCollections.observableArrayList("d", "e", "f"))
sourceList.sortWith(object : Comparator<ObservableList<String>> { sourceList.sortWith(Comparator<ObservableList<String>> { p0, p1 -> p0.size - p1.size })
override fun compare(p0: ObservableList<String>, p1: ObservableList<String>): Int {
return p0.size - p1.size
}
})
concatenatedList.checkInvariants() concatenatedList.checkInvariants()
assertEquals(replayedList.size, 7) assertEquals(replayedList.size, 7)
assertEquals(replayedList[0], "hello") assertEquals(replayedList[0], "hello")

View File

@ -44,7 +44,6 @@ class MappedListTest {
assertEquals(replayedList[0], 7) assertEquals(replayedList[0], 7)
assertEquals(replayedList[1], 5) assertEquals(replayedList[1], 5)
assertEquals(replayedList[2], 3) assertEquals(replayedList[2], 3)
} }
@Test @Test

View File

@ -20,14 +20,14 @@ import kotlin.test.assertEquals
class ReplayedMap<K, A>(sourceMap: ObservableMap<K, A>) : ReadOnlyBackedObservableMapBase<K, A, Unit>() { class ReplayedMap<K, A>(sourceMap: ObservableMap<K, A>) : ReadOnlyBackedObservableMapBase<K, A, Unit>() {
init { init {
sourceMap.forEach { sourceMap.forEach {
backingMap.set(it.key, Pair(it.value, Unit)) backingMap[it.key] = Pair(it.value, Unit)
} }
sourceMap.addListener { change: MapChangeListener.Change<out K, out A> -> sourceMap.addListener { change: MapChangeListener.Change<out K, out A> ->
if (change.wasRemoved()) { if (change.wasRemoved()) {
assertEquals(backingMap.remove(change.key)!!.first, change.valueRemoved) assertEquals(backingMap.remove(change.key)!!.first, change.valueRemoved)
} }
if (change.wasAdded()) { if (change.wasAdded()) {
backingMap.set(change.key, Pair(change.valueAdded, Unit)) backingMap[change.key] = Pair(change.valueAdded, Unit)
} }
fireChange(change) fireChange(change)
} }

View File

@ -52,5 +52,5 @@ fun CordaRPCOps.drainAndShutdown(): Observable<Unit> {
.doOnError { error -> .doOnError { error ->
throw error throw error
} }
.doOnCompleted { shutdown() }.map { } .doOnCompleted { shutdown() }.map { }
} }

View File

@ -11,10 +11,6 @@
package net.corda.client.rpc.internal package net.corda.client.rpc.internal
import co.paralleluniverse.common.util.SameThreadExecutor import co.paralleluniverse.common.util.SameThreadExecutor
import com.esotericsoftware.kryo.Kryo
import com.esotericsoftware.kryo.Serializer
import com.esotericsoftware.kryo.io.Input
import com.esotericsoftware.kryo.io.Output
import com.github.benmanes.caffeine.cache.Cache import com.github.benmanes.caffeine.cache.Cache
import com.github.benmanes.caffeine.cache.Caffeine import com.github.benmanes.caffeine.cache.Caffeine
import com.github.benmanes.caffeine.cache.RemovalCause import com.github.benmanes.caffeine.cache.RemovalCause
@ -44,18 +40,27 @@ import net.corda.nodeapi.internal.DeduplicationChecker
import org.apache.activemq.artemis.api.core.ActiveMQException import org.apache.activemq.artemis.api.core.ActiveMQException
import org.apache.activemq.artemis.api.core.RoutingType import org.apache.activemq.artemis.api.core.RoutingType
import org.apache.activemq.artemis.api.core.SimpleString import org.apache.activemq.artemis.api.core.SimpleString
import org.apache.activemq.artemis.api.core.client.*
import org.apache.activemq.artemis.api.core.client.ActiveMQClient.DEFAULT_ACK_BATCH_SIZE import org.apache.activemq.artemis.api.core.client.ActiveMQClient.DEFAULT_ACK_BATCH_SIZE
import org.apache.activemq.artemis.api.core.client.ClientConsumer
import org.apache.activemq.artemis.api.core.client.ClientMessage
import org.apache.activemq.artemis.api.core.client.ClientProducer
import org.apache.activemq.artemis.api.core.client.ClientSession
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory
import org.apache.activemq.artemis.api.core.client.FailoverEventType
import org.apache.activemq.artemis.api.core.client.ServerLocator
import rx.Notification import rx.Notification
import rx.Observable import rx.Observable
import rx.subjects.UnicastSubject import rx.subjects.UnicastSubject
import java.lang.reflect.InvocationHandler import java.lang.reflect.InvocationHandler
import java.lang.reflect.Method import java.lang.reflect.Method
import java.time.Instant
import java.util.* import java.util.*
import java.util.concurrent.* import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.ScheduledFuture
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicLong import java.util.concurrent.atomic.AtomicLong
import kotlin.reflect.jvm.javaMethod import kotlin.reflect.jvm.javaMethod
@ -162,7 +167,7 @@ class RPCClientProxyHandler(
private val serializationContextWithObservableContext = RpcClientObservableSerializer.createContext(serializationContext, observableContext) private val serializationContextWithObservableContext = RpcClientObservableSerializer.createContext(serializationContext, observableContext)
private fun createRpcObservableMap(): RpcObservableMap { private fun createRpcObservableMap(): RpcObservableMap {
val onObservableRemove = RemovalListener<InvocationId, UnicastSubject<Notification<*>>> { key, value, cause -> val onObservableRemove = RemovalListener<InvocationId, UnicastSubject<Notification<*>>> { key, _, cause ->
val observableId = key!! val observableId = key!!
val rpcCallSite = callSiteMap?.remove(observableId) val rpcCallSite = callSiteMap?.remove(observableId)
if (cause == RemovalCause.COLLECTED) { if (cause == RemovalCause.COLLECTED) {
@ -454,7 +459,7 @@ class RPCClientProxyHandler(
log.debug("Trying to connect using ${transport.params}") log.debug("Trying to connect using ${transport.params}")
try { try {
if (serverLocator != null && !serverLocator.isClosed) { if (!serverLocator.isClosed) {
sessionFactory = serverLocator.createSessionFactory(transport) sessionFactory = serverLocator.createSessionFactory(transport)
} else { } else {
log.warn("Stopping reconnect attempts.") log.warn("Stopping reconnect attempts.")

View File

@ -55,7 +55,6 @@ class KryoClientSerializationScheme : AbstractKryoSerializationScheme() {
}, },
if (classLoader != null) AMQP_P2P_CONTEXT.withClassLoader(classLoader) else AMQP_P2P_CONTEXT, if (classLoader != null) AMQP_P2P_CONTEXT.withClassLoader(classLoader) else AMQP_P2P_CONTEXT,
rpcClientContext = if (classLoader != null) KRYO_RPC_CLIENT_CONTEXT.withClassLoader(classLoader) else KRYO_RPC_CLIENT_CONTEXT) rpcClientContext = if (classLoader != null) KRYO_RPC_CLIENT_CONTEXT.withClassLoader(classLoader) else KRYO_RPC_CLIENT_CONTEXT)
} }
} }
} }

View File

@ -57,7 +57,7 @@ object RpcClientObservableSerializer : Serializer<Observable<*>>() {
}.dematerialize() }.dematerialize()
} }
private fun Input.readInvocationId() : Trace.InvocationId? { private fun Input.readInvocationId(): Trace.InvocationId? {
val value = readString() ?: return null val value = readString() ?: return null
val timestamp = readLong() val timestamp = readLong()

View File

@ -228,7 +228,7 @@ class StandaloneCordaRPClientTest {
flowHandle.returnValue.get() flowHandle.returnValue.get()
val balance = rpcProxy.getCashBalance(USD) val balance = rpcProxy.getCashBalance(USD)
println("Balance: " + balance) println("Balance: $balance")
assertEquals(629.DOLLARS, balance) assertEquals(629.DOLLARS, balance)
} }

View File

@ -59,7 +59,7 @@ class RPCConcurrencyTests : AbstractRPCTest() {
override fun newLatch(numberOfDowns: Int): Long { override fun newLatch(numberOfDowns: Int): Long {
val id = random63BitValue() val id = random63BitValue()
val latch = CountDownLatch(numberOfDowns) val latch = CountDownLatch(numberOfDowns)
latches.put(id, latch) latches[id] = latch
return id return id
} }

View File

@ -68,7 +68,7 @@ class RPCFailureTests {
} }
@Test @Test
fun `unserializable`() = rpc { fun unserializable() = rpc {
assertThatThrownBy { it.getUnserializable() }.isInstanceOf(KryoException::class.java) assertThatThrownBy { it.getUnserializable() }.isInstanceOf(KryoException::class.java)
} }

View File

@ -16,11 +16,11 @@ class RepeatingBytesInputStream(val bytesToRepeat: ByteArray, val numberOfBytes:
private var bytesLeft = numberOfBytes private var bytesLeft = numberOfBytes
override fun available() = bytesLeft override fun available() = bytesLeft
override fun read(): Int { override fun read(): Int {
if (bytesLeft == 0) { return if (bytesLeft == 0) {
return -1 -1
} else { } else {
bytesLeft-- bytesLeft--
return bytesToRepeat[(numberOfBytes - bytesLeft) % bytesToRepeat.size].toInt() bytesToRepeat[(numberOfBytes - bytesLeft) % bytesToRepeat.size].toInt()
} }
} }

View File

@ -90,7 +90,7 @@ class SwapIdentitiesFlow(private val otherParty: Party,
// TODO: for increased privacy, we should create one anonymous key per output state. // TODO: for increased privacy, we should create one anonymous key per output state.
val identities = LinkedHashMap<Party, AnonymousParty>() val identities = LinkedHashMap<Party, AnonymousParty>()
if (serviceHub.myInfo.isLegalIdentity(otherParty)) { if (serviceHub.myInfo.isLegalIdentity(otherParty)) {
identities.put(otherParty, legalIdentityAnonymous.party.anonymise()) identities[otherParty] = legalIdentityAnonymous.party.anonymise()
} else { } else {
val otherSession = initiateFlow(otherParty) val otherSession = initiateFlow(otherParty)
val data = buildDataToSign(legalIdentityAnonymous) val data = buildDataToSign(legalIdentityAnonymous)

View File

@ -119,7 +119,7 @@ class IdentitySyncFlowTests {
* Very lightweight wrapping flow to trigger the counterparty flow that receives the identities. * Very lightweight wrapping flow to trigger the counterparty flow that receives the identities.
*/ */
@InitiatingFlow @InitiatingFlow
class Initiator(private val otherSide: Party, private val tx: WireTransaction): FlowLogic<Boolean>() { class Initiator(private val otherSide: Party, private val tx: WireTransaction) : FlowLogic<Boolean>() {
@Suspendable @Suspendable
override fun call(): Boolean { override fun call(): Boolean {
val session = initiateFlow(otherSide) val session = initiateFlow(otherSide)
@ -130,7 +130,7 @@ class IdentitySyncFlowTests {
} }
@InitiatedBy(IdentitySyncFlowTests.Initiator::class) @InitiatedBy(IdentitySyncFlowTests.Initiator::class)
class Receive(private val otherSideSession: FlowSession): FlowLogic<Unit>() { class Receive(private val otherSideSession: FlowSession) : FlowLogic<Unit>() {
@Suspendable @Suspendable
override fun call() { override fun call() {
subFlow(IdentitySyncFlow.Receive(otherSideSession)) subFlow(IdentitySyncFlow.Receive(otherSideSession))

View File

@ -93,7 +93,7 @@ public class Base58 {
* @throws AddressFormatException if the given string is not a valid base58 string * @throws AddressFormatException if the given string is not a valid base58 string
*/ */
public static byte[] decode(String input) throws AddressFormatException { public static byte[] decode(String input) throws AddressFormatException {
if (input.length() == 0) { if (input.isEmpty()) {
return new byte[0]; return new byte[0];
} }
// Convert the base58-encoded ASCII chars to a base58 byte sequence (base58 digits). // Convert the base58-encoded ASCII chars to a base58 byte sequence (base58 digits).

View File

@ -20,7 +20,8 @@ public interface IdentifiableException {
/** /**
* @return the ID of the error, or null if the error doesn't have it set (yet). * @return the ID of the error, or null if the error doesn't have it set (yet).
*/ */
default @Nullable Long getErrorId() { @Nullable
default Long getErrorId() {
return null; return null;
} }
} }

View File

@ -18,10 +18,10 @@ object CordaOID {
/** Assigned to R3, see http://www.oid-info.com/cgi-bin/display?oid=1.3.6.1.4.1.50530&action=display */ /** Assigned to R3, see http://www.oid-info.com/cgi-bin/display?oid=1.3.6.1.4.1.50530&action=display */
const val R3_ROOT = "1.3.6.1.4.1.50530" const val R3_ROOT = "1.3.6.1.4.1.50530"
/** OIDs issued for the Corda platform */ /** OIDs issued for the Corda platform */
const val CORDA_PLATFORM = R3_ROOT + ".1" const val CORDA_PLATFORM = "$R3_ROOT.1"
/** /**
* Identifier for the X.509 certificate extension specifying the Corda role. See * Identifier for the X.509 certificate extension specifying the Corda role. See
* https://r3-cev.atlassian.net/wiki/spaces/AWG/pages/156860572/Certificate+identity+type+extension for details. * https://r3-cev.atlassian.net/wiki/spaces/AWG/pages/156860572/Certificate+identity+type+extension for details.
*/ */
const val X509_EXTENSION_CORDA_ROLE = CORDA_PLATFORM + ".1" const val X509_EXTENSION_CORDA_ROLE = "$CORDA_PLATFORM.1"
} }

View File

@ -46,12 +46,12 @@ internal fun <V, W> firstOf(futures: Array<out CordaFuture<out V>>, log: Logger,
val winnerChosen = AtomicBoolean() val winnerChosen = AtomicBoolean()
futures.forEach { futures.forEach {
it.then { it.then {
if (winnerChosen.compareAndSet(false, true)) { when {
resultFuture.capture { handler(it) } winnerChosen.compareAndSet(false, true) -> resultFuture.capture { handler(it) }
} else if (it.isCancelled) { it.isCancelled -> {
// Do nothing. // Do nothing.
} else { }
it.match({}, { log.error(shortCircuitedTaskFailedMessage, it) }) else -> it.match({}, { log.error(shortCircuitedTaskFailedMessage, it) })
} }
} }
} }

View File

@ -87,7 +87,6 @@ data class Actor(val id: Id, val serviceId: AuthServiceId, val owningLegalIdenti
*/ */
@CordaSerializable @CordaSerializable
data class Id(val value: String) data class Id(val value: String)
} }
/** /**

View File

@ -37,7 +37,7 @@ data class Trace(val invocationId: InvocationId, val sessionId: SessionId) {
class InvocationId(value: String, timestamp: Instant) : Id<String>(value, TYPE, timestamp) { class InvocationId(value: String, timestamp: Instant) : Id<String>(value, TYPE, timestamp) {
companion object { companion object {
private val TYPE = "Invocation" private const val TYPE = "Invocation"
/** /**
* Creates an invocation id using a [java.util.UUID] as value and [Instant.now] as timestamp. * Creates an invocation id using a [java.util.UUID] as value and [Instant.now] as timestamp.
@ -54,7 +54,7 @@ data class Trace(val invocationId: InvocationId, val sessionId: SessionId) {
class SessionId(value: String, timestamp: Instant) : Id<String>(value, TYPE, timestamp) { class SessionId(value: String, timestamp: Instant) : Id<String>(value, TYPE, timestamp) {
companion object { companion object {
private val TYPE = "Session" private const val TYPE = "Session"
/** /**
* Creates a session id using a [java.util.UUID] as value and [Instant.now] as timestamp. * Creates a session id using a [java.util.UUID] as value and [Instant.now] as timestamp.

View File

@ -260,7 +260,7 @@ data class Amount<T : Any>(val quantity: Long, val displayTokenSize: BigDecimal,
val residualTokens = quantity - (commonTokensPerPartition * partitions) val residualTokens = quantity - (commonTokensPerPartition * partitions)
val splitAmount = Amount(commonTokensPerPartition, displayTokenSize, token) val splitAmount = Amount(commonTokensPerPartition, displayTokenSize, token)
val splitAmountPlusOne = Amount(commonTokensPerPartition + 1L, displayTokenSize, token) val splitAmountPlusOne = Amount(commonTokensPerPartition + 1L, displayTokenSize, token)
return (0..partitions - 1).map { if (it < residualTokens) splitAmountPlusOne else splitAmount }.toList() return (0 until partitions).map { if (it < residualTokens) splitAmountPlusOne else splitAmount }.toList()
} }
/** /**

View File

@ -20,11 +20,11 @@ import net.corda.core.serialization.CordaSerializable
* @property additionalContracts Additional contract names contained within the JAR. * @property additionalContracts Additional contract names contained within the JAR.
*/ */
@CordaSerializable @CordaSerializable
class ContractAttachment @JvmOverloads constructor (val attachment: Attachment, val contract: ContractClassName, val additionalContracts: Set<ContractClassName> = emptySet(), val uploader: String? = null) : Attachment by attachment { class ContractAttachment @JvmOverloads constructor(val attachment: Attachment, val contract: ContractClassName, val additionalContracts: Set<ContractClassName> = emptySet(), val uploader: String? = null) : Attachment by attachment {
val allContracts: Set<ContractClassName> get() = additionalContracts + contract val allContracts: Set<ContractClassName> get() = additionalContracts + contract
override fun toString(): String { override fun toString(): String {
return "ContractAttachment(attachment=${attachment.id}, contracts='${allContracts}', uploader='${uploader}')" return "ContractAttachment(attachment=${attachment.id}, contracts='$allContracts', uploader='$uploader')"
} }
} }

View File

@ -30,7 +30,7 @@ import java.util.*
object Requirements { object Requirements {
/** Throws [IllegalArgumentException] if the given expression evaluates to false. */ /** Throws [IllegalArgumentException] if the given expression evaluates to false. */
@Suppress("NOTHING_TO_INLINE") // Inlining this takes it out of our committed ABI. @Suppress("NOTHING_TO_INLINE") // Inlining this takes it out of our committed ABI.
infix inline fun String.using(expr: Boolean) { inline infix fun String.using(expr: Boolean) {
if (!expr) throw IllegalArgumentException("Failed requirement: $this") if (!expr) throw IllegalArgumentException("Failed requirement: $this")
} }
} }

View File

@ -206,7 +206,7 @@ data class Command<T : CommandData>(val value: T, val signers: List<PublicKey>)
constructor(data: T, key: PublicKey) : this(data, listOf(key)) constructor(data: T, key: PublicKey) : this(data, listOf(key))
private fun commandDataToString() = value.toString().let { if (it.contains("@")) it.replace('$', '.').split("@")[0] else it } private fun commandDataToString() = value.toString().let { if (it.contains("@")) it.replace('$', '.').split("@")[0] else it }
override fun toString() = "${commandDataToString()} with pubkeys ${signers.map { it.toStringShort() }.joinToString()}" override fun toString() = "${commandDataToString()} with pubkeys ${signers.joinToString { it.toStringShort() }}"
} }
/** A common move command for contract states which can change owner. */ /** A common move command for contract states which can change owner. */

View File

@ -52,7 +52,7 @@ sealed class TransactionVerificationException(val txId: SecureHash, message: Str
* @property contractClass The fully qualified class name of the failing contract. * @property contractClass The fully qualified class name of the failing contract.
*/ */
class ContractRejection(txId: SecureHash, val contractClass: String, cause: Throwable) : TransactionVerificationException(txId, "Contract verification failed: ${cause.message}, contract: $contractClass", cause) { class ContractRejection(txId: SecureHash, val contractClass: String, cause: Throwable) : TransactionVerificationException(txId, "Contract verification failed: ${cause.message}, contract: $contractClass", cause) {
constructor(txId: SecureHash, contract: Contract, cause: Throwable) : this(txId, contract.javaClass.name, cause) constructor(txId: SecureHash, contract: Contract, cause: Throwable) : this(txId, contract.javaClass.name, cause)
} }
/** /**
@ -118,8 +118,10 @@ sealed class TransactionVerificationException(val txId: SecureHash, message: Str
/** Whether the inputs or outputs list contains an encumbrance issue, see [TransactionMissingEncumbranceException]. */ /** Whether the inputs or outputs list contains an encumbrance issue, see [TransactionMissingEncumbranceException]. */
@CordaSerializable @CordaSerializable
enum class Direction { enum class Direction {
/** Issue in the inputs list */ INPUT, /** Issue in the inputs list */
/** Issue in the outputs list */ OUTPUT INPUT,
/** Issue in the outputs list */
OUTPUT
} }
// We could revisit and throw this more appropriate type in a future release that uses targetVersion to // We could revisit and throw this more appropriate type in a future release that uses targetVersion to

View File

@ -43,7 +43,7 @@ interface Cordapp {
val contractClassNames: List<String> val contractClassNames: List<String>
val initiatedFlows: List<Class<out FlowLogic<*>>> val initiatedFlows: List<Class<out FlowLogic<*>>>
val rpcFlows: List<Class<out FlowLogic<*>>> val rpcFlows: List<Class<out FlowLogic<*>>>
val serviceFlows: List<Class<out FlowLogic<*>>> val serviceFlows: List<Class<out FlowLogic<*>>>
val schedulableFlows: List<Class<out FlowLogic<*>>> val schedulableFlows: List<Class<out FlowLogic<*>>>
val services: List<Class<out SerializeAsToken>> val services: List<Class<out SerializeAsToken>>
val serializationWhitelists: List<SerializationWhitelist> val serializationWhitelists: List<SerializationWhitelist>

View File

@ -110,7 +110,7 @@ class CompositeKey private constructor(val threshold: Int, children: List<NodeAn
// We can't print the node details, because doing so involves serializing the node, which we can't // We can't print the node details, because doing so involves serializing the node, which we can't
// do because of the cyclic graph. // do because of the cyclic graph.
require(!curVisitedMap.contains(node)) { "Cycle detected for CompositeKey" } require(!curVisitedMap.contains(node)) { "Cycle detected for CompositeKey" }
curVisitedMap.put(node, true) curVisitedMap[node] = true
node.cycleDetection(curVisitedMap) node.cycleDetection(curVisitedMap)
} }
} }
@ -126,7 +126,7 @@ class CompositeKey private constructor(val threshold: Int, children: List<NodeAn
fun checkValidity() { fun checkValidity() {
if (validated) return if (validated) return
val visitedMap = IdentityHashMap<CompositeKey, Boolean>() val visitedMap = IdentityHashMap<CompositeKey, Boolean>()
visitedMap.put(this, true) visitedMap[this] = true
cycleDetection(visitedMap) // Graph cycle testing on the root node. cycleDetection(visitedMap) // Graph cycle testing on the root node.
checkConstraints() checkConstraints()
for ((node, _) in children) { for ((node, _) in children) {
@ -281,15 +281,17 @@ class CompositeKey private constructor(val threshold: Int, children: List<NodeAn
fun build(threshold: Int? = null): PublicKey { fun build(threshold: Int? = null): PublicKey {
require(threshold == null || threshold > 0) require(threshold == null || threshold > 0)
val n = children.size val n = children.size
return if (n > 1) return when {
CompositeKey(threshold ?: children.map { (_, weight) -> weight }.sum(), children) n > 1 -> CompositeKey(threshold ?: children.map { (_, weight) -> weight }.sum(), children)
else if (n == 1) { n == 1 -> {
require(threshold == null || threshold == children.first().weight) require(threshold == null || threshold == children.first().weight)
{ "Trying to build invalid CompositeKey, threshold value different than weight of single child node." } { "Trying to build invalid CompositeKey, threshold value different than weight of single child node." }
// Returning the only child node which is [PublicKey] itself. We need to avoid single-key [CompositeKey] instances, // Returning the only child node which is [PublicKey] itself. We need to avoid single-key [CompositeKey] instances,
// as there are scenarios where developers expected the underlying key and its composite versions to be equivalent. // as there are scenarios where developers expected the underlying key and its composite versions to be equivalent.
children.first().node children.first().node
} else throw IllegalStateException("Trying to build CompositeKey without child nodes.") }
else -> throw IllegalStateException("Trying to build CompositeKey without child nodes.")
}
} }
} }
} }

View File

@ -58,8 +58,8 @@ sealed class MerkleTree {
* @return Tree root. * @return Tree root.
*/ */
private tailrec fun buildMerkleTree(lastNodesList: List<MerkleTree>): MerkleTree { private tailrec fun buildMerkleTree(lastNodesList: List<MerkleTree>): MerkleTree {
if (lastNodesList.size == 1) { return if (lastNodesList.size == 1) {
return lastNodesList[0] // Root reached. lastNodesList[0] // Root reached.
} else { } else {
val newLevelHashes: MutableList<MerkleTree> = ArrayList() val newLevelHashes: MutableList<MerkleTree> = ArrayList()
val n = lastNodesList.size val n = lastNodesList.size
@ -71,7 +71,7 @@ sealed class MerkleTree {
val combined = Node(newHash, left, right) val combined = Node(newHash, left, right)
newLevelHashes.add(combined) newLevelHashes.add(combined)
} }
return buildMerkleTree(newLevelHashes) buildMerkleTree(newLevelHashes)
} }
} }
} }

View File

@ -28,5 +28,4 @@ object NullKeys {
/** A signature with a key and value of zero. Useful when you want a signature object that you know won't ever be used. */ /** A signature with a key and value of zero. Useful when you want a signature object that you know won't ever be used. */
val NULL_SIGNATURE = TransactionSignature(ByteArray(32), NullPublicKey, SignatureMetadata(1, -1)) val NULL_SIGNATURE = TransactionSignature(ByteArray(32), NullPublicKey, SignatureMetadata(1, -1))
} }

View File

@ -46,7 +46,7 @@ open class SignedData<T : Any>(val raw: SerializedBytes<T>, val sig: DigitalSign
* @throws IllegalArgumentException if the data is invalid. * @throws IllegalArgumentException if the data is invalid.
*/ */
@Throws(IllegalArgumentException::class) @Throws(IllegalArgumentException::class)
open protected fun verifyData(data: T) { protected open fun verifyData(data: T) {
// By default we accept anything // By default we accept anything
} }
} }

View File

@ -80,7 +80,7 @@ abstract class AbstractStateReplacementFlow {
val finalTx = stx + signatures val finalTx = stx + signatures
serviceHub.recordTransactions(finalTx) serviceHub.recordTransactions(finalTx)
return stx.resolveBaseTransaction(serviceHub).outRef<T>(0) return stx.resolveBaseTransaction(serviceHub).outRef(0)
} }
/** /**
@ -88,7 +88,7 @@ abstract class AbstractStateReplacementFlow {
* *
* @return the transaction * @return the transaction
*/ */
abstract protected fun assembleTx(): UpgradeTx protected abstract fun assembleTx(): UpgradeTx
/** /**
* Initiate sessions with parties we want signatures from. * Initiate sessions with parties we want signatures from.
@ -186,7 +186,7 @@ abstract class AbstractStateReplacementFlow {
* The proposal is returned if acceptable, otherwise a [StateReplacementException] is thrown. * The proposal is returned if acceptable, otherwise a [StateReplacementException] is thrown.
*/ */
@Throws(StateReplacementException::class) @Throws(StateReplacementException::class)
abstract protected fun verifyProposal(stx: SignedTransaction, proposal: Proposal<T>) protected abstract fun verifyProposal(stx: SignedTransaction, proposal: Proposal<T>)
private fun checkMySignatureRequired(stx: SignedTransaction) { private fun checkMySignatureRequired(stx: SignedTransaction) {
// TODO: use keys from the keyManagementService instead // TODO: use keys from the keyManagementService instead

View File

@ -88,7 +88,8 @@ class CollectSignaturesFlow @JvmOverloads constructor(val partiallySignedTx: Sig
} }
@Suspendable override fun call(): SignedTransaction { @Suspendable
override fun call(): SignedTransaction {
// Check the signatures which have already been provided and that the transaction is valid. // Check the signatures which have already been provided and that the transaction is valid.
// Usually just the Initiator and possibly an oracle would have signed at this point. // Usually just the Initiator and possibly an oracle would have signed at this point.
val myKeys: Iterable<PublicKey> = myOptionalKeys ?: listOf(ourIdentity.owningKey) val myKeys: Iterable<PublicKey> = myOptionalKeys ?: listOf(ourIdentity.owningKey)
@ -216,7 +217,8 @@ abstract class SignTransactionFlow(val otherSideSession: FlowSession,
fun tracker() = ProgressTracker(RECEIVING, VERIFYING, SIGNING) fun tracker() = ProgressTracker(RECEIVING, VERIFYING, SIGNING)
} }
@Suspendable override fun call(): SignedTransaction { @Suspendable
override fun call(): SignedTransaction {
progressTracker.currentStep = RECEIVING progressTracker.currentStep = RECEIVING
// Receive transaction and resolve dependencies, check sufficient signatures is disabled as we don't have all signatures. // Receive transaction and resolve dependencies, check sufficient signatures is disabled as we don't have all signatures.
val stx = subFlow(ReceiveTransactionFlow(otherSideSession, checkSufficientSignatures = false)) val stx = subFlow(ReceiveTransactionFlow(otherSideSession, checkSufficientSignatures = false))
@ -253,12 +255,13 @@ abstract class SignTransactionFlow(val otherSideSession: FlowSession,
return stx + mySignatures return stx + mySignatures
} }
@Suspendable private fun checkSignatures(stx: SignedTransaction) { @Suspendable
private fun checkSignatures(stx: SignedTransaction) {
// We set `ignoreUnrecognisedParties` to `true` in `groupPublicKeysByWellKnownParty`. This is because we don't // We set `ignoreUnrecognisedParties` to `true` in `groupPublicKeysByWellKnownParty`. This is because we don't
// need to recognise all keys, but just the initiator's. // need to recognise all keys, but just the initiator's.
val signingWellKnownIdentities = groupPublicKeysByWellKnownParty(serviceHub, stx.sigs.map(TransactionSignature::by), true) val signingWellKnownIdentities = groupPublicKeysByWellKnownParty(serviceHub, stx.sigs.map(TransactionSignature::by), true)
require(otherSideSession.counterparty in signingWellKnownIdentities) { require(otherSideSession.counterparty in signingWellKnownIdentities) {
"The Initiator of CollectSignaturesFlow must have signed the transaction. Found ${signingWellKnownIdentities}, expected ${otherSideSession}" "The Initiator of CollectSignaturesFlow must have signed the transaction. Found $signingWellKnownIdentities, expected $otherSideSession"
} }
val signed = stx.sigs.map { it.by } val signed = stx.sigs.map { it.by }
val allSigners = stx.tx.requiredSigningKeys val allSigners = stx.tx.requiredSigningKeys
@ -288,9 +291,10 @@ abstract class SignTransactionFlow(val otherSideSession: FlowSession,
*/ */
@Suspendable @Suspendable
@Throws(FlowException::class) @Throws(FlowException::class)
abstract protected fun checkTransaction(stx: SignedTransaction) protected abstract fun checkTransaction(stx: SignedTransaction)
@Suspendable private fun checkMySignaturesRequired(stx: SignedTransaction, signingKeys: Iterable<PublicKey>) { @Suspendable
private fun checkMySignaturesRequired(stx: SignedTransaction, signingKeys: Iterable<PublicKey>) {
require(signingKeys.all { it in stx.tx.requiredSigningKeys }) { require(signingKeys.all { it in stx.tx.requiredSigningKeys }) {
"A signature was requested for a key that isn't part of the required signing keys for transaction ${stx.id}" "A signature was requested for a key that isn't part of the required signing keys for transaction ${stx.id}"
} }

View File

@ -36,6 +36,7 @@ open class FlowException(message: String?, cause: Throwable?) :
constructor(message: String?) : this(message, null) constructor(message: String?) : this(message, null)
constructor(cause: Throwable?) : this(cause?.toString(), cause) constructor(cause: Throwable?) : this(cause?.toString(), cause)
constructor() : this(null, null) constructor() : this(null, null)
var originalErrorId: Long? = null var originalErrorId: Long? = null
override fun getErrorId(): Long? = originalErrorId override fun getErrorId(): Long? = originalErrorId
} }
@ -50,5 +51,6 @@ class UnexpectedFlowEndException(message: String, cause: Throwable?, val origina
CordaRuntimeException(message, cause), IdentifiableException { CordaRuntimeException(message, cause), IdentifiableException {
constructor(message: String, cause: Throwable?) : this(message, cause, null) constructor(message: String, cause: Throwable?) : this(message, cause, null)
constructor(message: String) : this(message, null) constructor(message: String) : this(message, null)
override fun getErrorId(): Long? = originalErrorId override fun getErrorId(): Long? = originalErrorId
} }

View File

@ -60,20 +60,21 @@ sealed class FlowInitiator : Principal {
* class hierarchy (which is now deprecated). The returned object has less information than it could have, so * class hierarchy (which is now deprecated). The returned object has less information than it could have, so
* prefer to use fetch an invocation context directly if you can (e.g. in [net.corda.core.messaging.StateMachineInfo]) * prefer to use fetch an invocation context directly if you can (e.g. in [net.corda.core.messaging.StateMachineInfo])
*/ */
val invocationContext: InvocationContext get() { val invocationContext: InvocationContext
val unknownName = CordaX500Name("UNKNOWN", "UNKNOWN", "GB") get() {
var actor: Actor? = null val unknownName = CordaX500Name("UNKNOWN", "UNKNOWN", "GB")
val origin: InvocationOrigin var actor: Actor? = null
when (this) { val origin: InvocationOrigin
is FlowInitiator.RPC -> { when (this) {
actor = Actor(Actor.Id(this.username), AuthServiceId("UNKNOWN"), unknownName) is FlowInitiator.RPC -> {
origin = InvocationOrigin.RPC(actor) actor = Actor(Actor.Id(this.username), AuthServiceId("UNKNOWN"), unknownName)
origin = InvocationOrigin.RPC(actor)
}
is FlowInitiator.Peer -> origin = InvocationOrigin.Peer(this.party.name)
is FlowInitiator.Service -> origin = InvocationOrigin.Service(this.serviceClassName, unknownName)
FlowInitiator.Shell -> origin = InvocationOrigin.Shell
is FlowInitiator.Scheduled -> origin = InvocationOrigin.Scheduled(this.scheduledState)
} }
is FlowInitiator.Peer -> origin = InvocationOrigin.Peer(this.party.name) return InvocationContext.newInstance(origin = origin, actor = actor)
is FlowInitiator.Service -> origin = InvocationOrigin.Service(this.serviceClassName, unknownName)
FlowInitiator.Shell -> origin = InvocationOrigin.Shell
is FlowInitiator.Scheduled -> origin = InvocationOrigin.Scheduled(this.scheduledState)
} }
return InvocationContext.newInstance(origin = origin, actor = actor)
}
} }

View File

@ -128,9 +128,10 @@ data class CordaX500Name(val commonName: String?,
private var _x500Principal: X500Principal? = null private var _x500Principal: X500Principal? = null
/** Return the [X500Principal] equivalent of this name. */ /** Return the [X500Principal] equivalent of this name. */
val x500Principal: X500Principal get() { val x500Principal: X500Principal
return _x500Principal ?: X500Principal(this.x500Name.encoded).also { _x500Principal = it } get() {
} return _x500Principal ?: X500Principal(this.x500Name.encoded).also { _x500Principal = it }
}
override fun toString(): String = x500Principal.toString() override fun toString(): String = x500Principal.toString()
} }

View File

@ -60,7 +60,6 @@ object Emoji {
@JvmStatic @JvmStatic
val CODE_WARNING_SIGN: String = codePointsString(0x26A0, 0xFE0F) val CODE_WARNING_SIGN: String = codePointsString(0x26A0, 0xFE0F)
/** /**
* When non-null, toString() methods are allowed to use emoji in the output as we're going to render them to a * When non-null, toString() methods are allowed to use emoji in the output as we're going to render them to a
* sufficiently capable text surface. * sufficiently capable text surface.

View File

@ -145,7 +145,6 @@ sealed class FetchDataFlow<T : NamedByHash, in W : Any>(
} }
} }
/** /**
* Given a set of hashes either loads from from local storage or requests them from the other peer. Downloaded * Given a set of hashes either loads from from local storage or requests them from the other peer. Downloaded
* attachments are saved to local storage automatically. * attachments are saved to local storage automatically.

View File

@ -61,7 +61,8 @@ sealed class FlowIORequest<out R : Any> {
val shouldRetrySend: Boolean val shouldRetrySend: Boolean
) : FlowIORequest<Map<FlowSession, SerializedBytes<Any>>>() { ) : FlowIORequest<Map<FlowSession, SerializedBytes<Any>>>() {
override fun toString() = "SendAndReceive(${sessionToMessage.mapValues { (key, value) -> override fun toString() = "SendAndReceive(${sessionToMessage.mapValues { (key, value) ->
"$key=${value.hash}" }}, shouldRetrySend=$shouldRetrySend)" "$key=${value.hash}"
}}, shouldRetrySend=$shouldRetrySend)"
} }
/** /**

View File

@ -13,10 +13,12 @@ package net.corda.core.internal
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable
import net.corda.core.DoNotImplement import net.corda.core.DoNotImplement
import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.CordaFuture
import net.corda.core.flows.*
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.context.InvocationContext import net.corda.core.context.InvocationContext
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowSession
import net.corda.core.flows.FlowStackSnapshot
import net.corda.core.flows.StateMachineRunId
import net.corda.core.identity.Party
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import org.slf4j.Logger import org.slf4j.Logger

View File

@ -49,10 +49,10 @@ class LazyPool<A>(
lifeCycle.requireState(State.STARTED) lifeCycle.requireState(State.STARTED)
poolSemaphore.acquire() poolSemaphore.acquire()
val pooled = poolQueue.poll() val pooled = poolQueue.poll()
if (pooled == null) { return if (pooled == null) {
return newInstance() newInstance()
} else { } else {
return clearIfNeeded(pooled) clearIfNeeded(pooled)
} }
} }

View File

@ -76,6 +76,6 @@ class LazyStickyPool<A : Any>(
} }
fun close(): Iterable<A> { fun close(): Iterable<A> {
return boxes.map { it.instance?.poll() }.filterNotNull() return boxes.mapNotNull { it.instance?.poll() }
} }
} }

View File

@ -10,4 +10,4 @@
package net.corda.core.internal package net.corda.core.internal
val STRUCTURAL_STEP_PREFIX = "Structural step change in child of " const val STRUCTURAL_STEP_PREFIX = "Structural step change in child of "

View File

@ -39,7 +39,7 @@ class X509EdDSAEngine : Signature {
override fun engineInitVerify(publicKey: PublicKey) { override fun engineInitVerify(publicKey: PublicKey) {
val parsedKey = try { val parsedKey = try {
publicKey as? EdDSAPublicKey ?: EdDSAPublicKey(X509EncodedKeySpec(publicKey.encoded)) publicKey as? EdDSAPublicKey ?: EdDSAPublicKey(X509EncodedKeySpec(publicKey.encoded))
} catch(e: Exception) { } catch (e: Exception) {
throw (InvalidKeyException(e.message)) throw (InvalidKeyException(e.message))
} }
engine.initVerify(parsedKey) engine.initVerify(parsedKey)
@ -53,9 +53,9 @@ class X509EdDSAEngine : Signature {
override fun engineGetParameters(): AlgorithmParameters = engine.parameters override fun engineGetParameters(): AlgorithmParameters = engine.parameters
override fun engineSetParameter(params: AlgorithmParameterSpec) = engine.setParameter(params) override fun engineSetParameter(params: AlgorithmParameterSpec) = engine.setParameter(params)
@Suppress("DEPRECATION") @Suppress("DEPRECATION", "OverridingDeprecatedMember")
override fun engineGetParameter(param: String): Any = engine.getParameter(param) override fun engineGetParameter(param: String): Any = engine.getParameter(param)
@Suppress("DEPRECATION") @Suppress("DEPRECATION", "OverridingDeprecatedMember")
override fun engineSetParameter(param: String, value: Any?) = engine.setParameter(param, value) override fun engineSetParameter(param: String, value: Any?) = engine.setParameter(param, value)
} }

View File

@ -152,7 +152,7 @@ interface OpenFuture<V> : ValueOrException<V>, CordaFuture<V>
internal class CordaFutureImpl<V>(private val impl: CompletableFuture<V> = CompletableFuture()) : Future<V> by impl, OpenFuture<V> { internal class CordaFutureImpl<V>(private val impl: CompletableFuture<V> = CompletableFuture()) : Future<V> by impl, OpenFuture<V> {
companion object { companion object {
private val defaultLog = contextLogger() private val defaultLog = contextLogger()
internal val listenerFailedMessage = "Future listener failed:" internal const val listenerFailedMessage = "Future listener failed:"
} }
override fun set(value: V) = impl.complete(value) override fun set(value: V) = impl.complete(value)

View File

@ -23,7 +23,7 @@ data class CordappImpl(
override val contractClassNames: List<String>, override val contractClassNames: List<String>,
override val initiatedFlows: List<Class<out FlowLogic<*>>>, override val initiatedFlows: List<Class<out FlowLogic<*>>>,
override val rpcFlows: List<Class<out FlowLogic<*>>>, override val rpcFlows: List<Class<out FlowLogic<*>>>,
override val serviceFlows: List<Class<out FlowLogic<*>>>, override val serviceFlows: List<Class<out FlowLogic<*>>>,
override val schedulableFlows: List<Class<out FlowLogic<*>>>, override val schedulableFlows: List<Class<out FlowLogic<*>>>,
override val services: List<Class<out SerializeAsToken>>, override val services: List<Class<out SerializeAsToken>>,
override val serializationWhitelists: List<SerializationWhitelist>, override val serializationWhitelists: List<SerializationWhitelist>,

View File

@ -64,7 +64,6 @@ interface FlowProgressHandle<A> : FlowHandle<A> {
override fun close() override fun close()
} }
@CordaSerializable @CordaSerializable
data class FlowHandleImpl<A>( data class FlowHandleImpl<A>(
override val id: StateMachineRunId, override val id: StateMachineRunId,

View File

@ -36,5 +36,4 @@ interface AppServiceHub : ServiceHub {
* TODO it is assumed here that the flow object has an appropriate classloader. * TODO it is assumed here that the flow object has an appropriate classloader.
*/ */
fun <T> startTrackedFlow(flow: FlowLogic<T>): FlowProgressHandle<T> fun <T> startTrackedFlow(flow: FlowLogic<T>): FlowProgressHandle<T>
} }

View File

@ -41,7 +41,8 @@ data class NodeInfo(val addresses: List<NetworkHostAndPort>,
require(platformVersion > 0) { "Platform version must be at least 1" } require(platformVersion > 0) { "Platform version must be at least 1" }
} }
@Transient private var _legalIdentities: List<Party>? = null @Transient
private var _legalIdentities: List<Party>? = null
/** /**
* An ordered list of legal identities supported by this node. The node will always have at least one, so if you * An ordered list of legal identities supported by this node. The node will always have at least one, so if you

View File

@ -253,7 +253,7 @@ object Builder {
fun <R> Field.functionPredicate(predicate: ColumnPredicate<R>, groupByColumns: List<Column<Any, R>>? = null, orderBy: Sort.Direction? = null) = info().functionPredicate(predicate, groupByColumns, orderBy) fun <R> Field.functionPredicate(predicate: ColumnPredicate<R>, groupByColumns: List<Column<Any, R>>? = null, orderBy: Sort.Direction? = null) = info().functionPredicate(predicate, groupByColumns, orderBy)
fun <R> FieldInfo.functionPredicate(predicate: ColumnPredicate<R>, groupByColumns: List<Column<Any, R>>? = null, orderBy: Sort.Direction? = null) fun <R> FieldInfo.functionPredicate(predicate: ColumnPredicate<R>, groupByColumns: List<Column<Any, R>>? = null, orderBy: Sort.Direction? = null)
= CriteriaExpression.AggregateFunctionExpression(Column<Any, R>(this), predicate, groupByColumns, orderBy) = CriteriaExpression.AggregateFunctionExpression(Column(this), predicate, groupByColumns, orderBy)
fun <O, R : Comparable<R>> KProperty1<O, R?>.comparePredicate(operator: BinaryComparisonOperator, value: R) = predicate(compare(operator, value)) fun <O, R : Comparable<R>> KProperty1<O, R?>.comparePredicate(operator: BinaryComparisonOperator, value: R) = predicate(compare(operator, value))
@Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.") @Deprecated("Does not support fields from a MappedSuperclass. Use equivalent on a FieldInfo.")
@ -377,7 +377,7 @@ object Builder {
@JvmStatic @JvmStatic
@JvmOverloads @JvmOverloads
fun <R> FieldInfo.sum(groupByColumns: List<FieldInfo>? = null, orderBy: Sort.Direction? = null) = fun <R> FieldInfo.sum(groupByColumns: List<FieldInfo>? = null, orderBy: Sort.Direction? = null) =
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.SUM), groupByColumns?.map { Column<Any, R>(it) }, orderBy) functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.SUM), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
fun <O, R> KProperty1<O, R?>.count() = functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.COUNT)) fun <O, R> KProperty1<O, R?>.count() = functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.COUNT))
@JvmStatic @JvmStatic
@ -397,7 +397,7 @@ object Builder {
@JvmStatic @JvmStatic
@JvmOverloads @JvmOverloads
fun <R> FieldInfo.avg(groupByColumns: List<FieldInfo>? = null, orderBy: Sort.Direction? = null) = fun <R> FieldInfo.avg(groupByColumns: List<FieldInfo>? = null, orderBy: Sort.Direction? = null) =
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.AVG), groupByColumns?.map { Column<Any, R>(it) }, orderBy) functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.AVG), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
fun <O, R> KProperty1<O, R?>.min(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) = fun <O, R> KProperty1<O, R?>.min(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) =
functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MIN), groupByColumns?.map { Column(it) }, orderBy) functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MIN), groupByColumns?.map { Column(it) }, orderBy)
@ -410,7 +410,7 @@ object Builder {
@JvmStatic @JvmStatic
@JvmOverloads @JvmOverloads
fun <R> FieldInfo.min(groupByColumns: List<FieldInfo>? = null, orderBy: Sort.Direction? = null) = fun <R> FieldInfo.min(groupByColumns: List<FieldInfo>? = null, orderBy: Sort.Direction? = null) =
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.MIN), groupByColumns?.map { Column<Any, R>(it) }, orderBy) functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MIN), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
fun <O, R> KProperty1<O, R?>.max(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) = fun <O, R> KProperty1<O, R?>.max(groupByColumns: List<KProperty1<O, R>>? = null, orderBy: Sort.Direction? = null) =
functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MAX), groupByColumns?.map { Column(it) }, orderBy) functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MAX), groupByColumns?.map { Column(it) }, orderBy)
@ -423,7 +423,7 @@ object Builder {
@JvmStatic @JvmStatic
@JvmOverloads @JvmOverloads
fun <R> FieldInfo.max(groupByColumns: List<FieldInfo>? = null, orderBy: Sort.Direction? = null) = fun <R> FieldInfo.max(groupByColumns: List<FieldInfo>? = null, orderBy: Sort.Direction? = null) =
functionPredicate(ColumnPredicate.AggregateFunction<R>(AggregateFunctionType.MAX), groupByColumns?.map { Column<Any, R>(it) }, orderBy) functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MAX), groupByColumns?.map { Column<Any, R>(it) }, orderBy)
private fun Field.info(): FieldInfo = FieldInfo(name, declaringClass) private fun Field.info(): FieldInfo = FieldInfo(name, declaringClass)
} }

View File

@ -31,7 +31,7 @@ object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, vers
override val migrationResource = "common.changelog-master" override val migrationResource = "common.changelog-master"
@MappedSuperclass @MappedSuperclass
open class LinearState( class LinearState(
/** [ContractState] attributes */ /** [ContractState] attributes */
/** X500Name of participant parties **/ /** X500Name of participant parties **/
@ -56,7 +56,7 @@ object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, vers
} }
@MappedSuperclass @MappedSuperclass
open class FungibleState( class FungibleState(
/** [ContractState] attributes */ /** [ContractState] attributes */
/** X500Name of participant parties **/ /** X500Name of participant parties **/

View File

@ -89,7 +89,8 @@ open class MappedSchema(schemaFamily: Class<*>,
* [StateRef] will be set to the correct value by the framework (there's no need to set during mapping generation by the state itself). * [StateRef] will be set to the correct value by the framework (there's no need to set during mapping generation by the state itself).
*/ */
@MappedSuperclass @MappedSuperclass
@CordaSerializable open class PersistentState(@EmbeddedId var stateRef: PersistentStateRef? = null) : StatePersistable @CordaSerializable
class PersistentState(@EmbeddedId var stateRef: PersistentStateRef? = null) : StatePersistable
/** /**
* Embedded [StateRef] representation used in state mapping. * Embedded [StateRef] representation used in state mapping.

View File

@ -24,11 +24,11 @@ interface SerializationCustomSerializer<OBJ, PROXY> {
* Should facilitate the conversion of the third party object into the serializable * Should facilitate the conversion of the third party object into the serializable
* local class specified by [PROXY] * local class specified by [PROXY]
*/ */
fun toProxy(obj: OBJ) : PROXY fun toProxy(obj: OBJ): PROXY
/** /**
* Should facilitate the conversion of the proxy object into a new instance of the * Should facilitate the conversion of the proxy object into a new instance of the
* unserializable type * unserializable type
*/ */
fun fromProxy(proxy: PROXY) : OBJ fun fromProxy(proxy: PROXY): OBJ
} }

View File

@ -222,17 +222,17 @@ data class ContractUpgradeLedgerTransaction(
* Outputs are computed by running the contract upgrade logic on input states. This is done eagerly so that the * Outputs are computed by running the contract upgrade logic on input states. This is done eagerly so that the
* transaction is verified during construction. * transaction is verified during construction.
*/ */
override val outputs: List<TransactionState<ContractState>> = inputs.map { input -> override val outputs: List<TransactionState<ContractState>> = inputs.map { (state) ->
// TODO: if there are encumbrance states in the inputs, just copy them across without modifying // TODO: if there are encumbrance states in the inputs, just copy them across without modifying
val upgradedState = upgradedContract.upgrade(input.state.data) val upgradedState = upgradedContract.upgrade(state.data)
val inputConstraint = input.state.constraint val inputConstraint = state.constraint
val outputConstraint = when (inputConstraint) { val outputConstraint = when (inputConstraint) {
is HashAttachmentConstraint -> HashAttachmentConstraint(upgradedContractAttachment.id) is HashAttachmentConstraint -> HashAttachmentConstraint(upgradedContractAttachment.id)
WhitelistedByZoneAttachmentConstraint -> WhitelistedByZoneAttachmentConstraint WhitelistedByZoneAttachmentConstraint -> WhitelistedByZoneAttachmentConstraint
else -> throw IllegalArgumentException("Unsupported input contract constraint $inputConstraint") else -> throw IllegalArgumentException("Unsupported input contract constraint $inputConstraint")
} }
// TODO: re-map encumbrance pointers // TODO: re-map encumbrance pointers
input.state.copy( state.copy(
data = upgradedState, data = upgradedState,
contract = upgradedContractClassName, contract = upgradedContractClassName,
constraint = outputConstraint constraint = outputConstraint

View File

@ -116,7 +116,7 @@ class WireTransaction(componentGroups: List<ComponentGroup>, val privacySalt: Pr
resolveIdentity: (PublicKey) -> Party?, resolveIdentity: (PublicKey) -> Party?,
resolveAttachment: (SecureHash) -> Attachment?, resolveAttachment: (SecureHash) -> Attachment?,
resolveStateRef: (StateRef) -> TransactionState<*>?, resolveStateRef: (StateRef) -> TransactionState<*>?,
resolveContractAttachment: (TransactionState<ContractState>) -> AttachmentId? @SuppressWarnings("unused") resolveContractAttachment: (TransactionState<ContractState>) -> AttachmentId?
): LedgerTransaction { ): LedgerTransaction {
return toLedgerTransactionInternal(resolveIdentity, resolveAttachment, resolveStateRef, null) return toLedgerTransactionInternal(resolveIdentity, resolveAttachment, resolveStateRef, null)
} }

View File

@ -41,7 +41,6 @@ fun ByteArray.toBase64(): String = Base64.getEncoder().encodeToString(this)
/** Convert a byte array to a hex (Base16) capitalized encoded [String]. */ /** Convert a byte array to a hex (Base16) capitalized encoded [String]. */
fun ByteArray.toHex(): String = DatatypeConverter.printHexBinary(this) fun ByteArray.toHex(): String = DatatypeConverter.printHexBinary(this)
// [String] encoders and decoders // [String] encoders and decoders
/** Base58-String to the actual real [String], i.e. "JxF12TrwUP45BMd" -> "Hello World". */ /** Base58-String to the actual real [String], i.e. "JxF12TrwUP45BMd" -> "Hello World". */
@ -60,7 +59,6 @@ fun String.base64ToByteArray(): ByteArray = Base64.getDecoder().decode(this)
/** Hex-String to [ByteArray]. Accept any hex form (capitalized, lowercase, mixed). */ /** Hex-String to [ByteArray]. Accept any hex form (capitalized, lowercase, mixed). */
fun String.hexToByteArray(): ByteArray = DatatypeConverter.parseHexBinary(this) fun String.hexToByteArray(): ByteArray = DatatypeConverter.parseHexBinary(this)
// Encoding changers // Encoding changers
/** Encoding changer. Base58-[String] to Base64-[String], i.e. "SGVsbG8gV29ybGQ=" -> JxF12TrwUP45BMd" */ /** Encoding changer. Base58-[String] to Base64-[String], i.e. "SGVsbG8gV29ybGQ=" -> JxF12TrwUP45BMd" */

View File

@ -116,8 +116,10 @@ interface VariablePropertyDelegate<T> : PropertyDelegate<T> {
@CordaSerializable @CordaSerializable
private class TransientProperty<out T> internal constructor(private val initialiser: () -> T) : PropertyDelegate<T> { private class TransientProperty<out T> internal constructor(private val initialiser: () -> T) : PropertyDelegate<T> {
@Transient private var initialised = false @Transient
@Transient private var value: T? = null private var initialised = false
@Transient
private var value: T? = null
@Synchronized @Synchronized
override operator fun getValue(thisRef: Any?, property: KProperty<*>): T { override operator fun getValue(thisRef: Any?, property: KProperty<*>): T {

View File

@ -71,11 +71,11 @@ class ProgressTracker(vararg steps: Step) {
// Sentinel objects. Overrides equals() to survive process restarts and serialization. // Sentinel objects. Overrides equals() to survive process restarts and serialization.
object UNSTARTED : Step("Unstarted") { object UNSTARTED : Step("Unstarted") {
override fun equals(other: Any?) = other is UNSTARTED override fun equals(other: Any?) = other === UNSTARTED
} }
object DONE : Step("Done") { object DONE : Step("Done") {
override fun equals(other: Any?) = other is DONE override fun equals(other: Any?) = other === DONE
} }
@CordaSerializable @CordaSerializable

View File

@ -50,7 +50,6 @@ fun <T : Any> SerializedBytes<Any>.checkPayloadIs(type: Class<T>): Untrustworthy
} catch (ex: Exception) { } catch (ex: Exception) {
throw IllegalArgumentException("Payload invalid", ex) throw IllegalArgumentException("Payload invalid", ex)
} }
return type.castIfPossible(payloadData)?.let { UntrustworthyData(it) } ?: return type.castIfPossible(payloadData)?.let { UntrustworthyData(it) } ?: throw IllegalArgumentException("We were expecting a ${type.name} but we instead got a " +
throw IllegalArgumentException("We were expecting a ${type.name} but we instead got a " + "${payloadData.javaClass.name} ($payloadData)")
"${payloadData.javaClass.name} (${payloadData})")
} }

View File

@ -15,6 +15,6 @@ import java.util.*
class UuidGenerator { class UuidGenerator {
companion object { companion object {
fun next() : UUID = UUID.randomUUID() fun next(): UUID = UUID.randomUUID()
} }
} }

View File

@ -35,7 +35,7 @@ public class FlowsInJavaTest {
private Party bob; private Party bob;
@Before @Before
public void setUp() throws Exception { public void setUp() {
aliceNode = mockNet.createPartyNode(TestConstants.ALICE_NAME); aliceNode = mockNet.createPartyNode(TestConstants.ALICE_NAME);
bobNode = mockNet.createPartyNode(TestConstants.BOB_NAME); bobNode = mockNet.createPartyNode(TestConstants.BOB_NAME);
bob = singleIdentity(bobNode.getInfo()); bob = singleIdentity(bobNode.getInfo());
@ -134,7 +134,7 @@ public class FlowsInJavaTest {
@Suspendable @Suspendable
@Override @Override
public Void call() throws FlowException { public Void call() {
FlowSession session = initiateFlow(otherParty); FlowSession session = initiateFlow(otherParty);
session.receive(Primitives.unwrap(receiveType)); session.receive(Primitives.unwrap(receiveType));
return null; return null;

View File

@ -51,7 +51,6 @@ class AttachmentTest {
} }
assertEquals(1, closeCalls) assertEquals(1, closeCalls)
} }
} }
class UniqueIdentifierTests { class UniqueIdentifierTests {
@ -83,5 +82,4 @@ class UniqueIdentifierTests {
assertEquals(ids[1], ids[2]) assertEquals(ids[1], ids[2])
assertEquals(ids[1].hashCode(), ids[2].hashCode()) assertEquals(ids[1].hashCode(), ids[2].hashCode())
} }
} }

View File

@ -186,9 +186,9 @@ class EdDSATests {
/** A test vector object for digital signature schemes. */ /** A test vector object for digital signature schemes. */
private data class SignatureTestVector(val privateKeyHex: String, private data class SignatureTestVector(val privateKeyHex: String,
val publicKeyHex: String, val publicKeyHex: String,
val messageToSignHex: String, val messageToSignHex: String,
val signatureOutputHex: String) val signatureOutputHex: String)
// Required to implement a custom doSign function, because Corda's Crypto.doSign does not allow empty messages (testVector1). // Required to implement a custom doSign function, because Corda's Crypto.doSign does not allow empty messages (testVector1).
private fun doSign(privateKey: PrivateKey, clearData: ByteArray): ByteArray { private fun doSign(privateKey: PrivateKey, clearData: ByteArray): ByteArray {

View File

@ -136,6 +136,5 @@ class X509NameConstraintsTest {
pathValidator.validate(certPath, params) pathValidator.validate(certPath, params)
true true
} }
} }
} }

View File

@ -13,7 +13,6 @@ package net.corda.core.flows
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable
import net.corda.core.contracts.Attachment import net.corda.core.contracts.Attachment
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.sha256
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.FetchAttachmentsFlow import net.corda.core.internal.FetchAttachmentsFlow
import net.corda.core.internal.FetchDataFlow import net.corda.core.internal.FetchDataFlow
@ -92,7 +91,7 @@ class AttachmentTests {
} }
@Test @Test
fun `missing`() { fun missing() {
val aliceNode = mockNet.createPartyNode(ALICE_NAME) val aliceNode = mockNet.createPartyNode(ALICE_NAME)
val bobNode = mockNet.createPartyNode(BOB_NAME) val bobNode = mockNet.createPartyNode(BOB_NAME)
aliceNode.registerInitiatedFlow(FetchAttachmentsResponse::class.java) aliceNode.registerInitiatedFlow(FetchAttachmentsResponse::class.java)

View File

@ -23,7 +23,11 @@ import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.StartedNode import net.corda.node.internal.StartedNode
import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.* import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.CHARLIE_NAME
import net.corda.testing.core.TestIdentity
import net.corda.testing.core.singleIdentity
import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.rigorousMock
import net.corda.testing.node.MockServices import net.corda.testing.node.MockServices
import net.corda.testing.node.internal.InternalMockNetwork import net.corda.testing.node.internal.InternalMockNetwork
@ -32,7 +36,6 @@ import net.corda.testing.node.internal.startFlow
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import kotlin.reflect.KClass
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith
class CollectSignaturesFlowTests { class CollectSignaturesFlowTests {
@ -86,9 +89,11 @@ class CollectSignaturesFlowTests {
@InitiatedBy(TestFlow.Initiator::class) @InitiatedBy(TestFlow.Initiator::class)
class Responder(private val otherSideSession: FlowSession) : FlowLogic<Unit>() { class Responder(private val otherSideSession: FlowSession) : FlowLogic<Unit>() {
@Suspendable override fun call() { @Suspendable
override fun call() {
val signFlow = object : SignTransactionFlow(otherSideSession) { val signFlow = object : SignTransactionFlow(otherSideSession) {
@Suspendable override fun checkTransaction(stx: SignedTransaction) = requireThat { @Suspendable
override fun checkTransaction(stx: SignedTransaction) = requireThat {
val tx = stx.tx val tx = stx.tx
val ltx = tx.toLedgerTransaction(serviceHub) val ltx = tx.toLedgerTransaction(serviceHub)
"There should only be one output state" using (tx.outputs.size == 1) "There should only be one output state" using (tx.outputs.size == 1)

View File

@ -33,7 +33,7 @@ class PartyAndCertificateTest {
@Test @Test
fun `reject a path with no roles`() { fun `reject a path with no roles`() {
val path = X509Utilities.buildCertPath(DEV_ROOT_CA.certificate) val path = X509Utilities.buildCertPath(DEV_ROOT_CA.certificate)
assertFailsWith<IllegalArgumentException> { PartyAndCertificate(path) } assertFailsWith<IllegalArgumentException> { PartyAndCertificate(path) }
} }

View File

@ -19,7 +19,7 @@ import kotlin.test.assertNotEquals
class PartyTest { class PartyTest {
@Test @Test
fun `equality`() { fun equality() {
val key = entropyToKeyPair(BigInteger.valueOf(20170207L)).public val key = entropyToKeyPair(BigInteger.valueOf(20170207L)).public
val differentKey = entropyToKeyPair(BigInteger.valueOf(7201702L)).public val differentKey = entropyToKeyPair(BigInteger.valueOf(7201702L)).public
val anonymousParty = AnonymousParty(key) val anonymousParty = AnonymousParty(key)

View File

@ -21,7 +21,6 @@ import org.junit.Test
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
import kotlin.streams.toList
import kotlin.test.assertEquals import kotlin.test.assertEquals
class AbstractAttachmentTest { class AbstractAttachmentTest {

View File

@ -71,7 +71,7 @@ class LegalNameValidatorTest {
} }
// Latin capital letter turned m // Latin capital letter turned m
assertFailsWith<IllegalArgumentException> { assertFailsWith<IllegalArgumentException> {
LegalNameValidator.validateOrganization( "Test\u019CLtd", LegalNameValidator.Validation.FULL) LegalNameValidator.validateOrganization("Test\u019CLtd", LegalNameValidator.Validation.FULL)
} }
// Latin small letter turned e // Latin small letter turned e
assertFailsWith<IllegalArgumentException> { assertFailsWith<IllegalArgumentException> {
@ -94,7 +94,7 @@ class LegalNameValidatorTest {
} }
// Latin capital letter turned m // Latin capital letter turned m
assertFailsWith<IllegalArgumentException> { assertFailsWith<IllegalArgumentException> {
LegalNameValidator.validateNameAttribute( "Test\u019CLtd", LegalNameValidator.Validation.FULL) LegalNameValidator.validateNameAttribute("Test\u019CLtd", LegalNameValidator.Validation.FULL)
} }
// Latin small letter turned e // Latin small letter turned e
assertFailsWith<IllegalArgumentException> { assertFailsWith<IllegalArgumentException> {

View File

@ -24,7 +24,7 @@ import kotlin.test.assertFailsWith
class VaultUpdateTests { class VaultUpdateTests {
private companion object { private companion object {
val DUMMY_PROGRAM_ID = "net.corda.core.node.VaultUpdateTests.DummyContract" const val DUMMY_PROGRAM_ID = "net.corda.core.node.VaultUpdateTests.DummyContract"
val DUMMY_NOTARY = TestIdentity(DUMMY_NOTARY_NAME, 20).party val DUMMY_NOTARY = TestIdentity(DUMMY_NOTARY_NAME, 20).party
val emptyUpdate = Vault.Update(emptySet(), emptySet(), type = Vault.UpdateType.GENERAL) val emptyUpdate = Vault.Update(emptySet(), emptySet(), type = Vault.UpdateType.GENERAL)
} }
@ -68,7 +68,7 @@ class VaultUpdateTests {
@Test @Test
fun `nothing plus something is something`() { fun `nothing plus something is something`() {
val before = emptyUpdate val before = emptyUpdate
val after = before + Vault.Update<ContractState>(setOf(stateAndRef0, stateAndRef1), setOf(stateAndRef2, stateAndRef3)) val after = before + Vault.Update(setOf(stateAndRef0, stateAndRef1), setOf(stateAndRef2, stateAndRef3))
val expected = Vault.Update<ContractState>(setOf(stateAndRef0, stateAndRef1), setOf(stateAndRef2, stateAndRef3)) val expected = Vault.Update<ContractState>(setOf(stateAndRef0, stateAndRef1), setOf(stateAndRef2, stateAndRef3))
assertEquals(expected, after) assertEquals(expected, after)
} }
@ -76,7 +76,7 @@ class VaultUpdateTests {
@Test @Test
fun `something plus consume state 0 is something without state 0 output`() { fun `something plus consume state 0 is something without state 0 output`() {
val before = Vault.Update<ContractState>(setOf(stateAndRef2, stateAndRef3), setOf(stateAndRef0, stateAndRef1)) val before = Vault.Update<ContractState>(setOf(stateAndRef2, stateAndRef3), setOf(stateAndRef0, stateAndRef1))
val after = before + Vault.Update<ContractState>(setOf(stateAndRef0), setOf()) val after = before + Vault.Update(setOf(stateAndRef0), setOf())
val expected = Vault.Update<ContractState>(setOf(stateAndRef2, stateAndRef3), setOf(stateAndRef1)) val expected = Vault.Update<ContractState>(setOf(stateAndRef2, stateAndRef3), setOf(stateAndRef1))
assertEquals(expected, after) assertEquals(expected, after)
} }
@ -84,7 +84,7 @@ class VaultUpdateTests {
@Test @Test
fun `something plus produce state 4 is something with additional state 4 output`() { fun `something plus produce state 4 is something with additional state 4 output`() {
val before = Vault.Update<ContractState>(setOf(stateAndRef2, stateAndRef3), setOf(stateAndRef0, stateAndRef1)) val before = Vault.Update<ContractState>(setOf(stateAndRef2, stateAndRef3), setOf(stateAndRef0, stateAndRef1))
val after = before + Vault.Update<ContractState>(setOf(), setOf(stateAndRef4)) val after = before + Vault.Update(setOf(), setOf(stateAndRef4))
val expected = Vault.Update<ContractState>(setOf(stateAndRef2, stateAndRef3), setOf(stateAndRef0, stateAndRef1, stateAndRef4)) val expected = Vault.Update<ContractState>(setOf(stateAndRef2, stateAndRef3), setOf(stateAndRef0, stateAndRef1, stateAndRef4))
assertEquals(expected, after) assertEquals(expected, after)
} }
@ -92,7 +92,7 @@ class VaultUpdateTests {
@Test @Test
fun `something plus consume states 0 and 1, and produce state 4, is something without state 0 and 1 outputs and only state 4 output`() { fun `something plus consume states 0 and 1, and produce state 4, is something without state 0 and 1 outputs and only state 4 output`() {
val before = Vault.Update<ContractState>(setOf(stateAndRef2, stateAndRef3), setOf(stateAndRef0, stateAndRef1)) val before = Vault.Update<ContractState>(setOf(stateAndRef2, stateAndRef3), setOf(stateAndRef0, stateAndRef1))
val after = before + Vault.Update<ContractState>(setOf(stateAndRef0, stateAndRef1), setOf(stateAndRef4)) val after = before + Vault.Update(setOf(stateAndRef0, stateAndRef1), setOf(stateAndRef4))
val expected = Vault.Update<ContractState>(setOf(stateAndRef2, stateAndRef3), setOf(stateAndRef4)) val expected = Vault.Update<ContractState>(setOf(stateAndRef2, stateAndRef3), setOf(stateAndRef4))
assertEquals(expected, after) assertEquals(expected, after)
} }

View File

@ -52,6 +52,7 @@ private fun createAttachmentData(content: String) = ByteArrayOutputStream().appl
private fun Attachment.extractContent() = ByteArrayOutputStream().apply { extractFile("content", this) }.toString(UTF_8.name()) private fun Attachment.extractContent() = ByteArrayOutputStream().apply { extractFile("content", this) }.toString(UTF_8.name())
@SuppressWarnings("deprecation")
private fun StartedNode<*>.saveAttachment(content: String) = database.transaction { private fun StartedNode<*>.saveAttachment(content: String) = database.transaction {
attachments.importAttachment(createAttachmentData(content).inputStream()) attachments.importAttachment(createAttachmentData(content).inputStream())
} }

View File

@ -93,7 +93,7 @@ class TransactionSerializationTests {
stx.verifyRequiredSignatures() stx.verifyRequiredSignatures()
// Corrupt the data and ensure the signature catches the problem. // Corrupt the data and ensure the signature catches the problem.
val bytesField = stx.id::bytes.javaField?.apply { setAccessible(true) } val bytesField = stx.id::bytes.javaField?.apply { isAccessible = true }
val bytes = bytesField?.get(stx.id) as ByteArray val bytes = bytesField?.get(stx.id) as ByteArray
bytes[5] = bytes[5].inc() bytes[5] = bytes[5].inc()

View File

@ -62,12 +62,12 @@ class CompatibleTransactionTests {
// Do not add attachments (empty list). // Do not add attachments (empty list).
private val componentGroupsA by lazy { private val componentGroupsA by lazy {
listOf( listOf(
inputGroup, inputGroup,
outputGroup, outputGroup,
commandGroup, commandGroup,
notaryGroup, notaryGroup,
timeWindowGroup, timeWindowGroup,
signersGroup signersGroup
) )
} }
private val wireTransactionA by lazy { WireTransaction(componentGroups = componentGroupsA, privacySalt = privacySalt) } private val wireTransactionA by lazy { WireTransaction(componentGroups = componentGroupsA, privacySalt = privacySalt) }
@ -134,7 +134,8 @@ class CompatibleTransactionTests {
@Test @Test
fun `WireTransaction constructors and compatibility`() { fun `WireTransaction constructors and compatibility`() {
val wireTransactionOldConstructor = WireTransaction(inputs, attachments, outputs, commands, notary, timeWindow, privacySalt) val groups = WireTransaction.createComponentGroups(inputs, outputs, commands, attachments, notary, timeWindow)
val wireTransactionOldConstructor = WireTransaction(groups, privacySalt)
assertEquals(wireTransactionA, wireTransactionOldConstructor) assertEquals(wireTransactionA, wireTransactionOldConstructor)
// Malformed tx - attachments is not List<SecureHash>. For this example, we mistakenly added input-state (StateRef) serialised objects with ATTACHMENTS_GROUP.ordinal. // Malformed tx - attachments is not List<SecureHash>. For this example, we mistakenly added input-state (StateRef) serialised objects with ATTACHMENTS_GROUP.ordinal.
@ -396,7 +397,7 @@ class CompatibleTransactionTests {
assertFailsWith<IllegalStateException> { WireTransaction(componentGroups = componentGroupsLessSigners, privacySalt = PrivacySalt()) } assertFailsWith<IllegalStateException> { WireTransaction(componentGroups = componentGroupsLessSigners, privacySalt = PrivacySalt()) }
// Test if there is no command to sign. // Test if there is no command to sign.
val commandsNoKey1= listOf(dummyCommand(DUMMY_KEY_2.public)) val commandsNoKey1 = listOf(dummyCommand(DUMMY_KEY_2.public))
val componentGroupsNoKey1ToSign = listOf( val componentGroupsNoKey1ToSign = listOf(
inputGroup, inputGroup,
@ -409,7 +410,7 @@ class CompatibleTransactionTests {
) )
val wtxNoKey1 = WireTransaction(componentGroups = componentGroupsNoKey1ToSign, privacySalt = PrivacySalt()) val wtxNoKey1 = WireTransaction(componentGroups = componentGroupsNoKey1ToSign, privacySalt = PrivacySalt())
val allCommandsNoKey1Ftx= wtxNoKey1.buildFilteredTransaction(Predicate(::filterCommandsOnly)) val allCommandsNoKey1Ftx = wtxNoKey1.buildFilteredTransaction(Predicate(::filterCommandsOnly))
allCommandsNoKey1Ftx.checkCommandVisibility(DUMMY_KEY_1.public) // This will pass, because there are indeed no commands to sign in the original transaction. allCommandsNoKey1Ftx.checkCommandVisibility(DUMMY_KEY_1.public) // This will pass, because there are indeed no commands to sign in the original transaction.
} }
@ -500,7 +501,7 @@ class CompatibleTransactionTests {
// Remove both last signer (KEY1) and related command. // Remove both last signer (KEY1) and related command.
// Update partial Merkle tree for signers. // Update partial Merkle tree for signers.
val updatedFilteredComponentsNoLastCommandAndSigners = listOf(noLastCommandDataGroup, noLastSignerGroup) val updatedFilteredComponentsNoLastCommandAndSigners = listOf(noLastCommandDataGroup, noLastSignerGroup)
val ftxNoLastCommandAndSigners = ftxConstructor.invoke(key1CommandsFtx.id, updatedFilteredComponentsNoLastCommandAndSigners, key1CommandsFtx.groupHashes) as FilteredTransaction val ftxNoLastCommandAndSigners = ftxConstructor.invoke(key1CommandsFtx.id, updatedFilteredComponentsNoLastCommandAndSigners, key1CommandsFtx.groupHashes)
// verify() will pass as the transaction is well-formed. // verify() will pass as the transaction is well-formed.
ftxNoLastCommandAndSigners.verify() ftxNoLastCommandAndSigners.verify()
// checkCommandVisibility() will not pass, because checkAllComponentsVisible(ComponentGroupEnum.SIGNERS_GROUP) will fail. // checkCommandVisibility() will not pass, because checkAllComponentsVisible(ComponentGroupEnum.SIGNERS_GROUP) will fail.
@ -509,7 +510,7 @@ class CompatibleTransactionTests {
// Remove last signer for which there is no pointer from a visible commandData. This is the case of Key2. // Remove last signer for which there is no pointer from a visible commandData. This is the case of Key2.
// Do not change partial Merkle tree for signers. // Do not change partial Merkle tree for signers.
// This time the object can be constructed as there is no pointer mismatch. // This time the object can be constructed as there is no pointer mismatch.
val ftxNoLastSigner = ftxConstructor.invoke(key2CommandsFtx.id, updatedFilteredComponentsNoSignersKey2SamePMT, key2CommandsFtx.groupHashes) as FilteredTransaction val ftxNoLastSigner = ftxConstructor.invoke(key2CommandsFtx.id, updatedFilteredComponentsNoSignersKey2SamePMT, key2CommandsFtx.groupHashes)
// verify() will fail as we didn't change the partial Merkle tree. // verify() will fail as we didn't change the partial Merkle tree.
assertFailsWith<FilteredTransactionVerificationException> { ftxNoLastSigner.verify() } assertFailsWith<FilteredTransactionVerificationException> { ftxNoLastSigner.verify() }
// checkCommandVisibility() will not pass. // checkCommandVisibility() will not pass.
@ -517,7 +518,7 @@ class CompatibleTransactionTests {
// Remove last signer for which there is no pointer from a visible commandData. This is the case of Key2. // Remove last signer for which there is no pointer from a visible commandData. This is the case of Key2.
// Update partial Merkle tree for signers. // Update partial Merkle tree for signers.
val ftxNoLastSignerB = ftxConstructor.invoke(key2CommandsFtx.id, updatedFilteredComponentsNoSignersKey2, key2CommandsFtx.groupHashes) as FilteredTransaction val ftxNoLastSignerB = ftxConstructor.invoke(key2CommandsFtx.id, updatedFilteredComponentsNoSignersKey2, key2CommandsFtx.groupHashes)
// verify() will pass, the transaction is well-formed. // verify() will pass, the transaction is well-formed.
ftxNoLastSignerB.verify() ftxNoLastSignerB.verify()
// But, checkAllComponentsVisible() will not pass. // But, checkAllComponentsVisible() will not pass.
@ -542,14 +543,14 @@ class CompatibleTransactionTests {
val alterFilteredComponents = listOf(key1CommandsFtx.filteredComponentGroups[0], alterSignerGroup) val alterFilteredComponents = listOf(key1CommandsFtx.filteredComponentGroups[0], alterSignerGroup)
// Do not update groupHashes. // Do not update groupHashes.
val ftxAlterSigner = ftxConstructor.invoke(key1CommandsFtx.id, alterFilteredComponents, key1CommandsFtx.groupHashes) as FilteredTransaction val ftxAlterSigner = ftxConstructor.invoke(key1CommandsFtx.id, alterFilteredComponents, key1CommandsFtx.groupHashes)
// Visible components in signers group cannot be verified against their partial Merkle tree. // Visible components in signers group cannot be verified against their partial Merkle tree.
assertFailsWith<FilteredTransactionVerificationException> { ftxAlterSigner.verify() } assertFailsWith<FilteredTransactionVerificationException> { ftxAlterSigner.verify() }
// Also, checkAllComponentsVisible() will not pass (groupHash matching will fail). // Also, checkAllComponentsVisible() will not pass (groupHash matching will fail).
assertFailsWith<ComponentVisibilityException> { ftxAlterSigner.checkCommandVisibility(DUMMY_KEY_1.public) } assertFailsWith<ComponentVisibilityException> { ftxAlterSigner.checkCommandVisibility(DUMMY_KEY_1.public) }
// Update groupHashes. // Update groupHashes.
val ftxAlterSignerB = ftxConstructor.invoke(key1CommandsFtx.id, alterFilteredComponents, key1CommandsFtx.groupHashes.subList(0, 6) + alterMTree.hash) as FilteredTransaction val ftxAlterSignerB = ftxConstructor.invoke(key1CommandsFtx.id, alterFilteredComponents, key1CommandsFtx.groupHashes.subList(0, 6) + alterMTree.hash)
// Visible components in signers group cannot be verified against their partial Merkle tree. // Visible components in signers group cannot be verified against their partial Merkle tree.
assertFailsWith<FilteredTransactionVerificationException> { ftxAlterSignerB.verify() } assertFailsWith<FilteredTransactionVerificationException> { ftxAlterSignerB.verify() }
// Also, checkAllComponentsVisible() will not pass (top level Merkle tree cannot be verified against transaction's id). // Also, checkAllComponentsVisible() will not pass (top level Merkle tree cannot be verified against transaction's id).

View File

@ -32,7 +32,7 @@ import org.junit.Test
import java.time.Instant import java.time.Instant
import java.time.temporal.ChronoUnit import java.time.temporal.ChronoUnit
val TEST_TIMELOCK_ID = "net.corda.core.transactions.TransactionEncumbranceTests\$DummyTimeLock" const val TEST_TIMELOCK_ID = "net.corda.core.transactions.TransactionEncumbranceTests\$DummyTimeLock"
class TransactionEncumbranceTests { class TransactionEncumbranceTests {
private companion object { private companion object {

View File

@ -476,7 +476,7 @@ public class FlowCookbookJava {
subFlow(new SendStateAndRefFlow(counterpartySession, dummyStates)); subFlow(new SendStateAndRefFlow(counterpartySession, dummyStates));
// On the receive side ... // On the receive side ...
List<StateAndRef<DummyState>> resolvedStateAndRef = subFlow(new ReceiveStateAndRefFlow<DummyState>(counterpartySession)); List<StateAndRef<DummyState>> resolvedStateAndRef = subFlow(new ReceiveStateAndRefFlow<>(counterpartySession));
// DOCEND 14 // DOCEND 14
try { try {

View File

@ -60,7 +60,7 @@ public class CommercialPaper implements Contract {
requireThat(require -> { requireThat(require -> {
require.using("the paper must have matured", time.isAfter(input.getMaturityDate())); require.using("the paper must have matured", time.isAfter(input.getMaturityDate()));
require.using("the received amount equals the face value", received == input.getFaceValue()); require.using("the received amount equals the face value", received == input.getFaceValue());
require.using("the paper must be destroyed", outputs.size() == 0); require.using("the paper must be destroyed", outputs.isEmpty());
require.using("the transaction is signed by the owner of the CP", cmd.getSigners().contains(input.getOwner().getOwningKey())); require.using("the transaction is signed by the owner of the CP", cmd.getSigners().contains(input.getOwner().getOwningKey()));
return null; return null;
}); });

View File

@ -153,9 +153,8 @@ object TopupIssuerFlow {
// now invoke Cash subflow to Move issued assetType to issue requester // now invoke Cash subflow to Move issued assetType to issue requester
progressTracker.currentStep = TRANSFERRING progressTracker.currentStep = TRANSFERRING
val moveCashFlow = CashPaymentFlow(amount, issueTo, anonymous = false) val moveCashFlow = CashPaymentFlow(amount, issueTo, anonymous = false)
val moveTx = subFlow(moveCashFlow)
// NOTE: CashFlow PayCash calls FinalityFlow which performs a Broadcast (which stores a local copy of the txn to the ledger) // NOTE: CashFlow PayCash calls FinalityFlow which performs a Broadcast (which stores a local copy of the txn to the ledger)
return moveTx return subFlow(moveCashFlow)
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show More