mirror of
https://github.com/corda/corda.git
synced 2025-03-05 21:51:53 +00:00
Rename PublicKeyTree -> CompositeKey and unify terminology across documentation.
This commit is contained in:
parent
e34820a480
commit
64299591c3
@ -4,7 +4,7 @@ import javafx.collections.ObservableList
|
||||
import kotlinx.support.jdk8.collections.removeIf
|
||||
import net.corda.client.fxutils.foldToObservableList
|
||||
import net.corda.client.fxutils.map
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.node.services.NetworkMapCache
|
||||
import net.corda.node.services.network.NetworkMapService
|
||||
@ -34,7 +34,7 @@ class NetworkIdentityModel {
|
||||
return advertisedServices.any { it.info.type == NetworkMapService.type || it.info.type.isNotary() }
|
||||
}
|
||||
|
||||
fun lookup(publicKeyTree: PublicKeyTree): NodeInfo? {
|
||||
return parties.firstOrNull { it.legalIdentity.owningKey == publicKeyTree } ?: notaries.firstOrNull { it.notaryIdentity.owningKey == publicKeyTree }
|
||||
fun lookup(compositeKey: CompositeKey): NodeInfo? {
|
||||
return parties.firstOrNull { it.legalIdentity.owningKey == compositeKey } ?: notaries.firstOrNull { it.notaryIdentity.owningKey == compositeKey }
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
@file:JvmName("ContractsDSL")
|
||||
package net.corda.core.contracts
|
||||
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
@ -60,7 +60,7 @@ inline fun <R> requireThat(body: Requirements.() -> R) = R.body()
|
||||
//// Authenticated commands ///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Filters the command list by type, party and public key all at once. */
|
||||
inline fun <reified T : CommandData> Collection<AuthenticatedObject<CommandData>>.select(signer: PublicKeyTree? = null,
|
||||
inline fun <reified T : CommandData> Collection<AuthenticatedObject<CommandData>>.select(signer: CompositeKey? = null,
|
||||
party: Party? = null) =
|
||||
filter { it.value is T }.
|
||||
filter { if (signer == null) true else signer in it.signers }.
|
||||
@ -68,7 +68,7 @@ inline fun <reified T : CommandData> Collection<AuthenticatedObject<CommandData>
|
||||
map { AuthenticatedObject(it.signers, it.signingParties, it.value as T) }
|
||||
|
||||
/** Filters the command list by type, parties and public keys all at once. */
|
||||
inline fun <reified T : CommandData> Collection<AuthenticatedObject<CommandData>>.select(signers: Collection<PublicKeyTree>?,
|
||||
inline fun <reified T : CommandData> Collection<AuthenticatedObject<CommandData>>.select(signers: Collection<CompositeKey>?,
|
||||
parties: Collection<Party>?) =
|
||||
filter { it.value is T }.
|
||||
filter { if (signers == null) true else it.signers.containsAll(signers)}.
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.corda.core.contracts
|
||||
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
|
||||
@ -15,12 +15,12 @@ class DummyContract : Contract {
|
||||
val magicNumber: Int
|
||||
}
|
||||
|
||||
data class SingleOwnerState(override val magicNumber: Int = 0, override val owner: PublicKeyTree) : OwnableState, State {
|
||||
data class SingleOwnerState(override val magicNumber: Int = 0, override val owner: CompositeKey) : OwnableState, State {
|
||||
override val contract = DUMMY_PROGRAM_ID
|
||||
override val participants: List<PublicKeyTree>
|
||||
override val participants: List<CompositeKey>
|
||||
get() = listOf(owner)
|
||||
|
||||
override fun withNewOwner(newOwner: PublicKeyTree) = Pair(Commands.Move(), copy(owner = newOwner))
|
||||
override fun withNewOwner(newOwner: CompositeKey) = Pair(Commands.Move(), copy(owner = newOwner))
|
||||
}
|
||||
|
||||
/**
|
||||
@ -29,9 +29,9 @@ class DummyContract : Contract {
|
||||
* in a different field, however this is a good example of a contract with multiple states.
|
||||
*/
|
||||
data class MultiOwnerState(override val magicNumber: Int = 0,
|
||||
val owners: List<PublicKeyTree>) : ContractState, State {
|
||||
val owners: List<CompositeKey>) : ContractState, State {
|
||||
override val contract = DUMMY_PROGRAM_ID
|
||||
override val participants: List<PublicKeyTree>
|
||||
override val participants: List<CompositeKey>
|
||||
get() = owners
|
||||
}
|
||||
|
||||
@ -54,8 +54,8 @@ class DummyContract : Contract {
|
||||
return TransactionType.General.Builder(notary = notary).withItems(state, Command(Commands.Create(), owner.party.owningKey))
|
||||
}
|
||||
|
||||
fun move(prior: StateAndRef<DummyContract.SingleOwnerState>, newOwner: PublicKeyTree) = move(listOf(prior), newOwner)
|
||||
fun move(priors: List<StateAndRef<DummyContract.SingleOwnerState>>, newOwner: PublicKeyTree): TransactionBuilder {
|
||||
fun move(prior: StateAndRef<DummyContract.SingleOwnerState>, newOwner: CompositeKey) = move(listOf(prior), newOwner)
|
||||
fun move(priors: List<StateAndRef<DummyContract.SingleOwnerState>>, newOwner: CompositeKey): TransactionBuilder {
|
||||
require(priors.size > 0)
|
||||
val priorState = priors[0].state.data
|
||||
val (cmd, state) = priorState.withNewOwner(newOwner)
|
||||
|
@ -1,11 +1,11 @@
|
||||
package net.corda.core.contracts
|
||||
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
/**
|
||||
* Dummy state for use in testing. Not part of any contract, not even the [DummyContract].
|
||||
*/
|
||||
data class DummyState(val magicNumber: Int = 0) : ContractState {
|
||||
override val contract = DUMMY_PROGRAM_ID
|
||||
override val participants: List<PublicKeyTree>
|
||||
override val participants: List<CompositeKey>
|
||||
get() = emptyList()
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package net.corda.core.contracts
|
||||
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
|
||||
class InsufficientBalanceException(val amountMissing: Amount<*>) : Exception() {
|
||||
override fun toString() = "Insufficient balance, missing $amountMissing"
|
||||
@ -26,11 +26,11 @@ interface FungibleAsset<T> : OwnableState {
|
||||
* There must be an ExitCommand signed by these keys to destroy the amount. While all states require their
|
||||
* owner to sign, some (i.e. cash) also require the issuer.
|
||||
*/
|
||||
val exitKeys: Collection<PublicKeyTree>
|
||||
val exitKeys: Collection<CompositeKey>
|
||||
/** There must be a MoveCommand signed by this key to claim the amount */
|
||||
override val owner: PublicKeyTree
|
||||
override val owner: CompositeKey
|
||||
|
||||
fun move(newAmount: Amount<Issued<T>>, newOwner: PublicKeyTree): FungibleAsset<T>
|
||||
fun move(newAmount: Amount<Issued<T>>, newOwner: CompositeKey): FungibleAsset<T>
|
||||
|
||||
// Just for grouping
|
||||
interface Commands : CommandData {
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.corda.core.contracts
|
||||
|
||||
import net.corda.core.contracts.clauses.Clause
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.node.services.ServiceType
|
||||
import net.corda.core.protocols.ProtocolLogicRef
|
||||
@ -113,7 +113,7 @@ interface ContractState {
|
||||
* The participants list should normally be derived from the contents of the state. E.g. for [Cash] the participants
|
||||
* list should just contain the owner.
|
||||
*/
|
||||
val participants: List<PublicKeyTree>
|
||||
val participants: List<CompositeKey>
|
||||
|
||||
/**
|
||||
* All contract states may be _encumbered_ by up to one other state.
|
||||
@ -184,10 +184,10 @@ fun <T> Amount<Issued<T>>.withoutIssuer(): Amount<T> = Amount(quantity, token.pr
|
||||
*/
|
||||
interface OwnableState : ContractState {
|
||||
/** There must be a MoveCommand signed by this key to claim the amount */
|
||||
val owner: PublicKeyTree
|
||||
val owner: CompositeKey
|
||||
|
||||
/** Copies the underlying data structure, replacing the owner field with this new value and leaving the rest alone */
|
||||
fun withNewOwner(newOwner: PublicKeyTree): Pair<CommandData, OwnableState>
|
||||
fun withNewOwner(newOwner: CompositeKey): Pair<CommandData, OwnableState>
|
||||
}
|
||||
|
||||
/** Something which is scheduled to happen at a point in time */
|
||||
@ -351,12 +351,12 @@ abstract class TypeOnlyCommandData : CommandData {
|
||||
}
|
||||
|
||||
/** Command data/content plus pubkey pair: the signature is stored at the end of the serialized bytes */
|
||||
data class Command(val value: CommandData, val signers: List<PublicKeyTree>) {
|
||||
data class Command(val value: CommandData, val signers: List<CompositeKey>) {
|
||||
init {
|
||||
require(signers.isNotEmpty())
|
||||
}
|
||||
|
||||
constructor(data: CommandData, key: PublicKeyTree) : this(data, listOf(key))
|
||||
constructor(data: CommandData, key: CompositeKey) : this(data, listOf(key))
|
||||
|
||||
private fun commandDataToString() = value.toString().let { if (it.contains("@")) it.replace('$', '.').split("@")[0] else it }
|
||||
override fun toString() = "${commandDataToString()} with pubkeys ${signers.joinToString()}"
|
||||
@ -386,7 +386,7 @@ interface NetCommand : CommandData {
|
||||
|
||||
/** Wraps an object that was signed by a public key, which may be a well known/recognised institutional key. */
|
||||
data class AuthenticatedObject<out T : Any>(
|
||||
val signers: List<PublicKeyTree>,
|
||||
val signers: List<CompositeKey>,
|
||||
/** If any public keys were recognised, the looked up institutions are available here */
|
||||
val signingParties: List<Party>,
|
||||
val value: T
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.corda.core.contracts
|
||||
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
|
||||
@ -25,7 +25,7 @@ sealed class TransactionType {
|
||||
}
|
||||
|
||||
/** Check that the list of signers includes all the necessary keys */
|
||||
fun verifySigners(tx: LedgerTransaction): Set<PublicKeyTree> {
|
||||
fun verifySigners(tx: LedgerTransaction): Set<CompositeKey> {
|
||||
val notaryKey = tx.inputs.map { it.state.notary.owningKey }.toSet()
|
||||
if (notaryKey.size > 1) throw TransactionVerificationException.MoreThanOneNotary(tx)
|
||||
|
||||
@ -39,7 +39,7 @@ sealed class TransactionType {
|
||||
* Return the list of public keys that that require signatures for the transaction type.
|
||||
* Note: the notary key is checked separately for all transactions and need not be included.
|
||||
*/
|
||||
abstract fun getRequiredSigners(tx: LedgerTransaction): Set<PublicKeyTree>
|
||||
abstract fun getRequiredSigners(tx: LedgerTransaction): Set<CompositeKey>
|
||||
|
||||
/** Implement type specific transaction validation logic */
|
||||
abstract fun verifyTransaction(tx: LedgerTransaction)
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.corda.core.contracts
|
||||
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import java.util.*
|
||||
@ -93,7 +93,7 @@ class TransactionConflictException(val conflictRef: StateRef, val tx1: LedgerTra
|
||||
sealed class TransactionVerificationException(val tx: LedgerTransaction, cause: Throwable?) : Exception(cause) {
|
||||
class ContractRejection(tx: LedgerTransaction, val contract: Contract, cause: Throwable?) : TransactionVerificationException(tx, cause)
|
||||
class MoreThanOneNotary(tx: LedgerTransaction) : TransactionVerificationException(tx, null)
|
||||
class SignersMissing(tx: LedgerTransaction, val missing: List<PublicKeyTree>) : TransactionVerificationException(tx, null) {
|
||||
class SignersMissing(tx: LedgerTransaction, val missing: List<CompositeKey>) : TransactionVerificationException(tx, null) {
|
||||
override fun toString() = "Signers missing: ${missing.joinToString()}"
|
||||
}
|
||||
class InvalidNotaryChange(tx: LedgerTransaction) : TransactionVerificationException(tx, null)
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.corda.core.crypto
|
||||
|
||||
import net.corda.core.crypto.PublicKeyTree.Leaf
|
||||
import net.corda.core.crypto.PublicKeyTree.Node
|
||||
import net.corda.core.crypto.CompositeKey.Leaf
|
||||
import net.corda.core.crypto.CompositeKey.Node
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.serialization.serialize
|
||||
import java.security.PublicKey
|
||||
@ -19,7 +19,7 @@ import java.security.PublicKey
|
||||
* Using these constructs we can express e.g. 1 of N (OR) or N of N (AND) signature requirements. By nesting we can
|
||||
* create multi-level requirements such as *"either the CEO or 3 of 5 of his assistants need to sign"*.
|
||||
*/
|
||||
sealed class PublicKeyTree {
|
||||
sealed class CompositeKey {
|
||||
/** Checks whether [keys] match a sufficient amount of leaf nodes */
|
||||
abstract fun isFulfilledBy(keys: Iterable<PublicKey>): Boolean
|
||||
|
||||
@ -35,11 +35,11 @@ sealed class PublicKeyTree {
|
||||
fun toBase58String(): String = Base58.encode(this.serialize().bits)
|
||||
|
||||
companion object {
|
||||
fun parseFromBase58(encoded: String) = Base58.decode(encoded).deserialize<PublicKeyTree>()
|
||||
fun parseFromBase58(encoded: String) = Base58.decode(encoded).deserialize<CompositeKey>()
|
||||
}
|
||||
|
||||
/** The leaf node of the public key tree – a wrapper around a [PublicKey] primitive */
|
||||
class Leaf(val publicKey: PublicKey) : PublicKeyTree() {
|
||||
/** The leaf node of the tree – a wrapper around a [PublicKey] primitive */
|
||||
class Leaf(val publicKey: PublicKey) : CompositeKey() {
|
||||
override fun isFulfilledBy(keys: Iterable<PublicKey>) = publicKey in keys
|
||||
|
||||
override val keys: Set<PublicKey>
|
||||
@ -56,15 +56,15 @@ sealed class PublicKeyTree {
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a node in the [PublicKeyTree]. It maintains a list of child nodes – sub-trees, and associated
|
||||
* Represents a node in the key tree. It maintains a list of child nodes – sub-trees, and associated
|
||||
* [weights] carried by child node signatures.
|
||||
*
|
||||
* The [threshold] specifies the minimum total weight required (in the simple case – the minimum number of child
|
||||
* signatures required) to satisfy the public key sub-tree rooted at this node.
|
||||
* signatures required) to satisfy the sub-tree rooted at this node.
|
||||
*/
|
||||
class Node(val threshold: Int,
|
||||
val children: List<PublicKeyTree>,
|
||||
val weights: List<Int>) : PublicKeyTree() {
|
||||
val children: List<CompositeKey>,
|
||||
val weights: List<Int>) : CompositeKey() {
|
||||
|
||||
override fun isFulfilledBy(keys: Iterable<PublicKey>): Boolean {
|
||||
val totalWeight = children.mapIndexed { i, childNode ->
|
||||
@ -101,44 +101,44 @@ sealed class PublicKeyTree {
|
||||
override fun toString() = "(${children.joinToString()})"
|
||||
}
|
||||
|
||||
/** A helper class for building a [PublicKeyTree.Node]. */
|
||||
/** A helper class for building a [CompositeKey.Node]. */
|
||||
class Builder() {
|
||||
private val children: MutableList<PublicKeyTree> = mutableListOf()
|
||||
private val children: MutableList<CompositeKey> = mutableListOf()
|
||||
private val weights: MutableList<Int> = mutableListOf()
|
||||
|
||||
/** Adds a child [PublicKeyTree] node. Specifying a [weight] for the child is optional and will default to 1. */
|
||||
fun addKey(publicKey: PublicKeyTree, weight: Int = 1): Builder {
|
||||
children.add(publicKey)
|
||||
/** Adds a child [CompositeKey] node. Specifying a [weight] for the child is optional and will default to 1. */
|
||||
fun addKey(key: CompositeKey, weight: Int = 1): Builder {
|
||||
children.add(key)
|
||||
weights.add(weight)
|
||||
return this
|
||||
}
|
||||
|
||||
fun addKeys(vararg publicKeys: PublicKeyTree): Builder {
|
||||
publicKeys.forEach { addKey(it) }
|
||||
fun addKeys(vararg keys: CompositeKey): Builder {
|
||||
keys.forEach { addKey(it) }
|
||||
return this
|
||||
}
|
||||
|
||||
fun addKeys(publicKeys: List<PublicKeyTree>): Builder = addKeys(*publicKeys.toTypedArray())
|
||||
fun addKeys(keys: List<CompositeKey>): Builder = addKeys(*keys.toTypedArray())
|
||||
|
||||
/**
|
||||
* Builds the [PublicKeyTree.Node]. If [threshold] is not specified, it will default to
|
||||
* Builds the [CompositeKey.Node]. If [threshold] is not specified, it will default to
|
||||
* the size of the children, effectively generating an "N of N" requirement.
|
||||
*/
|
||||
fun build(threshold: Int? = null): PublicKeyTree {
|
||||
fun build(threshold: Int? = null): CompositeKey {
|
||||
return if (children.size == 1) children.first()
|
||||
else Node(threshold ?: children.size, children.toList(), weights.toList())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the enclosed [PublicKey] for a [PublicKeyTree] with a single node
|
||||
* Returns the enclosed [PublicKey] for a [CompositeKey] with a single leaf node
|
||||
*
|
||||
* @throws IllegalArgumentException if the [PublicKeyTree] contains more than one node
|
||||
* @throws IllegalArgumentException if the [CompositeKey] contains more than one node
|
||||
*/
|
||||
val singleKey: PublicKey
|
||||
get() = keys.singleOrNull() ?: throw IllegalStateException("The public key tree has more than one node")
|
||||
get() = keys.singleOrNull() ?: throw IllegalStateException("The key is composed of more than one PublicKey primitive")
|
||||
}
|
||||
|
||||
/** Returns the set of all [PublicKey]s contained in the leaves of the [PublicKeyTree]s */
|
||||
val Iterable<PublicKeyTree>.keys: Set<PublicKey>
|
||||
/** Returns the set of all [PublicKey]s contained in the leaves of the [CompositeKey]s */
|
||||
val Iterable<CompositeKey>.keys: Set<PublicKey>
|
||||
get() = flatMap { it.keys }.toSet()
|
@ -43,7 +43,7 @@ object NullPublicKey : PublicKey, Comparable<PublicKey> {
|
||||
override fun toString() = "NULL_KEY"
|
||||
}
|
||||
|
||||
val NullPublicKeyTree = NullPublicKey.tree
|
||||
val NullCompositeKey = NullPublicKey.composite
|
||||
|
||||
// TODO: Clean up this duplication between Null and Dummy public key
|
||||
class DummyPublicKey(val s: String) : PublicKey, Comparable<PublicKey> {
|
||||
@ -102,8 +102,8 @@ fun PublicKey.toStringShort(): String {
|
||||
} ?: toString()
|
||||
}
|
||||
|
||||
/** Creates a [PublicKeyTree] with a single leaf node containing the public key */
|
||||
val PublicKey.tree: PublicKeyTree get() = PublicKeyTree.Leaf(this)
|
||||
/** Creates a [CompositeKey] with a single leaf node containing the public key */
|
||||
val PublicKey.composite: CompositeKey get() = CompositeKey.Leaf(this)
|
||||
|
||||
/** Returns the set of all [PublicKey]s of the signatures */
|
||||
fun Iterable<DigitalSignature.WithKey>.byKeys() = map { it.by }.toSet()
|
||||
|
@ -7,7 +7,7 @@ import java.security.PublicKey
|
||||
/**
|
||||
* The [Party] class represents an entity on the network, which is typically identified by a legal [name] and public key
|
||||
* that it can sign transactions under. As parties may use multiple keys for signing and, for example, have offline backup
|
||||
* keys, the "public key" of a party is represented by a composite construct – a [PublicKeyTree], which combines multiple
|
||||
* keys, the "public key" of a party is represented by a composite construct – a [CompositeKey], which combines multiple
|
||||
* cryptographic public key primitives into a tree structure.
|
||||
*
|
||||
* For example: Alice has two key pairs (pub1/priv1 and pub2/priv2), and wants to be able to sign transactions with either of them.
|
||||
@ -15,14 +15,14 @@ import java.security.PublicKey
|
||||
*
|
||||
* [Party] is also used for service identities. E.g. Alice may also be running an interest rate oracle on her Corda node,
|
||||
* which requires a separate signing key (and an identifying name). Services can also be distributed – run by a coordinated
|
||||
* cluster of Corda nodes. A [Party] representing a distributed service will have a public key tree composed of the
|
||||
* cluster of Corda nodes. A [Party] representing a distributed service will use a composite key containing all
|
||||
* individual cluster nodes' public keys. Each of the nodes in the cluster will advertise the same group [Party].
|
||||
*
|
||||
* @see PublicKeyTree
|
||||
* @see CompositeKey
|
||||
*/
|
||||
data class Party(val name: String, val owningKey: PublicKeyTree) {
|
||||
/** A helper constructor that converts the given [PublicKey] in to a [PublicKeyTree] with a single node */
|
||||
constructor(name: String, owningKey: PublicKey) : this(name, owningKey.tree)
|
||||
data class Party(val name: String, val owningKey: CompositeKey) {
|
||||
/** A helper constructor that converts the given [PublicKey] in to a [CompositeKey] with a single node */
|
||||
constructor(name: String, owningKey: PublicKey) : this(name, owningKey.composite)
|
||||
|
||||
override fun toString() = name
|
||||
|
||||
|
@ -61,7 +61,7 @@ interface ServiceHub {
|
||||
* Typical use is during signing in protocols and for unit test signing.
|
||||
*
|
||||
* TODO: legalIdentity can now be composed of multiple keys, should we return a list of keyPairs here? Right now
|
||||
* the logic assumes the legal identity has a public key tree with only one node
|
||||
* the logic assumes the legal identity has a composite key with only one node
|
||||
*/
|
||||
val legalIdentityKey: KeyPair get() = this.keyManagementService.toKeyPair(this.myInfo.legalIdentity.owningKey.keys)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.corda.core.node.services
|
||||
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
|
||||
/**
|
||||
* An identity service maintains an bidirectional map of [Party]s to their associated public keys and thus supports
|
||||
@ -15,6 +15,6 @@ interface IdentityService {
|
||||
// indefinitely. It may be that in the long term we need to drop or archive very old Party information for space,
|
||||
// but for now this is not supported.
|
||||
|
||||
fun partyFromKey(key: PublicKeyTree): Party?
|
||||
fun partyFromKey(key: CompositeKey): Party?
|
||||
fun partyFromName(name: String): Party?
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ package net.corda.core.node.services
|
||||
import com.google.common.annotations.VisibleForTesting
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import net.corda.core.contracts.Contract
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.messaging.MessagingService
|
||||
import net.corda.core.messaging.SingleMessageRecipient
|
||||
import net.corda.core.node.NodeInfo
|
||||
@ -72,9 +72,9 @@ interface NetworkMapCache {
|
||||
fun getNodeByLegalName(name: String): NodeInfo?
|
||||
|
||||
/**
|
||||
* Look up the node info for a public key tree.
|
||||
* Look up the node info for a composite key.
|
||||
*/
|
||||
fun getNodeByPublicKeyTree(publicKeyTree: PublicKeyTree): NodeInfo?
|
||||
fun getNodeByCompositeKey(compositeKey: CompositeKey): NodeInfo?
|
||||
|
||||
/**
|
||||
* Given a [party], returns a node advertising it as an identity. If more than one node found the result
|
||||
|
@ -3,8 +3,8 @@ package net.corda.core.node.services
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import com.google.common.util.concurrent.SettableFuture
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.toStringShort
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
@ -185,8 +185,8 @@ interface VaultService {
|
||||
@Throws(InsufficientBalanceException::class)
|
||||
fun generateSpend(tx: TransactionBuilder,
|
||||
amount: Amount<Currency>,
|
||||
to: PublicKeyTree,
|
||||
onlyFromParties: Set<Party>? = null): Pair<TransactionBuilder, List<PublicKeyTree>>
|
||||
to: CompositeKey,
|
||||
onlyFromParties: Set<Party>? = null): Pair<TransactionBuilder, List<CompositeKey>>
|
||||
}
|
||||
|
||||
inline fun <reified T : LinearState> VaultService.linearHeadsOfType() = linearHeadsOfType_(T::class.java)
|
||||
|
@ -266,7 +266,7 @@ object WireTransactionSerializer : Serializer<WireTransaction>() {
|
||||
val outputs = kryo.readClassAndObject(input) as List<TransactionState<ContractState>>
|
||||
val commands = kryo.readClassAndObject(input) as List<Command>
|
||||
val notary = kryo.readClassAndObject(input) as Party?
|
||||
val signers = kryo.readClassAndObject(input) as List<PublicKeyTree>
|
||||
val signers = kryo.readClassAndObject(input) as List<CompositeKey>
|
||||
val transactionType = kryo.readClassAndObject(input) as TransactionType
|
||||
val timestamp = kryo.readClassAndObject(input) as Timestamp?
|
||||
|
||||
|
@ -39,15 +39,15 @@ class PublicKeyGenerator: Generator<PublicKey>(PublicKey::class.java) {
|
||||
}
|
||||
}
|
||||
|
||||
class PublicKeyTreeGenerator : Generator<PublicKeyTree>(PublicKeyTree::class.java) {
|
||||
override fun generate(random: SourceOfRandomness, status: GenerationStatus): PublicKeyTree {
|
||||
return entropyToKeyPair(random.nextBigInteger(32)).public.tree
|
||||
class CompositeKeyGenerator : Generator<CompositeKey>(CompositeKey::class.java) {
|
||||
override fun generate(random: SourceOfRandomness, status: GenerationStatus): CompositeKey {
|
||||
return entropyToKeyPair(random.nextBigInteger(32)).public.composite
|
||||
}
|
||||
}
|
||||
|
||||
class PartyGenerator: Generator<Party>(Party::class.java) {
|
||||
override fun generate(random: SourceOfRandomness, status: GenerationStatus): Party {
|
||||
return Party(StringGenerator().generate(random, status), PublicKeyTreeGenerator().generate(random, status))
|
||||
return Party(StringGenerator().generate(random, status), CompositeKeyGenerator().generate(random, status))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.corda.core.transactions
|
||||
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
@ -20,14 +20,14 @@ abstract class BaseTransaction(
|
||||
*/
|
||||
val notary: Party?,
|
||||
/**
|
||||
* Public key trees that need to be fulfilled by signatures in order for the transaction to be valid.
|
||||
* Composite keys that need to be fulfilled by signatures in order for the transaction to be valid.
|
||||
* In a [SignedTransaction] this list is used to check whether there are any missing signatures. Note that
|
||||
* there is nothing that forces the list to be the _correct_ list of signers for this transaction until
|
||||
* the transaction is verified by using [LedgerTransaction.verify].
|
||||
*
|
||||
* It includes the notary key, if the notary field is set.
|
||||
*/
|
||||
val mustSign: List<PublicKeyTree>,
|
||||
val mustSign: List<CompositeKey>,
|
||||
/**
|
||||
* Pointer to a class that defines the behaviour of this transaction: either normal, or "notary changing".
|
||||
*/
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.corda.core.transactions
|
||||
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
|
||||
/**
|
||||
@ -27,7 +27,7 @@ class LedgerTransaction(
|
||||
/** The hash of the original serialised WireTransaction. */
|
||||
override val id: SecureHash,
|
||||
notary: Party?,
|
||||
signers: List<PublicKeyTree>,
|
||||
signers: List<CompositeKey>,
|
||||
timestamp: Timestamp?,
|
||||
type: TransactionType
|
||||
) : BaseTransaction(inputs, outputs, notary, signers, type, timestamp) {
|
||||
|
@ -2,8 +2,8 @@ package net.corda.core.transactions
|
||||
|
||||
import net.corda.core.contracts.NamedByHash
|
||||
import net.corda.core.contracts.TransactionResolutionException
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.DigitalSignature
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.node.ServiceHub
|
||||
import net.corda.core.serialization.SerializedBytes
|
||||
@ -37,7 +37,7 @@ data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>,
|
||||
temp
|
||||
}
|
||||
|
||||
class SignaturesMissingException(val missing: Set<PublicKeyTree>, val descriptions: List<String>, override val id: SecureHash) : NamedByHash, SignatureException() {
|
||||
class SignaturesMissingException(val missing: Set<CompositeKey>, val descriptions: List<String>, override val id: SecureHash) : NamedByHash, SignatureException() {
|
||||
override fun toString(): String {
|
||||
return "Missing signatures for $descriptions on transaction ${id.prefixChars()} for ${missing.joinToString()}"
|
||||
}
|
||||
@ -56,7 +56,7 @@ data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>,
|
||||
* @throws SignaturesMissingException if any signatures should have been present but were not.
|
||||
*/
|
||||
@Throws(SignatureException::class)
|
||||
fun verifySignatures(vararg allowedToBeMissing: PublicKeyTree): WireTransaction {
|
||||
fun verifySignatures(vararg allowedToBeMissing: CompositeKey): WireTransaction {
|
||||
// Embedded WireTransaction is not deserialised until after we check the signatures.
|
||||
checkSignaturesAreValid()
|
||||
|
||||
@ -86,7 +86,7 @@ data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>,
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMissingSignatures(): Set<PublicKeyTree> {
|
||||
private fun getMissingSignatures(): Set<CompositeKey> {
|
||||
val sigKeys = sigs.map { it.by }.toSet()
|
||||
val missing = tx.mustSign.filter { !it.isFulfilledBy(sigKeys) }.toSet()
|
||||
return missing
|
||||
@ -96,7 +96,7 @@ data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>,
|
||||
* Get a human readable description of where signatures are required from, and are missing, to assist in debugging
|
||||
* the underlying cause.
|
||||
*/
|
||||
private fun getMissingKeyDescriptions(missing: Set<PublicKeyTree>): ArrayList<String> {
|
||||
private fun getMissingKeyDescriptions(missing: Set<CompositeKey>): ArrayList<String> {
|
||||
// TODO: We need a much better way of structuring this data
|
||||
val missingElements = ArrayList<String>()
|
||||
this.tx.commands.forEach { command ->
|
||||
|
@ -31,7 +31,7 @@ open class TransactionBuilder(
|
||||
protected val attachments: MutableList<SecureHash> = arrayListOf(),
|
||||
protected val outputs: MutableList<TransactionState<ContractState>> = arrayListOf(),
|
||||
protected val commands: MutableList<Command> = arrayListOf(),
|
||||
protected val signers: MutableSet<PublicKeyTree> = mutableSetOf(),
|
||||
protected val signers: MutableSet<CompositeKey> = mutableSetOf(),
|
||||
protected var timestamp: Timestamp? = null) {
|
||||
|
||||
val time: Timestamp? get() = timestamp
|
||||
@ -136,7 +136,7 @@ open class TransactionBuilder(
|
||||
fun toSignedTransaction(checkSufficientSignatures: Boolean = true): SignedTransaction {
|
||||
if (checkSufficientSignatures) {
|
||||
val gotKeys = currentSigs.map { it.by }.toSet()
|
||||
val missing: Set<PublicKeyTree> = signers.filter { !it.isFulfilledBy(gotKeys) }.toSet()
|
||||
val missing: Set<CompositeKey> = signers.filter { !it.isFulfilledBy(gotKeys) }.toSet()
|
||||
if (missing.isNotEmpty())
|
||||
throw IllegalStateException("Missing signatures on the transaction for the public keys: ${missing.joinToString()}")
|
||||
}
|
||||
@ -178,8 +178,8 @@ open class TransactionBuilder(
|
||||
commands.add(arg)
|
||||
}
|
||||
|
||||
fun addCommand(data: CommandData, vararg keys: PublicKeyTree) = addCommand(Command(data, listOf(*keys)))
|
||||
fun addCommand(data: CommandData, keys: List<PublicKeyTree>) = addCommand(Command(data, keys))
|
||||
fun addCommand(data: CommandData, vararg keys: CompositeKey) = addCommand(Command(data, listOf(*keys)))
|
||||
fun addCommand(data: CommandData, keys: List<CompositeKey>) = addCommand(Command(data, keys))
|
||||
|
||||
// Accessors that yield immutable snapshots.
|
||||
fun inputStates(): List<StateRef> = ArrayList(inputs)
|
||||
|
@ -2,8 +2,8 @@ package net.corda.core.transactions
|
||||
|
||||
import com.esotericsoftware.kryo.Kryo
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.indexOfOrThrow
|
||||
import net.corda.core.node.ServiceHub
|
||||
@ -30,7 +30,7 @@ class WireTransaction(
|
||||
/** Ordered list of ([CommandData], [PublicKey]) pairs that instruct the contracts what to do. */
|
||||
val commands: List<Command>,
|
||||
notary: Party?,
|
||||
signers: List<PublicKeyTree>,
|
||||
signers: List<CompositeKey>,
|
||||
type: TransactionType,
|
||||
timestamp: Timestamp?
|
||||
) : BaseTransaction(inputs, outputs, notary, signers, type, timestamp) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.corda.core.utilities
|
||||
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.node.ServiceHub
|
||||
import javax.ws.rs.core.Response
|
||||
|
||||
@ -17,7 +17,7 @@ class ApiUtils(val services: ServiceHub) {
|
||||
*/
|
||||
fun withParty(partyKeyStr: String, notFound: (String) -> Response = defaultNotFound, found: (Party) -> Response): Response {
|
||||
return try {
|
||||
val partyKey = PublicKeyTree.parseFromBase58(partyKeyStr)
|
||||
val partyKey = CompositeKey.parseFromBase58(partyKeyStr)
|
||||
val party = services.identityService.partyFromKey(partyKey)
|
||||
if(party == null) notFound("Unknown party") else found(party)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
|
@ -9,8 +9,8 @@ import java.time.Instant
|
||||
// A dummy time at which we will be pretending test transactions are created.
|
||||
val TEST_TX_TIME: Instant get() = Instant.parse("2015-04-17T12:00:00.00Z")
|
||||
|
||||
val DUMMY_PUBKEY_1: PublicKeyTree get() = DummyPublicKey("x1").tree
|
||||
val DUMMY_PUBKEY_2: PublicKeyTree get() = DummyPublicKey("x2").tree
|
||||
val DUMMY_PUBKEY_1: CompositeKey get() = DummyPublicKey("x1").composite
|
||||
val DUMMY_PUBKEY_2: CompositeKey get() = DummyPublicKey("x2").composite
|
||||
|
||||
val DUMMY_KEY_1: KeyPair by lazy { generateKeyPair() }
|
||||
val DUMMY_KEY_2: KeyPair by lazy { generateKeyPair() }
|
||||
|
@ -4,9 +4,9 @@ import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.contracts.ContractState
|
||||
import net.corda.core.contracts.StateAndRef
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.DigitalSignature
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.signWithECDSA
|
||||
import net.corda.core.node.recordTransactions
|
||||
import net.corda.core.protocols.ProtocolLogic
|
||||
@ -67,12 +67,12 @@ abstract class AbstractStateReplacementProtocol<T> {
|
||||
}
|
||||
|
||||
abstract protected fun assembleProposal(stateRef: StateRef, modification: T, stx: SignedTransaction): Proposal<T>
|
||||
abstract protected fun assembleTx(): Pair<SignedTransaction, List<PublicKeyTree>>
|
||||
abstract protected fun assembleTx(): Pair<SignedTransaction, List<CompositeKey>>
|
||||
|
||||
@Suspendable
|
||||
private fun collectSignatures(participants: List<PublicKeyTree>, stx: SignedTransaction): List<DigitalSignature.WithKey> {
|
||||
private fun collectSignatures(participants: List<CompositeKey>, stx: SignedTransaction): List<DigitalSignature.WithKey> {
|
||||
val parties = participants.map {
|
||||
val participantNode = serviceHub.networkMapCache.getNodeByPublicKeyTree(it) ?:
|
||||
val participantNode = serviceHub.networkMapCache.getNodeByCompositeKey(it) ?:
|
||||
throw IllegalStateException("Participant $it to state $originalState not found on the network")
|
||||
participantNode.legalIdentity
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ import net.corda.core.contracts.ContractState
|
||||
import net.corda.core.contracts.StateAndRef
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.utilities.ProgressTracker
|
||||
import net.corda.core.utilities.UntrustworthyData
|
||||
@ -36,7 +36,7 @@ object NotaryChangeProtocol: AbstractStateReplacementProtocol<Party>() {
|
||||
override fun assembleProposal(stateRef: StateRef, modification: Party, stx: SignedTransaction): AbstractStateReplacementProtocol.Proposal<Party>
|
||||
= Proposal(stateRef, modification, stx)
|
||||
|
||||
override fun assembleTx(): Pair<SignedTransaction, List<PublicKeyTree>> {
|
||||
override fun assembleTx(): Pair<SignedTransaction, List<CompositeKey>> {
|
||||
val state = originalState.state
|
||||
val newState = state.withNotary(modification)
|
||||
val participants = state.data.participants
|
||||
|
@ -170,7 +170,7 @@ sealed class NotaryError {
|
||||
|
||||
class TransactionInvalid : NotaryError()
|
||||
|
||||
class SignaturesMissing(val missingSigners: Set<PublicKeyTree>) : NotaryError() {
|
||||
class SignaturesMissing(val missingSigners: Set<CompositeKey>) : NotaryError() {
|
||||
override fun toString() = "Missing signatures from: ${missingSigners.map { it.toBase58String() }}"
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ object TwoPartyDealProtocol {
|
||||
}
|
||||
|
||||
// This object is serialised to the network and is the first protocol message the seller sends to the buyer.
|
||||
data class Handshake<out T>(val payload: T, val publicKey: PublicKeyTree)
|
||||
data class Handshake<out T>(val payload: T, val publicKey: CompositeKey)
|
||||
|
||||
class SignaturesFromPrimary(val sellerSig: DigitalSignature.WithKey, val notarySig: DigitalSignature.WithKey)
|
||||
|
||||
@ -87,7 +87,7 @@ object TwoPartyDealProtocol {
|
||||
progressTracker.currentStep = AWAITING_PROPOSAL
|
||||
|
||||
// Make the first message we'll send to kick off the protocol.
|
||||
val hello = Handshake(payload, myKeyPair.public.tree)
|
||||
val hello = Handshake(payload, myKeyPair.public.composite)
|
||||
val maybeSTX = sendAndReceive<SignedTransaction>(otherParty, hello)
|
||||
|
||||
return maybeSTX
|
||||
@ -101,7 +101,7 @@ object TwoPartyDealProtocol {
|
||||
progressTracker.nextStep()
|
||||
|
||||
// Check that the tx proposed by the buyer is valid.
|
||||
val wtx: WireTransaction = stx.verifySignatures(myKeyPair.public.tree, notaryNode.notaryIdentity.owningKey)
|
||||
val wtx: WireTransaction = stx.verifySignatures(myKeyPair.public.composite, notaryNode.notaryIdentity.owningKey)
|
||||
logger.trace { "Received partially signed transaction: ${stx.id}" }
|
||||
|
||||
checkDependencies(stx)
|
||||
@ -248,7 +248,7 @@ object TwoPartyDealProtocol {
|
||||
return sendAndReceive<SignaturesFromPrimary>(otherParty, stx).unwrap { it }
|
||||
}
|
||||
|
||||
private fun signWithOurKeys(signingPubKeys: List<PublicKeyTree>, ptx: TransactionBuilder): SignedTransaction {
|
||||
private fun signWithOurKeys(signingPubKeys: List<CompositeKey>, ptx: TransactionBuilder): SignedTransaction {
|
||||
// Now sign the transaction with whatever keys we need to move the cash.
|
||||
for (publicKey in signingPubKeys.keys) {
|
||||
val privateKey = serviceHub.keyManagementService.toPrivate(publicKey)
|
||||
@ -259,7 +259,7 @@ object TwoPartyDealProtocol {
|
||||
}
|
||||
|
||||
@Suspendable protected abstract fun validateHandshake(handshake: Handshake<U>): Handshake<U>
|
||||
@Suspendable protected abstract fun assembleSharedTX(handshake: Handshake<U>): Pair<TransactionBuilder, List<PublicKeyTree>>
|
||||
@Suspendable protected abstract fun assembleSharedTX(handshake: Handshake<U>): Pair<TransactionBuilder, List<CompositeKey>>
|
||||
}
|
||||
|
||||
|
||||
@ -292,7 +292,7 @@ object TwoPartyDealProtocol {
|
||||
return handshake.copy(payload = autoOffer.copy(dealBeingOffered = deal))
|
||||
}
|
||||
|
||||
override fun assembleSharedTX(handshake: Handshake<AutoOffer>): Pair<TransactionBuilder, List<PublicKeyTree>> {
|
||||
override fun assembleSharedTX(handshake: Handshake<AutoOffer>): Pair<TransactionBuilder, List<CompositeKey>> {
|
||||
val deal = handshake.payload.dealBeingOffered
|
||||
val ptx = deal.generateAgreement(handshake.payload.notary)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.corda.core.contracts
|
||||
|
||||
import net.corda.contracts.asset.Cash
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.utilities.DUMMY_PUBKEY_1
|
||||
import net.corda.core.utilities.DUMMY_PUBKEY_2
|
||||
@ -44,7 +44,7 @@ class TransactionEncumbranceTests {
|
||||
data class State(
|
||||
val validFrom: Instant
|
||||
) : ContractState {
|
||||
override val participants: List<PublicKeyTree> = emptyList()
|
||||
override val participants: List<CompositeKey> = emptyList()
|
||||
override val contract: Contract = TEST_TIMELOCK_ID
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.corda.core.contracts
|
||||
|
||||
import net.corda.core.crypto.composite
|
||||
import net.corda.core.crypto.newSecureRandom
|
||||
import net.corda.core.crypto.tree
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
import net.corda.core.utilities.DUMMY_NOTARY
|
||||
@ -32,7 +32,7 @@ class TransactionGraphSearchTests {
|
||||
fun buildTransactions(command: CommandData, signer: KeyPair): GraphTransactionStorage {
|
||||
val originTx = TransactionType.General.Builder(DUMMY_NOTARY).apply {
|
||||
addOutputState(DummyState(random31BitValue()))
|
||||
addCommand(command, signer.public.tree)
|
||||
addCommand(command, signer.public.composite)
|
||||
signWith(signer)
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
}.toSignedTransaction(false)
|
||||
|
@ -3,8 +3,8 @@ package net.corda.core.contracts
|
||||
import net.corda.contracts.asset.DUMMY_CASH_ISSUER_KEY
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.composite
|
||||
import net.corda.core.crypto.signWithECDSA
|
||||
import net.corda.core.crypto.tree
|
||||
import net.corda.core.serialization.SerializedBytes
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
@ -30,7 +30,7 @@ class TransactionTests {
|
||||
outputs = emptyList(),
|
||||
commands = emptyList(),
|
||||
notary = DUMMY_NOTARY,
|
||||
signers = listOf(DUMMY_KEY_1.public.tree, DUMMY_KEY_2.public.tree),
|
||||
signers = listOf(DUMMY_KEY_1.public.composite, DUMMY_KEY_2.public.composite),
|
||||
type = TransactionType.General(),
|
||||
timestamp = null
|
||||
)
|
||||
@ -39,20 +39,20 @@ class TransactionTests {
|
||||
assertFailsWith<IllegalArgumentException> { make().verifySignatures() }
|
||||
|
||||
assertEquals(
|
||||
setOf(DUMMY_KEY_1.public.tree),
|
||||
setOf(DUMMY_KEY_1.public.composite),
|
||||
assertFailsWith<SignedTransaction.SignaturesMissingException> { make(DUMMY_KEY_2).verifySignatures() }.missing
|
||||
)
|
||||
assertEquals(
|
||||
setOf(DUMMY_KEY_2.public.tree),
|
||||
setOf(DUMMY_KEY_2.public.composite),
|
||||
assertFailsWith<SignedTransaction.SignaturesMissingException> { make(DUMMY_KEY_1).verifySignatures() }.missing
|
||||
)
|
||||
assertEquals(
|
||||
setOf(DUMMY_KEY_2.public.tree),
|
||||
assertFailsWith<SignedTransaction.SignaturesMissingException> { make(DUMMY_CASH_ISSUER_KEY).verifySignatures(DUMMY_KEY_1.public.tree) }.missing
|
||||
setOf(DUMMY_KEY_2.public.composite),
|
||||
assertFailsWith<SignedTransaction.SignaturesMissingException> { make(DUMMY_CASH_ISSUER_KEY).verifySignatures(DUMMY_KEY_1.public.composite) }.missing
|
||||
)
|
||||
|
||||
make(DUMMY_KEY_1).verifySignatures(DUMMY_KEY_2.public.tree)
|
||||
make(DUMMY_KEY_2).verifySignatures(DUMMY_KEY_1.public.tree)
|
||||
make(DUMMY_KEY_1).verifySignatures(DUMMY_KEY_2.public.composite)
|
||||
make(DUMMY_KEY_2).verifySignatures(DUMMY_KEY_1.public.composite)
|
||||
|
||||
make(DUMMY_KEY_1, DUMMY_KEY_2).verifySignatures()
|
||||
}
|
||||
@ -65,7 +65,7 @@ class TransactionTests {
|
||||
val commands = emptyList<AuthenticatedObject<CommandData>>()
|
||||
val attachments = emptyList<Attachment>()
|
||||
val id = SecureHash.randomSHA256()
|
||||
val signers = listOf(DUMMY_NOTARY_KEY.public.tree)
|
||||
val signers = listOf(DUMMY_NOTARY_KEY.public.composite)
|
||||
val timestamp: Timestamp? = null
|
||||
val transaction: LedgerTransaction = LedgerTransaction(
|
||||
inputs,
|
||||
@ -92,7 +92,7 @@ class TransactionTests {
|
||||
val commands = emptyList<AuthenticatedObject<CommandData>>()
|
||||
val attachments = emptyList<Attachment>()
|
||||
val id = SecureHash.randomSHA256()
|
||||
val signers = listOf(DUMMY_NOTARY_KEY.public.tree)
|
||||
val signers = listOf(DUMMY_NOTARY_KEY.public.composite)
|
||||
val timestamp: Timestamp? = null
|
||||
val transaction: LedgerTransaction = LedgerTransaction(
|
||||
inputs,
|
||||
|
@ -5,14 +5,14 @@ import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class PublicKeyTreeTests {
|
||||
class CompositeKeyTests {
|
||||
val aliceKey = generateKeyPair()
|
||||
val bobKey = generateKeyPair()
|
||||
val charlieKey = generateKeyPair()
|
||||
|
||||
val alicePublicKey = PublicKeyTree.Leaf(aliceKey.public)
|
||||
val bobPublicKey = PublicKeyTree.Leaf(bobKey.public)
|
||||
val charliePublicKey = PublicKeyTree.Leaf(charlieKey.public)
|
||||
val alicePublicKey = CompositeKey.Leaf(aliceKey.public)
|
||||
val bobPublicKey = CompositeKey.Leaf(bobKey.public)
|
||||
val charliePublicKey = CompositeKey.Leaf(charlieKey.public)
|
||||
|
||||
val message = OpaqueBytes("Transaction".toByteArray())
|
||||
|
||||
@ -26,22 +26,22 @@ class PublicKeyTreeTests {
|
||||
|
||||
@Test
|
||||
fun `(Alice or Bob) fulfilled by Bob signature`() {
|
||||
val aliceOrBob = PublicKeyTree.Builder().addKeys(alicePublicKey, bobPublicKey).build(threshold = 1)
|
||||
val aliceOrBob = CompositeKey.Builder().addKeys(alicePublicKey, bobPublicKey).build(threshold = 1)
|
||||
assertTrue { aliceOrBob.isFulfilledBy(bobSignature.by) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `(Alice and Bob) fulfilled by Alice, Bob signatures`() {
|
||||
val aliceAndBob = PublicKeyTree.Builder().addKeys(alicePublicKey, bobPublicKey).build()
|
||||
val aliceAndBob = CompositeKey.Builder().addKeys(alicePublicKey, bobPublicKey).build()
|
||||
val signatures = listOf(aliceSignature, bobSignature)
|
||||
assertTrue { aliceAndBob.isFulfilledBy(signatures.byKeys()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `((Alice and Bob) or Charlie) signature verifies`() {
|
||||
// TODO: Look into a DSL for building multi-level public key trees if that becomes a common use case
|
||||
val aliceAndBob = PublicKeyTree.Builder().addKeys(alicePublicKey, bobPublicKey).build()
|
||||
val aliceAndBobOrCharlie = PublicKeyTree.Builder().addKeys(aliceAndBob, charliePublicKey).build(threshold = 1)
|
||||
// TODO: Look into a DSL for building multi-level composite keys if that becomes a common use case
|
||||
val aliceAndBob = CompositeKey.Builder().addKeys(alicePublicKey, bobPublicKey).build()
|
||||
val aliceAndBobOrCharlie = CompositeKey.Builder().addKeys(aliceAndBob, charliePublicKey).build(threshold = 1)
|
||||
|
||||
val signatures = listOf(aliceSignature, bobSignature)
|
||||
|
||||
@ -50,11 +50,11 @@ class PublicKeyTreeTests {
|
||||
|
||||
@Test
|
||||
fun `encoded tree decodes correctly`() {
|
||||
val aliceAndBob = PublicKeyTree.Builder().addKeys(alicePublicKey, bobPublicKey).build()
|
||||
val aliceAndBobOrCharlie = PublicKeyTree.Builder().addKeys(aliceAndBob, charliePublicKey).build(threshold = 1)
|
||||
val aliceAndBob = CompositeKey.Builder().addKeys(alicePublicKey, bobPublicKey).build()
|
||||
val aliceAndBobOrCharlie = CompositeKey.Builder().addKeys(aliceAndBob, charliePublicKey).build(threshold = 1)
|
||||
|
||||
val encoded = aliceAndBobOrCharlie.toBase58String()
|
||||
val decoded = PublicKeyTree.parseFromBase58(encoded)
|
||||
val decoded = CompositeKey.parseFromBase58(encoded)
|
||||
|
||||
assertEquals(decoded, aliceAndBobOrCharlie)
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package net.corda.core.node
|
||||
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.node.services.AttachmentStorage
|
||||
import net.corda.core.serialization.*
|
||||
@ -37,7 +37,7 @@ class AttachmentClassLoaderTests {
|
||||
class AttachmentDummyContract : Contract {
|
||||
data class State(val magicNumber: Int = 0) : ContractState {
|
||||
override val contract = ATTACHMENT_TEST_PROGRAM_ID
|
||||
override val participants: List<PublicKeyTree>
|
||||
override val participants: List<CompositeKey>
|
||||
get() = listOf()
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.corda.core.node
|
||||
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.node.services.Vault
|
||||
import net.corda.core.utilities.DUMMY_NOTARY
|
||||
@ -20,7 +20,7 @@ class VaultUpdateTests {
|
||||
}
|
||||
|
||||
private class DummyState : ContractState {
|
||||
override val participants: List<PublicKeyTree>
|
||||
override val participants: List<CompositeKey>
|
||||
get() = emptyList()
|
||||
override val contract = VaultUpdateTests.DummyContract
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package net.corda.core.serialization
|
||||
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.tree
|
||||
import net.corda.core.crypto.composite
|
||||
import net.corda.core.seconds
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.*
|
||||
@ -28,12 +28,12 @@ class TransactionSerializationTests {
|
||||
data class State(
|
||||
val deposit: PartyAndReference,
|
||||
val amount: Amount<Currency>,
|
||||
override val owner: PublicKeyTree) : OwnableState {
|
||||
override val owner: CompositeKey) : OwnableState {
|
||||
override val contract: Contract = TEST_PROGRAM_ID
|
||||
override val participants: List<PublicKeyTree>
|
||||
override val participants: List<CompositeKey>
|
||||
get() = listOf(owner)
|
||||
|
||||
override fun withNewOwner(newOwner: PublicKeyTree) = Pair(Commands.Move(), copy(owner = newOwner))
|
||||
override fun withNewOwner(newOwner: CompositeKey) = Pair(Commands.Move(), copy(owner = newOwner))
|
||||
}
|
||||
interface Commands : CommandData {
|
||||
class Move() : TypeOnlyCommandData(), Commands
|
||||
@ -46,7 +46,7 @@ class TransactionSerializationTests {
|
||||
val fakeStateRef = generateStateRef()
|
||||
val inputState = StateAndRef(TransactionState(TestCash.State(depositRef, 100.POUNDS, DUMMY_PUBKEY_1), DUMMY_NOTARY), fakeStateRef)
|
||||
val outputState = TransactionState(TestCash.State(depositRef, 600.POUNDS, DUMMY_PUBKEY_1), DUMMY_NOTARY)
|
||||
val changeState = TransactionState(TestCash.State(depositRef, 400.POUNDS, DUMMY_KEY_1.public.tree), DUMMY_NOTARY)
|
||||
val changeState = TransactionState(TestCash.State(depositRef, 400.POUNDS, DUMMY_KEY_1.public.composite), DUMMY_NOTARY)
|
||||
|
||||
|
||||
lateinit var tx: TransactionBuilder
|
||||
@ -54,7 +54,7 @@ class TransactionSerializationTests {
|
||||
@Before
|
||||
fun setup() {
|
||||
tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(
|
||||
inputState, outputState, changeState, Command(TestCash.Commands.Move(), arrayListOf(DUMMY_KEY_1.public.tree))
|
||||
inputState, outputState, changeState, Command(TestCash.Commands.Move(), arrayListOf(DUMMY_KEY_1.public.composite))
|
||||
)
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ class TransactionSerializationTests {
|
||||
// If the signature was replaced in transit, we don't like it.
|
||||
assertFailsWith(SignatureException::class) {
|
||||
val tx2 = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState, outputState, changeState,
|
||||
Command(TestCash.Commands.Move(), DUMMY_KEY_2.public.tree))
|
||||
Command(TestCash.Commands.Move(), DUMMY_KEY_2.public.composite))
|
||||
tx2.signWith(DUMMY_NOTARY_KEY)
|
||||
tx2.signWith(DUMMY_KEY_2)
|
||||
|
||||
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
@ -151,22 +151,22 @@ Multi-signature support
|
||||
Corda supports scenarios where more than one key or party is required to authorise a state object transition, for example:
|
||||
"Either the CEO or 3 out of 5 of his assistants need to provide signatures".
|
||||
|
||||
Key Trees
|
||||
^^^^^^^^^
|
||||
Composite Keys
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
This is achieved by public key composition, using a tree data structure ``PublicKeyTree``. A ``PublicKeyTree`` stores the
|
||||
cryptographic public key primitives in its leaves and the composition logic in the intermediary nodes. Every intermediary
|
||||
This is achieved by public key composition, using a tree data structure ``CompositeKey``. A ``CompositeKey`` is a tree that
|
||||
stores the cryptographic public key primitives in its leaves and the composition logic in the intermediary nodes. Every intermediary
|
||||
node specifies a *threshold* of how many child signatures it requires.
|
||||
|
||||
An illustration of an *"either Alice and Bob, or Charlie"* public key tree:
|
||||
An illustration of an *"either Alice and Bob, or Charlie"* composite key:
|
||||
|
||||
.. image:: resources/public-key-tree.png
|
||||
.. image:: resources/composite-key.png
|
||||
:width: 300px
|
||||
|
||||
To allow further flexibility, each child node can have an associated custom *weight* (the default is 1). The *threshold*
|
||||
then specifies the minimum total weight of all children required. Our previous example can also be expressed as:
|
||||
|
||||
.. image:: resources/public-key-tree-2.png
|
||||
.. image:: resources/composite-key-2.png
|
||||
:width: 300px
|
||||
|
||||
Verification
|
||||
@ -175,9 +175,9 @@ Verification
|
||||
Signature verification is performed in two stages:
|
||||
|
||||
1. Given a list of signatures, each signature is verified against the expected content.
|
||||
2. The public keys corresponding to the signatures are matched against the leaves of the public key tree in question,
|
||||
2. The public keys corresponding to the signatures are matched against the leaves of the composite key tree in question,
|
||||
and the total combined weight of all children is calculated for every intermediary node. If all thresholds are satisfied,
|
||||
the public key tree requirement is considered to be met.
|
||||
the composite key requirement is considered to be met.
|
||||
|
||||
Date support
|
||||
------------
|
||||
|
@ -405,24 +405,24 @@ the transaction will not be valid unless every key listed in every command has a
|
||||
structures are themselves opaque. In this way algorithmic agility is retained: new signature algorithms can be deployed
|
||||
without adjusting the code of the smart contracts themselves.
|
||||
|
||||
\subsection{Compound keys}\label{sec:compound-keys}
|
||||
\subsection{Composite keys}\label{sec:composite-keys}
|
||||
|
||||
The term ``public key'' in the description above actually refers to a \emph{compound key}. Compound keys are trees in
|
||||
The term ``public key'' in the description above actually refers to a \emph{composite key}. Composite keys are trees in
|
||||
which leaves are regular cryptographic public keys with an accompanying algorithm identifiers. Nodes in the tree specify
|
||||
both the weights of each child and a threshold weight that must be met. The validty of a set of signatures can be
|
||||
determined by walking the tree bottom-up, summing the weights of the keys that have a valid signature and comparing
|
||||
against the threshold. By using weights and thresholds a variety of conditions can be encoded, including boolean
|
||||
formulas with AND and OR.
|
||||
|
||||
Compound keys are useful in multiple scenarios. For example, assets can be placed under the control of a 2-of-2
|
||||
compound key where one leaf key is owned by a user, and the other by an independent risk analysis system. The
|
||||
Composite keys are useful in multiple scenarios. For example, assets can be placed under the control of a 2-of-2
|
||||
composite key where one leaf key is owned by a user, and the other by an independent risk analysis system. The
|
||||
risk analysis system refuses to sign if the transaction seems suspicious, like if too much value has been
|
||||
transferred in too short a time window. Another example involves encoding corporate structures into the key,
|
||||
allowing a CFO to sign a large transaction alone but his subordinates are required to work together. Compound keys
|
||||
allowing a CFO to sign a large transaction alone but his subordinates are required to work together. Composite keys
|
||||
are also useful for notaries. Each participant in a distributed notary is represented by a leaf, and the threshold
|
||||
is set such that some participants can be offline or refusing to sign yet the signature of the group is still valid.
|
||||
|
||||
Whilst there are threshold signature schemes in the literature that allow compound keys and signatures to be produced
|
||||
Whilst there are threshold signature schemes in the literature that allow composite keys and signatures to be produced
|
||||
mathematically, we choose the less space efficient explicit form in order to allow a mixture of keys using different
|
||||
algorithms. In this way old algorithms can be phased out and new algorithms phased in without requiring all
|
||||
participants in a group to upgrade simultaneously.
|
||||
@ -581,7 +581,7 @@ email address or EV (extended validation) organisation name.
|
||||
|
||||
Corda takes this concept further. States may define fields of type \texttt{Party}, which encapsulates an identity
|
||||
and a public key. When a state is deserialised from a transaction in its raw form, the identity field of the
|
||||
\texttt{Party} object is null and only the public (compound) key is present. If a transaction is deserialised
|
||||
\texttt{Party} object is null and only the public (composite) key is present. If a transaction is deserialised
|
||||
in conjunction with X.509 certificate chains linking the transient public keys to long term identity keys the
|
||||
identity field is set. In this way a single data representation can be used for both the anonymised case, such
|
||||
as when validating dependencies of a transaction, and the identified case, such as when trading directly with
|
||||
@ -689,8 +689,8 @@ publishing a bad contract version, at the cost of increased difficulty in releas
|
||||
may also specify third parties they wish to review contract code. Regardless of which set of tradeoffs is chosen,
|
||||
the framework can accomodate them.
|
||||
|
||||
A contract constraint may use a compound key of the type described in \cref{sec:compound-keys}. The standard JAR
|
||||
signing protocol allows for multiple signatures from different private keys, thus being able to satisfy compound
|
||||
A contract constraint may use a composite key of the type described in \cref{sec:composite-keys}. The standard JAR
|
||||
signing protocol allows for multiple signatures from different private keys, thus being able to satisfy composite
|
||||
keys. The allowed signing algorithms are \texttt{SHA256withRSA} and \texttt{SHA256withECDSA}. Note that the
|
||||
cryptographic algorithms used for code signing may not always be the same as those used for transaction signing,
|
||||
as for code signing we place initial focus on being able to re-use the infrastructure.
|
||||
@ -715,10 +715,10 @@ A ledger that cannot record the ownership of assets is not very useful. We defin
|
||||
asset-like behaviour and provide some platform contracts to ensure interoperable notions of cash and obligations.
|
||||
|
||||
We define the notion of an \texttt{OwnableState}, implemented as an interface which any state may conform to. Ownable
|
||||
states are required to have an \texttt{owner} field which is a compound key (see \cref{sec:compound-keys}). This is
|
||||
states are required to have an \texttt{owner} field which is a composite key (see \cref{sec:composite-keys}). This is
|
||||
utilised by generic code in the vault (see \cref{sec:vault}) to manipulate ownable states.
|
||||
|
||||
% TODO: Currently OwnableState.owner is just a regular PublicKeyTree.
|
||||
% TODO: Currently OwnableState.owner is just a regular CompositeKey.
|
||||
|
||||
From \texttt{OwnableState} we derive a \texttt{FungibleAsset} concept to represent assets of measurable quantity, in
|
||||
which units are sufficiently similar to represented together in a single ledger state. Making that concrete, pound notes
|
||||
@ -932,7 +932,7 @@ transaction ordering and timestamping services, thus abstracting the role miners
|
||||
component.
|
||||
|
||||
Notaries are expected to be composed of multiple mutually distrusting parties who use a standard consensus algorithm.
|
||||
Notaries are identified by and sign with compound public keys (\cref{sec:compound-keys})that conceptually follow the
|
||||
Notaries are identified by and sign with composite public keys (\cref{sec:composite-keys})that conceptually follow the
|
||||
Interledger Crypto-Conditions specification\cite{ILPCC}. Note that whilst it would be conventional to use a BFT
|
||||
algorithm for a notary service, there is no requirement to do so and in cases where the legal system is sufficient to
|
||||
ensure protocol compliance a higher performance algorithm like RAFT may be used. Because multiple notaries can co-exist
|
||||
@ -1669,7 +1669,7 @@ consensus systems, and the system operates without mining or a block chain.
|
||||
|
||||
A standard type system is provided for the modelling of financial logic. The design considers security throughout: it
|
||||
supports the integration of secure signing devices for transaction authorisation, secure enclaves for transaction
|
||||
processing, compound keys for expressing complex authorisation policies, and is based on binary protocols with
|
||||
processing, composite keys for expressing complex authorisation policies, and is based on binary protocols with
|
||||
length-prefixed buffers throughout for the systematic avoidance of common buffer management exploits. Users may analyse
|
||||
ledger data relevant to them by issuing ordinary SQL queries against mature database engines, and may craft complex
|
||||
multi-party transactions with ease in programming languages that are already familiar to them.
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.corda.contracts.universal
|
||||
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import java.math.BigDecimal
|
||||
@ -11,7 +11,7 @@ import java.time.Instant
|
||||
val UNIVERSAL_PROGRAM_ID = UniversalContract()
|
||||
|
||||
class UniversalContract : Contract {
|
||||
data class State(override val participants: List<PublicKeyTree>,
|
||||
data class State(override val participants: List<CompositeKey>,
|
||||
val details: Arrangement) : ContractState {
|
||||
override val contract = UNIVERSAL_PROGRAM_ID
|
||||
}
|
||||
@ -308,7 +308,7 @@ class UniversalContract : Contract {
|
||||
override val legalContractReference: SecureHash
|
||||
get() = throw UnsupportedOperationException()
|
||||
|
||||
fun generateIssue(tx: TransactionBuilder, arrangement: Arrangement, at: PartyAndReference, notary: PublicKeyTree) {
|
||||
fun generateIssue(tx: TransactionBuilder, arrangement: Arrangement, at: PartyAndReference, notary: CompositeKey) {
|
||||
check(tx.inputStates().isEmpty())
|
||||
tx.addOutputState(State(listOf(notary), arrangement))
|
||||
tx.addCommand(Commands.Issue(), at.party.owningKey)
|
||||
|
@ -3,8 +3,8 @@ package net.corda.contracts.universal
|
||||
import com.google.common.collect.ImmutableSet
|
||||
import com.google.common.collect.Sets
|
||||
import net.corda.core.contracts.Frequency
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import java.time.Instant
|
||||
import java.time.LocalDate
|
||||
|
||||
@ -12,44 +12,44 @@ fun Instant.toLocalDate(): LocalDate = LocalDate.ofEpochDay(this.epochSecond / 6
|
||||
|
||||
fun LocalDate.toInstant(): Instant = Instant.ofEpochSecond(this.toEpochDay() * 60 * 60 * 24)
|
||||
|
||||
private fun liablePartiesVisitor(arrangement: Arrangement): ImmutableSet<PublicKeyTree> =
|
||||
private fun liablePartiesVisitor(arrangement: Arrangement): ImmutableSet<CompositeKey> =
|
||||
when (arrangement) {
|
||||
is Zero -> ImmutableSet.of<PublicKeyTree>()
|
||||
is Zero -> ImmutableSet.of<CompositeKey>()
|
||||
is Transfer -> ImmutableSet.of(arrangement.from.owningKey)
|
||||
is And ->
|
||||
arrangement.arrangements.fold(ImmutableSet.builder<PublicKeyTree>(), { builder, k -> builder.addAll(liablePartiesVisitor(k)) }).build()
|
||||
arrangement.arrangements.fold(ImmutableSet.builder<CompositeKey>(), { builder, k -> builder.addAll(liablePartiesVisitor(k)) }).build()
|
||||
is Actions ->
|
||||
arrangement.actions.fold(ImmutableSet.builder<PublicKeyTree>(), { builder, k -> builder.addAll(liablePartiesVisitor(k)) }).build()
|
||||
arrangement.actions.fold(ImmutableSet.builder<CompositeKey>(), { builder, k -> builder.addAll(liablePartiesVisitor(k)) }).build()
|
||||
is RollOut -> liablePartiesVisitor(arrangement.template)
|
||||
is Continuation -> ImmutableSet.of<PublicKeyTree>()
|
||||
is Continuation -> ImmutableSet.of<CompositeKey>()
|
||||
else -> throw IllegalArgumentException("liableParties " + arrangement)
|
||||
}
|
||||
|
||||
private fun liablePartiesVisitor(action: Action): ImmutableSet<PublicKeyTree> =
|
||||
private fun liablePartiesVisitor(action: Action): ImmutableSet<CompositeKey> =
|
||||
if (action.actors.size != 1)
|
||||
liablePartiesVisitor(action.arrangement)
|
||||
else
|
||||
Sets.difference(liablePartiesVisitor(action.arrangement), ImmutableSet.of(action.actors.single())).immutableCopy()
|
||||
|
||||
/** Returns list of potentially liable parties for a given contract */
|
||||
fun liableParties(contract: Arrangement): Set<PublicKeyTree> = liablePartiesVisitor(contract)
|
||||
fun liableParties(contract: Arrangement): Set<CompositeKey> = liablePartiesVisitor(contract)
|
||||
|
||||
private fun involvedPartiesVisitor(action: Action): Set<PublicKeyTree> =
|
||||
private fun involvedPartiesVisitor(action: Action): Set<CompositeKey> =
|
||||
Sets.union(involvedPartiesVisitor(action.arrangement), action.actors.map { it.owningKey }.toSet()).immutableCopy()
|
||||
|
||||
private fun involvedPartiesVisitor(arrangement: Arrangement): ImmutableSet<PublicKeyTree> =
|
||||
private fun involvedPartiesVisitor(arrangement: Arrangement): ImmutableSet<CompositeKey> =
|
||||
when (arrangement) {
|
||||
is Zero -> ImmutableSet.of<PublicKeyTree>()
|
||||
is Zero -> ImmutableSet.of<CompositeKey>()
|
||||
is Transfer -> ImmutableSet.of(arrangement.from.owningKey)
|
||||
is And ->
|
||||
arrangement.arrangements.fold(ImmutableSet.builder<PublicKeyTree>(), { builder, k -> builder.addAll(involvedPartiesVisitor(k)) }).build()
|
||||
arrangement.arrangements.fold(ImmutableSet.builder<CompositeKey>(), { builder, k -> builder.addAll(involvedPartiesVisitor(k)) }).build()
|
||||
is Actions ->
|
||||
arrangement.actions.fold(ImmutableSet.builder<PublicKeyTree>(), { builder, k -> builder.addAll(involvedPartiesVisitor(k)) }).build()
|
||||
arrangement.actions.fold(ImmutableSet.builder<CompositeKey>(), { builder, k -> builder.addAll(involvedPartiesVisitor(k)) }).build()
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
|
||||
/** returns list of involved parties for a given contract */
|
||||
fun involvedParties(arrangement: Arrangement): Set<PublicKeyTree> = involvedPartiesVisitor(arrangement)
|
||||
fun involvedParties(arrangement: Arrangement): Set<CompositeKey> = involvedPartiesVisitor(arrangement)
|
||||
|
||||
fun replaceParty(action: Action, from: Party, to: Party): Action =
|
||||
if (action.actors.contains(from)) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.corda.contracts.isolated
|
||||
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
|
||||
@ -13,7 +13,7 @@ val ANOTHER_DUMMY_PROGRAM_ID = AnotherDummyContract()
|
||||
class AnotherDummyContract : Contract, net.corda.core.node.DummyContractBackdoor {
|
||||
data class State(val magicNumber: Int = 0) : ContractState {
|
||||
override val contract = ANOTHER_DUMMY_PROGRAM_ID
|
||||
override val participants: List<PublicKeyTree>
|
||||
override val participants: List<CompositeKey>
|
||||
get() = emptyList()
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ import net.corda.core.contracts.Amount;
|
||||
import net.corda.core.contracts.ContractState;
|
||||
import net.corda.core.contracts.Issued;
|
||||
import net.corda.core.contracts.PartyAndReference;
|
||||
import net.corda.core.crypto.PublicKeyTree;
|
||||
import net.corda.core.crypto.CompositeKey;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Currency;
|
||||
@ -15,7 +15,7 @@ import java.util.Currency;
|
||||
* ultimately either language can be used against a common test framework (and therefore can be used for real).
|
||||
*/
|
||||
public interface ICommercialPaperState extends ContractState {
|
||||
ICommercialPaperState withOwner(PublicKeyTree newOwner);
|
||||
ICommercialPaperState withOwner(CompositeKey newOwner);
|
||||
|
||||
ICommercialPaperState withIssuance(PartyAndReference newIssuance);
|
||||
|
||||
|
@ -10,9 +10,9 @@ import net.corda.core.contracts.clauses.AnyComposition;
|
||||
import net.corda.core.contracts.clauses.Clause;
|
||||
import net.corda.core.contracts.clauses.ClauseVerifier;
|
||||
import net.corda.core.contracts.clauses.GroupClauseVerifier;
|
||||
import net.corda.core.crypto.CompositeKey;
|
||||
import net.corda.core.crypto.CryptoUtilitiesKt;
|
||||
import net.corda.core.crypto.Party;
|
||||
import net.corda.core.crypto.PublicKeyTree;
|
||||
import net.corda.core.crypto.SecureHash;
|
||||
import net.corda.core.node.services.VaultService;
|
||||
import net.corda.core.transactions.TransactionBuilder;
|
||||
@ -40,14 +40,14 @@ public class JavaCommercialPaper implements Contract {
|
||||
|
||||
public static class State implements OwnableState, ICommercialPaperState {
|
||||
private PartyAndReference issuance;
|
||||
private PublicKeyTree owner;
|
||||
private CompositeKey owner;
|
||||
private Amount<Issued<Currency>> faceValue;
|
||||
private Instant maturityDate;
|
||||
|
||||
public State() {
|
||||
} // For serialization
|
||||
|
||||
public State(PartyAndReference issuance, PublicKeyTree owner, Amount<Issued<Currency>> faceValue,
|
||||
public State(PartyAndReference issuance, CompositeKey owner, Amount<Issued<Currency>> faceValue,
|
||||
Instant maturityDate) {
|
||||
this.issuance = issuance;
|
||||
this.owner = owner;
|
||||
@ -59,13 +59,13 @@ public class JavaCommercialPaper implements Contract {
|
||||
return new State(this.issuance, this.owner, this.faceValue, this.maturityDate);
|
||||
}
|
||||
|
||||
public ICommercialPaperState withOwner(PublicKeyTree newOwner) {
|
||||
public ICommercialPaperState withOwner(CompositeKey newOwner) {
|
||||
return new State(this.issuance, newOwner, this.faceValue, this.maturityDate);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Pair<CommandData, OwnableState> withNewOwner(@NotNull PublicKeyTree newOwner) {
|
||||
public Pair<CommandData, OwnableState> withNewOwner(@NotNull CompositeKey newOwner) {
|
||||
return new Pair<>(new Commands.Move(), new State(this.issuance, newOwner, this.faceValue, this.maturityDate));
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ public class JavaCommercialPaper implements Contract {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PublicKeyTree getOwner() {
|
||||
public CompositeKey getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
@ -127,12 +127,12 @@ public class JavaCommercialPaper implements Contract {
|
||||
}
|
||||
|
||||
public State withoutOwner() {
|
||||
return new State(issuance, CryptoUtilitiesKt.getNullPublicKeyTree(), faceValue, maturityDate);
|
||||
return new State(issuance, CryptoUtilitiesKt.getNullCompositeKey(), faceValue, maturityDate);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PublicKeyTree> getParticipants() {
|
||||
public List<CompositeKey> getParticipants() {
|
||||
return ImmutableList.of(this.owner);
|
||||
}
|
||||
|
||||
@ -321,7 +321,7 @@ public class JavaCommercialPaper implements Contract {
|
||||
tx.addCommand(new Command(new Commands.Redeem(), paper.getState().getData().getOwner()));
|
||||
}
|
||||
|
||||
public void generateMove(TransactionBuilder tx, StateAndRef<State> paper, PublicKeyTree newOwner) {
|
||||
public void generateMove(TransactionBuilder tx, StateAndRef<State> paper, CompositeKey newOwner) {
|
||||
tx.addInputState(paper);
|
||||
tx.addOutputState(new TransactionState<>(new State(paper.getState().getData().getIssuance(), newOwner, paper.getState().getData().getFaceValue(), paper.getState().getData().getMaturityDate()), paper.getState().getNotary()));
|
||||
tx.addCommand(new Command(new Commands.Move(), paper.getState().getData().getOwner()));
|
||||
|
@ -7,8 +7,8 @@ import net.corda.core.contracts.clauses.AnyComposition
|
||||
import net.corda.core.contracts.clauses.Clause
|
||||
import net.corda.core.contracts.clauses.GroupClauseVerifier
|
||||
import net.corda.core.contracts.clauses.verifyClause
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.node.services.VaultService
|
||||
import net.corda.core.random63BitValue
|
||||
@ -59,22 +59,22 @@ class CommercialPaper : Contract {
|
||||
|
||||
data class State(
|
||||
val issuance: PartyAndReference,
|
||||
override val owner: PublicKeyTree,
|
||||
override val owner: CompositeKey,
|
||||
val faceValue: Amount<Issued<Currency>>,
|
||||
val maturityDate: Instant
|
||||
) : OwnableState, QueryableState, ICommercialPaperState {
|
||||
override val contract = CP_PROGRAM_ID
|
||||
override val participants: List<PublicKeyTree>
|
||||
override val participants: List<CompositeKey>
|
||||
get() = listOf(owner)
|
||||
|
||||
val token: Issued<Terms>
|
||||
get() = Issued(issuance, Terms(faceValue.token, maturityDate))
|
||||
|
||||
override fun withNewOwner(newOwner: PublicKeyTree) = Pair(Commands.Move(), copy(owner = newOwner))
|
||||
override fun withNewOwner(newOwner: CompositeKey) = Pair(Commands.Move(), copy(owner = newOwner))
|
||||
override fun toString() = "${Emoji.newspaper}CommercialPaper(of $faceValue redeemable on $maturityDate by '$issuance', owned by $owner)"
|
||||
|
||||
// Although kotlin is smart enough not to need these, as we are using the ICommercialPaperState, we need to declare them explicitly for use later,
|
||||
override fun withOwner(newOwner: PublicKeyTree): ICommercialPaperState = copy(owner = newOwner)
|
||||
override fun withOwner(newOwner: CompositeKey): ICommercialPaperState = copy(owner = newOwner)
|
||||
|
||||
override fun withIssuance(newIssuance: PartyAndReference): ICommercialPaperState = copy(issuance = newIssuance)
|
||||
override fun withFaceValue(newFaceValue: Amount<Issued<Currency>>): ICommercialPaperState = copy(faceValue = newFaceValue)
|
||||
@ -200,7 +200,7 @@ class CommercialPaper : Contract {
|
||||
/**
|
||||
* Updates the given partial transaction with an input/output/command to reassign ownership of the paper.
|
||||
*/
|
||||
fun generateMove(tx: TransactionBuilder, paper: StateAndRef<State>, newOwner: PublicKeyTree) {
|
||||
fun generateMove(tx: TransactionBuilder, paper: StateAndRef<State>, newOwner: CompositeKey) {
|
||||
tx.addInputState(paper)
|
||||
tx.addOutputState(TransactionState(paper.state.data.copy(owner = newOwner), paper.state.notary))
|
||||
tx.addCommand(Commands.Move(), paper.state.data.owner)
|
||||
@ -223,8 +223,8 @@ class CommercialPaper : Contract {
|
||||
}
|
||||
}
|
||||
|
||||
infix fun CommercialPaper.State.`owned by`(owner: PublicKeyTree) = copy(owner = owner)
|
||||
infix fun CommercialPaper.State.`owned by`(owner: CompositeKey) = copy(owner = owner)
|
||||
infix fun CommercialPaper.State.`with notary`(notary: Party) = TransactionState(this, notary)
|
||||
infix fun ICommercialPaperState.`owned by`(newOwner: PublicKeyTree) = withOwner(newOwner)
|
||||
infix fun ICommercialPaperState.`owned by`(newOwner: CompositeKey) = withOwner(newOwner)
|
||||
|
||||
|
||||
|
@ -2,9 +2,9 @@ package net.corda.contracts
|
||||
|
||||
import net.corda.contracts.asset.sumCashBy
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.NullPublicKeyTree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.NullCompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.node.services.VaultService
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
@ -26,19 +26,19 @@ class CommercialPaperLegacy : Contract {
|
||||
|
||||
data class State(
|
||||
val issuance: PartyAndReference,
|
||||
override val owner: PublicKeyTree,
|
||||
override val owner: CompositeKey,
|
||||
val faceValue: Amount<Issued<Currency>>,
|
||||
val maturityDate: Instant
|
||||
) : OwnableState, ICommercialPaperState {
|
||||
override val contract = CP_LEGACY_PROGRAM_ID
|
||||
override val participants = listOf(owner)
|
||||
|
||||
fun withoutOwner() = copy(owner = NullPublicKeyTree)
|
||||
override fun withNewOwner(newOwner: PublicKeyTree) = Pair(Commands.Move(), copy(owner = newOwner))
|
||||
fun withoutOwner() = copy(owner = NullCompositeKey)
|
||||
override fun withNewOwner(newOwner: CompositeKey) = Pair(Commands.Move(), copy(owner = newOwner))
|
||||
override fun toString() = "${Emoji.newspaper}CommercialPaper(of $faceValue redeemable on $maturityDate by '$issuance', owned by $owner)"
|
||||
|
||||
// Although kotlin is smart enough not to need these, as we are using the ICommercialPaperState, we need to declare them explicitly for use later,
|
||||
override fun withOwner(newOwner: PublicKeyTree): ICommercialPaperState = copy(owner = newOwner)
|
||||
override fun withOwner(newOwner: CompositeKey): ICommercialPaperState = copy(owner = newOwner)
|
||||
|
||||
override fun withIssuance(newIssuance: PartyAndReference): ICommercialPaperState = copy(issuance = newIssuance)
|
||||
override fun withFaceValue(newFaceValue: Amount<Issued<Currency>>): ICommercialPaperState = copy(faceValue = newFaceValue)
|
||||
@ -117,7 +117,7 @@ class CommercialPaperLegacy : Contract {
|
||||
return TransactionBuilder(notary = notary).withItems(state, Command(Commands.Issue(), issuance.party.owningKey))
|
||||
}
|
||||
|
||||
fun generateMove(tx: TransactionBuilder, paper: StateAndRef<State>, newOwner: PublicKeyTree) {
|
||||
fun generateMove(tx: TransactionBuilder, paper: StateAndRef<State>, newOwner: CompositeKey) {
|
||||
tx.addInputState(paper)
|
||||
tx.addOutputState(paper.state.data.withOwner(newOwner))
|
||||
tx.addCommand(Command(Commands.Move(), paper.state.data.owner))
|
||||
|
@ -82,22 +82,22 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
|
||||
override val amount: Amount<Issued<Currency>>,
|
||||
|
||||
/** There must be a MoveCommand signed by this key to claim the amount. */
|
||||
override val owner: PublicKeyTree,
|
||||
override val owner: CompositeKey,
|
||||
override val encumbrance: Int? = null
|
||||
) : FungibleAsset<Currency>, QueryableState {
|
||||
constructor(deposit: PartyAndReference, amount: Amount<Currency>, owner: PublicKeyTree)
|
||||
constructor(deposit: PartyAndReference, amount: Amount<Currency>, owner: CompositeKey)
|
||||
: this(Amount(amount.quantity, Issued(deposit, amount.token)), owner)
|
||||
|
||||
override val exitKeys = setOf(owner, amount.token.issuer.party.owningKey)
|
||||
override val contract = CASH_PROGRAM_ID
|
||||
override val participants = listOf(owner)
|
||||
|
||||
override fun move(newAmount: Amount<Issued<Currency>>, newOwner: PublicKeyTree): FungibleAsset<Currency>
|
||||
override fun move(newAmount: Amount<Issued<Currency>>, newOwner: CompositeKey): FungibleAsset<Currency>
|
||||
= copy(amount = amount.copy(newAmount.quantity, amount.token), owner = newOwner)
|
||||
|
||||
override fun toString() = "${Emoji.bagOfCash}Cash($amount at ${amount.token.issuer} owned by $owner)"
|
||||
|
||||
override fun withNewOwner(newOwner: PublicKeyTree) = Pair(Commands.Move(), copy(owner = newOwner))
|
||||
override fun withNewOwner(newOwner: CompositeKey) = Pair(Commands.Move(), copy(owner = newOwner))
|
||||
|
||||
/** Object Relational Mapping support. */
|
||||
override fun generateMappedObject(schema: MappedSchema): PersistentState {
|
||||
@ -145,13 +145,13 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
|
||||
/**
|
||||
* Puts together an issuance transaction from the given template, that starts out being owned by the given pubkey.
|
||||
*/
|
||||
fun generateIssue(tx: TransactionBuilder, tokenDef: Issued<Currency>, pennies: Long, owner: PublicKeyTree, notary: Party)
|
||||
fun generateIssue(tx: TransactionBuilder, tokenDef: Issued<Currency>, pennies: Long, owner: CompositeKey, notary: Party)
|
||||
= generateIssue(tx, Amount(pennies, tokenDef), owner, notary)
|
||||
|
||||
/**
|
||||
* Puts together an issuance transaction for the specified amount that starts out being owned by the given pubkey.
|
||||
*/
|
||||
fun generateIssue(tx: TransactionBuilder, amount: Amount<Issued<Currency>>, owner: PublicKeyTree, notary: Party) {
|
||||
fun generateIssue(tx: TransactionBuilder, amount: Amount<Issued<Currency>>, owner: CompositeKey, notary: Party) {
|
||||
check(tx.inputStates().isEmpty())
|
||||
check(tx.outputStates().map { it.data }.sumCashOrNull() == null)
|
||||
val at = amount.token.issuer
|
||||
@ -159,7 +159,7 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
|
||||
tx.addCommand(generateIssueCommand(), at.party.owningKey)
|
||||
}
|
||||
|
||||
override fun deriveState(txState: TransactionState<State>, amount: Amount<Issued<Currency>>, owner: PublicKeyTree)
|
||||
override fun deriveState(txState: TransactionState<State>, amount: Amount<Issued<Currency>>, owner: CompositeKey)
|
||||
= txState.copy(data = txState.data.copy(amount = amount, owner = owner))
|
||||
override fun generateExitCommand(amount: Amount<Issued<Currency>>) = Commands.Exit(amount)
|
||||
override fun generateIssueCommand() = Commands.Issue()
|
||||
@ -176,7 +176,7 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
|
||||
* if there are none, or if any of the cash states cannot be added together (i.e. are
|
||||
* different currencies or issuers).
|
||||
*/
|
||||
fun Iterable<ContractState>.sumCashBy(owner: PublicKeyTree): Amount<Issued<Currency>> = filterIsInstance<Cash.State>().filter { it.owner == owner }.map { it.amount }.sumOrThrow()
|
||||
fun Iterable<ContractState>.sumCashBy(owner: CompositeKey): Amount<Issued<Currency>> = filterIsInstance<Cash.State>().filter { it.owner == owner }.map { it.amount }.sumOrThrow()
|
||||
|
||||
/**
|
||||
* Sums the cash states in the list, throwing an exception if there are none, or if any of the cash
|
||||
@ -192,12 +192,12 @@ fun Iterable<ContractState>.sumCashOrZero(currency: Issued<Currency>): Amount<Is
|
||||
return filterIsInstance<Cash.State>().map { it.amount }.sumOrZero(currency)
|
||||
}
|
||||
|
||||
fun Cash.State.ownedBy(owner: PublicKeyTree) = copy(owner = owner)
|
||||
fun Cash.State.ownedBy(owner: CompositeKey) = copy(owner = owner)
|
||||
fun Cash.State.issuedBy(party: Party) = copy(amount = Amount(amount.quantity, amount.token.copy(issuer = amount.token.issuer.copy(party = party))))
|
||||
fun Cash.State.issuedBy(deposit: PartyAndReference) = copy(amount = Amount(amount.quantity, amount.token.copy(issuer = deposit)))
|
||||
fun Cash.State.withDeposit(deposit: PartyAndReference): Cash.State = copy(amount = amount.copy(token = amount.token.copy(issuer = deposit)))
|
||||
|
||||
infix fun Cash.State.`owned by`(owner: PublicKeyTree) = ownedBy(owner)
|
||||
infix fun Cash.State.`owned by`(owner: CompositeKey) = ownedBy(owner)
|
||||
infix fun Cash.State.`issued by`(party: Party) = issuedBy(party)
|
||||
infix fun Cash.State.`issued by`(deposit: PartyAndReference) = issuedBy(deposit)
|
||||
infix fun Cash.State.`with deposit`(deposit: PartyAndReference): Cash.State = withDeposit(deposit)
|
||||
@ -207,8 +207,8 @@ infix fun Cash.State.`with deposit`(deposit: PartyAndReference): Cash.State = wi
|
||||
/** A randomly generated key. */
|
||||
val DUMMY_CASH_ISSUER_KEY by lazy { entropyToKeyPair(BigInteger.valueOf(10)) }
|
||||
/** A dummy, randomly generated issuer party by the name of "Snake Oil Issuer" */
|
||||
val DUMMY_CASH_ISSUER by lazy { Party("Snake Oil Issuer", DUMMY_CASH_ISSUER_KEY.public.tree).ref(1) }
|
||||
val DUMMY_CASH_ISSUER by lazy { Party("Snake Oil Issuer", DUMMY_CASH_ISSUER_KEY.public.composite).ref(1) }
|
||||
/** An extension property that lets you write 100.DOLLARS.CASH */
|
||||
val Amount<Currency>.CASH: Cash.State get() = Cash.State(Amount(quantity, Issued(DUMMY_CASH_ISSUER, token)), NullPublicKeyTree)
|
||||
val Amount<Currency>.CASH: Cash.State get() = Cash.State(Amount(quantity, Issued(DUMMY_CASH_ISSUER, token)), NullCompositeKey)
|
||||
/** An extension property that lets you get a cash state from an issued token, under the [NullPublicKey] */
|
||||
val Amount<Issued<Currency>>.STATE: Cash.State get() = Cash.State(this, NullPublicKeyTree)
|
||||
val Amount<Issued<Currency>>.STATE: Cash.State get() = Cash.State(this, NullCompositeKey)
|
||||
|
@ -7,8 +7,8 @@ import net.corda.core.contracts.*
|
||||
import net.corda.core.contracts.clauses.AnyComposition
|
||||
import net.corda.core.contracts.clauses.GroupClauseVerifier
|
||||
import net.corda.core.contracts.clauses.verifyClause
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.newSecureRandom
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
@ -95,21 +95,21 @@ class CommodityContract : OnLedgerAsset<Commodity, CommodityContract.Commands, C
|
||||
override val amount: Amount<Issued<Commodity>>,
|
||||
|
||||
/** There must be a MoveCommand signed by this key to claim the amount */
|
||||
override val owner: PublicKeyTree
|
||||
override val owner: CompositeKey
|
||||
) : FungibleAsset<Commodity> {
|
||||
constructor(deposit: PartyAndReference, amount: Amount<Commodity>, owner: PublicKeyTree)
|
||||
constructor(deposit: PartyAndReference, amount: Amount<Commodity>, owner: CompositeKey)
|
||||
: this(Amount(amount.quantity, Issued(deposit, amount.token)), owner)
|
||||
|
||||
override val contract = COMMODITY_PROGRAM_ID
|
||||
override val exitKeys = Collections.singleton(owner)
|
||||
override val participants = listOf(owner)
|
||||
|
||||
override fun move(newAmount: Amount<Issued<Commodity>>, newOwner: PublicKeyTree): FungibleAsset<Commodity>
|
||||
override fun move(newAmount: Amount<Issued<Commodity>>, newOwner: CompositeKey): FungibleAsset<Commodity>
|
||||
= copy(amount = amount.copy(newAmount.quantity, amount.token), owner = newOwner)
|
||||
|
||||
override fun toString() = "Commodity($amount at ${amount.token.issuer} owned by $owner)"
|
||||
|
||||
override fun withNewOwner(newOwner: PublicKeyTree) = Pair(Commands.Move(), copy(owner = newOwner))
|
||||
override fun withNewOwner(newOwner: CompositeKey) = Pair(Commands.Move(), copy(owner = newOwner))
|
||||
}
|
||||
|
||||
// Just for grouping
|
||||
@ -143,13 +143,13 @@ class CommodityContract : OnLedgerAsset<Commodity, CommodityContract.Commands, C
|
||||
/**
|
||||
* Puts together an issuance transaction from the given template, that starts out being owned by the given pubkey.
|
||||
*/
|
||||
fun generateIssue(tx: TransactionBuilder, tokenDef: Issued<Commodity>, pennies: Long, owner: PublicKeyTree, notary: Party)
|
||||
fun generateIssue(tx: TransactionBuilder, tokenDef: Issued<Commodity>, pennies: Long, owner: CompositeKey, notary: Party)
|
||||
= generateIssue(tx, Amount(pennies, tokenDef), owner, notary)
|
||||
|
||||
/**
|
||||
* Puts together an issuance transaction for the specified amount that starts out being owned by the given pubkey.
|
||||
*/
|
||||
fun generateIssue(tx: TransactionBuilder, amount: Amount<Issued<Commodity>>, owner: PublicKeyTree, notary: Party) {
|
||||
fun generateIssue(tx: TransactionBuilder, amount: Amount<Issued<Commodity>>, owner: CompositeKey, notary: Party) {
|
||||
check(tx.inputStates().isEmpty())
|
||||
check(tx.outputStates().map { it.data }.sumCashOrNull() == null)
|
||||
val at = amount.token.issuer
|
||||
@ -158,7 +158,7 @@ class CommodityContract : OnLedgerAsset<Commodity, CommodityContract.Commands, C
|
||||
}
|
||||
|
||||
|
||||
override fun deriveState(txState: TransactionState<State>, amount: Amount<Issued<Commodity>>, owner: PublicKeyTree)
|
||||
override fun deriveState(txState: TransactionState<State>, amount: Amount<Issued<Commodity>>, owner: CompositeKey)
|
||||
= txState.copy(data = txState.data.copy(amount = amount, owner = owner))
|
||||
override fun generateExitCommand(amount: Amount<Issued<Commodity>>) = Commands.Exit(amount)
|
||||
override fun generateIssueCommand() = Commands.Issue()
|
||||
|
@ -269,16 +269,16 @@ class Obligation<P> : Contract {
|
||||
val template: Terms<P>,
|
||||
val quantity: Long,
|
||||
/** The public key of the entity the contract pays to */
|
||||
val beneficiary: PublicKeyTree
|
||||
val beneficiary: CompositeKey
|
||||
) : FungibleAsset<Obligation.Terms<P>>, NettableState<State<P>, MultilateralNetState<P>> {
|
||||
override val amount: Amount<Issued<Terms<P>>> = Amount(quantity, Issued(obligor.ref(0), template))
|
||||
override val contract = OBLIGATION_PROGRAM_ID
|
||||
override val exitKeys: Collection<PublicKeyTree> = setOf(beneficiary)
|
||||
override val exitKeys: Collection<CompositeKey> = setOf(beneficiary)
|
||||
val dueBefore: Instant = template.dueBefore
|
||||
override val participants: List<PublicKeyTree> = listOf(obligor.owningKey, beneficiary)
|
||||
override val owner: PublicKeyTree = beneficiary
|
||||
override val participants: List<CompositeKey> = listOf(obligor.owningKey, beneficiary)
|
||||
override val owner: CompositeKey = beneficiary
|
||||
|
||||
override fun move(newAmount: Amount<Issued<Terms<P>>>, newOwner: PublicKeyTree): State<P>
|
||||
override fun move(newAmount: Amount<Issued<Terms<P>>>, newOwner: CompositeKey): State<P>
|
||||
= copy(quantity = newAmount.quantity, beneficiary = newOwner)
|
||||
|
||||
override fun toString() = when (lifecycle) {
|
||||
@ -311,7 +311,7 @@ class Obligation<P> : Contract {
|
||||
}
|
||||
}
|
||||
|
||||
override fun withNewOwner(newOwner: PublicKeyTree) = Pair(Commands.Move(), copy(beneficiary = newOwner))
|
||||
override fun withNewOwner(newOwner: CompositeKey) = Pair(Commands.Move(), copy(beneficiary = newOwner))
|
||||
}
|
||||
|
||||
// Just for grouping
|
||||
@ -416,7 +416,7 @@ class Obligation<P> : Contract {
|
||||
* and same parties involved).
|
||||
*/
|
||||
fun generateCloseOutNetting(tx: TransactionBuilder,
|
||||
signer: PublicKeyTree,
|
||||
signer: CompositeKey,
|
||||
vararg states: State<P>) {
|
||||
val netState = states.firstOrNull()?.bilateralNetState
|
||||
|
||||
@ -444,7 +444,7 @@ class Obligation<P> : Contract {
|
||||
*/
|
||||
@Suppress("unused")
|
||||
fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<Terms<P>>>,
|
||||
assetStates: List<StateAndRef<Obligation.State<P>>>): PublicKeyTree
|
||||
assetStates: List<StateAndRef<Obligation.State<P>>>): CompositeKey
|
||||
= Clauses.ConserveAmount<P>().generateExit(tx, amountIssued, assetStates,
|
||||
deriveState = { state, amount, owner -> state.copy(data = state.data.move(amount, owner)) },
|
||||
generateMoveCommand = { -> Commands.Move() },
|
||||
@ -458,7 +458,7 @@ class Obligation<P> : Contract {
|
||||
obligor: Party,
|
||||
issuanceDef: Terms<P>,
|
||||
pennies: Long,
|
||||
beneficiary: PublicKeyTree,
|
||||
beneficiary: CompositeKey,
|
||||
notary: Party) {
|
||||
check(tx.inputStates().isEmpty())
|
||||
check(tx.outputStates().map { it.data }.sumObligationsOrNull<P>() == null)
|
||||
@ -474,7 +474,7 @@ class Obligation<P> : Contract {
|
||||
"all states are in the normal lifecycle state " by (states.all { it.lifecycle == Lifecycle.NORMAL })
|
||||
}
|
||||
val groups = states.groupBy { it.multilateralNetState }
|
||||
val partyLookup = HashMap<PublicKeyTree, Party>()
|
||||
val partyLookup = HashMap<CompositeKey, Party>()
|
||||
val signers = states.map { it.beneficiary }.union(states.map { it.obligor.owningKey }).toSet()
|
||||
|
||||
// Create a lookup table of the party that each public key represents.
|
||||
@ -520,7 +520,7 @@ class Obligation<P> : Contract {
|
||||
// Produce a new set of states
|
||||
val groups = statesAndRefs.groupBy { it.state.data.amount.token }
|
||||
for ((aggregateState, stateAndRefs) in groups) {
|
||||
val partiesUsed = ArrayList<PublicKeyTree>()
|
||||
val partiesUsed = ArrayList<CompositeKey>()
|
||||
stateAndRefs.forEach { stateAndRef ->
|
||||
val outState = stateAndRef.state.data.copy(lifecycle = lifecycle)
|
||||
tx.addInputState(stateAndRef)
|
||||
@ -565,7 +565,7 @@ class Obligation<P> : Contract {
|
||||
val template: Terms<P> = issuanceDef.product
|
||||
val obligationTotal: Amount<P> = Amount(states.map { it.data }.sumObligations<P>().quantity, template.product)
|
||||
var obligationRemaining: Amount<P> = obligationTotal
|
||||
val assetSigners = HashSet<PublicKeyTree>()
|
||||
val assetSigners = HashSet<CompositeKey>()
|
||||
|
||||
statesAndRefs.forEach { tx.addInputState(it) }
|
||||
|
||||
@ -617,8 +617,8 @@ class Obligation<P> : Contract {
|
||||
*
|
||||
* @return a map of obligor/beneficiary pairs to the balance due.
|
||||
*/
|
||||
fun <P> extractAmountsDue(product: Obligation.Terms<P>, states: Iterable<Obligation.State<P>>): Map<Pair<PublicKeyTree, PublicKeyTree>, Amount<Obligation.Terms<P>>> {
|
||||
val balances = HashMap<Pair<PublicKeyTree, PublicKeyTree>, Amount<Obligation.Terms<P>>>()
|
||||
fun <P> extractAmountsDue(product: Obligation.Terms<P>, states: Iterable<Obligation.State<P>>): Map<Pair<CompositeKey, CompositeKey>, Amount<Obligation.Terms<P>>> {
|
||||
val balances = HashMap<Pair<CompositeKey, CompositeKey>, Amount<Obligation.Terms<P>>>()
|
||||
|
||||
states.forEach { state ->
|
||||
val key = Pair(state.obligor.owningKey, state.beneficiary)
|
||||
@ -632,8 +632,8 @@ fun <P> extractAmountsDue(product: Obligation.Terms<P>, states: Iterable<Obligat
|
||||
/**
|
||||
* Net off the amounts due between parties.
|
||||
*/
|
||||
fun <P> netAmountsDue(balances: Map<Pair<PublicKeyTree, PublicKeyTree>, Amount<P>>): Map<Pair<PublicKeyTree, PublicKeyTree>, Amount<P>> {
|
||||
val nettedBalances = HashMap<Pair<PublicKeyTree, PublicKeyTree>, Amount<P>>()
|
||||
fun <P> netAmountsDue(balances: Map<Pair<CompositeKey, CompositeKey>, Amount<P>>): Map<Pair<CompositeKey, CompositeKey>, Amount<P>> {
|
||||
val nettedBalances = HashMap<Pair<CompositeKey, CompositeKey>, Amount<P>>()
|
||||
|
||||
balances.forEach { balance ->
|
||||
val (obligor, beneficiary) = balance.key
|
||||
@ -657,8 +657,8 @@ fun <P> netAmountsDue(balances: Map<Pair<PublicKeyTree, PublicKeyTree>, Amount<P
|
||||
* @param balances payments due, indexed by obligor and beneficiary. Zero balances are stripped from the map before being
|
||||
* returned.
|
||||
*/
|
||||
fun <P> sumAmountsDue(balances: Map<Pair<PublicKeyTree, PublicKeyTree>, Amount<P>>): Map<PublicKeyTree, Long> {
|
||||
val sum = HashMap<PublicKeyTree, Long>()
|
||||
fun <P> sumAmountsDue(balances: Map<Pair<CompositeKey, CompositeKey>, Amount<P>>): Map<CompositeKey, Long> {
|
||||
val sum = HashMap<CompositeKey, Long>()
|
||||
|
||||
// Fill the map with zeroes initially
|
||||
balances.keys.forEach {
|
||||
@ -699,19 +699,19 @@ fun <P> Iterable<ContractState>.sumObligationsOrZero(issuanceDef: Issued<Obligat
|
||||
= filterIsInstance<Obligation.State<P>>().filter { it.lifecycle == Obligation.Lifecycle.NORMAL }.map { it.amount }.sumOrZero(issuanceDef)
|
||||
|
||||
infix fun <T> Obligation.State<T>.at(dueBefore: Instant) = copy(template = template.copy(dueBefore = dueBefore))
|
||||
infix fun <T> Obligation.State<T>.between(parties: Pair<Party, PublicKeyTree>) = copy(obligor = parties.first, beneficiary = parties.second)
|
||||
infix fun <T> Obligation.State<T>.`owned by`(owner: PublicKeyTree) = copy(beneficiary = owner)
|
||||
infix fun <T> Obligation.State<T>.between(parties: Pair<Party, CompositeKey>) = copy(obligor = parties.first, beneficiary = parties.second)
|
||||
infix fun <T> Obligation.State<T>.`owned by`(owner: CompositeKey) = copy(beneficiary = owner)
|
||||
infix fun <T> Obligation.State<T>.`issued by`(party: Party) = copy(obligor = party)
|
||||
// For Java users:
|
||||
@Suppress("unused") fun <T> Obligation.State<T>.ownedBy(owner: PublicKeyTree) = copy(beneficiary = owner)
|
||||
@Suppress("unused") fun <T> Obligation.State<T>.ownedBy(owner: CompositeKey) = copy(beneficiary = owner)
|
||||
@Suppress("unused") fun <T> Obligation.State<T>.issuedBy(party: Party) = copy(obligor = party)
|
||||
|
||||
/** A randomly generated key. */
|
||||
val DUMMY_OBLIGATION_ISSUER_KEY by lazy { entropyToKeyPair(BigInteger.valueOf(10)) }
|
||||
/** A dummy, randomly generated issuer party by the name of "Snake Oil Issuer" */
|
||||
val DUMMY_OBLIGATION_ISSUER by lazy { Party("Snake Oil Issuer", DUMMY_OBLIGATION_ISSUER_KEY.public.tree) }
|
||||
val DUMMY_OBLIGATION_ISSUER by lazy { Party("Snake Oil Issuer", DUMMY_OBLIGATION_ISSUER_KEY.public.composite) }
|
||||
|
||||
val Issued<Currency>.OBLIGATION_DEF: Obligation.Terms<Currency>
|
||||
get() = Obligation.Terms(nonEmptySetOf(Cash().legalContractReference), nonEmptySetOf(this), TEST_TX_TIME)
|
||||
val Amount<Issued<Currency>>.OBLIGATION: Obligation.State<Currency>
|
||||
get() = Obligation.State(Obligation.Lifecycle.NORMAL, DUMMY_OBLIGATION_ISSUER, token.OBLIGATION_DEF, quantity, NullPublicKeyTree)
|
||||
get() = Obligation.State(Obligation.Lifecycle.NORMAL, DUMMY_OBLIGATION_ISSUER, token.OBLIGATION_DEF, quantity, NullCompositeKey)
|
||||
|
@ -2,7 +2,7 @@ package net.corda.contracts.asset
|
||||
|
||||
import net.corda.contracts.clause.AbstractConserveAmount
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -39,7 +39,7 @@ abstract class OnLedgerAsset<T : Any, C: CommandData, S : FungibleAsset<T>> : Co
|
||||
* @return the public key of the assets issuer, who must sign the transaction for it to be valid.
|
||||
*/
|
||||
fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<T>>,
|
||||
assetStates: List<StateAndRef<S>>): PublicKeyTree
|
||||
assetStates: List<StateAndRef<S>>): CompositeKey
|
||||
= conserveClause.generateExit(tx, amountIssued, assetStates,
|
||||
deriveState = { state, amount, owner -> deriveState(state, amount, owner) },
|
||||
generateMoveCommand = { -> generateMoveCommand() },
|
||||
@ -55,5 +55,5 @@ abstract class OnLedgerAsset<T : Any, C: CommandData, S : FungibleAsset<T>> : Co
|
||||
* implementations to have fields in their state which we don't know about here, and we simply leave them untouched
|
||||
* when sending out "change" from spending/exiting.
|
||||
*/
|
||||
abstract fun deriveState(txState: TransactionState<S>, amount: Amount<Issued<T>>, owner: PublicKeyTree): TransactionState<S>
|
||||
abstract fun deriveState(txState: TransactionState<S>, amount: Amount<Issued<T>>, owner: CompositeKey): TransactionState<S>
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package net.corda.contracts.clause
|
||||
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.contracts.clauses.Clause
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import java.util.*
|
||||
|
||||
@ -47,9 +47,9 @@ abstract class AbstractConserveAmount<S : FungibleAsset<T>, C : CommandData, T :
|
||||
*/
|
||||
fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<T>>,
|
||||
assetStates: List<StateAndRef<S>>,
|
||||
deriveState: (TransactionState<S>, Amount<Issued<T>>, PublicKeyTree) -> TransactionState<S>,
|
||||
deriveState: (TransactionState<S>, Amount<Issued<T>>, CompositeKey) -> TransactionState<S>,
|
||||
generateMoveCommand: () -> CommandData,
|
||||
generateExitCommand: (Amount<Issued<T>>) -> CommandData): PublicKeyTree {
|
||||
generateExitCommand: (Amount<Issued<T>>) -> CommandData): CompositeKey {
|
||||
val owner = assetStates.map { it.state.data.owner }.toSet().single()
|
||||
val currency = amountIssued.token.product
|
||||
val amount = Amount(amountIssued.quantity, currency)
|
||||
@ -92,7 +92,7 @@ abstract class AbstractConserveAmount<S : FungibleAsset<T>, C : CommandData, T :
|
||||
val outputAmount: Amount<Issued<T>> = outputs.sumFungibleOrZero(groupingKey)
|
||||
|
||||
// If we want to remove assets from the ledger, that must be signed for by the issuer and owner.
|
||||
val exitKeys: Set<PublicKeyTree> = inputs.flatMap { it.exitKeys }.toSet()
|
||||
val exitKeys: Set<CompositeKey> = inputs.flatMap { it.exitKeys }.toSet()
|
||||
val exitCommand = matchedCommands.select<FungibleAsset.Commands.Exit<T>>(parties = null, signers = exitKeys).filter { it.value.amount.token == groupingKey }.singleOrNull()
|
||||
val amountExitingLedger: Amount<Issued<T>> = exitCommand?.value?.amount ?: Amount(0, groupingKey)
|
||||
|
||||
|
@ -6,7 +6,7 @@ import net.corda.contracts.asset.extractAmountsDue
|
||||
import net.corda.contracts.asset.sumAmountsDue
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.contracts.clauses.Clause
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
|
||||
/**
|
||||
* Common interface for the state subsets used when determining nettability of two or more states. Exposes the
|
||||
@ -22,7 +22,7 @@ interface NetState<P> {
|
||||
* Bilateral states are used in close-out netting.
|
||||
*/
|
||||
data class BilateralNetState<P>(
|
||||
val partyKeys: Set<PublicKeyTree>,
|
||||
val partyKeys: Set<CompositeKey>,
|
||||
override val template: Obligation.Terms<P>
|
||||
) : NetState<P>
|
||||
|
||||
|
@ -25,7 +25,7 @@ class ContractStateGenerator : Generator<ContractState>(ContractState::class.jav
|
||||
override fun generate(random: SourceOfRandomness, status: GenerationStatus): ContractState {
|
||||
return Cash.State(
|
||||
amount = AmountGenerator(IssuedGenerator(CurrencyGenerator())).generate(random, status),
|
||||
owner = PublicKeyTreeGenerator().generate(random, status)
|
||||
owner = CompositeKeyGenerator().generate(random, status)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -58,8 +58,8 @@ class CommandDataGenerator : Generator<CommandData>(CommandData::class.java) {
|
||||
class CommandGenerator : Generator<Command>(Command::class.java) {
|
||||
override fun generate(random: SourceOfRandomness, status: GenerationStatus): Command {
|
||||
val signersGenerator = ArrayListGenerator()
|
||||
signersGenerator.addComponentGenerators(listOf(PublicKeyTreeGenerator()))
|
||||
return Command(CommandDataGenerator().generate(random, status), PublicKeyTreeGenerator().generate(random, status))
|
||||
signersGenerator.addComponentGenerators(listOf(CompositeKeyGenerator()))
|
||||
return Command(CommandDataGenerator().generate(random, status), CompositeKeyGenerator().generate(random, status))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,8 @@ import net.corda.core.contracts.Amount
|
||||
import net.corda.core.contracts.Issued
|
||||
import net.corda.core.contracts.PartyAndReference
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.node.ServiceHub
|
||||
import net.corda.core.node.services.Vault
|
||||
import net.corda.core.serialization.OpaqueBytes
|
||||
@ -35,12 +35,12 @@ fun ServiceHub.fillWithSomeTestCash(howMuch: Amount<Currency>,
|
||||
atMostThisManyStates: Int = 10,
|
||||
rng: Random = Random(),
|
||||
ref: OpaqueBytes = OpaqueBytes(ByteArray(1, { 1 })),
|
||||
ownedBy: PublicKeyTree? = null,
|
||||
ownedBy: CompositeKey? = null,
|
||||
issuedBy: PartyAndReference = DUMMY_CASH_ISSUER,
|
||||
issuerKey: KeyPair = DUMMY_CASH_ISSUER_KEY): Vault {
|
||||
val amounts = calculateRandomlySizedAmounts(howMuch, atLeastThisManyStates, atMostThisManyStates, rng)
|
||||
|
||||
val myKey: PublicKeyTree = ownedBy ?: myInfo.legalIdentity.owningKey
|
||||
val myKey: CompositeKey = ownedBy ?: myInfo.legalIdentity.owningKey
|
||||
|
||||
// We will allocate one state to one transaction, for simplicities sake.
|
||||
val cash = Cash()
|
||||
|
@ -51,7 +51,7 @@ object TwoPartyTradeProtocol {
|
||||
data class SellerTradeInfo(
|
||||
val assetForSale: StateAndRef<OwnableState>,
|
||||
val price: Amount<Currency>,
|
||||
val sellerOwnerKey: PublicKeyTree
|
||||
val sellerOwnerKey: CompositeKey
|
||||
)
|
||||
|
||||
data class SignaturesFromSeller(val sellerSig: DigitalSignature.WithKey,
|
||||
@ -99,7 +99,7 @@ object TwoPartyTradeProtocol {
|
||||
private fun receiveAndCheckProposedTransaction(): SignedTransaction {
|
||||
progressTracker.currentStep = AWAITING_PROPOSAL
|
||||
|
||||
val myPublicKey = myKeyPair.public.tree
|
||||
val myPublicKey = myKeyPair.public.composite
|
||||
// Make the first message we'll send to kick off the protocol.
|
||||
val hello = SellerTradeInfo(assetToSell, price, myPublicKey)
|
||||
|
||||
@ -223,7 +223,7 @@ object TwoPartyTradeProtocol {
|
||||
return sendAndReceive<SignaturesFromSeller>(otherParty, stx).unwrap { it }
|
||||
}
|
||||
|
||||
private fun signWithOurKeys(cashSigningPubKeys: List<PublicKeyTree>, ptx: TransactionBuilder): SignedTransaction {
|
||||
private fun signWithOurKeys(cashSigningPubKeys: List<CompositeKey>, ptx: TransactionBuilder): SignedTransaction {
|
||||
// Now sign the transaction with whatever keys we need to move the cash.
|
||||
for (publicKey in cashSigningPubKeys.keys) {
|
||||
val privateKey = serviceHub.keyManagementService.toPrivate(publicKey)
|
||||
@ -233,7 +233,7 @@ object TwoPartyTradeProtocol {
|
||||
return ptx.toSignedTransaction(checkSufficientSignatures = false)
|
||||
}
|
||||
|
||||
private fun assembleSharedTX(tradeRequest: SellerTradeInfo): Pair<TransactionBuilder, List<PublicKeyTree>> {
|
||||
private fun assembleSharedTX(tradeRequest: SellerTradeInfo): Pair<TransactionBuilder, List<CompositeKey>> {
|
||||
val ptx = TransactionType.General.Builder(notary)
|
||||
|
||||
// Add input and output states for the movement of cash, by using the Cash contract to generate the states
|
||||
@ -247,7 +247,7 @@ object TwoPartyTradeProtocol {
|
||||
// reveal who the owner actually is. The key management service is expected to derive a unique key from some
|
||||
// initial seed in order to provide privacy protection.
|
||||
val freshKey = serviceHub.keyManagementService.freshKey()
|
||||
val (command, state) = tradeRequest.assetForSale.state.data.withNewOwner(freshKey.public.tree)
|
||||
val (command, state) = tradeRequest.assetForSale.state.data.withNewOwner(freshKey.public.composite)
|
||||
tx.addOutputState(state, tradeRequest.assetForSale.state.notary)
|
||||
tx.addCommand(command, tradeRequest.assetForSale.state.data.owner)
|
||||
|
||||
|
@ -5,7 +5,7 @@ import net.corda.contracts.testing.fillWithSomeTestCash
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.tree
|
||||
import net.corda.core.crypto.composite
|
||||
import net.corda.core.days
|
||||
import net.corda.core.node.recordTransactions
|
||||
import net.corda.core.node.services.Vault
|
||||
@ -278,8 +278,8 @@ class CommercialPaperTestsGeneric {
|
||||
// Alice pays $9000 to BigCorp to own some of their debt.
|
||||
moveTX = run {
|
||||
val ptx = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
aliceVaultService.generateSpend(ptx, 9000.DOLLARS, bigCorpServices.key.public.tree)
|
||||
CommercialPaper().generateMove(ptx, issueTX.tx.outRef(0), aliceServices.key.public.tree)
|
||||
aliceVaultService.generateSpend(ptx, 9000.DOLLARS, bigCorpServices.key.public.composite)
|
||||
CommercialPaper().generateMove(ptx, issueTX.tx.outRef(0), aliceServices.key.public.composite)
|
||||
ptx.signWith(bigCorpServices.key)
|
||||
ptx.signWith(aliceServices.key)
|
||||
ptx.signWith(DUMMY_NOTARY_KEY)
|
||||
|
@ -455,7 +455,7 @@ class CashTests {
|
||||
// Spend tx generation
|
||||
|
||||
val OUR_KEY: KeyPair by lazy { generateKeyPair() }
|
||||
val OUR_PUBKEY_1: PublicKeyTree get() = OUR_KEY.public.tree
|
||||
val OUR_PUBKEY_1: CompositeKey get() = OUR_KEY.public.composite
|
||||
|
||||
val THEIR_PUBKEY_1 = DUMMY_PUBKEY_2
|
||||
|
||||
@ -481,7 +481,7 @@ class CashTests {
|
||||
return tx.toWireTransaction()
|
||||
}
|
||||
|
||||
fun makeSpend(amount: Amount<Currency>, dest: PublicKeyTree): WireTransaction {
|
||||
fun makeSpend(amount: Amount<Currency>, dest: CompositeKey): WireTransaction {
|
||||
val tx = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
databaseTransaction(database) {
|
||||
vault.generateSpend(tx, amount, dest)
|
||||
|
@ -2,8 +2,8 @@ package net.corda.contracts.asset
|
||||
|
||||
import net.corda.contracts.asset.Obligation.Lifecycle
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.NullPublicKeyTree
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.NullCompositeKey
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.serialization.OpaqueBytes
|
||||
import net.corda.core.utilities.*
|
||||
@ -506,7 +506,7 @@ class ObligationTests {
|
||||
val oneUnitFcoj = Amount(1, defaultFcoj)
|
||||
val obligationDef = Obligation.Terms(nonEmptySetOf(CommodityContract().legalContractReference), nonEmptySetOf(defaultFcoj), TEST_TX_TIME)
|
||||
val oneUnitFcojObligation = Obligation.State(Obligation.Lifecycle.NORMAL, ALICE,
|
||||
obligationDef, oneUnitFcoj.quantity, NullPublicKeyTree)
|
||||
obligationDef, oneUnitFcoj.quantity, NullCompositeKey)
|
||||
// Try settling a simple commodity obligation
|
||||
ledger {
|
||||
unverifiedTransaction {
|
||||
@ -830,7 +830,7 @@ class ObligationTests {
|
||||
Pair(Pair(ALICE_PUBKEY, BOB_PUBKEY), Amount(100000000, GBP)),
|
||||
Pair(Pair(BOB_PUBKEY, ALICE_PUBKEY), Amount(100000000, GBP))
|
||||
)
|
||||
val expected: Map<Pair<PublicKeyTree, PublicKeyTree>, Amount<Currency>> = emptyMap() // Zero balances are stripped before returning
|
||||
val expected: Map<Pair<CompositeKey, CompositeKey>, Amount<Currency>> = emptyMap() // Zero balances are stripped before returning
|
||||
val actual = netAmountsDue(balanced)
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
@ -851,8 +851,8 @@ class ObligationTests {
|
||||
|
||||
@Test
|
||||
fun `summing empty balances due between parties`() {
|
||||
val empty = emptyMap<Pair<PublicKeyTree, PublicKeyTree>, Amount<Currency>>()
|
||||
val expected = emptyMap<PublicKeyTree, Long>()
|
||||
val empty = emptyMap<Pair<CompositeKey, CompositeKey>, Amount<Currency>>()
|
||||
val expected = emptyMap<CompositeKey, Long>()
|
||||
val actual = sumAmountsDue(empty)
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
@ -872,7 +872,7 @@ class ObligationTests {
|
||||
Pair(Pair(ALICE_PUBKEY, BOB_PUBKEY), Amount(100000000, GBP)),
|
||||
Pair(Pair(BOB_PUBKEY, ALICE_PUBKEY), Amount(100000000, GBP))
|
||||
)
|
||||
val expected: Map<PublicKeyTree, Long> = emptyMap() // Zero balances are stripped before returning
|
||||
val expected: Map<CompositeKey, Long> = emptyMap() // Zero balances are stripped before returning
|
||||
val actual = sumAmountsDue(balanced)
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
@ -5,10 +5,10 @@ import net.corda.core.contracts.DummyContract
|
||||
import net.corda.core.contracts.StateAndRef
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.composite
|
||||
import net.corda.core.crypto.generateKeyPair
|
||||
import net.corda.core.crypto.tree
|
||||
import net.corda.core.messaging.SingleMessageRecipient
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.core.random63BitValue
|
||||
@ -92,7 +92,7 @@ class DistributedNotaryTests {
|
||||
val notaryClusterAddress = freeLocalHostAndPort()
|
||||
val keyPairs = (1..clusterSize).map { generateKeyPair() }
|
||||
|
||||
val notaryKeyTree = PublicKeyTree.Builder().addKeys(keyPairs.map { it.public.tree }).build(1)
|
||||
val notaryKeyTree = CompositeKey.Builder().addKeys(keyPairs.map { it.public.composite }).build(1)
|
||||
val notaryParty = Party(notaryName, notaryKeyTree).serialize()
|
||||
|
||||
var networkMapAddress: SingleMessageRecipient? = null
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.corda.node.services.identity
|
||||
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.node.services.IdentityService
|
||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
@ -12,7 +12,7 @@ import javax.annotation.concurrent.ThreadSafe
|
||||
*/
|
||||
@ThreadSafe
|
||||
class InMemoryIdentityService() : SingletonSerializeAsToken(), IdentityService {
|
||||
private val keyToParties = ConcurrentHashMap<PublicKeyTree, Party>()
|
||||
private val keyToParties = ConcurrentHashMap<CompositeKey, Party>()
|
||||
private val nameToParties = ConcurrentHashMap<String, Party>()
|
||||
|
||||
override fun registerIdentity(party: Party) {
|
||||
@ -20,6 +20,6 @@ class InMemoryIdentityService() : SingletonSerializeAsToken(), IdentityService {
|
||||
nameToParties[party.name] = party
|
||||
}
|
||||
|
||||
override fun partyFromKey(key: PublicKeyTree): Party? = keyToParties[key]
|
||||
override fun partyFromKey(key: CompositeKey): Party? = keyToParties[key]
|
||||
override fun partyFromName(name: String): Party? = nameToParties[name]
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package net.corda.node.services.messaging
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting
|
||||
import com.google.common.net.HostAndPort
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.messaging.MessageRecipients
|
||||
import net.corda.core.messaging.SingleMessageRecipient
|
||||
import net.corda.core.read
|
||||
@ -75,7 +75,7 @@ abstract class ArtemisMessagingComponent() : SingletonSerializeAsToken() {
|
||||
* may change or evolve and code that relies upon it being a simple host/port may not function correctly.
|
||||
* For instance it may contain onion routing data.
|
||||
*/
|
||||
data class NodeAddress(val identity: PublicKeyTree, override val hostAndPort: HostAndPort) : SingleMessageRecipient, ArtemisAddress {
|
||||
data class NodeAddress(val identity: CompositeKey, override val hostAndPort: HostAndPort) : SingleMessageRecipient, ArtemisAddress {
|
||||
override val queueName: SimpleString by lazy { SimpleString(PEERS_PREFIX+identity.toBase58String()) }
|
||||
override fun toString(): String = "${javaClass.simpleName}(identity = $queueName, $hostAndPort)"
|
||||
}
|
||||
@ -83,9 +83,9 @@ abstract class ArtemisMessagingComponent() : SingletonSerializeAsToken() {
|
||||
/** The config object is used to pass in the passwords for the certificate KeyStore and TrustStore */
|
||||
abstract val config: NodeSSLConfiguration
|
||||
|
||||
protected fun parseKeyFromQueueName(name: String): PublicKeyTree {
|
||||
protected fun parseKeyFromQueueName(name: String): CompositeKey {
|
||||
require(name.startsWith(PEERS_PREFIX))
|
||||
return PublicKeyTree.parseFromBase58(name.substring(PEERS_PREFIX.length))
|
||||
return CompositeKey.parseFromBase58(name.substring(PEERS_PREFIX.length))
|
||||
}
|
||||
|
||||
protected enum class ConnectionDirection { INBOUND, OUTBOUND }
|
||||
|
@ -150,7 +150,7 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
|
||||
if (queueName.startsWith(PEERS_PREFIX) && queueName != NETWORK_MAP_ADDRESS) {
|
||||
try {
|
||||
val identity = parseKeyFromQueueName(queueName.toString())
|
||||
val nodeInfo = networkMapCache.getNodeByPublicKeyTree(identity)
|
||||
val nodeInfo = networkMapCache.getNodeByCompositeKey(identity)
|
||||
if (nodeInfo != null) {
|
||||
maybeDeployBridgeForAddress(queueName, nodeInfo.address)
|
||||
} else {
|
||||
|
@ -3,7 +3,7 @@ package net.corda.node.services.messaging
|
||||
import com.google.common.net.HostAndPort
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import net.corda.core.ThreadBox
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.messaging.*
|
||||
import net.corda.core.serialization.SerializedBytes
|
||||
import net.corda.core.serialization.opaque
|
||||
@ -51,7 +51,7 @@ import javax.annotation.concurrent.ThreadSafe
|
||||
@ThreadSafe
|
||||
class NodeMessagingClient(override val config: NodeConfiguration,
|
||||
val serverHostPort: HostAndPort,
|
||||
val myIdentity: PublicKeyTree?,
|
||||
val myIdentity: CompositeKey?,
|
||||
val executor: AffinityExecutor,
|
||||
val database: Database,
|
||||
val networkMapRegistrationFuture: ListenableFuture<Unit>) : ArtemisMessagingComponent(), MessagingServiceInternal {
|
||||
|
@ -14,11 +14,10 @@ import de.javakaffee.kryoserializers.ArraysAsListSerializer
|
||||
import de.javakaffee.kryoserializers.guava.*
|
||||
import net.corda.contracts.asset.Cash
|
||||
import net.corda.core.ErrorOr
|
||||
import net.corda.core.TransientProperty
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.DigitalSignature
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.node.*
|
||||
import net.corda.core.node.services.*
|
||||
@ -36,7 +35,6 @@ import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import rx.Notification
|
||||
import rx.Observable
|
||||
import java.security.PublicKey
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
|
||||
@ -160,8 +158,8 @@ private class RPCKryo(observableSerializer: Serializer<Observable<Any>>? = null)
|
||||
register(ByteArray::class.java)
|
||||
register(EdDSAPublicKey::class.java, Ed25519PublicKeySerializer)
|
||||
register(EdDSAPrivateKey::class.java, Ed25519PrivateKeySerializer)
|
||||
register(PublicKeyTree.Leaf::class.java)
|
||||
register(PublicKeyTree.Node::class.java)
|
||||
register(CompositeKey.Leaf::class.java)
|
||||
register(CompositeKey.Node::class.java)
|
||||
register(Vault::class.java)
|
||||
register(Vault.Update::class.java)
|
||||
register(StateMachineRunId::class.java)
|
||||
@ -193,7 +191,7 @@ private class RPCKryo(observableSerializer: Serializer<Observable<Any>>? = null)
|
||||
register(ArtemisMessagingComponent.NodeAddress::class.java,
|
||||
read = { kryo, input ->
|
||||
ArtemisMessagingComponent.NodeAddress(
|
||||
PublicKeyTree.parseFromBase58(kryo.readObject(input, String::class.java)),
|
||||
CompositeKey.parseFromBase58(kryo.readObject(input, String::class.java)),
|
||||
kryo.readObject(input, HostAndPort::class.java))
|
||||
},
|
||||
write = { kryo, output, nodeAddress ->
|
||||
|
@ -5,8 +5,8 @@ import com.google.common.util.concurrent.ListenableFuture
|
||||
import com.google.common.util.concurrent.SettableFuture
|
||||
import net.corda.core.bufferUntilSubscribed
|
||||
import net.corda.core.contracts.Contract
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.map
|
||||
import net.corda.core.messaging.MessagingService
|
||||
import net.corda.core.messaging.SingleMessageRecipient
|
||||
@ -68,14 +68,14 @@ open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCach
|
||||
override fun get(serviceType: ServiceType) = registeredNodes.filterValues { it.advertisedServices.any { it.info.type.isSubTypeOf(serviceType) } }.map { it.value }
|
||||
override fun getRecommended(type: ServiceType, contract: Contract, vararg party: Party): NodeInfo? = get(type).firstOrNull()
|
||||
override fun getNodeByLegalName(name: String) = get().singleOrNull { it.legalIdentity.name == name }
|
||||
override fun getNodeByPublicKeyTree(publicKeyTree: PublicKeyTree): NodeInfo? {
|
||||
override fun getNodeByCompositeKey(compositeKey: CompositeKey): NodeInfo? {
|
||||
// Although we should never have more than one match, it is theoretically possible. Report an error if it happens.
|
||||
val candidates = get().filter {
|
||||
(it.legalIdentity.owningKey == publicKeyTree)
|
||||
|| it.advertisedServices.any { it.identity.owningKey == publicKeyTree }
|
||||
(it.legalIdentity.owningKey == compositeKey)
|
||||
|| it.advertisedServices.any { it.identity.owningKey == compositeKey }
|
||||
}
|
||||
if (candidates.size > 1) {
|
||||
throw IllegalStateException("Found more than one match for key $publicKeyTree")
|
||||
throw IllegalStateException("Found more than one match for key $compositeKey")
|
||||
}
|
||||
return candidates.singleOrNull()
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ class StateMachineManager(val serviceHub: ServiceHubInternal,
|
||||
}
|
||||
|
||||
private fun sendSessionMessage(party: Party, message: SessionMessage, psm: ProtocolStateMachineImpl<*>?) {
|
||||
val node = serviceHub.networkMapCache.getNodeByPublicKeyTree(party.owningKey)
|
||||
val node = serviceHub.networkMapCache.getNodeByCompositeKey(party.owningKey)
|
||||
?: throw IllegalArgumentException("Don't know about party $party")
|
||||
val logger = psm?.logger ?: logger
|
||||
logger.trace { "Sending $message to party $party" }
|
||||
|
@ -5,8 +5,8 @@ import net.corda.contracts.asset.Cash
|
||||
import net.corda.core.ThreadBox
|
||||
import net.corda.core.bufferUntilSubscribed
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.node.ServiceHub
|
||||
import net.corda.core.node.services.Vault
|
||||
@ -154,8 +154,8 @@ class NodeVaultService(private val services: ServiceHub) : SingletonSerializeAsT
|
||||
*/
|
||||
override fun generateSpend(tx: TransactionBuilder,
|
||||
amount: Amount<Currency>,
|
||||
to: PublicKeyTree,
|
||||
onlyFromParties: Set<Party>?): Pair<TransactionBuilder, List<PublicKeyTree>> {
|
||||
to: CompositeKey,
|
||||
onlyFromParties: Set<Party>?): Pair<TransactionBuilder, List<CompositeKey>> {
|
||||
// Discussion
|
||||
//
|
||||
// This code is analogous to the Wallet.send() set of methods in bitcoinj, and has the same general outline.
|
||||
@ -238,7 +238,7 @@ class NodeVaultService(private val services: ServiceHub) : SingletonSerializeAsT
|
||||
return Pair(tx, keysList)
|
||||
}
|
||||
|
||||
private fun deriveState(txState: TransactionState<Cash.State>, amount: Amount<Issued<Currency>>, owner: PublicKeyTree)
|
||||
private fun deriveState(txState: TransactionState<Cash.State>, amount: Amount<Issued<Currency>>, owner: CompositeKey)
|
||||
= txState.copy(data = txState.data.copy(amount = amount, owner = owner))
|
||||
|
||||
/**
|
||||
|
@ -3,7 +3,7 @@ package net.corda.node.utilities
|
||||
import co.paralleluniverse.strands.Strand
|
||||
import com.zaxxer.hikari.HikariConfig
|
||||
import com.zaxxer.hikari.HikariDataSource
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.parsePublicKeyBase58
|
||||
import net.corda.core.crypto.toBase58String
|
||||
@ -138,7 +138,7 @@ class StrandLocalTransactionManager(initWithDatabase: Database) : TransactionMan
|
||||
}
|
||||
|
||||
// Composite columns for use with below Exposed helpers.
|
||||
data class PartyColumns(val name: Column<String>, val owningKey: Column<PublicKeyTree>)
|
||||
data class PartyColumns(val name: Column<String>, val owningKey: Column<CompositeKey>)
|
||||
data class StateRefColumns(val txId: Column<SecureHash>, val index: Column<Int>)
|
||||
data class TxnNoteColumns(val txId: Column<SecureHash>, val note: Column<String>)
|
||||
|
||||
@ -147,9 +147,9 @@ data class TxnNoteColumns(val txId: Column<SecureHash>, val note: Column<String>
|
||||
*/
|
||||
fun Table.publicKey(name: String) = this.registerColumn<PublicKey>(name, PublicKeyColumnType)
|
||||
|
||||
fun Table.publicKeyTree(name: String) = this.registerColumn<PublicKeyTree>(name, PublicKeyTreeColumnType)
|
||||
fun Table.compositeKey(name: String) = this.registerColumn<CompositeKey>(name, CompositeKeyColumnType)
|
||||
fun Table.secureHash(name: String) = this.registerColumn<SecureHash>(name, SecureHashColumnType)
|
||||
fun Table.party(nameColumnName: String, keyColumnName: String) = PartyColumns(this.varchar(nameColumnName, length = 255), this.publicKeyTree(keyColumnName))
|
||||
fun Table.party(nameColumnName: String, keyColumnName: String) = PartyColumns(this.varchar(nameColumnName, length = 255), this.compositeKey(keyColumnName))
|
||||
fun Table.uuidString(name: String) = this.registerColumn<UUID>(name, UUIDStringColumnType)
|
||||
fun Table.localDate(name: String) = this.registerColumn<LocalDate>(name, LocalDateColumnType)
|
||||
fun Table.localDateTime(name: String) = this.registerColumn<LocalDateTime>(name, LocalDateTimeColumnType)
|
||||
@ -169,12 +169,12 @@ object PublicKeyColumnType : ColumnType() {
|
||||
}
|
||||
|
||||
/**
|
||||
* [ColumnType] for marshalling to/from database on behalf of [PublicKeyTree].
|
||||
* [ColumnType] for marshalling to/from database on behalf of [CompositeKey].
|
||||
*/
|
||||
object PublicKeyTreeColumnType : ColumnType() {
|
||||
object CompositeKeyColumnType : ColumnType() {
|
||||
override fun sqlType(): String = "VARCHAR"
|
||||
override fun valueFromDB(value: Any): Any = PublicKeyTree.parseFromBase58(value.toString())
|
||||
override fun notNullValueToDB(value: Any): Any = if (value is PublicKeyTree) value.toBase58String() else value
|
||||
override fun valueFromDB(value: Any): Any = CompositeKey.parseFromBase58(value.toString())
|
||||
override fun notNullValueToDB(value: Any): Any = if (value is CompositeKey) value.toBase58String() else value
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,6 @@ import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.node.services.IdentityService
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.crypto.*
|
||||
import net.i2p.crypto.eddsa.EdDSAPublicKey
|
||||
import java.math.BigDecimal
|
||||
import java.time.LocalDate
|
||||
@ -54,9 +53,9 @@ object JsonSupport {
|
||||
cordaModule.addSerializer(EdDSAPublicKey::class.java, PublicKeySerializer)
|
||||
cordaModule.addDeserializer(EdDSAPublicKey::class.java, PublicKeyDeserializer)
|
||||
|
||||
// For public key trees
|
||||
cordaModule.addSerializer(PublicKeyTree::class.java, PublicKeyTreeSerializer)
|
||||
cordaModule.addDeserializer(PublicKeyTree::class.java, PublicKeyTreeDeserializer)
|
||||
// For composite keys
|
||||
cordaModule.addSerializer(CompositeKey::class.java, CompositeKeySerializer)
|
||||
cordaModule.addDeserializer(CompositeKey::class.java, CompositeKeyDeserializer)
|
||||
|
||||
// For NodeInfo
|
||||
// TODO this tunnels the Kryo representation as a Base58 encoded string. Replace when RPC supports this.
|
||||
@ -181,18 +180,18 @@ object JsonSupport {
|
||||
}
|
||||
}
|
||||
|
||||
object PublicKeyTreeSerializer : JsonSerializer<PublicKeyTree>() {
|
||||
override fun serialize(obj: PublicKeyTree, generator: JsonGenerator, provider: SerializerProvider) {
|
||||
object CompositeKeySerializer : JsonSerializer<CompositeKey>() {
|
||||
override fun serialize(obj: CompositeKey, generator: JsonGenerator, provider: SerializerProvider) {
|
||||
generator.writeString(obj.toBase58String())
|
||||
}
|
||||
}
|
||||
|
||||
object PublicKeyTreeDeserializer : JsonDeserializer<PublicKeyTree>() {
|
||||
override fun deserialize(parser: JsonParser, context: DeserializationContext): PublicKeyTree {
|
||||
object CompositeKeyDeserializer : JsonDeserializer<CompositeKey>() {
|
||||
override fun deserialize(parser: JsonParser, context: DeserializationContext): CompositeKey {
|
||||
return try {
|
||||
PublicKeyTree.parseFromBase58(parser.text)
|
||||
CompositeKey.parseFromBase58(parser.text)
|
||||
} catch (e: Exception) {
|
||||
throw JsonParseException(parser, "Invalid public key tree ${parser.text}: ${e.message}")
|
||||
throw JsonParseException(parser, "Invalid composite key ${parser.text}: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,10 @@ import net.corda.contracts.CommercialPaper
|
||||
import net.corda.contracts.asset.*
|
||||
import net.corda.contracts.testing.fillWithSomeTestCash
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.tree
|
||||
import net.corda.core.crypto.composite
|
||||
import net.corda.core.days
|
||||
import net.corda.core.map
|
||||
import net.corda.core.messaging.SingleMessageRecipient
|
||||
@ -251,7 +251,7 @@ class TwoPartyTradeProtocolTests {
|
||||
}
|
||||
val attachmentID = attachment(ByteArrayInputStream(stream.toByteArray()))
|
||||
|
||||
val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public.tree, notaryNode.info.notaryIdentity).second
|
||||
val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public.composite, notaryNode.info.notaryIdentity).second
|
||||
val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode)
|
||||
val alicesFakePaper = fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
|
||||
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID, notaryNode.info.notaryIdentity).second
|
||||
@ -343,7 +343,7 @@ class TwoPartyTradeProtocolTests {
|
||||
}
|
||||
val attachmentID = attachment(ByteArrayInputStream(stream.toByteArray()))
|
||||
|
||||
val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public.tree, notaryNode.info.notaryIdentity).second
|
||||
val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public.composite, notaryNode.info.notaryIdentity).second
|
||||
insertFakeTransactions(bobsFakeCash, bobNode)
|
||||
val alicesFakePaper = fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
|
||||
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID, notaryNode.info.notaryIdentity).second
|
||||
@ -434,7 +434,7 @@ class TwoPartyTradeProtocolTests {
|
||||
val bobKey = bobNode.services.legalIdentityKey
|
||||
val issuer = MEGA_CORP.ref(1, 2, 3)
|
||||
|
||||
val bobsBadCash = fillUpForBuyer(bobError, bobKey.public.tree, notaryNode.info.notaryIdentity).second
|
||||
val bobsBadCash = fillUpForBuyer(bobError, bobKey.public.composite, notaryNode.info.notaryIdentity).second
|
||||
val alicesFakePaper = fillUpForSeller(aliceError, aliceNode.info.legalIdentity.owningKey,
|
||||
1200.DOLLARS `issued by` issuer, null, notaryNode.info.notaryIdentity).second
|
||||
|
||||
@ -481,7 +481,7 @@ class TwoPartyTradeProtocolTests {
|
||||
|
||||
private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForBuyer(
|
||||
withError: Boolean,
|
||||
owner: PublicKeyTree = BOB_PUBKEY,
|
||||
owner: CompositeKey = BOB_PUBKEY,
|
||||
notary: Party): Pair<Vault, List<WireTransaction>> {
|
||||
val issuer = DUMMY_CASH_ISSUER
|
||||
// Bob (Buyer) has some cash he got from the Bank of Elbonia, Alice (Seller) has some commercial paper she
|
||||
@ -491,10 +491,10 @@ class TwoPartyTradeProtocolTests {
|
||||
output("elbonian money 1", notary = notary) { 800.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY }
|
||||
output("elbonian money 2", notary = notary) { 1000.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY }
|
||||
if (!withError)
|
||||
command(DUMMY_CASH_ISSUER_KEY.public.tree) { Cash.Commands.Issue() }
|
||||
command(DUMMY_CASH_ISSUER_KEY.public.composite) { Cash.Commands.Issue() }
|
||||
else
|
||||
// Put a broken command on so at least a signature is created
|
||||
command(DUMMY_CASH_ISSUER_KEY.public.tree) { Cash.Commands.Move() }
|
||||
command(DUMMY_CASH_ISSUER_KEY.public.composite) { Cash.Commands.Move() }
|
||||
timestamp(TEST_TX_TIME)
|
||||
if (withError) {
|
||||
this.fails()
|
||||
@ -525,7 +525,7 @@ class TwoPartyTradeProtocolTests {
|
||||
|
||||
private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForSeller(
|
||||
withError: Boolean,
|
||||
owner: PublicKeyTree,
|
||||
owner: CompositeKey,
|
||||
amount: Amount<Issued<Currency>>,
|
||||
attachmentID: SecureHash?,
|
||||
notary: Party): Pair<Vault, List<WireTransaction>> {
|
||||
|
@ -5,8 +5,8 @@ import com.google.common.util.concurrent.Futures
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import com.google.common.util.concurrent.SettableFuture
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import net.corda.core.crypto.composite
|
||||
import net.corda.core.crypto.generateKeyPair
|
||||
import net.corda.core.crypto.tree
|
||||
import net.corda.core.messaging.Message
|
||||
import net.corda.core.messaging.createMessage
|
||||
import net.corda.core.node.services.DEFAULT_SESSION_ID
|
||||
@ -222,7 +222,7 @@ class ArtemisMessagingTests {
|
||||
|
||||
private fun createMessagingClient(server: HostAndPort = hostAndPort): NodeMessagingClient {
|
||||
return databaseTransaction(database) {
|
||||
NodeMessagingClient(config, server, identity.public.tree, AffinityExecutor.ServiceAffinityExecutor("ArtemisMessagingTests", 1), database, networkMapRegistrationFuture).apply {
|
||||
NodeMessagingClient(config, server, identity.public.composite, AffinityExecutor.ServiceAffinityExecutor("ArtemisMessagingTests", 1), database, networkMapRegistrationFuture).apply {
|
||||
configureWithDevSSLCertificate()
|
||||
messagingClient = this
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.corda.node.services
|
||||
|
||||
import net.corda.core.crypto.composite
|
||||
import net.corda.core.crypto.generateKeyPair
|
||||
import net.corda.core.crypto.tree
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.node.services.network.NetworkMapService
|
||||
import net.corda.testing.expect
|
||||
@ -34,12 +34,12 @@ class InMemoryNetworkMapCacheTest {
|
||||
val nodeB = network.createNode(null, -1, MockNetwork.DefaultFactory, true, "Node B", keyPair, ServiceInfo(NetworkMapService.type))
|
||||
|
||||
// Node A currently knows only about itself, so this returns node A
|
||||
assertEquals(nodeA.netMapCache.getNodeByPublicKeyTree(keyPair.public.tree), nodeA.info)
|
||||
assertEquals(nodeA.netMapCache.getNodeByCompositeKey(keyPair.public.composite), nodeA.info)
|
||||
|
||||
nodeA.netMapCache.addNode(nodeB.info)
|
||||
// Now both nodes match, so it throws an error
|
||||
expect<IllegalStateException> {
|
||||
nodeA.netMapCache.getNodeByPublicKeyTree(keyPair.public.tree)
|
||||
nodeA.netMapCache.getNodeByCompositeKey(keyPair.public.composite)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.corda.node.services
|
||||
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.tree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.composite
|
||||
import net.corda.core.days
|
||||
import net.corda.core.node.ServiceHub
|
||||
import net.corda.core.node.recordTransactions
|
||||
@ -111,7 +111,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
|
||||
}
|
||||
|
||||
class TestState(val protocolLogicRef: ProtocolLogicRef, val instant: Instant) : LinearState, SchedulableState {
|
||||
override val participants: List<PublicKeyTree>
|
||||
override val participants: List<CompositeKey>
|
||||
get() = throw UnsupportedOperationException()
|
||||
|
||||
override val linearId = UniqueIdentifier()
|
||||
@ -270,7 +270,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
|
||||
val state = TestState(factory.create(TestProtocolLogic::class.java, increment), instant)
|
||||
val usefulTX = TransactionType.General.Builder(null).apply {
|
||||
addOutputState(state, DUMMY_NOTARY)
|
||||
addCommand(Command(), freshKey.public.tree)
|
||||
addCommand(Command(), freshKey.public.composite)
|
||||
signWith(freshKey)
|
||||
}.toSignedTransaction()
|
||||
val txHash = usefulTX.id
|
||||
|
@ -6,7 +6,7 @@ import net.corda.core.contracts.DOLLARS
|
||||
import net.corda.core.contracts.POUNDS
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.contracts.`issued by`
|
||||
import net.corda.core.crypto.tree
|
||||
import net.corda.core.crypto.composite
|
||||
import net.corda.core.node.services.TxWritableStorageService
|
||||
import net.corda.core.node.services.VaultService
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
@ -103,7 +103,7 @@ class NodeVaultServiceTest {
|
||||
|
||||
// Issue a txn to Send us some Money
|
||||
val usefulTX = TransactionType.General.Builder(null).apply {
|
||||
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), freshKey.public.tree, DUMMY_NOTARY)
|
||||
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), freshKey.public.composite, DUMMY_NOTARY)
|
||||
signWith(MEGA_CORP_KEY)
|
||||
}.toSignedTransaction()
|
||||
|
||||
@ -117,7 +117,7 @@ class NodeVaultServiceTest {
|
||||
|
||||
// Issue more Money (GBP)
|
||||
val anotherTX = TransactionType.General.Builder(null).apply {
|
||||
Cash().generateIssue(this, 200.POUNDS `issued by` MEGA_CORP.ref(1), freshKey.public.tree, DUMMY_NOTARY)
|
||||
Cash().generateIssue(this, 200.POUNDS `issued by` MEGA_CORP.ref(1), freshKey.public.composite, DUMMY_NOTARY)
|
||||
signWith(MEGA_CORP_KEY)
|
||||
}.toSignedTransaction()
|
||||
|
||||
|
@ -3,7 +3,7 @@ package net.corda.node.services
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.DigitalSignature
|
||||
import net.corda.core.crypto.tree
|
||||
import net.corda.core.crypto.composite
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.utilities.DUMMY_NOTARY
|
||||
@ -57,7 +57,7 @@ class ValidatingNotaryServiceTests {
|
||||
}
|
||||
|
||||
@Test fun `should report error for missing signatures`() {
|
||||
val expectedMissingKey = MEGA_CORP_KEY.public.tree
|
||||
val expectedMissingKey = MEGA_CORP_KEY.public.composite
|
||||
val stx = run {
|
||||
val inputState = issueState(clientNode)
|
||||
|
||||
|
@ -4,7 +4,7 @@ import net.corda.contracts.asset.Cash
|
||||
import net.corda.contracts.asset.DUMMY_CASH_ISSUER
|
||||
import net.corda.contracts.testing.fillWithSomeTestCash
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.tree
|
||||
import net.corda.core.crypto.composite
|
||||
import net.corda.core.node.recordTransactions
|
||||
import net.corda.core.node.services.VaultService
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
@ -73,7 +73,7 @@ class VaultWithCashTest {
|
||||
|
||||
val state = w.states.toList()[0].state.data as Cash.State
|
||||
assertEquals(30.45.DOLLARS `issued by` DUMMY_CASH_ISSUER, state.amount)
|
||||
assertEquals(services.key.public.tree, state.owner)
|
||||
assertEquals(services.key.public.composite, state.owner)
|
||||
|
||||
assertEquals(34.70.DOLLARS `issued by` DUMMY_CASH_ISSUER, (w.states.toList()[2].state.data as Cash.State).amount)
|
||||
assertEquals(34.85.DOLLARS `issued by` DUMMY_CASH_ISSUER, (w.states.toList()[1].state.data as Cash.State).amount)
|
||||
@ -86,7 +86,7 @@ class VaultWithCashTest {
|
||||
// A tx that sends us money.
|
||||
val freshKey = services.keyManagementService.freshKey()
|
||||
val usefulTX = TransactionType.General.Builder(null).apply {
|
||||
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), freshKey.public.tree, DUMMY_NOTARY)
|
||||
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), freshKey.public.composite, DUMMY_NOTARY)
|
||||
signWith(MEGA_CORP_KEY)
|
||||
}.toSignedTransaction()
|
||||
|
||||
@ -104,7 +104,7 @@ class VaultWithCashTest {
|
||||
|
||||
// A tx that doesn't send us anything.
|
||||
val irrelevantTX = TransactionType.General.Builder(DUMMY_NOTARY).apply {
|
||||
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), BOB_KEY.public.tree, DUMMY_NOTARY)
|
||||
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), BOB_KEY.public.composite, DUMMY_NOTARY)
|
||||
signWith(MEGA_CORP_KEY)
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
}.toSignedTransaction()
|
||||
@ -128,8 +128,8 @@ class VaultWithCashTest {
|
||||
|
||||
// Issue a linear state
|
||||
val dummyIssue = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
|
||||
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public.tree)))
|
||||
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public.tree)))
|
||||
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public.composite)))
|
||||
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public.composite)))
|
||||
signWith(freshKey)
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
}.toSignedTransaction()
|
||||
@ -149,7 +149,7 @@ class VaultWithCashTest {
|
||||
|
||||
// Issue a linear state
|
||||
val dummyIssue = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
|
||||
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public.tree)))
|
||||
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public.composite)))
|
||||
signWith(freshKey)
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
}.toSignedTransaction()
|
||||
@ -161,7 +161,7 @@ class VaultWithCashTest {
|
||||
|
||||
// Move the same state
|
||||
val dummyMove = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
|
||||
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public.tree)))
|
||||
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public.composite)))
|
||||
addInputState(dummyIssue.tx.outRef<LinearState>(0))
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
}.toSignedTransaction()
|
||||
|
@ -2,8 +2,8 @@ package net.corda.irs.contract
|
||||
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.contracts.clauses.*
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.node.services.ServiceType
|
||||
import net.corda.core.protocols.ProtocolLogicRefFactory
|
||||
@ -664,7 +664,7 @@ class InterestRateSwap() : Contract {
|
||||
|
||||
override val ref = common.tradeID
|
||||
|
||||
override val participants: List<PublicKeyTree>
|
||||
override val participants: List<CompositeKey>
|
||||
get() = parties.map { it.owningKey }
|
||||
|
||||
override fun isRelevant(ourKeys: Set<PublicKey>): Boolean {
|
||||
|
@ -3,9 +3,8 @@ package net.corda.irs.protocols
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.TransientProperty
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.node.CordaPluginRegistry
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.node.PluginServiceHub
|
||||
import net.corda.core.node.services.ServiceType
|
||||
@ -15,11 +14,9 @@ import net.corda.core.transactions.FilterFuns
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.utilities.ProgressTracker
|
||||
import net.corda.core.utilities.trace
|
||||
import net.corda.node.services.api.ServiceHubInternal
|
||||
import net.corda.protocols.TwoPartyDealProtocol
|
||||
import java.math.BigDecimal
|
||||
import java.security.KeyPair
|
||||
import java.security.PublicKey
|
||||
|
||||
object FixingProtocol {
|
||||
|
||||
@ -58,7 +55,7 @@ object FixingProtocol {
|
||||
}
|
||||
|
||||
@Suspendable
|
||||
override fun assembleSharedTX(handshake: TwoPartyDealProtocol.Handshake<FixingSession>): Pair<TransactionBuilder, List<PublicKeyTree>> {
|
||||
override fun assembleSharedTX(handshake: TwoPartyDealProtocol.Handshake<FixingSession>): Pair<TransactionBuilder, List<CompositeKey>> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val fixOf = deal.nextFixingOf()!!
|
||||
|
||||
|
@ -2,8 +2,8 @@ package net.corda.vega.api
|
||||
|
||||
import com.opengamma.strata.basics.currency.MultiCurrencyAmount
|
||||
import net.corda.core.contracts.StateAndRef
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.node.ServiceHub
|
||||
import net.corda.core.node.services.dealsWith
|
||||
import net.corda.vega.analytics.InitialMarginTriple
|
||||
@ -33,7 +33,7 @@ class PortfolioApi(val services: ServiceHub) {
|
||||
* Used as such: withParty(name) { doSomethingWith(it) }
|
||||
*/
|
||||
private fun withParty(partyName: String, func: (Party) -> Response): Response {
|
||||
val otherParty = services.identityService.partyFromKey(PublicKeyTree.parseFromBase58(partyName))
|
||||
val otherParty = services.identityService.partyFromKey(CompositeKey.parseFromBase58(partyName))
|
||||
return if (otherParty != null) {
|
||||
func(otherParty)
|
||||
} else {
|
||||
|
@ -4,11 +4,10 @@ import net.corda.core.contracts.Command
|
||||
import net.corda.core.contracts.DealState
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.contracts.UniqueIdentifier
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import java.security.PublicKey
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Represents an OpenGamma IRS between two parties. Does not implement any fixing functionality.
|
||||
@ -32,6 +31,6 @@ data class IRSState(val swap: SwapData,
|
||||
return TransactionType.General.Builder(notary).withItems(state, Command(OGTrade.Commands.Agree(), parties.map { it.owningKey }))
|
||||
}
|
||||
|
||||
override val participants: List<PublicKeyTree>
|
||||
override val participants: List<CompositeKey>
|
||||
get() = parties.map { it.owningKey }
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.corda.vega.contracts
|
||||
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.protocols.ProtocolLogicRefFactory
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.vega.protocols.SimmRevaluation
|
||||
@ -10,7 +10,6 @@ import java.security.PublicKey
|
||||
import java.time.LocalDate
|
||||
import java.time.ZoneOffset
|
||||
import java.time.temporal.ChronoUnit
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Represents an aggregate set of trades agreed between two parties and a possible valuation of that portfolio at a
|
||||
@ -29,7 +28,7 @@ data class PortfolioState(val portfolio: List<StateRef>,
|
||||
override val ref: String = linearId.toString()
|
||||
val valuer: Party get() = parties[0]
|
||||
|
||||
override val participants: List<PublicKeyTree>
|
||||
override val participants: List<CompositeKey>
|
||||
get() = parties.map { it.owningKey }
|
||||
|
||||
override fun nextScheduledActivity(thisStateRef: StateRef, protocolLogicRefFactory: ProtocolLogicRefFactory): ScheduledActivity {
|
||||
|
@ -2,14 +2,13 @@ package net.corda.vega.protocols
|
||||
|
||||
import net.corda.core.contracts.StateAndRef
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.seconds
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.utilities.UntrustworthyData
|
||||
import net.corda.protocols.AbstractStateReplacementProtocol
|
||||
import net.corda.vega.contracts.RevisionedState
|
||||
import java.security.PublicKey
|
||||
|
||||
/**
|
||||
* Protocol that generates an update on a mutable deal state and commits the resulting transaction reaching consensus
|
||||
@ -25,7 +24,7 @@ object StateRevisionProtocol {
|
||||
override fun assembleProposal(stateRef: StateRef, modification: T, stx: SignedTransaction): AbstractStateReplacementProtocol.Proposal<T>
|
||||
= Proposal(stateRef, modification, stx)
|
||||
|
||||
override fun assembleTx(): Pair<SignedTransaction, List<PublicKeyTree>> {
|
||||
override fun assembleTx(): Pair<SignedTransaction, List<CompositeKey>> {
|
||||
val state = originalState.state.data
|
||||
val tx = state.generateRevision(originalState.state.notary, originalState, updatedData)
|
||||
tx.setTime(serviceHub.clock.instant(), 30.seconds)
|
||||
|
@ -13,7 +13,6 @@ import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.utilities.ProgressTracker
|
||||
import net.corda.protocols.NotaryProtocol
|
||||
import net.corda.protocols.TwoPartyTradeProtocol
|
||||
import java.security.PublicKey
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
|
||||
@ -41,7 +40,7 @@ class SellerProtocol(val otherParty: Party,
|
||||
|
||||
val notary: NodeInfo = serviceHub.networkMapCache.notaryNodes[0]
|
||||
val cpOwnerKey = serviceHub.legalIdentityKey
|
||||
val commercialPaper = selfIssueSomeCommercialPaper(cpOwnerKey.public.tree, notary)
|
||||
val commercialPaper = selfIssueSomeCommercialPaper(cpOwnerKey.public.composite, notary)
|
||||
|
||||
progressTracker.currentStep = TRADING
|
||||
|
||||
@ -61,7 +60,7 @@ class SellerProtocol(val otherParty: Party,
|
||||
}
|
||||
|
||||
@Suspendable
|
||||
fun selfIssueSomeCommercialPaper(ownedBy: PublicKeyTree, notaryNode: NodeInfo): StateAndRef<CommercialPaper.State> {
|
||||
fun selfIssueSomeCommercialPaper(ownedBy: CompositeKey, notaryNode: NodeInfo): StateAndRef<CommercialPaper.State> {
|
||||
// Make a fake company that's issued its own paper.
|
||||
val keyPair = generateKeyPair()
|
||||
val party = Party("Bank of London", keyPair.public)
|
||||
|
@ -45,24 +45,24 @@ import kotlin.reflect.KClass
|
||||
|
||||
// A few dummy values for testing.
|
||||
val MEGA_CORP_KEY: KeyPair by lazy { generateKeyPair() }
|
||||
val MEGA_CORP_PUBKEY: PublicKeyTree get() = MEGA_CORP_KEY.public.tree
|
||||
val MEGA_CORP_PUBKEY: CompositeKey get() = MEGA_CORP_KEY.public.composite
|
||||
|
||||
val MINI_CORP_KEY: KeyPair by lazy { generateKeyPair() }
|
||||
val MINI_CORP_PUBKEY: PublicKeyTree get() = MINI_CORP_KEY.public.tree
|
||||
val MINI_CORP_PUBKEY: CompositeKey get() = MINI_CORP_KEY.public.composite
|
||||
|
||||
val ORACLE_KEY: KeyPair by lazy { generateKeyPair() }
|
||||
val ORACLE_PUBKEY: PublicKeyTree get() = ORACLE_KEY.public.tree
|
||||
val ORACLE_PUBKEY: CompositeKey get() = ORACLE_KEY.public.composite
|
||||
|
||||
val ALICE_KEY: KeyPair by lazy { generateKeyPair() }
|
||||
val ALICE_PUBKEY: PublicKeyTree get() = ALICE_KEY.public.tree
|
||||
val ALICE_PUBKEY: CompositeKey get() = ALICE_KEY.public.composite
|
||||
val ALICE: Party get() = Party("Alice", ALICE_PUBKEY)
|
||||
|
||||
val BOB_KEY: KeyPair by lazy { generateKeyPair() }
|
||||
val BOB_PUBKEY: PublicKeyTree get() = BOB_KEY.public.tree
|
||||
val BOB_PUBKEY: CompositeKey get() = BOB_KEY.public.composite
|
||||
val BOB: Party get() = Party("Bob", BOB_PUBKEY)
|
||||
|
||||
val CHARLIE_KEY: KeyPair by lazy { generateKeyPair() }
|
||||
val CHARLIE_PUBKEY: PublicKeyTree get() = CHARLIE_KEY.public.tree
|
||||
val CHARLIE_PUBKEY: CompositeKey get() = CHARLIE_KEY.public.composite
|
||||
val CHARLIE: Party get() = Party("Charlie", CHARLIE_PUBKEY)
|
||||
|
||||
val MEGA_CORP: Party get() = Party("MegaCorp", MEGA_CORP_PUBKEY)
|
||||
|
@ -4,7 +4,7 @@ import net.corda.core.contracts.*
|
||||
import net.corda.core.contracts.clauses.Clause
|
||||
import net.corda.core.contracts.clauses.FilterOn
|
||||
import net.corda.core.contracts.clauses.verifyClause
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import java.security.PublicKey
|
||||
|
||||
@ -19,7 +19,7 @@ class DummyLinearContract: Contract {
|
||||
class State(
|
||||
override val linearId: UniqueIdentifier = UniqueIdentifier(),
|
||||
override val contract: Contract = DummyLinearContract(),
|
||||
override val participants: List<PublicKeyTree> = listOf(),
|
||||
override val participants: List<CompositeKey> = listOf(),
|
||||
val nonce: SecureHash = SecureHash.randomSHA256()) : LinearState {
|
||||
|
||||
override fun isRelevant(ourKeys: Set<PublicKey>): Boolean {
|
||||
|
@ -129,7 +129,7 @@ data class TestTransactionDSLInterpreter private constructor(
|
||||
transactionBuilder.addAttachment(attachmentId)
|
||||
}
|
||||
|
||||
override fun _command(signers: List<PublicKeyTree>, commandData: CommandData) {
|
||||
override fun _command(signers: List<CompositeKey>, commandData: CommandData) {
|
||||
val command = Command(commandData, signers)
|
||||
transactionBuilder.addCommand(command)
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.corda.testing
|
||||
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.Party
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.seconds
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
@ -46,7 +46,7 @@ interface TransactionDSLInterpreter : Verifies, OutputStateLookup {
|
||||
* @param signers The signer public keys.
|
||||
* @param commandData The contents of the command.
|
||||
*/
|
||||
fun _command(signers: List<PublicKeyTree>, commandData: CommandData)
|
||||
fun _command(signers: List<CompositeKey>, commandData: CommandData)
|
||||
|
||||
/**
|
||||
* Adds a timestamp to the transaction.
|
||||
@ -99,12 +99,12 @@ class TransactionDSL<out T : TransactionDSLInterpreter>(val interpreter: T) : Tr
|
||||
/**
|
||||
* @see TransactionDSLInterpreter._command
|
||||
*/
|
||||
fun command(vararg signers: PublicKeyTree, commandDataClosure: () -> CommandData) =
|
||||
fun command(vararg signers: CompositeKey, commandDataClosure: () -> CommandData) =
|
||||
_command(listOf(*signers), commandDataClosure())
|
||||
/**
|
||||
* @see TransactionDSLInterpreter._command
|
||||
*/
|
||||
fun command(signer: PublicKeyTree, commandData: CommandData) = _command(listOf(signer), commandData)
|
||||
fun command(signer: CompositeKey, commandData: CommandData) = _command(listOf(signer), commandData)
|
||||
|
||||
/**
|
||||
* Adds a timestamp command to the transaction.
|
||||
|
@ -60,18 +60,18 @@ open class MockServices(val key: KeyPair = generateKeyPair()) : ServiceHub {
|
||||
override val networkMapCache: NetworkMapCache get() = throw UnsupportedOperationException()
|
||||
override val clock: Clock get() = throw UnsupportedOperationException()
|
||||
override val schedulerService: SchedulerService get() = throw UnsupportedOperationException()
|
||||
override val myInfo: NodeInfo get() = NodeInfo(object : SingleMessageRecipient {}, Party("MegaCorp", key.public.tree))
|
||||
override val myInfo: NodeInfo get() = NodeInfo(object : SingleMessageRecipient {}, Party("MegaCorp", key.public.composite))
|
||||
}
|
||||
|
||||
@ThreadSafe
|
||||
class MockIdentityService(val identities: List<Party>) : IdentityService, SingletonSerializeAsToken() {
|
||||
private val keyToParties: Map<PublicKeyTree, Party>
|
||||
private val keyToParties: Map<CompositeKey, Party>
|
||||
get() = synchronized(identities) { identities.associateBy { it.owningKey } }
|
||||
private val nameToParties: Map<String, Party>
|
||||
get() = synchronized(identities) { identities.associateBy { it.name } }
|
||||
|
||||
override fun registerIdentity(party: Party) { throw UnsupportedOperationException() }
|
||||
override fun partyFromKey(key: PublicKeyTree): Party? = keyToParties[key]
|
||||
override fun partyFromKey(key: CompositeKey): Party? = keyToParties[key]
|
||||
override fun partyFromName(name: String): Party? = nameToParties[name]
|
||||
}
|
||||
|
||||
|
@ -21,8 +21,8 @@ import net.corda.client.fxutils.*
|
||||
import net.corda.client.model.*
|
||||
import net.corda.contracts.asset.Cash
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.PublicKeyTree
|
||||
import net.corda.core.crypto.tree
|
||||
import net.corda.core.crypto.CompositeKey
|
||||
import net.corda.core.crypto.composite
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.protocols.StateMachineRunId
|
||||
import net.corda.explorer.AmountDiff
|
||||
@ -147,7 +147,7 @@ class TransactionViewer : CordaView("Transactions") {
|
||||
override val root: Parent by fxml()
|
||||
private val inputs: ListView<StateNode> by fxid()
|
||||
private val outputs: ListView<StateNode> by fxid()
|
||||
private val signatures: ListView<PublicKeyTree> by fxid()
|
||||
private val signatures: ListView<CompositeKey> by fxid()
|
||||
private val inputPane: TitledPane by fxid()
|
||||
private val outputPane: TitledPane by fxid()
|
||||
private val signaturesPane: TitledPane by fxid()
|
||||
@ -159,7 +159,7 @@ class TransactionViewer : CordaView("Transactions") {
|
||||
StateNode(PartiallyResolvedTransaction.InputResolution.Resolved(StateAndRef(transactionState, stateRef)).lift(), stateRef)
|
||||
}
|
||||
|
||||
val signatureData = transaction.transaction.sigs.map { it.by.tree }
|
||||
val signatureData = transaction.transaction.sigs.map { it.by.composite }
|
||||
// Bind count to TitlePane
|
||||
inputPane.textProperty().bind(inputStates.lift().map { "Input (${it.count()})" })
|
||||
outputPane.textProperty().bind(outputStates.lift().map { "Output (${it.count()})" })
|
||||
|
Loading…
x
Reference in New Issue
Block a user