mirror of
https://github.com/corda/corda.git
synced 2025-06-18 07:08:15 +00:00
Adapt Party comparison to use owningKey
Change Party instances to be uniquely identified by the owning key, without taking into account name. This requires that mock node key generation is reworked so that keys for services and the node itself are distinct, otherwise the network map service cannot differentiate them. Signed-off-by: Ross Nicoll <ross.nicoll@r3.com>
This commit is contained in:
@ -275,16 +275,16 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
}
|
||||
|
||||
private fun makeInfo(): NodeInfo {
|
||||
val services = makeServiceEntries()
|
||||
val advertisedServiceEntries = makeServiceEntries()
|
||||
val legalIdentity = obtainLegalIdentity()
|
||||
return NodeInfo(net.myAddress, legalIdentity, services, findMyLocation())
|
||||
return NodeInfo(net.myAddress, legalIdentity, advertisedServiceEntries, findMyLocation())
|
||||
}
|
||||
|
||||
/**
|
||||
* A service entry contains the advertised [ServiceInfo] along with the service identity. The identity *name* is
|
||||
* taken from the configuration or, if non specified, generated by combining the node's legal name and the service id.
|
||||
*/
|
||||
protected fun makeServiceEntries(): List<ServiceEntry> {
|
||||
protected open fun makeServiceEntries(): List<ServiceEntry> {
|
||||
return advertisedServices.map {
|
||||
val serviceId = it.type.id
|
||||
val serviceName = it.name ?: "$serviceId|${configuration.myLegalName}"
|
||||
|
@ -14,11 +14,14 @@ import net.corda.node.services.network.NetworkMapService
|
||||
import net.corda.node.services.persistence.NodeAttachmentService
|
||||
import net.corda.node.services.transactions.SimpleNotaryService
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import net.i2p.crypto.eddsa.KeyPairGenerator
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.math.BigInteger
|
||||
import java.security.KeyPair
|
||||
import java.security.KeyPairGeneratorSpi
|
||||
import java.util.jar.JarOutputStream
|
||||
import java.util.zip.ZipEntry
|
||||
import kotlin.test.assertEquals
|
||||
@ -84,8 +87,10 @@ class AttachmentTests {
|
||||
// Make a node that doesn't do sanity checking at load time.
|
||||
val n0 = network.createNode(null, -1, object : MockNetwork.Factory {
|
||||
override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?,
|
||||
advertisedServices: Set<ServiceInfo>, id: Int, keyPair: KeyPair?): MockNetwork.MockNode {
|
||||
return object : MockNetwork.MockNode(config, network, networkMapAddr, advertisedServices, id, keyPair) {
|
||||
advertisedServices: Set<ServiceInfo>, id: Int,
|
||||
overrideServices: Map<ServiceInfo, KeyPair>?,
|
||||
entropyRoot: BigInteger): MockNetwork.MockNode {
|
||||
return object : MockNetwork.MockNode(config, network, networkMapAddr, advertisedServices, id, overrideServices, entropyRoot) {
|
||||
override fun start(): MockNetwork.MockNode {
|
||||
super.start()
|
||||
(storage.attachments as NodeAttachmentService).checkAttachmentsOnLoad = false
|
||||
|
@ -20,7 +20,6 @@ import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
import net.corda.core.utilities.DUMMY_NOTARY
|
||||
import net.corda.core.utilities.DUMMY_NOTARY_KEY
|
||||
import net.corda.core.utilities.LogHelper
|
||||
import net.corda.core.utilities.TEST_TX_TIME
|
||||
import net.corda.flows.TwoPartyTradeFlow.Buyer
|
||||
@ -43,6 +42,7 @@ import org.junit.Test
|
||||
import rx.Observable
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.math.BigInteger
|
||||
import java.security.KeyPair
|
||||
import java.util.*
|
||||
import java.util.concurrent.Future
|
||||
@ -60,9 +60,6 @@ import kotlin.test.assertTrue
|
||||
*/
|
||||
class TwoPartyTradeFlowTests {
|
||||
lateinit var net: MockNetwork
|
||||
lateinit var notaryNode: MockNetwork.MockNode
|
||||
lateinit var aliceNode: MockNetwork.MockNode
|
||||
lateinit var bobNode: MockNetwork.MockNode
|
||||
|
||||
@Before
|
||||
fun before() {
|
||||
@ -84,9 +81,9 @@ class TwoPartyTradeFlowTests {
|
||||
net = MockNetwork(false, true)
|
||||
|
||||
ledger {
|
||||
notaryNode = net.createNotaryNode(null, DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
|
||||
aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name, ALICE_KEY)
|
||||
bobNode = net.createPartyNode(notaryNode.info.address, BOB.name, BOB_KEY)
|
||||
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
|
||||
|
||||
@ -99,9 +96,10 @@ class TwoPartyTradeFlowTests {
|
||||
val alicesFakePaper = fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
|
||||
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null, notaryNode.info.notaryIdentity).second
|
||||
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey, notaryKey)
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, aliceKey, notaryKey)
|
||||
|
||||
val (bobStateMachine, aliceResult) = runBuyerAndSeller("alice's paper".outputStateAndRef())
|
||||
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notaryNode, aliceNode, bobNode,
|
||||
"alice's paper".outputStateAndRef())
|
||||
|
||||
// TODO: Verify that the result was inserted into the transaction database.
|
||||
// assertEquals(bobResult.get(), aliceNode.storage.validatedTransactions[aliceResult.get().id])
|
||||
@ -124,9 +122,9 @@ class TwoPartyTradeFlowTests {
|
||||
@Test
|
||||
fun `shutdown and restore`() {
|
||||
ledger {
|
||||
notaryNode = net.createNotaryNode(null, DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
|
||||
aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name, ALICE_KEY)
|
||||
bobNode = net.createPartyNode(notaryNode.info.address, BOB.name, BOB_KEY)
|
||||
val notaryNode = net.createNotaryNode(null, DUMMY_NOTARY.name)
|
||||
val aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name)
|
||||
var bobNode = net.createPartyNode(notaryNode.info.address, BOB.name)
|
||||
aliceNode.disableDBCloseOnStop()
|
||||
bobNode.disableDBCloseOnStop()
|
||||
val aliceKey = aliceNode.services.legalIdentityKey
|
||||
@ -142,8 +140,8 @@ class TwoPartyTradeFlowTests {
|
||||
}
|
||||
val alicesFakePaper = fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
|
||||
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null, notaryNode.info.notaryIdentity).second
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey, notaryKey)
|
||||
val aliceFuture = runBuyerAndSeller("alice's paper".outputStateAndRef()).sellerResult
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, aliceKey, notaryKey)
|
||||
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.
|
||||
// Seller Alice already sent a message to Buyer Bob. Pump once:
|
||||
@ -179,10 +177,11 @@ class TwoPartyTradeFlowTests {
|
||||
// that Bob was waiting on before the reboot occurred.
|
||||
bobNode = net.createNode(networkMapAddr, bobAddr.id, object : MockNetwork.Factory {
|
||||
override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?,
|
||||
advertisedServices: Set<ServiceInfo>, id: Int, keyPair: KeyPair?): MockNetwork.MockNode {
|
||||
return MockNetwork.MockNode(config, network, networkMapAddr, advertisedServices, bobAddr.id, BOB_KEY)
|
||||
advertisedServices: Set<ServiceInfo>, id: Int, overrideServices: Map<ServiceInfo, KeyPair>?,
|
||||
entropyRoot: BigInteger): MockNetwork.MockNode {
|
||||
return MockNetwork.MockNode(config, network, networkMapAddr, advertisedServices, bobAddr.id, overrideServices, entropyRoot)
|
||||
}
|
||||
}, true, BOB.name, BOB_KEY)
|
||||
}, true, BOB.name)
|
||||
|
||||
// Find the future representing the result of this state machine again.
|
||||
val bobFuture = bobNode.smm.findStateMachines(Buyer::class.java).single().second
|
||||
@ -213,12 +212,16 @@ class TwoPartyTradeFlowTests {
|
||||
|
||||
// Creates a mock node with an overridden storage service that uses a RecordingMap, that lets us test the order
|
||||
// of gets and puts.
|
||||
private fun makeNodeWithTracking(networkMapAddr: SingleMessageRecipient?, name: String, keyPair: KeyPair): MockNetwork.MockNode {
|
||||
private fun makeNodeWithTracking(networkMapAddr: SingleMessageRecipient?, name: String, overrideServices: Map<ServiceInfo, KeyPair>? = null): MockNetwork.MockNode {
|
||||
// Create a node in the mock network ...
|
||||
return net.createNode(networkMapAddr, -1, object : MockNetwork.Factory {
|
||||
override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?,
|
||||
advertisedServices: Set<ServiceInfo>, id: Int, keyPair: KeyPair?): MockNetwork.MockNode {
|
||||
return object : MockNetwork.MockNode(config, network, networkMapAddr, advertisedServices, id, keyPair) {
|
||||
override fun create(config: NodeConfiguration,
|
||||
network: MockNetwork,
|
||||
networkMapAddr: SingleMessageRecipient?,
|
||||
advertisedServices: Set<ServiceInfo>, id: Int,
|
||||
overrideServices: Map<ServiceInfo, KeyPair>?,
|
||||
entropyRoot: BigInteger): MockNetwork.MockNode {
|
||||
return object : MockNetwork.MockNode(config, network, networkMapAddr, advertisedServices, id, overrideServices, entropyRoot) {
|
||||
// That constructs the storage service object in a customised way ...
|
||||
override fun constructStorageService(
|
||||
attachments: NodeAttachmentService,
|
||||
@ -229,14 +232,14 @@ class TwoPartyTradeFlowTests {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, true, name, keyPair)
|
||||
}, true, name, overrideServices)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `check dependencies of sale asset are resolved`() {
|
||||
notaryNode = net.createNotaryNode(null, DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
|
||||
aliceNode = makeNodeWithTracking(notaryNode.info.address, ALICE.name, ALICE_KEY)
|
||||
bobNode = makeNodeWithTracking(notaryNode.info.address, BOB.name, BOB_KEY)
|
||||
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) {
|
||||
@ -250,15 +253,18 @@ class TwoPartyTradeFlowTests {
|
||||
}
|
||||
val attachmentID = attachment(ByteArrayInputStream(stream.toByteArray()))
|
||||
|
||||
val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public.composite, notaryNode.info.notaryIdentity).second
|
||||
val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode)
|
||||
val extraKey = bobNode.keyManagement.freshKey()
|
||||
val bobsFakeCash = fillUpForBuyer(false, extraKey.public.composite,
|
||||
DUMMY_CASH_ISSUER.party,
|
||||
notaryNode.info.notaryIdentity).second
|
||||
val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bobNode.services.legalIdentityKey, extraKey)
|
||||
val alicesFakePaper = fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
|
||||
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID, notaryNode.info.notaryIdentity).second
|
||||
val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey)
|
||||
val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, aliceKey)
|
||||
|
||||
net.runNetwork() // Clear network map registration messages
|
||||
|
||||
runBuyerAndSeller("alice's paper".outputStateAndRef())
|
||||
runBuyerAndSeller(notaryNode, aliceNode, bobNode, "alice's paper".outputStateAndRef())
|
||||
|
||||
net.runNetwork()
|
||||
|
||||
@ -326,9 +332,9 @@ class TwoPartyTradeFlowTests {
|
||||
@Test
|
||||
fun `track() works`() {
|
||||
|
||||
notaryNode = net.createNotaryNode(null, DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
|
||||
aliceNode = makeNodeWithTracking(notaryNode.info.address, ALICE.name, ALICE_KEY)
|
||||
bobNode = makeNodeWithTracking(notaryNode.info.address, BOB.name, BOB_KEY)
|
||||
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) {
|
||||
@ -342,11 +348,13 @@ class TwoPartyTradeFlowTests {
|
||||
}
|
||||
val attachmentID = attachment(ByteArrayInputStream(stream.toByteArray()))
|
||||
|
||||
val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public.composite, notaryNode.info.notaryIdentity).second
|
||||
insertFakeTransactions(bobsFakeCash, bobNode)
|
||||
val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public.composite,
|
||||
DUMMY_CASH_ISSUER.party,
|
||||
notaryNode.info.notaryIdentity).second
|
||||
insertFakeTransactions(bobsFakeCash, bobNode, notaryNode)
|
||||
val alicesFakePaper = fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
|
||||
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID, notaryNode.info.notaryIdentity).second
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey)
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, aliceKey)
|
||||
|
||||
net.runNetwork() // Clear network map registration messages
|
||||
|
||||
@ -356,7 +364,8 @@ class TwoPartyTradeFlowTests {
|
||||
val aliceTxMappings = databaseTransaction(aliceNode.database) {
|
||||
aliceMappingsStorage.track().second
|
||||
}
|
||||
val aliceSmId = runBuyerAndSeller("alice's paper".outputStateAndRef()).sellerId
|
||||
val aliceSmId = runBuyerAndSeller(notaryNode, aliceNode, bobNode,
|
||||
"alice's paper".outputStateAndRef()).sellerId
|
||||
|
||||
net.runNetwork()
|
||||
|
||||
@ -412,12 +421,15 @@ class TwoPartyTradeFlowTests {
|
||||
val sellerId: StateMachineRunId
|
||||
)
|
||||
|
||||
private fun runBuyerAndSeller(assetToSell: StateAndRef<OwnableState>): RunResult {
|
||||
val buyerFuture = bobNode.initiateSingleShotFlow(Seller::class) { otherParty ->
|
||||
private fun runBuyerAndSeller(notaryNode: MockNetwork.MockNode,
|
||||
sellerNode: MockNetwork.MockNode,
|
||||
buyerNode: MockNetwork.MockNode,
|
||||
assetToSell: StateAndRef<OwnableState>): RunResult {
|
||||
val buyerFuture = buyerNode.initiateSingleShotFlow(Seller::class) { otherParty ->
|
||||
Buyer(otherParty, notaryNode.info.notaryIdentity, 1000.DOLLARS, CommercialPaper.State::class.java)
|
||||
}.map { it.stateMachine }
|
||||
val seller = Seller(bobNode.info.legalIdentity, notaryNode.info, assetToSell, 1000.DOLLARS, ALICE_KEY)
|
||||
val sellerResultFuture = aliceNode.services.startFlow(seller).resultFuture
|
||||
val seller = Seller(buyerNode.info.legalIdentity, notaryNode.info, assetToSell, 1000.DOLLARS, sellerNode.services.legalIdentityKey)
|
||||
val sellerResultFuture = sellerNode.services.startFlow(seller).resultFuture
|
||||
return RunResult(buyerFuture, sellerResultFuture, seller.stateMachine.id)
|
||||
}
|
||||
|
||||
@ -426,23 +438,24 @@ class TwoPartyTradeFlowTests {
|
||||
aliceError: Boolean,
|
||||
expectedMessageSubstring: String
|
||||
) {
|
||||
notaryNode = net.createNotaryNode(null, DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
|
||||
aliceNode = net.createPartyNode(notaryNode.info.address, ALICE.name, ALICE_KEY)
|
||||
bobNode = net.createPartyNode(notaryNode.info.address, BOB.name, BOB_KEY)
|
||||
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 bobKey = bobNode.services.legalIdentityKey
|
||||
val issuer = MEGA_CORP.ref(1, 2, 3)
|
||||
|
||||
val bobsBadCash = fillUpForBuyer(bobError, bobKey.public.composite, notaryNode.info.notaryIdentity).second
|
||||
val bobsBadCash = fillUpForBuyer(bobError, bobKey.public.composite, DUMMY_CASH_ISSUER.party,
|
||||
notaryNode.info.notaryIdentity).second
|
||||
val alicesFakePaper = fillUpForSeller(aliceError, aliceNode.info.legalIdentity.owningKey,
|
||||
1200.DOLLARS `issued by` issuer, null, notaryNode.info.notaryIdentity).second
|
||||
|
||||
insertFakeTransactions(bobsBadCash, bobNode, bobKey)
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey)
|
||||
insertFakeTransactions(bobsBadCash, bobNode, notaryNode, bobKey)
|
||||
insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, aliceKey)
|
||||
|
||||
net.runNetwork() // Clear network map registration messages
|
||||
|
||||
val (bobStateMachine, aliceResult) = runBuyerAndSeller("alice's paper".outputStateAndRef())
|
||||
val (bobStateMachine, aliceResult) = runBuyerAndSeller(notaryNode, aliceNode, bobNode, "alice's paper".outputStateAndRef())
|
||||
|
||||
net.runNetwork()
|
||||
|
||||
@ -461,9 +474,10 @@ class TwoPartyTradeFlowTests {
|
||||
private fun insertFakeTransactions(
|
||||
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)
|
||||
return databaseTransaction(node.database) {
|
||||
val signed: List<SignedTransaction> = signAll(wtxToSign, extraKeys.toList() + DUMMY_CASH_ISSUER_KEY)
|
||||
node.services.recordTransactions(signed)
|
||||
val validatedTransactions = node.services.storageService.validatedTransactions
|
||||
if (validatedTransactions is RecordingTransactionStorage) {
|
||||
@ -475,20 +489,21 @@ class TwoPartyTradeFlowTests {
|
||||
|
||||
private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForBuyer(
|
||||
withError: Boolean,
|
||||
owner: CompositeKey = BOB_PUBKEY,
|
||||
owner: CompositeKey,
|
||||
issuer: Party,
|
||||
notary: Party): Pair<Vault, List<WireTransaction>> {
|
||||
val issuer = DUMMY_CASH_ISSUER
|
||||
val interimOwnerKey = MEGA_CORP_PUBKEY
|
||||
// Bob (Buyer) has some cash he got from the Bank of Elbonia, Alice (Seller) has some commercial paper she
|
||||
// wants to sell to Bob.
|
||||
val eb1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
||||
// Issued money to itself.
|
||||
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 }
|
||||
output("elbonian money 1", notary = notary) { 800.DOLLARS.CASH `issued by` issuer `owned by` interimOwnerKey }
|
||||
output("elbonian money 2", notary = notary) { 1000.DOLLARS.CASH `issued by` issuer `owned by` interimOwnerKey }
|
||||
if (!withError) {
|
||||
command(DUMMY_CASH_ISSUER_KEY.public.composite) { Cash.Commands.Issue() }
|
||||
command(issuer.owningKey) { Cash.Commands.Issue() }
|
||||
} else {
|
||||
// Put a broken command on so at least a signature is created
|
||||
command(DUMMY_CASH_ISSUER_KEY.public.composite) { Cash.Commands.Move() }
|
||||
command(issuer.owningKey) { Cash.Commands.Move() }
|
||||
}
|
||||
timestamp(TEST_TX_TIME)
|
||||
if (withError) {
|
||||
@ -502,15 +517,15 @@ class TwoPartyTradeFlowTests {
|
||||
val bc1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
||||
input("elbonian money 1")
|
||||
output("bob cash 1", notary = notary) { 800.DOLLARS.CASH `issued by` issuer `owned by` owner }
|
||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
||||
command(interimOwnerKey) { Cash.Commands.Move() }
|
||||
this.verifies()
|
||||
}
|
||||
|
||||
val bc2 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
|
||||
input("elbonian money 2")
|
||||
output("bob cash 2", notary = notary) { 300.DOLLARS.CASH `issued by` issuer `owned by` owner }
|
||||
output(notary = notary) { 700.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } // Change output.
|
||||
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
|
||||
output(notary = notary) { 700.DOLLARS.CASH `issued by` issuer `owned by` interimOwnerKey } // Change output.
|
||||
command(interimOwnerKey) { Cash.Commands.Move() }
|
||||
this.verifies()
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package net.corda.node.services
|
||||
|
||||
import net.corda.core.crypto.composite
|
||||
import net.corda.core.crypto.generateKeyPair
|
||||
import net.corda.core.getOrThrow
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.node.services.network.NetworkMapService
|
||||
@ -9,6 +7,7 @@ import net.corda.node.utilities.databaseTransaction
|
||||
import net.corda.testing.expect
|
||||
import net.corda.testing.node.MockNetwork
|
||||
import org.junit.Test
|
||||
import java.math.BigInteger
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class InMemoryNetworkMapCacheTest {
|
||||
@ -24,19 +23,23 @@ class InMemoryNetworkMapCacheTest {
|
||||
|
||||
@Test
|
||||
fun `key collision`() {
|
||||
val keyPair = generateKeyPair()
|
||||
val nodeA = network.createNode(null, -1, MockNetwork.DefaultFactory, true, "Node A", keyPair, ServiceInfo(NetworkMapService.type))
|
||||
val nodeB = network.createNode(null, -1, MockNetwork.DefaultFactory, true, "Node B", keyPair, ServiceInfo(NetworkMapService.type))
|
||||
val entropy = BigInteger.valueOf(24012017L)
|
||||
val nodeA = network.createNode(null, -1, MockNetwork.DefaultFactory, true, "Node A", null, entropy, ServiceInfo(NetworkMapService.type))
|
||||
val nodeB = network.createNode(null, -1, MockNetwork.DefaultFactory, true, "Node B", null, entropy, ServiceInfo(NetworkMapService.type))
|
||||
assertEquals(nodeA.info.legalIdentity, nodeB.info.legalIdentity)
|
||||
|
||||
// Node A currently knows only about itself, so this returns node A
|
||||
assertEquals(nodeA.netMapCache.getNodeByLegalIdentityKey(keyPair.public.composite), nodeA.info)
|
||||
assertEquals(nodeA.netMapCache.getNodeByLegalIdentityKey(nodeA.info.legalIdentity.owningKey), nodeA.info)
|
||||
|
||||
databaseTransaction(nodeA.database) {
|
||||
nodeA.netMapCache.addNode(nodeB.info)
|
||||
}
|
||||
// Now both nodes match, so it throws an error
|
||||
expect<IllegalStateException> {
|
||||
nodeA.netMapCache.getNodeByLegalIdentityKey(keyPair.public.composite)
|
||||
nodeA.netMapCache.getNodeByLegalIdentityKey(nodeA.info.legalIdentity.owningKey)
|
||||
}
|
||||
expect<IllegalStateException> {
|
||||
nodeA.netMapCache.getNodeByLegalIdentityKey(nodeB.info.legalIdentity.owningKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ class NotaryChangeTests {
|
||||
net = MockNetwork()
|
||||
oldNotaryNode = net.createNode(
|
||||
legalName = DUMMY_NOTARY.name,
|
||||
keyPair = DUMMY_NOTARY_KEY,
|
||||
advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)))
|
||||
clientNodeA = net.createNode(networkMapAddress = oldNotaryNode.info.address)
|
||||
clientNodeB = net.createNode(networkMapAddress = oldNotaryNode.info.address)
|
||||
|
@ -23,6 +23,7 @@ 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
|
||||
@ -32,14 +33,15 @@ 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()
|
||||
notaryNode = net.createNode(
|
||||
legalName = DUMMY_NOTARY.name,
|
||||
keyPair = DUMMY_NOTARY_KEY,
|
||||
advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)))
|
||||
clientNode = net.createNode(networkMapAddress = notaryNode.info.address, keyPair = MINI_CORP_KEY)
|
||||
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,7 +50,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(clientNode.keyPair!!)
|
||||
tx.signWith(clientKeyPair)
|
||||
tx.toSignedTransaction(false)
|
||||
}
|
||||
|
||||
@ -61,7 +63,7 @@ class NotaryServiceTests {
|
||||
val stx = run {
|
||||
val inputState = issueState(clientNode)
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
tx.signWith(clientNode.keyPair!!)
|
||||
tx.signWith(clientKeyPair)
|
||||
tx.toSignedTransaction(false)
|
||||
}
|
||||
|
||||
@ -75,7 +77,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(clientNode.keyPair!!)
|
||||
tx.signWith(clientKeyPair)
|
||||
tx.toSignedTransaction(false)
|
||||
}
|
||||
|
||||
@ -89,7 +91,7 @@ class NotaryServiceTests {
|
||||
val stx = run {
|
||||
val inputState = issueState(clientNode)
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
tx.signWith(clientNode.keyPair!!)
|
||||
tx.signWith(clientKeyPair)
|
||||
tx.toSignedTransaction(false)
|
||||
}
|
||||
|
||||
@ -107,13 +109,13 @@ class NotaryServiceTests {
|
||||
val inputState = issueState(clientNode)
|
||||
val stx = run {
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
tx.signWith(clientNode.keyPair!!)
|
||||
tx.signWith(clientKeyPair)
|
||||
tx.toSignedTransaction(false)
|
||||
}
|
||||
val stx2 = run {
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
tx.addInputState(issueState(clientNode))
|
||||
tx.signWith(clientNode.keyPair!!)
|
||||
tx.signWith(clientKeyPair)
|
||||
tx.toSignedTransaction(false)
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,9 @@ import net.corda.testing.node.MockNetwork
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import java.math.BigInteger
|
||||
import java.security.KeyPair
|
||||
import java.security.KeyPairGeneratorSpi
|
||||
|
||||
/**
|
||||
* This class mirrors [InMemoryNetworkMapServiceTest] but switches in a [PersistentNetworkMapService] and
|
||||
@ -55,8 +57,10 @@ class PersistentNetworkMapServiceTest : AbstractNetworkMapServiceTest() {
|
||||
|
||||
private object NodeFactory : MockNetwork.Factory {
|
||||
override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?,
|
||||
advertisedServices: Set<ServiceInfo>, id: Int, keyPair: KeyPair?): MockNetwork.MockNode {
|
||||
return object : MockNetwork.MockNode(config, network, networkMapAddr, advertisedServices, id, keyPair) {
|
||||
advertisedServices: Set<ServiceInfo>, id: Int,
|
||||
overrideServices: Map<ServiceInfo, KeyPair>?,
|
||||
entropyRoot: BigInteger): MockNetwork.MockNode {
|
||||
return object : MockNetwork.MockNode(config, network, networkMapAddr, advertisedServices, id, overrideServices, entropyRoot) {
|
||||
|
||||
override fun makeNetworkMapService() {
|
||||
inNodeNetworkMapService = SwizzleNetworkMapService(services)
|
||||
|
@ -98,7 +98,6 @@ class ScheduledFlowTests {
|
||||
net = MockNetwork(threadPerNode = true)
|
||||
notaryNode = net.createNode(
|
||||
legalName = DUMMY_NOTARY.name,
|
||||
keyPair = DUMMY_NOTARY_KEY,
|
||||
advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(ValidatingNotaryService.type)))
|
||||
nodeA = net.createNode(notaryNode.info.address, start = false)
|
||||
nodeB = net.createNode(notaryNode.info.address, start = false)
|
||||
|
@ -34,10 +34,9 @@ class ValidatingNotaryServiceTests {
|
||||
net = MockNetwork()
|
||||
notaryNode = net.createNode(
|
||||
legalName = DUMMY_NOTARY.name,
|
||||
keyPair = DUMMY_NOTARY_KEY,
|
||||
advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(ValidatingNotaryService.type))
|
||||
)
|
||||
clientNode = net.createNode(networkMapAddress = notaryNode.info.address, keyPair = MINI_CORP_KEY)
|
||||
clientNode = net.createNode(networkMapAddress = notaryNode.info.address)
|
||||
net.runNetwork() // Clear network map registration messages
|
||||
}
|
||||
|
||||
@ -45,7 +44,8 @@ class ValidatingNotaryServiceTests {
|
||||
val stx = run {
|
||||
val inputState = issueInvalidState(clientNode, notaryNode.info.notaryIdentity)
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
tx.signWith(clientNode.keyPair!!)
|
||||
val keyPair = clientNode.services.keyManagementService.toKeyPair(clientNode.info.legalIdentity.owningKey.keys.single())
|
||||
tx.signWith(keyPair)
|
||||
tx.toSignedTransaction(false)
|
||||
}
|
||||
|
||||
@ -62,7 +62,8 @@ class ValidatingNotaryServiceTests {
|
||||
|
||||
val command = Command(DummyContract.Commands.Move(), expectedMissingKey)
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState, command)
|
||||
tx.signWith(clientNode.keyPair!!)
|
||||
val keyPair = clientNode.services.keyManagementService.toKeyPair(clientNode.info.legalIdentity.owningKey.keys.single())
|
||||
tx.signWith(keyPair)
|
||||
tx.toSignedTransaction(false)
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@ import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.getOrThrow
|
||||
import net.corda.core.map
|
||||
import net.corda.core.messaging.MessageRecipients
|
||||
import net.corda.core.node.services.PartyInfo
|
||||
import net.corda.core.node.services.ServiceInfo
|
||||
import net.corda.core.random63BitValue
|
||||
import net.corda.core.rootCause
|
||||
import net.corda.core.serialization.OpaqueBytes
|
||||
@ -21,6 +23,7 @@ import net.corda.flows.CashCommand
|
||||
import net.corda.flows.CashFlow
|
||||
import net.corda.flows.NotaryFlow
|
||||
import net.corda.node.services.persistence.checkpoints
|
||||
import net.corda.node.services.transactions.ValidatingNotaryService
|
||||
import net.corda.node.utilities.databaseTransaction
|
||||
import net.corda.testing.expect
|
||||
import net.corda.testing.expectEvents
|
||||
@ -55,10 +58,12 @@ class StateMachineManagerTests {
|
||||
node1 = nodes.first
|
||||
node2 = nodes.second
|
||||
val notaryKeyPair = generateKeyPair()
|
||||
val notaryService = ServiceInfo(ValidatingNotaryService.type, "notary-service-2000")
|
||||
val overrideServices = mapOf(Pair(notaryService, notaryKeyPair))
|
||||
// Note that these notaries don't operate correctly as they don't share their state. They are only used for testing
|
||||
// service addressing.
|
||||
notary1 = net.createNotaryNode(networkMapAddr = node1.services.myInfo.address, keyPair = notaryKeyPair, serviceName = "notary-service-2000")
|
||||
notary2 = net.createNotaryNode(networkMapAddr = node1.services.myInfo.address, keyPair = notaryKeyPair, serviceName = "notary-service-2000")
|
||||
notary1 = net.createNotaryNode(networkMapAddr = node1.services.myInfo.address, overrideServices = overrideServices, serviceName = "notary-service-2000")
|
||||
notary2 = net.createNotaryNode(networkMapAddr = node1.services.myInfo.address, overrideServices = overrideServices, serviceName = "notary-service-2000")
|
||||
|
||||
net.messagingNetwork.receivedMessages.toSessionTransfers().forEach { sessionTransfers += it }
|
||||
net.runNetwork()
|
||||
@ -321,6 +326,8 @@ class StateMachineManagerTests {
|
||||
net.runNetwork()
|
||||
}
|
||||
val endpoint = net.messagingNetwork.endpoint(notary1.net.myAddress as InMemoryMessagingNetwork.PeerHandle)!!
|
||||
val party1Info = notary1.services.networkMapCache.getPartyInfo(notary1.info.notaryIdentity)!!
|
||||
assert(party1Info is PartyInfo.Service)
|
||||
val notary1Address: MessageRecipients = endpoint.getAddressOfParty(notary1.services.networkMapCache.getPartyInfo(notary1.info.notaryIdentity)!!)
|
||||
assert(notary1Address is InMemoryMessagingNetwork.ServiceHandle)
|
||||
assertEquals(notary1Address, endpoint.getAddressOfParty(notary2.services.networkMapCache.getPartyInfo(notary2.info.notaryIdentity)!!))
|
||||
|
Reference in New Issue
Block a user