Refactor of CompositeKeys to implement PublicKey interface. (#433)

* Make CompositeKey implement PublicKey

The initial implementation of composite keys as their own distinct class separate from PublicKey
means that the keys cannot be used on standard classes such as Certificate. This work is a beginning
to modifying CompositeKey to being a PublicKey implementation, although significant further work
is required to integrate this properly with the standard Java APIs, especially around verifying
signatures using the new key type.

* First stage of making CompositeKey implement PublicKey interface. Revert to using PublicKey everywhere we expect a key.

* Move algorithm and format into companion object (#432)

Move algorithm and format into companion object so that they can be referenced from other
classes (i.e. the upcoming signature class).

* Add simple invariants to construction of CompositeKey.
Builder emits CompositeKeys in simplified normalised form. Forbid keys with single child node, force ordering on children and forbid duplicates on the same level. It's not full semantical normalisation.

* Make constructor of CompositeKey private, move NodeWeight inside the class.
Add utility function for Kryo deserialization to read list with length constraints.
This commit is contained in:
kasiastreich
2017-04-12 11:13:20 +01:00
committed by GitHub
parent cb84f7b707
commit 36d5d0d7b2
124 changed files with 707 additions and 606 deletions

View File

@ -4,8 +4,8 @@ import co.paralleluniverse.fibers.Suspendable
import com.google.common.net.HostAndPort
import net.corda.client.rpc.CordaRPCClientImpl
import net.corda.core.crypto.Party
import net.corda.core.crypto.composite
import net.corda.core.crypto.generateKeyPair
import net.corda.core.crypto.toBase58String
import net.corda.core.flows.FlowLogic
import net.corda.core.getOrThrow
import net.corda.core.messaging.CordaRPCOps
@ -90,7 +90,7 @@ abstract class MQSecurityTest : NodeBasedTest() {
@Test
fun `create queue for unknown peer`() {
val invalidPeerQueue = "$PEERS_PREFIX${generateKeyPair().public.composite.toBase58String()}"
val invalidPeerQueue = "$PEERS_PREFIX${generateKeyPair().public.toBase58String()}"
assertAllQueueCreationAttacksFail(invalidPeerQueue)
}

View File

@ -4,7 +4,6 @@ import net.corda.core.contracts.Amount
import net.corda.core.contracts.ContractState
import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.UpgradedContract
import net.corda.core.crypto.CompositeKey
import net.corda.core.crypto.SecureHash
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StateMachineRunId
@ -27,6 +26,7 @@ import net.corda.node.utilities.databaseTransaction
import org.jetbrains.exposed.sql.Database
import rx.Observable
import java.io.InputStream
import java.security.PublicKey
import java.time.Instant
import java.util.*
@ -142,7 +142,7 @@ class CordaRPCOpsImpl(
}
override fun waitUntilRegisteredWithNetworkMap() = services.networkMapCache.mapServiceRegistered
override fun partyFromKey(key: CompositeKey) = services.identityService.partyFromKey(key)
override fun partyFromKey(key: PublicKey) = services.identityService.partyFromKey(key)
override fun partyFromName(name: String) = services.identityService.partyFromName(name)
override fun registeredFlows(): List<String> = services.flowLogicRefFactory.flowWhitelist.keys.sorted()

View File

@ -2,12 +2,12 @@ package net.corda.node.services.identity
import net.corda.core.contracts.PartyAndReference
import net.corda.core.crypto.AnonymousParty
import net.corda.core.crypto.CompositeKey
import net.corda.core.crypto.Party
import net.corda.core.node.services.IdentityService
import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.utilities.loggerFor
import net.corda.core.utilities.trace
import java.security.PublicKey
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import javax.annotation.concurrent.ThreadSafe
@ -21,7 +21,7 @@ class InMemoryIdentityService : SingletonSerializeAsToken(), IdentityService {
private val log = loggerFor<InMemoryIdentityService>()
}
private val keyToParties = ConcurrentHashMap<CompositeKey, Party>()
private val keyToParties = ConcurrentHashMap<PublicKey, Party>()
private val nameToParties = ConcurrentHashMap<String, Party>()
override fun registerIdentity(party: Party) {
@ -33,7 +33,7 @@ class InMemoryIdentityService : SingletonSerializeAsToken(), IdentityService {
// We give the caller a copy of the data set to avoid any locking problems
override fun getAllIdentities(): Iterable<Party> = ArrayList(keyToParties.values)
override fun partyFromKey(key: CompositeKey): Party? = keyToParties[key]
override fun partyFromKey(key: PublicKey): Party? = keyToParties[key]
override fun partyFromName(name: String): Party? = nameToParties[name]
override fun partyFromAnonymous(party: AnonymousParty): Party? = partyFromKey(party.owningKey)
override fun partyFromAnonymous(partyRef: PartyAndReference) = partyFromAnonymous(partyRef.party)

View File

@ -279,7 +279,7 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
when {
queueName.startsWith(PEERS_PREFIX) -> try {
val identity = CompositeKey.parseFromBase58(queueName.substring(PEERS_PREFIX.length))
val identity = parsePublicKeyBase58(queueName.substring(PEERS_PREFIX.length))
val nodeInfo = networkMapCache.getNodeByLegalIdentityKey(identity)
if (nodeInfo != null) {
deployBridgeToPeer(nodeInfo)
@ -291,7 +291,7 @@ class ArtemisMessagingServer(override val config: NodeConfiguration,
}
queueName.startsWith(SERVICES_PREFIX) -> try {
val identity = CompositeKey.parseFromBase58(queueName.substring(SERVICES_PREFIX.length))
val identity = parsePublicKeyBase58(queueName.substring(SERVICES_PREFIX.length))
val nodeInfos = networkMapCache.getNodesByAdvertisedServiceIdentityKey(identity)
// Create a bridge for each node advertising the service.
for (nodeInfo in nodeInfos) {

View File

@ -3,7 +3,6 @@ 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.CompositeKey
import net.corda.core.messaging.*
import net.corda.core.node.NodeVersionInfo
import net.corda.core.node.services.PartyInfo
@ -45,6 +44,7 @@ import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import javax.annotation.concurrent.ThreadSafe
import java.security.PublicKey
// TODO: Stop the wallet explorer and other clients from using this class and get rid of persistentInbox
@ -70,7 +70,7 @@ import javax.annotation.concurrent.ThreadSafe
class NodeMessagingClient(override val config: NodeConfiguration,
nodeVersionInfo: NodeVersionInfo,
val serverHostPort: HostAndPort,
val myIdentity: CompositeKey?,
val myIdentity: PublicKey?,
val nodeExecutor: AffinityExecutor,
val database: Database,
val networkMapRegistrationFuture: ListenableFuture<Unit>,

View File

@ -4,7 +4,6 @@ import com.google.common.annotations.VisibleForTesting
import com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.SettableFuture
import net.corda.core.bufferUntilSubscribed
import net.corda.core.crypto.CompositeKey
import net.corda.core.crypto.Party
import net.corda.core.map
import net.corda.core.messaging.MessagingService
@ -28,6 +27,7 @@ import net.corda.node.utilities.bufferUntilDatabaseCommit
import net.corda.node.utilities.wrapWithDatabaseTransaction
import rx.Observable
import rx.subjects.PublishSubject
import java.security.PublicKey
import java.security.SignatureException
import java.util.*
import javax.annotation.concurrent.ThreadSafe
@ -52,7 +52,7 @@ open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCach
override val mapServiceRegistered: ListenableFuture<Unit> get() = _registrationFuture
private var registeredForPush = false
protected var registeredNodes: MutableMap<CompositeKey, NodeInfo> = Collections.synchronizedMap(HashMap())
protected var registeredNodes: MutableMap<PublicKey, NodeInfo> = Collections.synchronizedMap(HashMap())
override fun getPartyInfo(party: Party): PartyInfo? {
val node = registeredNodes[party.owningKey]
@ -69,7 +69,7 @@ open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCach
return null
}
override fun getNodeByLegalIdentityKey(compositeKey: CompositeKey): NodeInfo? = registeredNodes[compositeKey]
override fun getNodeByLegalIdentityKey(identityKey: PublicKey): NodeInfo? = registeredNodes[identityKey]
override fun track(): Pair<List<NodeInfo>, Observable<MapChange>> {
synchronized(_changed) {

View File

@ -2,10 +2,7 @@ package net.corda.node.services.network
import com.google.common.annotations.VisibleForTesting
import net.corda.core.ThreadBox
import net.corda.core.crypto.DigitalSignature
import net.corda.core.crypto.Party
import net.corda.core.crypto.SignedData
import net.corda.core.crypto.signWithECDSA
import net.corda.core.crypto.*
import net.corda.core.messaging.MessageHandlerRegistration
import net.corda.core.messaging.MessageRecipients
import net.corda.core.messaging.SingleMessageRecipient
@ -311,7 +308,7 @@ data class NodeRegistration(val node: NodeInfo, val serial: Long, val type: AddO
*/
fun toWire(privateKey: PrivateKey): WireNodeRegistration {
val regSerialized = this.serialize()
val regSig = privateKey.signWithECDSA(regSerialized.bytes, node.legalIdentity.owningKey.singleKey)
val regSig = privateKey.signWithECDSA(regSerialized.bytes, node.legalIdentity.owningKey)
return WireNodeRegistration(regSerialized, regSig)
}

View File

@ -17,6 +17,8 @@ import net.corda.core.crypto.AbstractParty
import net.corda.core.crypto.CompositeKey
import net.corda.core.crypto.Party
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.containsAny
import net.corda.core.crypto.toBase58String
import net.corda.core.node.ServiceHub
import net.corda.core.node.services.StatesNotAvailableException
import net.corda.core.node.services.Vault
@ -177,7 +179,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
override fun <T : ContractState> states(clazzes: Set<Class<T>>, statuses: EnumSet<Vault.StateStatus>, includeSoftLockedStates: Boolean): Iterable<StateAndRef<T>> {
val stateAndRefs =
session.withTransaction(TransactionIsolation.REPEATABLE_READ) {
var query = select(VaultSchema.VaultStates::class)
val query = select(VaultSchema.VaultStates::class)
.where(VaultSchema.VaultStates::stateStatus `in` statuses)
// TODO: temporary fix to continue supporting track() function (until becomes Typed)
if (!clazzes.map { it.name }.contains(ContractState::class.java.name))
@ -442,8 +444,8 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
@Suspendable
override fun generateSpend(tx: TransactionBuilder,
amount: Amount<Currency>,
to: CompositeKey,
onlyFromParties: Set<AbstractParty>?): Pair<TransactionBuilder, List<CompositeKey>> {
to: PublicKey,
onlyFromParties: Set<AbstractParty>?): Pair<TransactionBuilder, List<PublicKey>> {
// Discussion
//
// This code is analogous to the Wallet.send() set of methods in bitcoinj, and has the same general outline.
@ -520,7 +522,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
return Pair(tx, keysUsed)
}
private fun deriveState(txState: TransactionState<Cash.State>, amount: Amount<Issued<Currency>>, owner: CompositeKey)
private fun deriveState(txState: TransactionState<Cash.State>, amount: Amount<Issued<Currency>>, owner: PublicKey)
= txState.copy(data = txState.data.copy(amount = amount, owner = owner))
/**

View File

@ -3,7 +3,6 @@ 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.CompositeKey
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.parsePublicKeyBase58
import net.corda.core.crypto.toBase58String
@ -260,8 +259,7 @@ fun <T : Any> rx.Observable<T>.wrapWithDatabaseTransaction(db: Database? = null)
}
// Composite columns for use with below Exposed helpers.
data class PartyColumns(val name: Column<String>, val owningKey: Column<CompositeKey>)
data class PartyColumns(val name: Column<String>, val owningKey: Column<PublicKey>)
data class StateRefColumns(val txId: Column<SecureHash>, val index: Column<Int>)
data class TxnNoteColumns(val txId: Column<SecureHash>, val note: Column<String>)
@ -269,10 +267,8 @@ data class TxnNoteColumns(val txId: Column<SecureHash>, val note: Column<String>
* [Table] column helpers for use with Exposed, as per [varchar] etc.
*/
fun Table.publicKey(name: String) = this.registerColumn<PublicKey>(name, PublicKeyColumnType)
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.compositeKey(keyColumnName))
fun Table.party(nameColumnName: String, keyColumnName: String) = PartyColumns(this.varchar(nameColumnName, length = 255), this.publicKey(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)
@ -283,23 +279,17 @@ fun Table.txnNote(txIdColumnName: String, txnNoteColumnName: String) = TxnNoteCo
/**
* [ColumnType] for marshalling to/from database on behalf of [PublicKey].
*/
// TODO Rethink how we store CompositeKeys in db. Currently they are stored as Base58 strings and as we don't know the size
// of a CompositeKey they could be CLOB fields. Given the time to fetch these types and that they are unsuitable as table keys,
// having a shorter primary key (such as SHA256 hash or a UUID generated on demand) that references a common composite key table may make more sense.
object PublicKeyColumnType : ColumnType() {
override fun sqlType(): String = "VARCHAR(255)"
override fun sqlType(): String = "VARCHAR"
override fun valueFromDB(value: Any): Any = parsePublicKeyBase58(value.toString())
override fun notNullValueToDB(value: Any): Any = if (value is PublicKey) value.toBase58String() else value
}
/**
* [ColumnType] for marshalling to/from database on behalf of [CompositeKey].
*/
object CompositeKeyColumnType : ColumnType() {
override fun sqlType(): String = "VARCHAR"
override fun valueFromDB(value: Any): Any = CompositeKey.parseFromBase58(value.toString())
override fun notNullValueToDB(value: Any): Any = if (value is CompositeKey) value.toBase58String() else value
}
/**
* [ColumnType] for marshalling to/from database on behalf of [SecureHash].
*/

View File

@ -2,7 +2,6 @@ package net.corda.node.utilities
import net.corda.core.crypto.CompositeKey
import net.corda.core.crypto.Party
import net.corda.core.crypto.composite
import net.corda.core.crypto.generateKeyPair
import net.corda.core.serialization.serialize
import net.corda.core.utilities.loggerFor
@ -22,13 +21,13 @@ object ServiceIdentityGenerator {
* @param dirs List of node directories to place the generated identity and key pairs in.
* @param serviceId The service id of the distributed service.
* @param serviceName The legal name of the distributed service.
* @param threshold The threshold for the generated group [CompositeKey.Node].
* @param threshold The threshold for the generated group [CompositeKey].
*/
fun generateToDisk(dirs: List<Path>, serviceId: String, serviceName: String, threshold: Int = 1) {
log.trace { "Generating a group identity \"serviceName\" for nodes: ${dirs.joinToString()}" }
val keyPairs = (1..dirs.size).map { generateKeyPair() }
val notaryKey = CompositeKey.Builder().addKeys(keyPairs.map { it.public.composite }).build(threshold)
val notaryKey = CompositeKey.Builder().addKeys(keyPairs.map { it.public }).build(threshold)
val notaryParty = Party(serviceName, notaryKey).serialize()
keyPairs.zip(dirs) { keyPair, dir ->

View File

@ -2,6 +2,8 @@ package net.corda.node
import net.corda.contracts.asset.Cash
import net.corda.core.contracts.*
import net.corda.core.crypto.isFulfilledBy
import net.corda.core.crypto.keys
import net.corda.core.flows.StateMachineRunId
import net.corda.core.messaging.StateMachineUpdate
import net.corda.core.messaging.startFlow

View File

@ -40,6 +40,7 @@ import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.math.BigInteger
import java.security.KeyPair
import java.security.PublicKey
import java.util.*
import java.util.concurrent.Future
import java.util.jar.JarOutputStream
@ -257,7 +258,7 @@ class TwoPartyTradeFlowTests {
}
val extraKey = bobNode.keyManagement.freshKey()
val bobsFakeCash = fillUpForBuyer(false, extraKey.public.composite,
val bobsFakeCash = fillUpForBuyer(false, extraKey.public,
DUMMY_CASH_ISSUER.party,
notaryNode.info.notaryIdentity).second
val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bobNode.services.legalIdentityKey, extraKey)
@ -357,7 +358,7 @@ class TwoPartyTradeFlowTests {
attachment(ByteArrayInputStream(stream.toByteArray()))
}
val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public.composite,
val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public,
DUMMY_CASH_ISSUER.party,
notaryNode.info.notaryIdentity).second
insertFakeTransactions(bobsFakeCash, bobNode, notaryNode)
@ -458,7 +459,7 @@ class TwoPartyTradeFlowTests {
val bobKey = bobNode.services.legalIdentityKey
val issuer = MEGA_CORP.ref(1, 2, 3)
val bobsBadCash = fillUpForBuyer(bobError, bobKey.public.composite, DUMMY_CASH_ISSUER.party,
val bobsBadCash = fillUpForBuyer(bobError, bobKey.public, DUMMY_CASH_ISSUER.party,
notaryNode.info.notaryIdentity).second
val alicesFakePaper = databaseTransaction(aliceNode.database) {
fillUpForSeller(aliceError, aliceNode.info.legalIdentity.owningKey,
@ -505,7 +506,7 @@ class TwoPartyTradeFlowTests {
private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForBuyer(
withError: Boolean,
owner: CompositeKey,
owner: PublicKey,
issuer: AnonymousParty,
notary: Party): Pair<Vault<ContractState>, List<WireTransaction>> {
val interimOwnerKey = MEGA_CORP_PUBKEY
@ -551,7 +552,7 @@ class TwoPartyTradeFlowTests {
private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForSeller(
withError: Boolean,
owner: CompositeKey,
owner: PublicKey,
amount: Amount<Issued<Currency>>,
attachmentID: SecureHash?,
notary: Party): Pair<Vault<ContractState>, List<WireTransaction>> {

View File

@ -1,7 +1,6 @@
package net.corda.node.services
import net.corda.core.crypto.Party
import net.corda.core.crypto.composite
import net.corda.core.crypto.generateKeyPair
import net.corda.node.services.identity.InMemoryIdentityService
import net.corda.testing.ALICE
@ -51,7 +50,7 @@ class InMemoryIdentityServiceTests {
@Test
fun `get identity by name`() {
val service = InMemoryIdentityService()
val identities = listOf("Node A", "Node B", "Node C").map { Party(it, generateKeyPair().public.composite) }
val identities = listOf("Node A", "Node B", "Node C").map { Party(it, generateKeyPair().public) }
assertNull(service.partyFromName(identities.first().name))
identities.forEach { service.registerIdentity(it) }
identities.forEach { assertEquals(it, service.partyFromName(it.name)) }

View File

@ -1,8 +1,6 @@
package net.corda.node.services
import net.corda.core.contracts.*
import net.corda.core.crypto.CompositeKey
import net.corda.core.crypto.composite
import net.corda.core.days
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowLogicRef
@ -113,7 +111,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
}
class TestState(val flowLogicRef: FlowLogicRef, val instant: Instant) : LinearState, SchedulableState {
override val participants: List<CompositeKey>
override val participants: List<PublicKey>
get() = throw UnsupportedOperationException()
override val linearId = UniqueIdentifier()
@ -272,7 +270,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
val state = TestState(factory.create(TestFlowLogic::class.java, increment), instant)
val usefulTX = TransactionType.General.Builder(null).apply {
addOutputState(state, DUMMY_NOTARY)
addCommand(Command(), freshKey.public.composite)
addCommand(Command(), freshKey.public)
signWith(freshKey)
}.toSignedTransaction()
val txHash = usefulTX.id

View File

@ -6,6 +6,7 @@ import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.StateRef
import net.corda.core.contracts.TransactionType
import net.corda.core.crypto.DigitalSignature
import net.corda.core.crypto.keys
import net.corda.core.getOrThrow
import net.corda.core.node.services.ServiceInfo
import net.corda.core.seconds

View File

@ -4,6 +4,7 @@ import co.paralleluniverse.fibers.Suspendable
import net.corda.core.contracts.*
import net.corda.core.crypto.CompositeKey
import net.corda.core.crypto.Party
import net.corda.core.crypto.containsAny
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowLogicRefFactory
import net.corda.core.node.CordaPluginRegistry
@ -44,7 +45,7 @@ class ScheduledFlowTests {
}
}
override val participants: List<CompositeKey> = listOf(source.owningKey, destination.owningKey)
override val participants: List<PublicKey> = listOf(source.owningKey, destination.owningKey)
override fun isRelevant(ourKeys: Set<PublicKey>): Boolean {
return participants.any { it.containsAny(ourKeys) }

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.composite
import net.corda.core.crypto.keys
import net.corda.core.getOrThrow
import net.corda.core.node.services.ServiceInfo
import net.corda.core.transactions.SignedTransaction
@ -54,7 +54,7 @@ class ValidatingNotaryServiceTests {
}
@Test fun `should report error for missing signatures`() {
val expectedMissingKey = MEGA_CORP_KEY.public.composite
val expectedMissingKey = MEGA_CORP_KEY.public
val stx = run {
val inputState = issueState(clientNode)

View File

@ -6,7 +6,6 @@ import net.corda.contracts.testing.fillWithSomeTestCash
import net.corda.contracts.testing.fillWithSomeTestDeals
import net.corda.contracts.testing.fillWithSomeTestLinearStates
import net.corda.core.contracts.*
import net.corda.core.crypto.composite
import net.corda.core.node.services.VaultService
import net.corda.core.node.services.consumedStates
import net.corda.core.node.services.unconsumedStates
@ -82,7 +81,7 @@ class VaultWithCashTest {
val state = w[0].state.data
assertEquals(30.45.DOLLARS `issued by` DUMMY_CASH_ISSUER, state.amount)
assertEquals(services.key.public.composite, state.owner)
assertEquals(services.key.public, state.owner)
assertEquals(34.70.DOLLARS `issued by` DUMMY_CASH_ISSUER, (w[2].state.data).amount)
assertEquals(34.85.DOLLARS `issued by` DUMMY_CASH_ISSUER, (w[1].state.data).amount)
@ -95,7 +94,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.composite, DUMMY_NOTARY)
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), freshKey.public, DUMMY_NOTARY)
signWith(MEGA_CORP_KEY)
}.toSignedTransaction()
@ -113,7 +112,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.composite, DUMMY_NOTARY)
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), BOB_KEY.public, DUMMY_NOTARY)
signWith(MEGA_CORP_KEY)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
@ -137,7 +136,7 @@ class VaultWithCashTest {
services.fillWithSomeTestCash(100.DOLLARS, DUMMY_NOTARY, 10, 10, Random(0L),
issuedBy = MEGA_CORP.ref(1),
issuerKey = MEGA_CORP_KEY,
ownedBy = freshKey.public.composite)
ownedBy = freshKey.public)
println("Cash balance: ${vault.cashBalances[USD]}")
assertThat(vault.unconsumedStates<Cash.State>()).hasSize(10)
@ -226,8 +225,8 @@ class VaultWithCashTest {
// Issue a linear state
val dummyIssue = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
addOutputState(net.corda.contracts.testing.DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public.composite)))
addOutputState(net.corda.contracts.testing.DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public.composite)))
addOutputState(net.corda.contracts.testing.DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public)))
addOutputState(net.corda.contracts.testing.DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public)))
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
@ -247,7 +246,7 @@ class VaultWithCashTest {
// Issue a linear state
val dummyIssue = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
addOutputState(net.corda.contracts.testing.DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public.composite)))
addOutputState(net.corda.contracts.testing.DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public)))
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
@ -259,7 +258,7 @@ class VaultWithCashTest {
// Move the same state
val dummyMove = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
addOutputState(net.corda.contracts.testing.DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public.composite)))
addOutputState(net.corda.contracts.testing.DummyLinearContract.State(linearId = linearId, participants = listOf(freshKey.public)))
addInputState(dummyIssue.tx.outRef<LinearState>(0))
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
@ -276,7 +275,7 @@ class VaultWithCashTest {
val freshKey = services.keyManagementService.freshKey()
databaseTransaction(database) {
services.fillWithSomeTestCash(100.DOLLARS, DUMMY_NOTARY, 3, 3, Random(0L), ownedBy = freshKey.public.composite)
services.fillWithSomeTestCash(100.DOLLARS, DUMMY_NOTARY, 3, 3, Random(0L), ownedBy = freshKey.public)
services.fillWithSomeTestCash(100.SWISS_FRANCS, DUMMY_NOTARY, 2, 2, Random(0L))
services.fillWithSomeTestCash(100.POUNDS, DUMMY_NOTARY, 1, 1, Random(0L))
val cash = vault.unconsumedStates<Cash.State>()
@ -320,8 +319,8 @@ class VaultWithCashTest {
// Create a txn consuming different contract types
val dummyMove = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
addOutputState(net.corda.contracts.testing.DummyLinearContract.State(participants = listOf(freshKey.public.composite)))
addOutputState(net.corda.contracts.testing.DummyDealContract.State(ref = "999", participants = listOf(freshKey.public.composite)))
addOutputState(net.corda.contracts.testing.DummyLinearContract.State(participants = listOf(freshKey.public)))
addOutputState(net.corda.contracts.testing.DummyDealContract.State(ref = "999", participants = listOf(freshKey.public)))
addInputState(linearStates.first())
addInputState(deals.first())
signWith(DUMMY_NOTARY_KEY)

View File

@ -9,6 +9,7 @@ import net.corda.core.contracts.TransactionType
import net.corda.core.crypto.DigitalSignature
import net.corda.core.crypto.NullPublicKey
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.toBase58String
import net.corda.core.node.services.Vault
import net.corda.core.serialization.serialize
import net.corda.core.serialization.storageKryo

View File

@ -5,7 +5,7 @@ import com.google.common.net.HostAndPort
import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.SettableFuture
import net.corda.core.crypto.composite
import com.typesafe.config.ConfigFactory.empty
import net.corda.core.crypto.generateKeyPair
import net.corda.core.messaging.Message
import net.corda.core.messaging.RPCOps
@ -225,7 +225,7 @@ class ArtemisMessagingTests {
config,
MOCK_NODE_VERSION_INFO,
server,
identity.public.composite,
identity.public,
ServiceAffinityExecutor("ArtemisMessagingTests", 1),
database,
networkMapRegistrationFuture,

View File

@ -4,7 +4,6 @@ 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.composite
import net.corda.core.node.services.StatesNotAvailableException
import net.corda.core.node.services.TxWritableStorageService
import net.corda.core.node.services.VaultService
@ -406,7 +405,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.composite, DUMMY_NOTARY)
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), freshKey.public, DUMMY_NOTARY)
signWith(MEGA_CORP_KEY)
}.toSignedTransaction()
@ -419,7 +418,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.composite, DUMMY_NOTARY)
Cash().generateIssue(this, 200.POUNDS `issued by` MEGA_CORP.ref(1), freshKey.public, DUMMY_NOTARY)
signWith(MEGA_CORP_KEY)
}.toSignedTransaction()