Rename PublicKeyTree -> CompositeKey and unify terminology across documentation.

This commit is contained in:
Andrius Dagys 2016-11-21 11:51:36 +00:00
parent e34820a480
commit 64299591c3
89 changed files with 403 additions and 413 deletions

View File

@ -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 }
}
}

View File

@ -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)}.

View File

@ -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)

View File

@ -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()
}

View File

@ -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 {

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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()

View File

@ -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()

View File

@ -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

View File

@ -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)

View File

@ -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?
}

View File

@ -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

View File

@ -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)

View File

@ -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?

View File

@ -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))
}
}

View File

@ -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".
*/

View File

@ -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) {

View File

@ -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 ->

View File

@ -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)

View File

@ -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) {

View File

@ -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) {

View File

@ -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() }

View File

@ -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
}

View File

@ -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

View File

@ -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() }}"
}
}

View File

@ -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)

View File

@ -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
}
}

View File

@ -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)

View File

@ -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,

View File

@ -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)
}

View File

@ -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()
}

View File

@ -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
}

View File

@ -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)

View File

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -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
------------

View File

@ -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.

View File

@ -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)

View File

@ -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)) {

View File

@ -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()
}

View File

@ -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);

View File

@ -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()));

View File

@ -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)

View File

@ -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))

View File

@ -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)

View File

@ -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()

View File

@ -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)

View File

@ -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>
}

View File

@ -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)

View File

@ -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>

View File

@ -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))
}
}

View File

@ -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()

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)
}

View File

@ -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

View File

@ -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]
}

View File

@ -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 }

View File

@ -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 {

View File

@ -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 {

View File

@ -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 ->

View File

@ -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()
}

View File

@ -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" }

View File

@ -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))
/**

View File

@ -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
}
/**

View File

@ -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}")
}
}
}

View File

@ -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>> {

View File

@ -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
}

View File

@ -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)
}
}
}

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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()

View File

@ -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 {

View File

@ -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()!!

View File

@ -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 {

View File

@ -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 }
}

View File

@ -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 {

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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 {

View File

@ -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)
}

View File

@ -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.

View File

@ -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]
}

View File

@ -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()})" })