First cut at removing PrivateKey leakage from KeyManagementService

Fixup after rebase

Restore original key property names

Fixup after rebase

Undo extra import that IntelliJ keeps erroneously adding.

Add comments and fix docs for transaction signing.

Fixes after rebase

More fixes after rebase

Address PR requests

Address PR requests
This commit is contained in:
Matthew Nesbit
2017-05-12 17:42:13 +01:00
parent ccbe76eb84
commit 05a97b11f3
58 changed files with 454 additions and 399 deletions

View File

@ -23,7 +23,6 @@ import net.corda.node.utilities.transaction
import net.corda.testing.node.NodeBasedTest
import org.bouncycastle.asn1.x500.X500Name
import org.junit.Test
import java.security.KeyPair
import java.util.*
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
@ -43,25 +42,21 @@ class BFTNotaryServiceTests : NodeBasedTest() {
val alice = startNode(ALICE.name).getOrThrow()
val notaryParty = alice.netMapCache.getNotary(notaryCommonName)!!
val notaryNodeKeyPair = with(masterNode) { database.transaction { services.notaryIdentityKey } }
val aliceKey = with(alice) { database.transaction { services.legalIdentityKey } }
val inputState = issueState(alice, notaryParty, notaryNodeKeyPair)
val inputState = issueState(alice, notaryParty)
val firstSpendTx = TransactionType.General.Builder(notaryParty).withItems(inputState).run {
signWith(aliceKey)
toSignedTransaction(false)
}
val firstTxBuilder = TransactionType.General.Builder(notaryParty).withItems(inputState)
val firstSpendTx = alice.services.signInitialTransaction(firstTxBuilder)
val firstSpend = alice.services.startFlow(NotaryFlow.Client(firstSpendTx))
firstSpend.resultFuture.getOrThrow()
val secondSpendTx = TransactionType.General.Builder(notaryParty).withItems(inputState).run {
val secondSpendBuilder = TransactionType.General.Builder(notaryParty).withItems(inputState).run {
val dummyState = DummyContract.SingleOwnerState(0, alice.info.legalIdentity)
addOutputState(dummyState)
signWith(aliceKey)
toSignedTransaction(false)
this
}
val secondSpendTx = alice.services.signInitialTransaction(secondSpendBuilder)
val secondSpend = alice.services.startFlow(NotaryFlow.Client(secondSpendTx))
val ex = assertFailsWith(NotaryException::class) { secondSpend.resultFuture.getOrThrow() }
@ -69,14 +64,12 @@ class BFTNotaryServiceTests : NodeBasedTest() {
assertEquals(error.txId, secondSpendTx.id)
}
private fun issueState(node: AbstractNode, notary: Party, notaryKey: KeyPair): StateAndRef<*> {
private fun issueState(node: AbstractNode, notary: Party): StateAndRef<*> {
return node.database.transaction {
val tx = DummyContract.generateInitial(Random().nextInt(), notary, node.info.legalIdentity.ref(0))
tx.signWith(node.services.legalIdentityKey)
tx.signWith(notaryKey)
val stx = tx.toSignedTransaction()
val builder = DummyContract.generateInitial(Random().nextInt(), notary, node.info.legalIdentity.ref(0))
val stx = node.services.signInitialTransaction(builder)
node.services.recordTransactions(listOf(stx))
StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
StateAndRef(builder.outputStates().first(), StateRef(stx.id, 0))
}
}

View File

@ -17,7 +17,6 @@ import net.corda.node.utilities.transaction
import net.corda.testing.node.NodeBasedTest
import org.bouncycastle.asn1.x500.X500Name
import org.junit.Test
import java.security.KeyPair
import java.util.*
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
@ -33,24 +32,21 @@ class RaftNotaryServiceTests : NodeBasedTest() {
).getOrThrow()
val notaryParty = alice.netMapCache.getNotary(notaryName)!!
val notaryNodeKeyPair = with(masterNode) { database.transaction { services.notaryIdentityKey } }
val aliceKey = with(alice) { database.transaction { services.legalIdentityKey } }
val inputState = issueState(alice, notaryParty, notaryNodeKeyPair)
val inputState = issueState(alice, notaryParty)
val firstTxBuilder = TransactionType.General.Builder(notaryParty).withItems(inputState)
val firstSpendTx = alice.services.signInitialTransaction(firstTxBuilder)
val firstSpendTx = TransactionType.General.Builder(notaryParty).withItems(inputState).run {
signWith(aliceKey)
toSignedTransaction(false)
}
val firstSpend = alice.services.startFlow(NotaryFlow.Client(firstSpendTx))
firstSpend.resultFuture.getOrThrow()
val secondSpendTx = TransactionType.General.Builder(notaryParty).withItems(inputState).run {
val secondSpendBuilder = TransactionType.General.Builder(notaryParty).withItems(inputState).run {
val dummyState = DummyContract.SingleOwnerState(0, alice.info.legalIdentity)
addOutputState(dummyState)
signWith(aliceKey)
toSignedTransaction(false)
this
}
val secondSpendTx = alice.services.signInitialTransaction(secondSpendBuilder)
val secondSpend = alice.services.startFlow(NotaryFlow.Client(secondSpendTx))
val ex = assertFailsWith(NotaryException::class) { secondSpend.resultFuture.getOrThrow() }
@ -58,14 +54,12 @@ class RaftNotaryServiceTests : NodeBasedTest() {
assertEquals(error.txId, secondSpendTx.id)
}
private fun issueState(node: AbstractNode, notary: Party, notaryKey: KeyPair): StateAndRef<*> {
private fun issueState(node: AbstractNode, notary: Party): StateAndRef<*> {
return node.database.transaction {
val tx = DummyContract.generateInitial(Random().nextInt(), notary, node.info.legalIdentity.ref(0))
tx.signWith(node.services.legalIdentityKey)
tx.signWith(notaryKey)
val stx = tx.toSignedTransaction()
val builder = DummyContract.generateInitial(Random().nextInt(), notary, node.info.legalIdentity.ref(0))
val stx = node.services.signInitialTransaction(builder)
node.services.recordTransactions(listOf(stx))
StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
StateAndRef(builder.outputStates().first(), StateRef(stx.id, 0))
}
}
}

View File

@ -70,7 +70,7 @@ class P2PSecurityTest : NodeBasedTest() {
private fun SimpleNode.registerWithNetworkMap(registrationName: X500Name): ListenableFuture<NetworkMapService.RegistrationResponse> {
val nodeInfo = NodeInfo(net.myAddress, Party(registrationName, identity.public), MOCK_VERSION_INFO.platformVersion)
val registration = NodeRegistration(nodeInfo, System.currentTimeMillis(), AddOrRemove.ADD, Instant.MAX)
val request = RegistrationRequest(registration.toWire(identity.private), net.myAddress)
val request = RegistrationRequest(registration.toWire(keyService, identity.public), net.myAddress)
return net.sendRequest<NetworkMapService.RegistrationResponse>(NetworkMapService.REGISTER_TOPIC, request, networkMapNode.net.myAddress)
}
}

View File

@ -490,7 +490,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
val expires = instant + NetworkMapService.DEFAULT_EXPIRATION_PERIOD
val reg = NodeRegistration(info, instant.toEpochMilli(), ADD, expires)
val legalIdentityKey = obtainLegalIdentityKey()
val request = NetworkMapService.RegistrationRequest(reg.toWire(legalIdentityKey.private), net.myAddress)
val request = NetworkMapService.RegistrationRequest(reg.toWire(keyManagement, legalIdentityKey.public), net.myAddress)
return net.sendRequest(NetworkMapService.REGISTER_TOPIC, request, networkMapAddress)
}

View File

@ -1,7 +1,10 @@
package net.corda.node.services.keys
import net.corda.core.ThreadBox
import net.corda.core.crypto.DigitalSignature
import net.corda.core.crypto.generateKeyPair
import net.corda.core.crypto.keys
import net.corda.core.crypto.sign
import net.corda.core.node.services.KeyManagementService
import net.corda.core.serialization.SingletonSerializeAsToken
import java.security.KeyPair
@ -38,13 +41,26 @@ class E2ETestKeyManagementService(initialKeys: Set<KeyPair>) : SingletonSerializ
}
// Accessing this map clones it.
override val keys: Map<PublicKey, PrivateKey> get() = mutex.locked { HashMap(keys) }
override val keys: Set<PublicKey> get() = mutex.locked { keys.keys }
override fun freshKey(): KeyPair {
override fun freshKey(): PublicKey {
val keyPair = generateKeyPair()
mutex.locked {
keys[keyPair.public] = keyPair.private
}
return keyPair
return keyPair.public
}
private fun getSigningKeyPair(publicKey: PublicKey): KeyPair {
return mutex.locked {
val pk = publicKey.keys.first { keys.containsKey(it) }
KeyPair(pk, keys[pk]!!)
}
}
override fun sign(bytes: ByteArray, publicKey: PublicKey): DigitalSignature.WithKey {
val keyPair = getSigningKeyPair(publicKey)
val signature = keyPair.sign(bytes)
return signature
}
}

View File

@ -1,7 +1,10 @@
package net.corda.node.services.keys
import net.corda.core.ThreadBox
import net.corda.core.crypto.DigitalSignature
import net.corda.core.crypto.generateKeyPair
import net.corda.core.crypto.keys
import net.corda.core.crypto.sign
import net.corda.core.node.services.KeyManagementService
import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.node.utilities.*
@ -10,7 +13,6 @@ import org.jetbrains.exposed.sql.statements.InsertStatement
import java.security.KeyPair
import java.security.PrivateKey
import java.security.PublicKey
import java.util.*
/**
* A persistent re-implementation of [E2ETestKeyManagementService] to support node re-start.
@ -50,13 +52,27 @@ class PersistentKeyManagementService(initialKeys: Set<KeyPair>) : SingletonSeria
}
}
override val keys: Map<PublicKey, PrivateKey> get() = mutex.locked { HashMap(keys) }
override val keys: Set<PublicKey> get() = mutex.locked { keys.keys }
override fun freshKey(): KeyPair {
override fun freshKey(): PublicKey {
val keyPair = generateKeyPair()
mutex.locked {
keys[keyPair.public] = keyPair.private
}
return keyPair
return keyPair.public
}
private fun getSigningKeyPair(publicKey: PublicKey): KeyPair {
return mutex.locked {
val pk = publicKey.keys.first { keys.containsKey(it) }
KeyPair(pk, keys[pk]!!)
}
}
override fun sign(bytes: ByteArray, publicKey: PublicKey): DigitalSignature.WithKey {
val keyPair = getSigningKeyPair(publicKey)
val signature = keyPair.sign(bytes)
return signature
}
}

View File

@ -8,6 +8,7 @@ import net.corda.core.messaging.MessageRecipients
import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.NodeInfo
import net.corda.core.node.services.DEFAULT_SESSION_ID
import net.corda.core.node.services.KeyManagementService
import net.corda.core.node.services.NetworkMapCache
import net.corda.core.node.services.ServiceType
import net.corda.core.random63BitValue
@ -31,7 +32,7 @@ import net.corda.node.services.network.NetworkMapService.Companion.SUBSCRIPTION_
import net.corda.node.utilities.AddOrRemove
import net.corda.node.utilities.AddOrRemove.ADD
import net.corda.node.utilities.AddOrRemove.REMOVE
import java.security.PrivateKey
import java.security.PublicKey
import java.security.SignatureException
import java.time.Instant
import java.time.Period
@ -322,9 +323,9 @@ data class NodeRegistration(val node: NodeInfo, val serial: Long, val type: AddO
/**
* Build a node registration in wire format.
*/
fun toWire(privateKey: PrivateKey): WireNodeRegistration {
fun toWire(keyManager: KeyManagementService, publicKey: PublicKey): WireNodeRegistration {
val regSerialized = this.serialize()
val regSig = privateKey.sign(regSerialized.bytes, node.legalIdentity.owningKey)
val regSig = keyManager.sign(regSerialized.bytes, publicKey)
return WireNodeRegistration(regSerialized, regSig)
}

View File

@ -9,7 +9,10 @@ import bftsmart.tom.server.defaultservices.DefaultReplier
import bftsmart.tom.util.Extractor
import net.corda.core.contracts.StateRef
import net.corda.core.contracts.Timestamp
import net.corda.core.crypto.*
import net.corda.core.crypto.DigitalSignature
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.SignedData
import net.corda.core.crypto.sign
import net.corda.core.identity.Party
import net.corda.core.node.services.TimestampChecker
import net.corda.core.node.services.UniquenessProvider
@ -198,8 +201,7 @@ object BFTSMaRt {
}
protected fun sign(bytes: ByteArray): DigitalSignature.WithKey {
val mySigningKey = db.transaction { services.notaryIdentityKey }
return mySigningKey.sign(bytes)
return db.transaction { services.keyManagementService.sign(bytes, services.notaryIdentityKey) }
}
// TODO:

View File

@ -243,7 +243,7 @@ class NodeVaultService(private val services: ServiceHub, dataSourceProperties: P
}
override fun notifyAll(txns: Iterable<WireTransaction>) {
val ourKeys = services.keyManagementService.keys.keys
val ourKeys = services.keyManagementService.keys
val netDelta = txns.fold(Vault.NoUpdate) { netDelta, txn -> netDelta + makeUpdate(txn, ourKeys) }
if (netDelta != Vault.NoUpdate) {
recordUpdate(netDelta)

View File

@ -5,21 +5,24 @@ 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.identity.AnonymousParty
import net.corda.core.identity.Party
import net.corda.core.crypto.DigitalSignature
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.sign
import net.corda.core.days
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.FlowStateMachine
import net.corda.core.flows.InitiatingFlow
import net.corda.core.flows.StateMachineRunId
import net.corda.core.getOrThrow
import net.corda.core.identity.AnonymousParty
import net.corda.core.identity.Party
import net.corda.core.identity.AbstractParty
import net.corda.core.map
import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.node.NodeInfo
import net.corda.core.node.services.*
import net.corda.core.rootCause
import net.corda.core.serialization.serialize
import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.transactions.WireTransaction
@ -87,8 +90,6 @@ class TwoPartyTradeFlowTests {
val notaryNode = net.createNotaryNode(null, DUMMY_NOTARY.name)
val aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name)
val bobNode = net.createPartyNode(notaryNode.info.address, BOB.name)
val aliceKey = aliceNode.services.legalIdentityKey
val notaryKey = notaryNode.services.notaryIdentityKey
aliceNode.disableDBCloseOnStop()
bobNode.disableDBCloseOnStop()
@ -102,7 +103,7 @@ class TwoPartyTradeFlowTests {
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null, notaryNode.info.notaryIdentity).second
}
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, aliceKey, notaryKey)
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, MEGA_CORP_PUBKEY)
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notaryNode, aliceNode, bobNode,
"alice's paper".outputStateAndRef())
@ -133,8 +134,6 @@ class TwoPartyTradeFlowTests {
val notaryNode = net.createNotaryNode(null, DUMMY_NOTARY.name)
val aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name)
val bobNode = net.createPartyNode(notaryNode.info.address, BOB.name)
val aliceKey = aliceNode.services.legalIdentityKey
val notaryKey = notaryNode.services.notaryIdentityKey
aliceNode.disableDBCloseOnStop()
bobNode.disableDBCloseOnStop()
@ -149,7 +148,7 @@ class TwoPartyTradeFlowTests {
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null, notaryNode.info.notaryIdentity).second
}
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, aliceKey, notaryKey)
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, MEGA_CORP_PUBKEY)
val cashLockId = UUID.randomUUID()
bobNode.database.transaction {
@ -184,8 +183,6 @@ class TwoPartyTradeFlowTests {
var bobNode = net.createPartyNode(notaryNode.info.address, BOB.name)
aliceNode.disableDBCloseOnStop()
bobNode.disableDBCloseOnStop()
val aliceKey = aliceNode.services.legalIdentityKey
val notaryKey = notaryNode.services.notaryIdentityKey
val bobAddr = bobNode.net.myAddress as InMemoryMessagingNetwork.PeerHandle
val networkMapAddr = notaryNode.info.address
@ -199,7 +196,7 @@ class TwoPartyTradeFlowTests {
fillUpForSeller(false, aliceNode.info.legalIdentity,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null, notaryNode.info.notaryIdentity).second
}
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, aliceKey, notaryKey)
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, MEGA_CORP_PUBKEY)
val aliceFuture = runBuyerAndSeller(notaryNode, aliceNode, bobNode, "alice's paper".outputStateAndRef()).sellerResult
// Everything is on this thread so we can now step through the flow one step at a time.
@ -302,8 +299,6 @@ class TwoPartyTradeFlowTests {
val notaryNode = net.createNotaryNode(null, DUMMY_NOTARY.name)
val aliceNode = makeNodeWithTracking(notaryNode.info.address, ALICE.name)
val bobNode = makeNodeWithTracking(notaryNode.info.address, BOB.name)
val alice = aliceNode.info.legalIdentity
val aliceKey = aliceNode.services.legalIdentityKey
ledger(aliceNode.services) {
@ -319,16 +314,15 @@ class TwoPartyTradeFlowTests {
}
val extraKey = bobNode.keyManagement.freshKey()
val extraPublicKey = extraKey.public
val bobsFakeCash = fillUpForBuyer(false, AnonymousParty(extraPublicKey),
val bobsFakeCash = fillUpForBuyer(false, AnonymousParty(extraKey),
DUMMY_CASH_ISSUER.party,
notaryNode.info.notaryIdentity).second
val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bobNode.services.legalIdentityKey, extraKey)
val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, extraKey, DUMMY_CASH_ISSUER_KEY.public, MEGA_CORP_PUBKEY)
val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, alice,
fillUpForSeller(false, aliceNode.info.legalIdentity,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID, notaryNode.info.notaryIdentity).second
}
val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, aliceKey)
val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, MEGA_CORP_PUBKEY)
net.runNetwork() // Clear network map registration messages
@ -404,7 +398,6 @@ class TwoPartyTradeFlowTests {
val notaryNode = net.createNotaryNode(null, DUMMY_NOTARY.name)
val aliceNode = makeNodeWithTracking(notaryNode.info.address, ALICE.name)
val bobNode = makeNodeWithTracking(notaryNode.info.address, BOB.name)
val aliceKey = aliceNode.services.legalIdentityKey
ledger(aliceNode.services) {
@ -419,18 +412,18 @@ class TwoPartyTradeFlowTests {
attachment(ByteArrayInputStream(stream.toByteArray()))
}
val bobsKey = bobNode.keyManagement.freshKey().public
val bobsKey = bobNode.keyManagement.freshKey()
val bobsFakeCash = fillUpForBuyer(false, AnonymousParty(bobsKey),
DUMMY_CASH_ISSUER.party,
notaryNode.info.notaryIdentity).second
insertFakeTransactions(bobsFakeCash, bobNode, notaryNode)
insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, DUMMY_CASH_ISSUER_KEY.public, MEGA_CORP_PUBKEY)
val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(false, aliceNode.info.legalIdentity,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID, notaryNode.info.notaryIdentity).second
}
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, aliceKey)
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, MEGA_CORP_PUBKEY)
net.runNetwork() // Clear network map registration messages
@ -524,21 +517,19 @@ class TwoPartyTradeFlowTests {
val notaryNode = net.createNotaryNode(null, DUMMY_NOTARY.name)
val aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name)
val bobNode = net.createPartyNode(notaryNode.info.address, BOB.name)
val alice = aliceNode.info.legalIdentity
val aliceKey = aliceNode.services.legalIdentityKey
val bob = bobNode.info.legalIdentity
val bobKey = bobNode.services.legalIdentityKey
val issuer = MEGA_CORP.ref(1, 2, 3)
val bobsBadCash = fillUpForBuyer(bobError, bob, DUMMY_CASH_ISSUER.party,
notaryNode.info.notaryIdentity).second
val bobsBadCash = bobNode.database.transaction {
fillUpForBuyer(bobError, bobNode.info.legalIdentity, DUMMY_CASH_ISSUER.party,
notaryNode.info.notaryIdentity).second
}
val alicesFakePaper = aliceNode.database.transaction {
fillUpForSeller(aliceError, alice,
fillUpForSeller(aliceError, aliceNode.info.legalIdentity,
1200.DOLLARS `issued by` issuer, null, notaryNode.info.notaryIdentity).second
}
insertFakeTransactions(bobsBadCash, bobNode, notaryNode, bobKey)
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, aliceKey)
insertFakeTransactions(bobsBadCash, bobNode, notaryNode, DUMMY_CASH_ISSUER_KEY.public, MEGA_CORP_PUBKEY)
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, MEGA_CORP_PUBKEY)
net.runNetwork() // Clear network map registration messages
@ -563,8 +554,25 @@ class TwoPartyTradeFlowTests {
wtxToSign: List<WireTransaction>,
node: AbstractNode,
notaryNode: MockNetwork.MockNode,
vararg extraKeys: KeyPair): Map<SecureHash, SignedTransaction> {
val signed: List<SignedTransaction> = signAll(wtxToSign, extraKeys.toList() + notaryNode.services.notaryIdentityKey + DUMMY_CASH_ISSUER_KEY)
vararg extraKeys: PublicKey): Map<SecureHash, SignedTransaction> {
val signed = wtxToSign.map {
val bits = it.serialize()
val id = it.id
val sigs = mutableListOf<DigitalSignature.WithKey>()
sigs.add(node.services.keyManagementService.sign(id.bytes, node.services.legalIdentityKey))
sigs.add(notaryNode.services.keyManagementService.sign(id.bytes, notaryNode.services.notaryIdentityKey))
for (extraKey in extraKeys) {
if (extraKey == DUMMY_CASH_ISSUER_KEY.public) {
sigs.add(DUMMY_CASH_ISSUER_KEY.sign(id.bytes))
} else if (extraKey == MEGA_CORP_PUBKEY) {
sigs.add(MEGA_CORP_KEY.sign(id.bytes))
} else {
sigs.add(node.services.keyManagementService.sign(id.bytes, extraKey))
}
}
SignedTransaction(bits, sigs)
}
return node.database.transaction {
node.services.recordTransactions(signed)
val validatedTransactions = node.services.storageService.validatedTransactions

View File

@ -133,9 +133,7 @@ class NotaryChangeTests {
addOutputState(stateC, notary)
addOutputState(stateB, notary, encumbrance = 1) // Encumbered by stateC
}
val nodeKey = node.services.legalIdentityKey
tx.signWith(nodeKey)
val stx = tx.toSignedTransaction()
val stx = node.services.signInitialTransaction(tx)
node.services.recordTransactions(listOf(stx))
return tx.toWireTransaction()
}
@ -151,11 +149,8 @@ class NotaryChangeTests {
fun issueState(node: AbstractNode, notaryNode: AbstractNode): StateAndRef<*> {
val tx = DummyContract.generateInitial(Random().nextInt(), notaryNode.info.notaryIdentity, node.info.legalIdentity.ref(0))
val nodeKey = node.services.legalIdentityKey
tx.signWith(nodeKey)
val notaryKeyPair = notaryNode.services.notaryIdentityKey
tx.signWith(notaryKeyPair)
val stx = tx.toSignedTransaction()
val signedByNode = node.services.signInitialTransaction(tx)
val stx = notaryNode.services.addSignature(signedByNode, notaryNode.services.notaryIdentityKey)
node.services.recordTransactions(listOf(stx))
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
}
@ -164,13 +159,9 @@ fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode, notaryNode: A
val state = TransactionState(DummyContract.MultiOwnerState(0,
listOf(nodeA.info.legalIdentity, nodeB.info.legalIdentity)), notaryNode.info.notaryIdentity)
val tx = TransactionType.NotaryChange.Builder(notaryNode.info.notaryIdentity).withItems(state)
val nodeAKey = nodeA.services.legalIdentityKey
val nodeBKey = nodeB.services.legalIdentityKey
tx.signWith(nodeAKey)
tx.signWith(nodeBKey)
val notaryKeyPair = notaryNode.services.notaryIdentityKey
tx.signWith(notaryKeyPair)
val stx = tx.toSignedTransaction()
val signedByA = nodeA.services.signInitialTransaction(tx)
val signedByAB = nodeB.services.addSignature(signedByA)
val stx = notaryNode.services.addSignature(signedByAB, notaryNode.services.notaryIdentityKey)
nodeA.services.recordTransactions(listOf(stx))
nodeB.services.recordTransactions(listOf(stx))
val stateAndRef = StateAndRef(state, StateRef(stx.id, 0))
@ -180,9 +171,7 @@ fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode, notaryNode: A
fun issueInvalidState(node: AbstractNode, notary: Party): StateAndRef<*> {
val tx = DummyContract.generateInitial(Random().nextInt(), notary, node.info.legalIdentity.ref(0))
tx.setTime(Instant.now(), 30.seconds)
val nodeKey = node.services.legalIdentityKey
tx.signWith(nodeKey)
val stx = tx.toSignedTransaction(false)
val stx = node.services.signInitialTransaction(tx)
node.services.recordTransactions(listOf(stx))
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
}

View File

@ -271,11 +271,11 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
apply {
val freshKey = services.keyManagementService.freshKey()
val state = TestState(FlowLogicRefFactoryImpl.createForRPC(TestFlowLogic::class.java, increment), instant)
val usefulTX = TransactionType.General.Builder(null).apply {
val builder = TransactionType.General.Builder(null).apply {
addOutputState(state, DUMMY_NOTARY)
addCommand(Command(), freshKey.public)
signWith(freshKey)
}.toSignedTransaction()
addCommand(Command(), freshKey)
}
val usefulTX = services.signInitialTransaction(builder, freshKey)
val txHash = usefulTX.id
services.recordTransactions(usefulTX)

View File

@ -62,8 +62,8 @@ class ScheduledFlowTests {
val notary = serviceHub.networkMapCache.getAnyNotary()
val builder = TransactionType.General.Builder(notary)
val tx = builder.withItems(scheduledState).
signWith(serviceHub.legalIdentityKey).toSignedTransaction(false)
builder.withItems(scheduledState)
val tx = serviceHub.signInitialTransaction(builder)
subFlow(FinalityFlow(tx, setOf(serviceHub.myInfo.legalIdentity)))
}
}
@ -82,8 +82,8 @@ class ScheduledFlowTests {
val notary = state.state.notary
val newStateOutput = scheduledState.copy(processed = true)
val builder = TransactionType.General.Builder(notary)
val tx = builder.withItems(state, newStateOutput).
signWith(serviceHub.legalIdentityKey).toSignedTransaction(false)
builder.withItems(state, newStateOutput)
val tx = serviceHub.signInitialTransaction(builder)
subFlow(FinalityFlow(tx, setOf(scheduledState.source, scheduledState.destination)))
}
}

View File

@ -216,7 +216,7 @@ abstract class AbstractNetworkMapServiceTest<out S : AbstractNetworkMapService>
}
val expires = Instant.now() + NetworkMapService.DEFAULT_EXPIRATION_PERIOD
val nodeRegistration = NodeRegistration(info, distinctSerial, addOrRemove, expires)
val request = RegistrationRequest(nodeRegistration.toWire(services.legalIdentityKey.private), info.address)
val request = RegistrationRequest(nodeRegistration.toWire(services.keyManagementService, services.legalIdentityKey), info.address)
val response = services.networkService.sendRequest<RegistrationResponse>(REGISTER_TOPIC, request, mapServiceNode.info.address)
network.runNetwork()
return response

View File

@ -46,9 +46,7 @@ class DataVendingServiceTests {
Cash().generateIssue(ptx, Amount(100, Issued(deposit, USD)), beneficiary, DUMMY_NOTARY)
// Complete the cash transaction, and then manually relay it
val registerKey = registerNode.services.legalIdentityKey
ptx.signWith(registerKey)
val tx = ptx.toSignedTransaction()
val tx = registerNode.services.signInitialTransaction(ptx)
vaultServiceNode.database.transaction {
assertThat(vaultServiceNode.services.vaultService.unconsumedStates<Cash.State>()).isEmpty()
@ -76,9 +74,7 @@ class DataVendingServiceTests {
Cash().generateIssue(ptx, Amount(100, Issued(deposit, USD)), beneficiary, DUMMY_NOTARY)
// The transaction tries issuing MEGA_CORP cash, but we aren't the issuer, so it's invalid
val registerKey = registerNode.services.legalIdentityKey
ptx.signWith(registerKey)
val tx = ptx.toSignedTransaction(false)
val tx = registerNode.services.signInitialTransaction(ptx)
vaultServiceNode.database.transaction {
assertThat(vaultServiceNode.services.vaultService.unconsumedStates<Cash.State>()).isEmpty()

View File

@ -560,8 +560,7 @@ class FlowFrameworkTests {
fun `wait for transaction`() {
val ptx = TransactionBuilder(notary = notary1.info.notaryIdentity)
ptx.addOutputState(DummyState())
ptx.signWith(node1.services.legalIdentityKey)
val stx = ptx.toSignedTransaction()
val stx = node1.services.signInitialTransaction(ptx)
val committerFiber = node1
.initiateSingleShotFlow(WaitingFlows.Waiter::class) { WaitingFlows.Committer(it) }
@ -575,8 +574,7 @@ class FlowFrameworkTests {
fun `committer throws exception before calling the finality flow`() {
val ptx = TransactionBuilder(notary = notary1.info.notaryIdentity)
ptx.addOutputState(DummyState())
ptx.signWith(node1.services.legalIdentityKey)
val stx = ptx.toSignedTransaction()
val stx = node1.services.signInitialTransaction(ptx)
node1.registerServiceFlow(WaitingFlows.Waiter::class) {
WaitingFlows.Committer(it) { throw Exception("Error") }

View File

@ -6,7 +6,6 @@ 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
@ -21,7 +20,6 @@ import net.corda.testing.node.MockNetwork
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import java.security.KeyPair
import java.time.Instant
import java.util.*
import kotlin.test.assertEquals
@ -31,7 +29,6 @@ class NotaryServiceTests {
lateinit var net: MockNetwork
lateinit var notaryNode: MockNetwork.MockNode
lateinit var clientNode: MockNetwork.MockNode
lateinit var clientKeyPair: KeyPair
@Before fun setup() {
net = MockNetwork()
@ -39,7 +36,6 @@ class NotaryServiceTests {
legalName = DUMMY_NOTARY.name,
advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)))
clientNode = net.createNode(networkMapAddress = notaryNode.info.address)
clientKeyPair = clientNode.keyManagement.toKeyPair(clientNode.info.legalIdentity.owningKey.keys.single())
net.runNetwork() // Clear network map registration messages
}
@ -48,8 +44,7 @@ class NotaryServiceTests {
val inputState = issueState(clientNode)
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
tx.setTime(Instant.now(), 30.seconds)
tx.signWith(clientKeyPair)
tx.toSignedTransaction(false)
clientNode.services.signInitialTransaction(tx)
}
val future = runNotaryClient(stx)
@ -61,8 +56,7 @@ class NotaryServiceTests {
val stx = run {
val inputState = issueState(clientNode)
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
tx.signWith(clientKeyPair)
tx.toSignedTransaction(false)
clientNode.services.signInitialTransaction(tx)
}
val future = runNotaryClient(stx)
@ -75,8 +69,7 @@ class NotaryServiceTests {
val inputState = issueState(clientNode)
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
tx.setTime(Instant.now().plusSeconds(3600), 30.seconds)
tx.signWith(clientKeyPair)
tx.toSignedTransaction(false)
clientNode.services.signInitialTransaction(tx)
}
val future = runNotaryClient(stx)
@ -89,8 +82,7 @@ class NotaryServiceTests {
val stx = run {
val inputState = issueState(clientNode)
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
tx.signWith(clientKeyPair)
tx.toSignedTransaction(false)
clientNode.services.signInitialTransaction(tx)
}
val firstAttempt = NotaryFlow.Client(stx)
@ -107,14 +99,12 @@ class NotaryServiceTests {
val inputState = issueState(clientNode)
val stx = run {
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
tx.signWith(clientKeyPair)
tx.toSignedTransaction(false)
clientNode.services.signInitialTransaction(tx)
}
val stx2 = run {
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
tx.addInputState(issueState(clientNode))
tx.signWith(clientKeyPair)
tx.toSignedTransaction(false)
clientNode.services.signInitialTransaction(tx)
}
val firstSpend = NotaryFlow.Client(stx)
@ -139,11 +129,8 @@ class NotaryServiceTests {
fun issueState(node: AbstractNode): StateAndRef<*> {
val tx = DummyContract.generateInitial(Random().nextInt(), notaryNode.info.notaryIdentity, node.info.legalIdentity.ref(0))
val nodeKey = node.services.legalIdentityKey
tx.signWith(nodeKey)
val notaryKeyPair = notaryNode.services.notaryIdentityKey
tx.signWith(notaryKeyPair)
val stx = tx.toSignedTransaction()
val signedByNode = node.services.signInitialTransaction(tx)
val stx = notaryNode.services.addSignature(signedByNode, notaryNode.services.notaryIdentityKey)
node.services.recordTransactions(listOf(stx))
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
}

View File

@ -3,7 +3,6 @@ package net.corda.node.services.transactions
import com.google.common.util.concurrent.ListenableFuture
import net.corda.core.contracts.*
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.transactions.SignedTransaction
@ -42,9 +41,7 @@ class ValidatingNotaryServiceTests {
val stx = run {
val inputState = issueInvalidState(clientNode, notaryNode.info.notaryIdentity)
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
val keyPair = clientNode.services.keyManagementService.toKeyPair(clientNode.info.legalIdentity.owningKey.keys.single())
tx.signWith(keyPair)
tx.toSignedTransaction(false)
clientNode.services.signInitialTransaction(tx)
}
val future = runClient(stx)
@ -60,9 +57,7 @@ class ValidatingNotaryServiceTests {
val command = Command(DummyContract.Commands.Move(), expectedMissingKey)
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState, command)
val keyPair = clientNode.services.keyManagementService.toKeyPair(clientNode.info.legalIdentity.owningKey.keys.single())
tx.signWith(keyPair)
tx.toSignedTransaction(false)
clientNode.services.signInitialTransaction(tx)
}
val ex = assertFailsWith(NotaryException::class) {
@ -85,11 +80,8 @@ class ValidatingNotaryServiceTests {
fun issueState(node: AbstractNode): StateAndRef<*> {
val tx = DummyContract.generateInitial(Random().nextInt(), notaryNode.info.notaryIdentity, node.info.legalIdentity.ref(0))
val nodeKey = node.services.legalIdentityKey
tx.signWith(nodeKey)
val notaryKeyPair = notaryNode.services.notaryIdentityKey
tx.signWith(notaryKeyPair)
val stx = tx.toSignedTransaction()
val signedByNode = node.services.signInitialTransaction(tx)
val stx = notaryNode.services.addSignature(signedByNode, notaryNode.services.notaryIdentityKey)
node.services.recordTransactions(listOf(stx))
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
}

View File

@ -402,7 +402,7 @@ class NodeVaultServiceTest {
fun addNoteToTransaction() {
database.transaction {
val freshKey = services.legalIdentityKey.public
val freshKey = services.legalIdentityKey
// Issue a txn to Send us some Money
val usefulTX = TransactionType.General.Builder(null).apply {

View File

@ -91,9 +91,8 @@ class VaultWithCashTest {
database.transaction {
// A tx that sends us money.
val freshKey = services.keyManagementService.freshKey()
val freshPublicKey = freshKey.public
val usefulTX = TransactionType.General.Builder(null).apply {
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), AnonymousParty(freshPublicKey), DUMMY_NOTARY)
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), AnonymousParty(freshKey), DUMMY_NOTARY)
signWith(MEGA_CORP_KEY)
}.toSignedTransaction()
@ -101,11 +100,11 @@ class VaultWithCashTest {
services.recordTransactions(usefulTX)
// A tx that spends our money.
val spendTX = TransactionType.General.Builder(DUMMY_NOTARY).apply {
val spendTXBuilder = TransactionType.General.Builder(DUMMY_NOTARY).apply {
vault.generateSpend(this, 80.DOLLARS, BOB)
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
}
val spendTX = services.signInitialTransaction(spendTXBuilder, freshKey)
assertEquals(100.DOLLARS, vault.cashBalances[USD])
@ -129,14 +128,13 @@ class VaultWithCashTest {
@Test
fun `issue and attempt double spend`() {
val freshKey = services.keyManagementService.freshKey()
val freshPublicKey = freshKey.public
database.transaction {
// A tx that sends us money.
services.fillWithSomeTestCash(100.DOLLARS, DUMMY_NOTARY, 10, 10, Random(0L),
issuedBy = MEGA_CORP.ref(1),
issuerKey = MEGA_CORP_KEY,
ownedBy = AnonymousParty(freshPublicKey))
ownedBy = AnonymousParty(freshKey))
println("Cash balance: ${vault.cashBalances[USD]}")
assertThat(vault.unconsumedStates<Cash.State>()).hasSize(10)
@ -149,12 +147,12 @@ class VaultWithCashTest {
backgroundExecutor.submit {
database.transaction {
try {
val txn1 =
val txn1Builder =
TransactionType.General.Builder(DUMMY_NOTARY).apply {
vault.generateSpend(this, 60.DOLLARS, BOB)
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
}
val txn1 = services.signInitialTransaction(txn1Builder, freshKey)
println("txn1: ${txn1.id} spent ${((txn1.tx.outputs[0].data) as Cash.State).amount}")
println("""txn1 states:
UNCONSUMED: ${vault.unconsumedStates<Cash.State>().count()} : ${vault.unconsumedStates<Cash.State>()},
@ -181,12 +179,12 @@ class VaultWithCashTest {
backgroundExecutor.submit {
database.transaction {
try {
val txn2 =
val txn2Builder =
TransactionType.General.Builder(DUMMY_NOTARY).apply {
vault.generateSpend(this, 80.DOLLARS, BOB)
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
}
val txn2 = services.signInitialTransaction(txn2Builder, freshKey)
println("txn2: ${txn2.id} spent ${((txn2.tx.outputs[0].data) as Cash.State).amount}")
println("""txn2 states:
UNCONSUMED: ${vault.unconsumedStates<Cash.State>().count()} : ${vault.unconsumedStates<Cash.State>()},
@ -221,17 +219,16 @@ class VaultWithCashTest {
fun `branching LinearStates fails to verify`() {
database.transaction {
val freshKey = services.keyManagementService.freshKey()
val freshPublicKey = freshKey.public
val freshIdentity = AnonymousParty(freshPublicKey)
val freshIdentity = AnonymousParty(freshKey)
val linearId = UniqueIdentifier()
// Issue a linear state
val dummyIssue = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
val dummyIssueBuilder = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)))
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)))
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
}
val dummyIssue = services.signInitialTransaction(dummyIssueBuilder)
assertThatThrownBy {
dummyIssue.toLedgerTransaction(services).verify()
@ -243,17 +240,16 @@ class VaultWithCashTest {
fun `sequencing LinearStates works`() {
database.transaction {
val freshKey = services.keyManagementService.freshKey()
val freshPublicKey = freshKey.public
val freshIdentity = AnonymousParty(freshPublicKey)
val freshIdentity = AnonymousParty(freshKey)
val linearId = UniqueIdentifier()
// Issue a linear state
val dummyIssue = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
val dummyIssueBuilder = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)))
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
}
val dummyIssue = services.signInitialTransaction(dummyIssueBuilder, services.legalIdentityKey)
dummyIssue.toLedgerTransaction(services).verify()
@ -278,9 +274,8 @@ class VaultWithCashTest {
fun `spending cash in vault of mixed state types works`() {
val freshKey = services.keyManagementService.freshKey()
val freshPublicKey = freshKey.public
database.transaction {
services.fillWithSomeTestCash(100.DOLLARS, DUMMY_NOTARY, 3, 3, Random(0L), ownedBy = AnonymousParty(freshPublicKey))
services.fillWithSomeTestCash(100.DOLLARS, DUMMY_NOTARY, 3, 3, Random(0L), ownedBy = AnonymousParty(freshKey))
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>()
@ -293,11 +288,11 @@ class VaultWithCashTest {
database.transaction {
// A tx that spends our money.
val spendTX = TransactionType.General.Builder(DUMMY_NOTARY).apply {
val spendTXBuilder = TransactionType.General.Builder(DUMMY_NOTARY).apply {
vault.generateSpend(this, 80.DOLLARS, BOB)
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
}
val spendTX = services.signInitialTransaction(spendTXBuilder, freshKey)
services.recordTransactions(spendTX)
val consumedStates = vault.consumedStates<ContractState>()
@ -312,8 +307,7 @@ class VaultWithCashTest {
fun `consuming multiple contract state types in same transaction`() {
val freshKey = services.keyManagementService.freshKey()
val freshPublicKey = freshKey.public
val freshIdentity = AnonymousParty(freshPublicKey)
val freshIdentity = AnonymousParty(freshKey)
database.transaction {
services.fillWithSomeTestDeals(listOf("123", "456", "789"))