Merged in mnesbit-fix-irs (pull request #399)

Fix IRS Demo by giving advertised services an identity
This commit is contained in:
Matthew Nesbit 2016-10-07 14:03:27 +01:00
commit 7a440d890d
64 changed files with 463 additions and 325 deletions

View File

@ -44,7 +44,7 @@ class NodeMonitorModelTest {
thread {
driver {
val aliceNodeFuture = startNode("Alice")
val notaryNodeFuture = startNode("Notary", advertisedServices = setOf(ServiceInfo(SimpleNotaryService.Type)))
val notaryNodeFuture = startNode("Notary", advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)))
aliceNode = aliceNodeFuture.get()
notaryNode = notaryNodeFuture.get()
@ -79,8 +79,8 @@ class NodeMonitorModelTest {
clientToService.onNext(ClientToServiceCommand.IssueCash(
amount = Amount(100, USD),
issueRef = OpaqueBytes(ByteArray(1, { 1 })),
recipient = aliceNode.identity,
notary = notaryNode.identity
recipient = aliceNode.legalIdentity,
notary = notaryNode.notaryIdentity
))
vaultUpdates.expectEvents(isStrict = false) {
@ -105,13 +105,13 @@ class NodeMonitorModelTest {
clientToService.onNext(ClientToServiceCommand.IssueCash(
amount = Amount(100, USD),
issueRef = OpaqueBytes(ByteArray(1, { 1 })),
recipient = aliceNode.identity,
notary = notaryNode.identity
recipient = aliceNode.legalIdentity,
notary = notaryNode.notaryIdentity
))
clientToService.onNext(ClientToServiceCommand.PayCash(
amount = Amount(100, Issued(PartyAndReference(aliceNode.identity, OpaqueBytes(ByteArray(1, { 1 }))), USD)),
recipient = aliceNode.identity
amount = Amount(100, Issued(PartyAndReference(aliceNode.legalIdentity, OpaqueBytes(ByteArray(1, { 1 }))), USD)),
recipient = aliceNode.legalIdentity
))
var issueSmId: StateMachineRunId? = null
@ -146,7 +146,7 @@ class NodeMonitorModelTest {
val signaturePubKeys = tx.sigs.map { it.by }.toSet()
// Only Alice signed
require(signaturePubKeys.size == 1)
require(signaturePubKeys.contains(aliceNode.identity.owningKey))
require(signaturePubKeys.contains(aliceNode.legalIdentity.owningKey))
issueTx = tx
},
// MOVE
@ -156,8 +156,8 @@ class NodeMonitorModelTest {
val signaturePubKeys = tx.sigs.map { it.by }.toSet()
// Alice and Notary signed
require(signaturePubKeys.size == 2)
require(signaturePubKeys.contains(aliceNode.identity.owningKey))
require(signaturePubKeys.contains(notaryNode.identity.owningKey))
require(signaturePubKeys.contains(aliceNode.legalIdentity.owningKey))
require(signaturePubKeys.contains(notaryNode.notaryIdentity.owningKey))
moveTx = tx
}
)

View File

@ -188,7 +188,9 @@ class FloatingRatePaymentEvent(date: LocalDate,
class InterestRateSwap() : Contract {
override val legalContractReference = SecureHash.sha256("is_this_the_text_of_the_contract ? TBD")
object OracleType : ServiceType("corda.interest_rates")
companion object {
val oracleType = ServiceType.corda.getSubType("interest_rates")
}
/**
* This Common area contains all the information that is not leg specific.
@ -657,7 +659,7 @@ class InterestRateSwap() : Contract {
override val contract = IRS_PROGRAM_ID
override val oracleType: ServiceType
get() = OracleType
get() = InterestRateSwap.oracleType
override val ref = common.tradeID

View File

@ -37,7 +37,7 @@ fun ServiceHub.fillWithSomeTestCash(howMuch: Amount<Currency>,
ownedBy: PublicKey? = null): Vault {
val amounts = calculateRandomlySizedAmounts(howMuch, atLeastThisManyStates, atMostThisManyStates, rng)
val myKey: PublicKey = ownedBy ?: storageService.myLegalIdentityKey.public
val myKey: PublicKey = ownedBy ?: myInfo.legalIdentity.owningKey
// We will allocate one state to one transaction, for simplicities sake.
val cash = Cash()

View File

@ -8,6 +8,7 @@ import com.r3corda.core.crypto.DigitalSignature
import com.r3corda.core.crypto.Party
import com.r3corda.core.crypto.signWithECDSA
import com.r3corda.core.node.NodeInfo
import com.r3corda.core.node.services.ServiceType
import com.r3corda.core.protocols.ProtocolLogic
import com.r3corda.core.seconds
import com.r3corda.core.transactions.SignedTransaction
@ -113,7 +114,7 @@ object TwoPartyTradeProtocol {
progressTracker.nextStep()
// Check that the tx proposed by the buyer is valid.
val wtx: WireTransaction = it.verifySignatures(myKeyPair.public, notaryNode.identity.owningKey)
val wtx: WireTransaction = it.verifySignatures(myKeyPair.public, notaryNode.notaryIdentity.owningKey)
logger.trace { "Received partially signed transaction: ${it.id}" }
// Download and check all the things that this transaction depends on and verify it is contract-valid,

View File

@ -211,7 +211,7 @@ class CommercialPaperTestsGeneric {
// BigCorp™ issues $10,000 of commercial paper, to mature in 30 days, owned initially by itself.
val faceValue = 10000.DOLLARS `issued by` DUMMY_CASH_ISSUER
val issuance = bigCorpServices.storageService.myLegalIdentity.ref(1)
val issuance = bigCorpServices.myInfo.legalIdentity.ref(1)
val issueTX: SignedTransaction =
CommercialPaper().generateIssue(issuance, faceValue, TEST_TX_TIME + 30.days, DUMMY_NOTARY).apply {
setTime(TEST_TX_TIME, 30.seconds)

View File

@ -3,10 +3,21 @@ package com.r3corda.core.node
import com.r3corda.core.crypto.Party
import com.r3corda.core.messaging.SingleMessageRecipient
import com.r3corda.core.node.services.ServiceInfo
import com.r3corda.core.node.services.ServiceType
/**
* Information for an advertised service including the service specific identity information.
* The identity can be used in protocols and is distinct from the Node's legalIdentity
*/
data class ServiceEntry(val info: ServiceInfo, val identity: Party)
/**
* Info about a network node that acts on behalf of some form of contract party.
*/
data class NodeInfo(val address: SingleMessageRecipient, val identity: Party,
var advertisedServices: Set<ServiceInfo> = emptySet(),
val physicalLocation: PhysicalLocation? = null)
data class NodeInfo(val address: SingleMessageRecipient,
val legalIdentity: Party,
var advertisedServices: List<ServiceEntry> = emptyList(),
val physicalLocation: PhysicalLocation? = null) {
val notaryIdentity: Party get() = advertisedServices.single { it.info.type.isNotary() }.identity
fun serviceIdentities(type: ServiceType): List<Party> = advertisedServices.filter { it.info.type.isSubTypeOf(type) }.map { it.identity }
}

View File

@ -8,6 +8,7 @@ import com.r3corda.core.contracts.TransactionState
import com.r3corda.core.messaging.MessagingService
import com.r3corda.core.node.services.*
import com.r3corda.core.protocols.ProtocolLogic
import java.security.KeyPair
import java.time.Clock
/**
@ -27,6 +28,7 @@ interface ServiceHub {
val networkMapCache: NetworkMapCache
val schedulerService: SchedulerService
val clock: Clock
val myInfo: NodeInfo
/**
* Given a list of [SignedTransaction]s, writes them to the local storage for validated transactions and then
@ -52,6 +54,23 @@ interface ServiceHub {
* @throws IllegalProtocolLogicException or IllegalArgumentException if there are problems with the [logicType] or [args].
*/
fun <T : Any> invokeProtocolAsync(logicType: Class<out ProtocolLogic<T>>, vararg args: Any?): ListenableFuture<T>
/**
* Helper property to shorten code for fetching the Node's KeyPair associated with the
* public legalIdentity Party from the key management service.
* Typical use is during signing in protocols and for unit test signing.
*/
val legalIdentityKey: KeyPair get() = this.keyManagementService.toKeyPair(this.myInfo.legalIdentity.owningKey)
/**
* Helper property to shorten code for fetching the Node's KeyPair associated with the
* public notaryIdentity Party from the key management service. It is assumed that this is only
* used in contexts where the Node knows it is hosting a Notary Service. Otherwise, it will throw
* an IllegalArgumentException.
* Typical use is during signing in protocols and for unit test signing.
*/
val notaryIdentityKey: KeyPair get() = this.keyManagementService.toKeyPair(this.myInfo.notaryIdentity.owningKey)
}
/**
* Given some [SignedTransaction]s, writes them to the local storage for validated transactions and then

View File

@ -3,7 +3,7 @@ package com.r3corda.core.node.services
/**
* A container for additional information for an advertised service.
*
* @param ServiceType the service type identifier
* @param type the ServiceType identifier
* @param name the service name, used for differentiating multiple services of the same type. Can also be used as a
* grouping identifier for nodes collectively running a distributed service.
*/
@ -12,7 +12,7 @@ data class ServiceInfo(val type: ServiceType, val name: String? = null) {
fun parse(encoded: String): ServiceInfo {
val parts = encoded.split("|")
require(parts.size > 0 && parts.size <= 2) { "Invalid number of elements found" }
val type = object : ServiceType(parts[0]) {}
val type = ServiceType.parse(parts[0])
val name = parts.getOrNull(1)
return ServiceInfo(type, name)
}

View File

@ -5,7 +5,7 @@ package com.r3corda.core.node.services
* map advertisements. Services that are purely local and are not providing functionality to other parts of the network
* don't need a declared service type.
*/
abstract class ServiceType(val id: String) {
sealed class ServiceType(val id: String) {
init {
// Enforce:
//
@ -14,14 +14,41 @@ abstract class ServiceType(val id: String) {
require(id.matches(Regex("[a-z][a-zA-Z0-9._]+")))
}
override operator fun equals(other: Any?): Boolean =
if (other is ServiceType) {
id == other.id
} else {
false
private class ServiceTypeImpl(baseId: String, subTypeId: String) : ServiceType("$baseId.$subTypeId") {
init {
// only allowed one level of subtype
require(subTypeId.matches(Regex("[a-z]\\w+")))
}
}
private class ServiceTypeDirect(id: String) : ServiceType(id)
companion object {
val corda: ServiceType
get() {
val stack = Throwable().stackTrace
val caller = stack.first().className
require(caller.startsWith("com.r3corda.")) { "Corda ServiceType namespace is reserved for Corda core components" }
return ServiceTypeDirect("corda")
}
val notary: ServiceType = corda.getSubType("notary")
val regulator: ServiceType = corda.getSubType("regulator")
fun getServiceType(namespace: String, typeId: String): ServiceType {
require(!namespace.startsWith("corda")) { "Corda namespace is protected" }
return ServiceTypeImpl(namespace, typeId)
}
fun parse(id: String): ServiceType = ServiceTypeDirect(id)
}
fun getSubType(subTypeId: String): ServiceType = ServiceTypeImpl(id, subTypeId)
override operator fun equals(other: Any?): Boolean = (other is ServiceType) && (other.id == this.id)
fun isSubTypeOf(superType: ServiceType) = (id == superType.id) || id.startsWith(superType.id + ".")
fun isNotary() = isSubTypeOf(notary)
override fun hashCode(): Int = id.hashCode()
override fun toString(): String = id.toString()

View File

@ -191,14 +191,6 @@ interface StorageService {
val attachments: AttachmentStorage
val stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage
/**
* Returns the legal identity that this node is configured with. Assumed to be initialised when the node is
* first installed.
*/
//TODO this should be in the IdentityService, or somewhere not here
val myLegalIdentity: Party
val myLegalIdentityKey: KeyPair
}
/**

View File

@ -52,7 +52,7 @@ abstract class AbstractStateReplacementProtocol<T> {
progressTracker.currentStep = SIGNING
val myKey = serviceHub.storageService.myLegalIdentity.owningKey
val myKey = serviceHub.myInfo.legalIdentity.owningKey
val me = listOf(myKey)
val signatures = if (participants == me) {
@ -74,7 +74,7 @@ abstract class AbstractStateReplacementProtocol<T> {
val parties = participants.map {
val participantNode = serviceHub.networkMapCache.getNodeByPublicKey(it) ?:
throw IllegalStateException("Participant $it to state $originalState not found on the network")
participantNode.identity
participantNode.legalIdentity
}
val participantSignatures = parties.map { getParticipantSignature(it, stx) }
@ -134,7 +134,7 @@ abstract class AbstractStateReplacementProtocol<T> {
// TODO: catch only specific exceptions. However, there are numerous validation exceptions
// that might occur (tx validation/resolution, invalid proposal). Need to rethink how
// we manage exceptions and maybe introduce some platform exception hierarchy
val myIdentity = serviceHub.storageService.myLegalIdentity
val myIdentity = serviceHub.myInfo.legalIdentity
val state = maybeProposal.unwrap { it.stateRef }
val reason = StateReplacementRefused(myIdentity, state, e.message)
@ -186,7 +186,7 @@ abstract class AbstractStateReplacementProtocol<T> {
private fun checkMySignatureRequired(tx: WireTransaction) {
// TODO: use keys from the keyManagementService instead
val myKey = serviceHub.storageService.myLegalIdentity.owningKey
val myKey = serviceHub.myInfo.legalIdentity.owningKey
require(myKey in tx.mustSign) { "Party is not a participant for any of the input states of transaction ${tx.id}" }
}
@ -195,7 +195,10 @@ abstract class AbstractStateReplacementProtocol<T> {
subProtocol(ResolveTransactionsProtocol(stx.tx, otherSide))
}
private fun sign(stx: SignedTransaction) = serviceHub.storageService.myLegalIdentityKey.signWithECDSA(stx.txBits)
private fun sign(stx: SignedTransaction): DigitalSignature.WithKey {
val myKey = serviceHub.legalIdentityKey
return myKey.signWithECDSA(stx.txBits)
}
}
// TODO: similar classes occur in other places (NotaryProtocol), need to consolidate

View File

@ -34,7 +34,7 @@ class BroadcastTransactionProtocol(val notarisedTransaction: SignedTransaction,
// TODO: Messaging layer should handle this broadcast for us
val msg = NotifyTxRequest(notarisedTransaction, events)
participants.filter { it != serviceHub.storageService.myLegalIdentity }.forEach { participant ->
participants.filter { it != serviceHub.myInfo.legalIdentity }.forEach { participant ->
send(participant, msg)
}
}

View File

@ -41,7 +41,8 @@ object NotaryChangeProtocol: AbstractStateReplacementProtocol<Party>() {
val newState = state.withNotary(modification)
val participants = state.data.participants
val tx = TransactionType.NotaryChange.Builder(originalState.state.notary).withItems(originalState, newState)
tx.signWith(serviceHub.storageService.myLegalIdentityKey)
val myKey = serviceHub.legalIdentityKey
tx.signWith(myKey)
val stx = tx.toSignedTransaction(false)
return Pair(stx, participants)
@ -63,7 +64,7 @@ object NotaryChangeProtocol: AbstractStateReplacementProtocol<Party>() {
override fun verifyProposal(maybeProposal: UntrustworthyData<AbstractStateReplacementProtocol.Proposal<Party>>): AbstractStateReplacementProtocol.Proposal<Party> {
return maybeProposal.unwrap { proposal ->
val newNotary = proposal.modification
val isNotary = serviceHub.networkMapCache.notaryNodes.any { it.identity == newNotary }
val isNotary = serviceHub.networkMapCache.notaryNodes.any { it.notaryIdentity == newNotary }
require(isNotary) { "The proposed node $newNotary does not run a Notary service " }
val state = proposal.stateRef

View File

@ -49,7 +49,7 @@ object NotaryProtocol {
"Input states must have the same Notary"
}
val request = SignRequest(stx, serviceHub.storageService.myLegalIdentity)
val request = SignRequest(stx, serviceHub.myInfo.legalIdentity)
val response = sendAndReceive<Result>(notaryParty, request)
return validateResponse(response)
@ -141,8 +141,9 @@ object NotaryProtocol {
}
private fun <T : Any> sign(bits: SerializedBytes<T>): DigitalSignature.LegallyIdentifiable {
val mySigningKey = serviceHub.storageService.myLegalIdentityKey
val myIdentity = serviceHub.storageService.myLegalIdentity
val myNodeInfo = serviceHub.myInfo
val myIdentity = myNodeInfo.notaryIdentity
val mySigningKey = serviceHub.notaryIdentityKey
return mySigningKey.signWithECDSA(bits, myIdentity)
}
}

View File

@ -78,7 +78,7 @@ object TwoPartyDealProtocol {
abstract val myKeyPair: KeyPair
override fun getCounterpartyMarker(party: Party): Class<*> {
return if (serviceHub.networkMapCache.regulators.any { it.identity == party }) {
return if (serviceHub.networkMapCache.regulators.any { it.legalIdentity == party }) {
MarkerForBogusRegulatorProtocol::class.java
} else {
super.getCounterpartyMarker(party)
@ -104,7 +104,7 @@ object TwoPartyDealProtocol {
progressTracker.nextStep()
// Check that the tx proposed by the buyer is valid.
val wtx: WireTransaction = stx.verifySignatures(myKeyPair.public, notaryNode.identity.owningKey)
val wtx: WireTransaction = stx.verifySignatures(myKeyPair.public, notaryNode.notaryIdentity.owningKey)
logger.trace { "Received partially signed transaction: ${stx.id}" }
checkDependencies(stx)
@ -155,7 +155,7 @@ object TwoPartyDealProtocol {
if (regulators.isNotEmpty()) {
// Copy the transaction to every regulator in the network. This is obviously completely bogus, it's
// just for demo purposes.
regulators.forEach { send(it.identity, fullySigned) }
regulators.forEach { send(it.serviceIdentities(ServiceType.regulator).first(), fullySigned) }
}
return fullySigned
@ -277,7 +277,7 @@ object TwoPartyDealProtocol {
override val progressTracker: ProgressTracker = Primary.tracker()) : Primary() {
override val notaryNode: NodeInfo get() =
serviceHub.networkMapCache.notaryNodes.filter { it.identity == payload.notary }.single()
serviceHub.networkMapCache.notaryNodes.filter { it.notaryIdentity == payload.notary }.single()
}
/**
@ -301,7 +301,7 @@ object TwoPartyDealProtocol {
// And add a request for timestamping: it may be that none of the contracts need this! But it can't hurt
// to have one.
ptx.setTime(serviceHub.clock.instant(), 30.seconds)
return Pair(ptx, arrayListOf(deal.parties.single { it.name == serviceHub.storageService.myLegalIdentity.name }.owningKey))
return Pair(ptx, arrayListOf(deal.parties.single { it.name == serviceHub.myInfo.legalIdentity.name }.owningKey))
}
}
@ -326,7 +326,7 @@ object TwoPartyDealProtocol {
// validate the party that initiated is the one on the deal and that the recipient corresponds with it.
// TODO: this is in no way secure and will be replaced by general session initiation logic in the future
val myName = serviceHub.storageService.myLegalIdentity.name
val myName = serviceHub.myInfo.legalIdentity.name
// Also check we are one of the parties
deal.parties.filter { it.name == myName }.single()
@ -339,7 +339,7 @@ object TwoPartyDealProtocol {
val fixOf = deal.nextFixingOf()!!
// TODO Do we need/want to substitute in new public keys for the Parties?
val myName = serviceHub.storageService.myLegalIdentity.name
val myName = serviceHub.myInfo.legalIdentity.name
val myOldParty = deal.parties.single { it.name == myName }
val newDeal = deal
@ -348,7 +348,7 @@ object TwoPartyDealProtocol {
val oracle = serviceHub.networkMapCache.get(handshake.payload.oracleType).first()
val addFixing = object : RatesFixProtocol(ptx, oracle.identity, fixOf, BigDecimal.ZERO, BigDecimal.ONE) {
val addFixing = object : RatesFixProtocol(ptx, oracle.serviceIdentities(handshake.payload.oracleType).first(), fixOf, BigDecimal.ZERO, BigDecimal.ONE) {
@Suspendable
override fun beforeSigning(fix: Fix) {
newDeal.generateFix(ptx, StateAndRef(txState, handshake.payload.ref), fix)
@ -381,13 +381,13 @@ object TwoPartyDealProtocol {
}
override val myKeyPair: KeyPair get() {
val myName = serviceHub.storageService.myLegalIdentity.name
val myName = serviceHub.myInfo.legalIdentity.name
val publicKey = dealToFix.state.data.parties.filter { it.name == myName }.single().owningKey
return serviceHub.keyManagementService.toKeyPair(publicKey)
}
override val notaryNode: NodeInfo get() =
serviceHub.networkMapCache.notaryNodes.filter { it.identity == dealToFix.state.notary }.single()
serviceHub.networkMapCache.notaryNodes.filter { it.notaryIdentity == dealToFix.state.notary }.single()
}
@ -419,7 +419,7 @@ object TwoPartyDealProtocol {
// TODO: this is not the eventual mechanism for identifying the parties
val fixableDeal = (dealToFix.data as FixableDealState)
val sortedParties = fixableDeal.parties.sortedBy { it.name }
if (sortedParties[0].name == serviceHub.storageService.myLegalIdentity.name) {
if (sortedParties[0].name == serviceHub.myInfo.legalIdentity.name) {
val fixing = FixingSession(ref, fixableDeal.oracleType)
// Start the Floater which will then kick-off the Fixer
subProtocol(Floater(sortedParties[1], fixing))

View File

@ -38,7 +38,7 @@ class ValidatingNotaryProtocol(otherSide: Party,
private fun checkSignatures(stx: SignedTransaction) {
try {
stx.verifySignatures(serviceHub.storageService.myLegalIdentity.owningKey)
stx.verifySignatures(serviceHub.myInfo.legalIdentity.owningKey)
} catch(e: SignedTransaction.SignaturesMissingException) {
throw NotaryException(NotaryError.SignaturesMissing(e.missing))
}

View File

@ -7,7 +7,7 @@ import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
class ServiceInfoTests {
val serviceType = object : ServiceType("corda.service.subservice") {}
val serviceType = ServiceType.getServiceType("test", "service").getSubType("subservice")
val name = "service.name"
@Test

View File

@ -32,7 +32,7 @@ class ResolveTransactionsProtocolTest {
val nodes = net.createSomeNodes()
a = nodes.partyNodes[0]
b = nodes.partyNodes[1]
notary = nodes.notaryNode.info.identity
notary = nodes.notaryNode.info.notaryIdentity
net.runNetwork()
}
@ -44,7 +44,7 @@ class ResolveTransactionsProtocolTest {
@Test
fun `resolve from two hashes`() {
val (stx1, stx2) = makeTransactions()
val p = ResolveTransactionsProtocol(setOf(stx2.id), a.info.identity)
val p = ResolveTransactionsProtocol(setOf(stx2.id), a.info.legalIdentity)
val future = b.services.startProtocol("resolve", p)
net.runNetwork()
val results = future.get()
@ -56,7 +56,7 @@ class ResolveTransactionsProtocolTest {
@Test
fun `dependency with an error`() {
val stx = makeTransactions(signFirstTX = false).second
val p = ResolveTransactionsProtocol(setOf(stx.id), a.info.identity)
val p = ResolveTransactionsProtocol(setOf(stx.id), a.info.legalIdentity)
val future = b.services.startProtocol("resolve", p)
net.runNetwork()
assertFailsWith(SignatureException::class) {
@ -67,7 +67,7 @@ class ResolveTransactionsProtocolTest {
@Test
fun `resolve from a signed transaction`() {
val (stx1, stx2) = makeTransactions()
val p = ResolveTransactionsProtocol(stx2, a.info.identity)
val p = ResolveTransactionsProtocol(stx2, a.info.legalIdentity)
val future = b.services.startProtocol("resolve", p)
net.runNetwork()
future.get()
@ -89,7 +89,7 @@ class ResolveTransactionsProtocolTest {
a.services.recordTransactions(stx)
cursor = stx
}
val p = ResolveTransactionsProtocol(setOf(cursor.id), a.info.identity)
val p = ResolveTransactionsProtocol(setOf(cursor.id), a.info.legalIdentity)
p.transactionCountLimit = 40
val future = b.services.startProtocol("resolve", p)
net.runNetwork()
@ -116,7 +116,7 @@ class ResolveTransactionsProtocolTest {
a.services.recordTransactions(stx2, stx3)
val p = ResolveTransactionsProtocol(setOf(stx3.id), a.info.identity)
val p = ResolveTransactionsProtocol(setOf(stx3.id), a.info.legalIdentity)
val future = b.services.startProtocol("resolve", p)
net.runNetwork()
future.get()
@ -126,7 +126,7 @@ class ResolveTransactionsProtocolTest {
fun attachment() {
val id = a.services.storageService.attachments.importAttachment("Some test file".toByteArray().opaque().open())
val stx2 = makeTransactions(withAttachment = id).second
val p = ResolveTransactionsProtocol(stx2, a.info.identity)
val p = ResolveTransactionsProtocol(stx2, a.info.legalIdentity)
val future = b.services.startProtocol("resolve", p)
net.runNetwork()
future.get()

View File

@ -37,22 +37,22 @@ class Main : App() {
driver(portAllocation = portAllocation) {
val aliceNodeFuture = startNode("Alice")
val notaryNodeFuture = startNode("Notary", advertisedServices = setOf(ServiceInfo(SimpleNotaryService.Type)))
val notaryNodeFuture = startNode("Notary", advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)))
val aliceNode = aliceNodeFuture.get()
val notaryNode = notaryNodeFuture.get()
val aliceClient = startClient(aliceNode).get()
Models.get<IdentityModel>(Main::class).myIdentity.set(aliceNode.identity)
Models.get<IdentityModel>(Main::class).myIdentity.set(aliceNode.legalIdentity)
Models.get<NodeMonitorModel>(Main::class).register(aliceNode, aliceClient.config.certificatesPath)
for (i in 0 .. 10000) {
Thread.sleep(500)
val eventGenerator = EventGenerator(
parties = listOf(aliceNode.identity),
notary = notaryNode.identity
parties = listOf(aliceNode.legalIdentity),
notary = notaryNode.notaryIdentity
)
eventGenerator.clientToServiceCommandGenerator.map { command ->

View File

@ -236,7 +236,7 @@ class NetworkMapVisualiser : Application() {
if (change.tracker == tracker) {
// Protocol done; schedule it for removal in a few seconds. We batch them up to make nicer
// animations.
println("Protocol done for ${node.info.identity.name}")
println("Protocol done for ${node.info.legalIdentity.name}")
viewModel.doneTrackers += tracker
} else {
// Subprotocol is done; ignore it.
@ -244,7 +244,7 @@ class NetworkMapVisualiser : Application() {
} else if (!viewModel.trackerBoxes.containsKey(tracker)) {
// New protocol started up; add.
val extraLabel = viewModel.simulation.extraNodeLabels[node]
val label = if (extraLabel != null) "${node.storage.myLegalIdentity.name}: $extraLabel" else node.storage.myLegalIdentity.name
val label = if (extraLabel != null) "${node.info.legalIdentity.name}: $extraLabel" else node.info.legalIdentity.name
val widget = view.buildProgressTrackerWidget(label, tracker.topLevelTracker)
bindProgressTracketWidget(tracker.topLevelTracker, widget)
println("Added: ${tracker}, ${widget}")

View File

@ -85,7 +85,7 @@ class VisualiserViewModel {
try {
return node.place.coordinate.project(view.mapImage.fitWidth, view.mapImage.fitHeight, 64.3209, 29.8406, -23.2031, 33.0469)
} catch(e: Exception) {
throw Exception("Cannot project ${node.info.identity}", e)
throw Exception("Cannot project ${node.info.legalIdentity}", e)
}
}

View File

@ -16,7 +16,7 @@ class DriverTests {
// Check that the node is registered in the network map
poll("network map cache for $nodeName") {
networkMapCache.get().firstOrNull {
it.identity.name == nodeName
it.legalIdentity.name == nodeName
}
}
// Check that the port is bound
@ -33,8 +33,8 @@ class DriverTests {
@Test
fun simpleNodeStartupShutdownWorks() {
val (notary, regulator) = driver {
val notary = startNode("TestNotary", setOf(ServiceInfo(SimpleNotaryService.Type)))
val regulator = startNode("Regulator", setOf(ServiceInfo(RegulatorService.Type)))
val notary = startNode("TestNotary", setOf(ServiceInfo(SimpleNotaryService.type)))
val regulator = startNode("Regulator", setOf(ServiceInfo(RegulatorService.type)))
nodeMustBeUp(networkMapCache, notary.get(), "TestNotary")
nodeMustBeUp(networkMapCache, regulator.get(), "Regulator")

View File

@ -77,7 +77,7 @@ fun DriverDSLExposedInterface.startClient(localServer: ArtemisMessagingServer) =
fun DriverDSLExposedInterface.startClient(remoteNodeInfo: NodeInfo, providedName: String? = null) =
startClient(
providedName = providedName ?: "${remoteNodeInfo.identity.name}-client",
providedName = providedName ?: "${remoteNodeInfo.legalIdentity.name}-client",
serverAddress = ArtemisMessagingComponent.toHostAndPort(remoteNodeInfo.address)
)
@ -309,7 +309,7 @@ class DriverDSL(
registerProcess(DriverDSL.startNode(config, quasarJarPath, debugPort))
poll("network map cache for $name") {
networkMapCache.partyNodes.forEach {
if (it.identity.name == name) {
if (it.legalIdentity.name == name) {
return@poll it
}
}
@ -383,7 +383,7 @@ class DriverDSL(
networkMapCache.addMapService(networkMapClient, networkMapAddr, true)
networkMapNodeInfo = poll("network map cache for $networkMapName") {
networkMapCache.partyNodes.forEach {
if (it.identity.name == networkMapName) {
if (it.legalIdentity.name == networkMapName) {
return@poll it
}
}

View File

@ -8,10 +8,7 @@ import com.r3corda.core.RunOnCallerThread
import com.r3corda.core.crypto.Party
import com.r3corda.core.crypto.X509Utilities
import com.r3corda.core.messaging.SingleMessageRecipient
import com.r3corda.core.node.CityDatabase
import com.r3corda.core.node.CordaPluginRegistry
import com.r3corda.core.node.NodeInfo
import com.r3corda.core.node.PhysicalLocation
import com.r3corda.core.node.*
import com.r3corda.core.node.services.*
import com.r3corda.core.node.services.NetworkMapCache.MapChangeType
import com.r3corda.core.protocols.ProtocolLogic
@ -96,6 +93,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
val servicesThatAcceptUploads: List<AcceptsFileUpload> = _servicesThatAcceptUploads
private val protocolFactories = ConcurrentHashMap<Class<*>, (Party) -> ProtocolLogic<*>>()
protected val partyKeys = mutableSetOf<KeyPair>()
val services = object : ServiceHubInternal() {
override val networkService: MessagingServiceInternal get() = net
@ -106,6 +104,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
override val identityService: IdentityService get() = identity
override val schedulerService: SchedulerService get() = scheduler
override val clock: Clock = platformClock
override val myInfo: NodeInfo get() = info
override val schemaService: SchemaService get() = schemas
// Internal only
@ -130,7 +129,13 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
}
val info: NodeInfo by lazy {
NodeInfo(net.myAddress, storage.myLegalIdentity, advertisedServices, findMyLocation())
val services = mutableListOf<ServiceEntry>()
for (service in advertisedServices) {
val identity = obtainKeyPair(configuration.basedir, service.type.id + "-private-key", service.type.id + "-public", service.type.id).first
services += ServiceEntry(service, identity)
}
val legalIdentity = obtainLegalIdentity()
NodeInfo(net.myAddress, legalIdentity, services, findMyLocation())
}
open fun findMyLocation(): PhysicalLocation? = CityDatabase[configuration.nearestCity]
@ -214,7 +219,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
// TODO: uniquenessProvider creation should be inside makeNotaryService(), but notary service initialisation
// depends on smm, while smm depends on tokenizableServices, which uniquenessProvider is part of
advertisedServices.singleOrNull { it.type.isSubTypeOf(NotaryService.Type) }?.let {
advertisedServices.singleOrNull { it.type.isNotary() }?.let {
uniquenessProvider = makeUniquenessProvider()
tokenizableServices.add(uniquenessProvider!!)
}
@ -321,10 +326,10 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
}
private fun buildAdvertisedServices() {
val serviceTypes = info.advertisedServices.map { it.type }
if (NetworkMapService.Type in serviceTypes) makeNetworkMapService()
val serviceTypes = info.advertisedServices.map { it.info.type }
if (NetworkMapService.type in serviceTypes) makeNetworkMapService()
val notaryServiceType = serviceTypes.singleOrNull { it.isSubTypeOf(NotaryService.Type) }
val notaryServiceType = serviceTypes.singleOrNull { it.isNotary() }
if (notaryServiceType != null) {
inNodeNotaryService = makeNotaryService(notaryServiceType)
}
@ -335,7 +340,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
* updates) if one has been supplied.
*/
private fun registerWithNetworkMap(): ListenableFuture<Unit> {
require(networkMapService != null || NetworkMapService.Type in advertisedServices.map { it.type }) {
require(networkMapService != null || NetworkMapService.type in advertisedServices.map { it.type }) {
"Initial network map address must indicate a node that provides a network map service"
}
services.networkMapCache.addNode(info)
@ -365,11 +370,12 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
val instant = platformClock.instant()
val expires = instant + NetworkMapService.DEFAULT_EXPIRATION_PERIOD
val reg = NodeRegistration(info, instant.toEpochMilli(), type, expires)
val request = NetworkMapService.RegistrationRequest(reg.toWire(storage.myLegalIdentityKey.private), net.myAddress)
val legalIdentityKey = obtainLegalIdentityKey()
val request = NetworkMapService.RegistrationRequest(reg.toWire(legalIdentityKey.private), net.myAddress)
return net.sendRequest(REGISTER_PROTOCOL_TOPIC, request, networkMapAddr, RunOnCallerThread)
}
protected open fun makeKeyManagementService(): KeyManagementService = PersistentKeyManagementService(setOf(storage.myLegalIdentityKey))
protected open fun makeKeyManagementService(): KeyManagementService = PersistentKeyManagementService(partyKeys)
open protected fun makeNetworkMapService() {
inNodeNetworkMapService = PersistentNetworkMapService(services)
@ -379,8 +385,8 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
val timestampChecker = TimestampChecker(platformClock, 30.seconds)
return when (type) {
SimpleNotaryService.Type -> SimpleNotaryService(services, timestampChecker, uniquenessProvider!!)
ValidatingNotaryService.Type -> ValidatingNotaryService(services, timestampChecker, uniquenessProvider!!)
SimpleNotaryService.type -> SimpleNotaryService(services, timestampChecker, uniquenessProvider!!)
ValidatingNotaryService.type -> ValidatingNotaryService(services, timestampChecker, uniquenessProvider!!)
else -> {
throw IllegalArgumentException("Notary type ${type.id} is not handled by makeNotaryService.")
}
@ -392,13 +398,14 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
protected open fun makeIdentityService(): IdentityService {
val service = InMemoryIdentityService()
service.registerIdentity(storage.myLegalIdentity)
service.registerIdentity(info.legalIdentity)
services.networkMapCache.partyNodes.forEach { service.registerIdentity(it.identity) }
services.networkMapCache.partyNodes.forEach { service.registerIdentity(it.legalIdentity) }
netMapCache.changed.subscribe { mapChange ->
// TODO how should we handle network map removal
if (mapChange.type == MapChangeType.Added) {
service.registerIdentity(mapChange.node.identity)
service.registerIdentity(mapChange.node.legalIdentity)
}
}
@ -437,35 +444,42 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
val checkpointStorage = initialiseCheckpointService(dir)
val transactionStorage = PerFileTransactionStorage(dir.resolve("transactions"))
_servicesThatAcceptUploads += attachments
val (identity, keyPair) = obtainKeyPair(dir)
// Populate the partyKeys set.
obtainKeyPair(dir, PRIVATE_KEY_FILE_NAME, PUBLIC_IDENTITY_FILE_NAME)
for (service in advertisedServices) {
// Ensure all required keys exist.
obtainKeyPair(configuration.basedir, service.type.id + "-private-key", service.type.id + "-public", service.type.id)
}
val stateMachineTransactionMappingStorage = InMemoryStateMachineRecordedTransactionMappingStorage()
return Pair(
constructStorageService(attachments, transactionStorage, stateMachineTransactionMappingStorage, keyPair, identity),
constructStorageService(attachments, transactionStorage, stateMachineTransactionMappingStorage),
checkpointStorage
)
}
protected open fun constructStorageService(attachments: NodeAttachmentService,
transactionStorage: TransactionStorage,
stateMachineRecordedTransactionMappingStorage: StateMachineRecordedTransactionMappingStorage,
keyPair: KeyPair,
identity: Party) =
StorageServiceImpl(attachments, transactionStorage, stateMachineRecordedTransactionMappingStorage, keyPair, identity)
stateMachineRecordedTransactionMappingStorage: StateMachineRecordedTransactionMappingStorage) =
StorageServiceImpl(attachments, transactionStorage, stateMachineRecordedTransactionMappingStorage)
private fun obtainKeyPair(dir: Path): Pair<Party, KeyPair> {
protected fun obtainLegalIdentity(): Party = obtainKeyPair(configuration.basedir, PRIVATE_KEY_FILE_NAME, PUBLIC_IDENTITY_FILE_NAME).first
protected fun obtainLegalIdentityKey(): KeyPair = obtainKeyPair(configuration.basedir, PRIVATE_KEY_FILE_NAME, PUBLIC_IDENTITY_FILE_NAME).second
private fun obtainKeyPair(dir: Path, privateKeyFileName: String, publicKeyFileName: String, serviceName: String? = null): Pair<Party, KeyPair> {
// Load the private identity key, creating it if necessary. The identity key is a long term well known key that
// is distributed to other peers and we use it (or a key signed by it) when we need to do something
// "permissioned". The identity file is what gets distributed and contains the node's legal name along with
// the public key. Obviously in a real system this would need to be a certificate chain of some kind to ensure
// the legal name is actually validated in some way.
val privKeyFile = dir.resolve(PRIVATE_KEY_FILE_NAME)
val pubIdentityFile = dir.resolve(PUBLIC_IDENTITY_FILE_NAME)
val privKeyFile = dir.resolve(privateKeyFileName)
val pubIdentityFile = dir.resolve(publicKeyFileName)
val identityName = if (serviceName == null) configuration.myLegalName else configuration.myLegalName + "|" + serviceName
return if (!Files.exists(privKeyFile)) {
val identityAndKey = if (!Files.exists(privKeyFile)) {
log.info("Identity key not found, generating fresh key!")
val keyPair: KeyPair = generateKeyPair()
keyPair.serialize().writeToFile(privKeyFile)
val myIdentity = Party(configuration.myLegalName, keyPair.public)
val myIdentity = Party(identityName, keyPair.public)
// We include the Party class with the file here to help catch mixups when admins provide files of the
// wrong type by mistake.
myIdentity.serialize().writeToFile(pubIdentityFile)
@ -475,13 +489,15 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
// This is just a sanity check. It shouldn't fail unless the admin has fiddled with the files and messed
// things up for us.
val myIdentity = Files.readAllBytes(pubIdentityFile).deserialize<Party>()
if (myIdentity.name != configuration.myLegalName)
if (myIdentity.name != identityName)
throw ConfigurationException("The legal name in the config file doesn't match the stored identity file:" +
"${configuration.myLegalName} vs ${myIdentity.name}")
"${identityName} vs ${myIdentity.name}")
// Load the private key.
val keyPair = Files.readAllBytes(privKeyFile).deserialize<KeyPair>()
Pair(myIdentity, keyPair)
}
partyKeys += identityAndKey.second
return identityAndKey
}
protected open fun generateKeyPair() = com.r3corda.core.crypto.generateKeyPair()

View File

@ -117,7 +117,8 @@ class Node(override val configuration: FullNodeConfiguration, networkMapAddress:
artemisAddress
}()
}
val myIdentityOrNullIfNetworkMapService = if (networkMapService != null) services.storageService.myLegalIdentityKey.public else null
val legalIdentity = obtainLegalIdentity()
val myIdentityOrNullIfNetworkMapService = if (networkMapService != null) legalIdentity.owningKey else null
return NodeMessagingClient(configuration, serverAddr, myIdentityOrNullIfNetworkMapService, serverThread,
persistenceTx = { body: () -> Unit -> databaseTransaction(database) { body() } })
}

View File

@ -8,7 +8,6 @@ import com.r3corda.core.crypto.toStringShort
import com.r3corda.core.node.ServiceHub
import com.r3corda.core.node.services.Vault
import com.r3corda.core.transactions.TransactionBuilder
import com.r3corda.node.services.api.ServiceHubInternal
import com.r3corda.node.services.messaging.CordaRPCOps
import com.r3corda.node.services.messaging.StateMachineInfo
import com.r3corda.node.services.messaging.StateMachineUpdate
@ -93,10 +92,11 @@ class ServerRPCOps(
private fun exitCash(req: ClientToServiceCommand.ExitCash): TransactionBuildResult {
val builder: TransactionBuilder = TransactionType.General.Builder(null)
try {
val issuer = PartyAndReference(services.storageService.myLegalIdentity, req.issueRef)
val issuer = PartyAndReference(services.myInfo.legalIdentity, req.issueRef)
Cash().generateExit(builder, req.amount.issuedBy(issuer),
services.vaultService.currentVault.statesOfType<Cash.State>().filter { it.state.data.owner == issuer.party.owningKey })
builder.signWith(services.storageService.myLegalIdentityKey)
val myKey = services.legalIdentityKey
builder.signWith(myKey)
// Work out who the owners of the burnt states were
val inputStatesNullable = services.vaultService.statesForRefs(builder.inputStates())
@ -126,9 +126,10 @@ class ServerRPCOps(
// TODO: Make a lightweight protocol that manages this workflow, rather than embedding it directly in the service
private fun issueCash(req: ClientToServiceCommand.IssueCash): TransactionBuildResult {
val builder: TransactionBuilder = TransactionType.General.Builder(notary = null)
val issuer = PartyAndReference(services.storageService.myLegalIdentity, req.issueRef)
val issuer = PartyAndReference(services.myInfo.legalIdentity, req.issueRef)
Cash().generateIssue(builder, req.amount.issuedBy(issuer), req.recipient.owningKey, req.notary)
builder.signWith(services.storageService.myLegalIdentityKey)
val myKey = services.legalIdentityKey
builder.signWith(myKey)
val tx = builder.toSignedTransaction(checkSufficientSignatures = true)
// Issuance transactions do not need to be notarised, so we can skip directly to broadcasting it
val protocol = BroadcastTransactionProtocol(tx, setOf(req), setOf(req.recipient))

View File

@ -6,6 +6,7 @@ import com.r3corda.core.node.services.ServiceType
* Placeholder interface for regulator services.
*/
interface RegulatorService {
object Type : ServiceType("corda.regulator")
companion object {
val type = ServiceType.regulator
}
}

View File

@ -54,7 +54,7 @@ class FullNodeConfiguration(config: Config) : NodeConfiguration {
advertisedServices.add(ServiceInfo.parse(serviceId))
}
}
if (networkMapAddress == null) advertisedServices.add(ServiceInfo(NetworkMapService.Type))
if (networkMapAddress == null) advertisedServices.add(ServiceInfo(NetworkMapService.type))
val networkMapMessageAddress: SingleMessageRecipient? = if (networkMapAddress == null) null else NodeMessagingClient.makeNetworkMapAddress(networkMapAddress!!)
return Node(this, networkMapMessageAddress, advertisedServices)
}

View File

@ -41,11 +41,11 @@ import javax.annotation.concurrent.ThreadSafe
@ThreadSafe
open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCache {
override val networkMapNodes: List<NodeInfo>
get() = get(NetworkMapService.Type)
get() = get(NetworkMapService.type)
override val regulators: List<NodeInfo>
get() = get(RegulatorService.Type)
get() = get(ServiceType.regulator)
override val notaryNodes: List<NodeInfo>
get() = get(NotaryService.Type)
get() = get(ServiceType.notary)
override val partyNodes: List<NodeInfo>
get() = registeredNodes.map { it.value }
private val _changed = PublishSubject.create<MapChange>()
@ -58,10 +58,13 @@ open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCach
protected var registeredNodes = Collections.synchronizedMap(HashMap<Party, NodeInfo>())
override fun get() = registeredNodes.map { it.value }
override fun get(serviceType: ServiceType) = registeredNodes.filterValues { it.advertisedServices.any { it.type.isSubTypeOf(serviceType) } }.map { it.value }
override fun get(serviceType: ServiceType) = registeredNodes.filterValues { it.advertisedServices.any { it.info.type.isSubTypeOf(serviceType) } }.map { it.value }
override fun getRecommended(type: ServiceType, contract: Contract, vararg party: Party): NodeInfo? = get(type).firstOrNull()
override fun getNodeByLegalName(name: String) = get().singleOrNull { it.identity.name == name }
override fun getNodeByPublicKey(publicKey: PublicKey) = get().singleOrNull { it.identity.owningKey == publicKey }
override fun getNodeByLegalName(name: String) = get().singleOrNull { it.legalIdentity.name == name }
override fun getNodeByPublicKey(publicKey: PublicKey) = get().singleOrNull {
(it.legalIdentity.owningKey == publicKey)
|| it.advertisedServices.any { it.identity.owningKey == publicKey }
}
override fun addMapService(net: MessagingService, networkMapAddress: SingleMessageRecipient, subscribe: Boolean,
ifChangedSinceVer: Int?): ListenableFuture<Unit> {
@ -96,7 +99,7 @@ open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCach
}
override fun addNode(node: NodeInfo) {
val oldValue = registeredNodes.put(node.identity, node)
val oldValue = registeredNodes.put(node.legalIdentity, node)
if (oldValue == null) {
_changed.onNext(MapChange(node, oldValue, MapChangeType.Added))
} else if(oldValue != node) {
@ -105,7 +108,7 @@ open class InMemoryNetworkMapCache : SingletonSerializeAsToken(), NetworkMapCach
}
override fun removeNode(node: NodeInfo) {
val oldValue = registeredNodes.remove(node.identity)
val oldValue = registeredNodes.remove(node.legalIdentity)
_changed.onNext(MapChange(node, oldValue, MapChangeType.Removed))
}

View File

@ -48,7 +48,6 @@ import javax.annotation.concurrent.ThreadSafe
// a concept of identity changes over time, should that include the node for an identity? If so, that is likely to
// replace this service.
interface NetworkMapService {
object Type : ServiceType("corda.network_map")
companion object {
val DEFAULT_EXPIRATION_PERIOD = Period.ofWeeks(4)
@ -63,6 +62,8 @@ interface NetworkMapService {
val PUSH_ACK_PROTOCOL_TOPIC = "platform.network_map.push_ack"
val logger = loggerFor<NetworkMapService>()
val type = ServiceType.corda.getSubType("network_map")
}
val nodes: List<NodeInfo>
@ -270,7 +271,7 @@ abstract class AbstractNetworkMapService
// Update the current value atomically, so that if multiple updates come
// in on different threads, there is no risk of a race condition while checking
// sequence numbers.
val registrationInfo = registeredNodes.compute(node.identity, { mapKey: Party, existing: NodeRegistrationInfo? ->
val registrationInfo = registeredNodes.compute(node.legalIdentity, { mapKey: Party, existing: NodeRegistrationInfo? ->
changed = existing == null || existing.reg.serial < change.serial
if (changed) {
when (change.type) {
@ -332,7 +333,7 @@ class NodeRegistration(val node: NodeInfo, val serial: Long, val type: AddOrRemo
*/
fun toWire(privateKey: PrivateKey): WireNodeRegistration {
val regSerialized = this.serialize()
val regSig = privateKey.signWithECDSA(regSerialized.bits, node.identity.owningKey)
val regSig = privateKey.signWithECDSA(regSerialized.bits, node.legalIdentity.owningKey)
return WireNodeRegistration(regSerialized, regSig)
}
@ -346,7 +347,7 @@ class NodeRegistration(val node: NodeInfo, val serial: Long, val type: AddOrRemo
class WireNodeRegistration(raw: SerializedBytes<NodeRegistration>, sig: DigitalSignature.WithKey) : SignedData<NodeRegistration>(raw, sig) {
@Throws(IllegalArgumentException::class)
override fun verifyData(data: NodeRegistration) {
require(data.node.identity.owningKey == sig.by)
require(data.node.legalIdentity.owningKey == sig.by)
}
}

View File

@ -1,16 +1,12 @@
package com.r3corda.node.services.persistence
import com.r3corda.core.crypto.Party
import com.r3corda.core.node.services.AttachmentStorage
import com.r3corda.core.node.services.StateMachineRecordedTransactionMappingStorage
import com.r3corda.core.node.services.TransactionStorage
import com.r3corda.core.node.services.TxWritableStorageService
import com.r3corda.core.serialization.SingletonSerializeAsToken
import java.security.KeyPair
open class StorageServiceImpl(override val attachments: AttachmentStorage,
override val validatedTransactions: TransactionStorage,
override val stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage,
override val myLegalIdentityKey: KeyPair,
override val myLegalIdentity: Party = Party("Unit test party", myLegalIdentityKey.public))
override val stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage)
: SingletonSerializeAsToken(), TxWritableStorageService

View File

@ -187,7 +187,7 @@ class ProtocolStateMachineImpl<R>(override val id: StateMachineRunId,
val session = ProtocolSession(sessionProtocol, otherParty, random63BitValue(), null)
openSessions[Pair(sessionProtocol, otherParty)] = session
val counterpartyProtocol = sessionProtocol.getCounterpartyMarker(otherParty).name
val sessionInit = SessionInit(session.ourSessionId, serviceHub.storageService.myLegalIdentity, counterpartyProtocol)
val sessionInit = SessionInit(session.ourSessionId, serviceHub.myInfo.legalIdentity, counterpartyProtocol)
val sessionInitResponse = sendAndReceiveInternal(session, sessionInit, SessionInitResponse::class.java)
if (sessionInitResponse is SessionConfirm) {
session.otherPartySessionId = sessionInitResponse.initiatedSessionId

View File

@ -386,7 +386,7 @@ class StateMachineManager(val serviceHub: ServiceHubInternal,
}
private fun sendSessionMessage(party: Party, message: SessionMessage, psm: ProtocolStateMachineImpl<*>?) {
val node = serviceHub.networkMapCache.getNodeByLegalName(party.name)
val node = serviceHub.networkMapCache.getNodeByPublicKey(party.owningKey)
?: throw IllegalArgumentException("Don't know about party $party")
val logger = psm?.logger ?: logger
logger.trace { "${psm?.id} sending $message to party $party" }

View File

@ -5,6 +5,7 @@ import com.r3corda.core.node.services.ServiceType
import com.r3corda.core.serialization.SingletonSerializeAsToken
import com.r3corda.node.services.api.ServiceHubInternal
import com.r3corda.protocols.NotaryProtocol
import kotlin.reflect.KClass
/**
* A Notary service acts as the final signer of a transaction ensuring two things:
@ -16,9 +17,6 @@ import com.r3corda.protocols.NotaryProtocol
* This is the base implementation that can be customised with specific Notary transaction commit protocol.
*/
abstract class NotaryService(services: ServiceHubInternal) : SingletonSerializeAsToken() {
// Do not specify this as an advertised service. Use a concrete implementation.
// TODO: We do not want a service type that cannot be used. Fix the type system abuse here.
object Type : ServiceType("corda.notary")
init {
services.registerProtocolInitiator(NotaryProtocol.Client::class) { createProtocol(it) }

View File

@ -12,7 +12,9 @@ import com.r3corda.protocols.NotaryProtocol
class SimpleNotaryService(services: ServiceHubInternal,
val timestampChecker: TimestampChecker,
val uniquenessProvider: UniquenessProvider) : NotaryService(services) {
object Type : ServiceType("corda.notary.simple")
companion object {
val type = ServiceType.notary.getSubType("simple")
}
override fun createProtocol(otherParty: Party): NotaryProtocol.Service {
return NotaryProtocol.Service(otherParty, timestampChecker, uniquenessProvider)

View File

@ -11,7 +11,9 @@ import com.r3corda.protocols.ValidatingNotaryProtocol
class ValidatingNotaryService(services: ServiceHubInternal,
val timestampChecker: TimestampChecker,
val uniquenessProvider: UniquenessProvider) : NotaryService(services) {
object Type : ServiceType("corda.notary.validating")
companion object {
val type = ServiceType.notary.getSubType("validating")
}
override fun createProtocol(otherParty: Party): ValidatingNotaryProtocol {
return ValidatingNotaryProtocol(otherParty, timestampChecker, uniquenessProvider)

View File

@ -38,9 +38,9 @@ class ServerRPCTest {
@Before
fun setup() {
network = MockNetwork()
val networkMap = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.Type))
val networkMap = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.type))
aliceNode = network.createNode(networkMapAddress = networkMap.info.address)
notaryNode = network.createNode(advertisedServices = ServiceInfo(SimpleNotaryService.Type), networkMapAddress = networkMap.info.address)
notaryNode = network.createNode(advertisedServices = ServiceInfo(SimpleNotaryService.type), networkMapAddress = networkMap.info.address)
rpc = ServerRPCOps(aliceNode.services, aliceNode.smm, aliceNode.database)
stateMachineUpdates = rpc.stateMachinesAndUpdates().second
@ -57,13 +57,13 @@ class ServerRPCTest {
assertFalse(aliceNode.services.vaultService.currentVault.states.iterator().hasNext())
// Tell the monitoring service node to issue some cash
val recipient = aliceNode.services.storageService.myLegalIdentity
val outEvent = ClientToServiceCommand.IssueCash(Amount(quantity, GBP), ref, recipient, DUMMY_NOTARY)
val recipient = aliceNode.info.legalIdentity
val outEvent = ClientToServiceCommand.IssueCash(Amount(quantity, GBP), ref, recipient, notaryNode.info.notaryIdentity)
rpc.executeCommand(outEvent)
network.runNetwork()
val expectedState = Cash.State(Amount(quantity,
Issued(aliceNode.services.storageService.myLegalIdentity.ref(ref), GBP)),
Issued(aliceNode.info.legalIdentity.ref(ref), GBP)),
recipient.owningKey)
var issueSmId: StateMachineRunId? = null
@ -99,15 +99,15 @@ class ServerRPCTest {
rpc.executeCommand(ClientToServiceCommand.IssueCash(
amount = Amount(100, USD),
issueRef = OpaqueBytes(ByteArray(1, { 1 })),
recipient = aliceNode.services.storageService.myLegalIdentity,
notary = notaryNode.services.storageService.myLegalIdentity
recipient = aliceNode.info.legalIdentity,
notary = notaryNode.info.notaryIdentity
))
network.runNetwork()
rpc.executeCommand(ClientToServiceCommand.PayCash(
amount = Amount(100, Issued(PartyAndReference(aliceNode.services.storageService.myLegalIdentity, OpaqueBytes(ByteArray(1, { 1 }))), USD)),
recipient = aliceNode.services.storageService.myLegalIdentity
amount = Amount(100, Issued(PartyAndReference(aliceNode.info.legalIdentity, OpaqueBytes(ByteArray(1, { 1 }))), USD)),
recipient = aliceNode.info.legalIdentity
))
network.runNetwork()
@ -142,7 +142,7 @@ class ServerRPCTest {
val signaturePubKeys = tx.sigs.map { it.by }.toSet()
// Only Alice signed
require(signaturePubKeys.size == 1)
require(signaturePubKeys.contains(aliceNode.services.storageService.myLegalIdentity.owningKey))
require(signaturePubKeys.contains(aliceNode.info.legalIdentity.owningKey))
},
// MOVE
expect { tx ->
@ -151,8 +151,8 @@ class ServerRPCTest {
val signaturePubKeys = tx.sigs.map { it.by }.toSet()
// Alice and Notary signed
require(signaturePubKeys.size == 2)
require(signaturePubKeys.contains(aliceNode.services.storageService.myLegalIdentity.owningKey))
require(signaturePubKeys.contains(notaryNode.services.storageService.myLegalIdentity.owningKey))
require(signaturePubKeys.contains(aliceNode.info.legalIdentity.owningKey))
require(signaturePubKeys.contains(notaryNode.info.notaryIdentity.owningKey))
}
)
}

View File

@ -54,7 +54,7 @@ class AttachmentTests {
// Get node one to run a protocol to fetch it and insert it.
network.runNetwork()
val f1 = n1.services.startProtocol("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.identity))
val f1 = n1.services.startProtocol("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.legalIdentity))
network.runNetwork()
assertEquals(0, f1.get().fromDisk.size)
@ -65,7 +65,7 @@ class AttachmentTests {
// Shut down node zero and ensure node one can still resolve the attachment.
n0.stop()
val response: FetchDataProtocol.Result<Attachment> = n1.services.startProtocol("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.identity)).get()
val response: FetchDataProtocol.Result<Attachment> = n1.services.startProtocol("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.legalIdentity)).get()
assertEquals(attachment, response.fromDisk[0])
}
@ -76,7 +76,7 @@ class AttachmentTests {
// Get node one to fetch a non-existent attachment.
val hash = SecureHash.randomSHA256()
network.runNetwork()
val f1 = n1.services.startProtocol("tests.fetch2", FetchAttachmentsProtocol(setOf(hash), n0.info.identity))
val f1 = n1.services.startProtocol("tests.fetch2", FetchAttachmentsProtocol(setOf(hash), n0.info.legalIdentity))
network.runNetwork()
val e = assertFailsWith<FetchDataProtocol.HashNotFound> { rootCauseExceptions { f1.get() } }
assertEquals(hash, e.requested)
@ -96,7 +96,7 @@ class AttachmentTests {
}
}
}
}, true, null, null, ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type))
}, true, null, null, ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type))
val n1 = network.createNode(n0.info.address)
// Insert an attachment into node zero's store directly.
@ -109,7 +109,7 @@ class AttachmentTests {
// Get n1 to fetch the attachment. Should receive corrupted bytes.
network.runNetwork()
val f1 = n1.services.startProtocol("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.identity))
val f1 = n1.services.startProtocol("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.legalIdentity))
network.runNetwork()
assertFailsWith<FetchDataProtocol.DownloadedVsRequestedDataMismatch> {
rootCauseExceptions { f1.get() }

View File

@ -41,7 +41,7 @@ class InMemoryMessagingTests {
@Test
fun basics() {
val node1 = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.Type))
val node1 = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.type))
val node2 = network.createNode(networkMapAddress = node1.info.address)
val node3 = network.createNode(networkMapAddress = node1.info.address)
@ -70,7 +70,7 @@ class InMemoryMessagingTests {
@Test
fun broadcast() {
val node1 = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.Type))
val node1 = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.type))
val node2 = network.createNode(networkMapAddress = node1.info.address)
val node3 = network.createNode(networkMapAddress = node1.info.address)
@ -89,7 +89,7 @@ class InMemoryMessagingTests {
*/
@Test
fun `skip unhandled messages`() {
val node1 = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.Type))
val node1 = network.createNode(advertisedServices = ServiceInfo(NetworkMapService.type))
val node2 = network.createNode(networkMapAddress = node1.info.address)
var received: Int = 0

View File

@ -8,11 +8,11 @@ import com.r3corda.core.crypto.Party
import com.r3corda.core.crypto.SecureHash
import com.r3corda.core.days
import com.r3corda.core.messaging.SingleMessageRecipient
import com.r3corda.core.node.ServiceHub
import com.r3corda.core.node.services.*
import com.r3corda.core.protocols.ProtocolStateMachine
import com.r3corda.core.protocols.StateMachineRunId
import com.r3corda.core.transactions.SignedTransaction
import com.r3corda.core.transactions.TransactionBuilder
import com.r3corda.core.transactions.WireTransaction
import com.r3corda.core.utilities.DUMMY_NOTARY
import com.r3corda.core.utilities.DUMMY_NOTARY_KEY
@ -85,16 +85,20 @@ class TwoPartyTradeProtocolTests {
notaryNode = net.createNotaryNode(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 aliceKey = aliceNode.services.legalIdentityKey
val notaryKey = notaryNode.services.notaryIdentityKey
aliceNode.disableDBCloseOnStop()
bobNode.disableDBCloseOnStop()
databaseTransaction(bobNode.database) {
bobNode.services.fillWithSomeTestCash(2000.DOLLARS)
bobNode.services.fillWithSomeTestCash(2000.DOLLARS, outputNotary = notaryNode.info.notaryIdentity)
}
val alicesFakePaper = fillUpForSeller(false, aliceNode.storage.myLegalIdentity.owningKey,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null).second
insertFakeTransactions(alicesFakePaper, aliceNode, aliceNode.storage.myLegalIdentityKey, notaryNode.storage.myLegalIdentityKey)
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 (bobPsm, aliceResult) = runBuyerAndSeller("alice's paper".outputStateAndRef())
// TODO: Verify that the result was inserted into the transaction database.
@ -121,6 +125,8 @@ class TwoPartyTradeProtocolTests {
notaryNode = net.createNotaryNode(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 aliceKey = aliceNode.services.legalIdentityKey
val notaryKey = notaryNode.services.notaryIdentityKey
val bobAddr = bobNode.net.myAddress as InMemoryMessagingNetwork.Handle
val networkMapAddr = notaryNode.info.address
@ -128,11 +134,11 @@ class TwoPartyTradeProtocolTests {
net.runNetwork() // Clear network map registration messages
databaseTransaction(bobNode.database) {
bobNode.services.fillWithSomeTestCash(2000.DOLLARS)
bobNode.services.fillWithSomeTestCash(2000.DOLLARS, outputNotary = notaryNode.info.notaryIdentity)
}
val alicesFakePaper = fillUpForSeller(false, aliceNode.storage.myLegalIdentity.owningKey,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, null).second
insertFakeTransactions(alicesFakePaper, aliceNode, aliceNode.storage.myLegalIdentityKey)
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
// Everything is on this thread so we can now step through the protocol one step at a time.
@ -200,11 +206,9 @@ class TwoPartyTradeProtocolTests {
override fun constructStorageService(
attachments: NodeAttachmentService,
transactionStorage: TransactionStorage,
stateMachineRecordedTransactionMappingStorage: StateMachineRecordedTransactionMappingStorage,
keyPair: KeyPair,
identity: Party
stateMachineRecordedTransactionMappingStorage: StateMachineRecordedTransactionMappingStorage
): StorageServiceImpl {
return StorageServiceImpl(attachments, RecordingTransactionStorage(transactionStorage), stateMachineRecordedTransactionMappingStorage, keyPair, identity)
return StorageServiceImpl(attachments, RecordingTransactionStorage(transactionStorage), stateMachineRecordedTransactionMappingStorage)
}
}
}
@ -216,6 +220,7 @@ class TwoPartyTradeProtocolTests {
notaryNode = net.createNotaryNode(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 aliceKey = aliceNode.services.legalIdentityKey
ledger(aliceNode.services) {
@ -228,11 +233,11 @@ class TwoPartyTradeProtocolTests {
}
val attachmentID = attachment(ByteArrayInputStream(stream.toByteArray()))
val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public).second
val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public, notaryNode.info.notaryIdentity).second
val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode)
val alicesFakePaper = fillUpForSeller(false, aliceNode.storage.myLegalIdentity.owningKey,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID).second
val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, aliceNode.storage.myLegalIdentityKey)
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)
net.runNetwork() // Clear network map registration messages
@ -307,6 +312,7 @@ class TwoPartyTradeProtocolTests {
notaryNode = net.createNotaryNode(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 aliceKey = aliceNode.services.legalIdentityKey
ledger(aliceNode.services) {
@ -319,11 +325,11 @@ class TwoPartyTradeProtocolTests {
}
val attachmentID = attachment(ByteArrayInputStream(stream.toByteArray()))
val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public).second
val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public, notaryNode.info.notaryIdentity).second
insertFakeTransactions(bobsFakeCash, bobNode)
val alicesFakePaper = fillUpForSeller(false, aliceNode.storage.myLegalIdentity.owningKey,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID).second
insertFakeTransactions(alicesFakePaper, aliceNode, aliceNode.storage.myLegalIdentityKey)
val alicesFakePaper = fillUpForSeller(false, aliceNode.info.legalIdentity.owningKey,
1200.DOLLARS `issued by` DUMMY_CASH_ISSUER, attachmentID, notaryNode.info.notaryIdentity).second
insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey)
net.runNetwork() // Clear network map registration messages
@ -387,9 +393,9 @@ class TwoPartyTradeProtocolTests {
private fun runBuyerAndSeller(assetToSell: StateAndRef<OwnableState>) : RunResult {
val buyerFuture = bobNode.initiateSingleShotProtocol(Seller::class) { otherParty ->
Buyer(otherParty, notaryNode.info.identity, 1000.DOLLARS, CommercialPaper.State::class.java)
Buyer(otherParty, notaryNode.info.notaryIdentity, 1000.DOLLARS, CommercialPaper.State::class.java)
}
val seller = Seller(bobNode.info.identity, notaryNode.info, assetToSell, 1000.DOLLARS, ALICE_KEY)
val seller = Seller(bobNode.info.legalIdentity, notaryNode.info, assetToSell, 1000.DOLLARS, ALICE_KEY)
val sellerResultFuture = aliceNode.smm.add("seller", seller).resultFuture
return RunResult(buyerFuture, sellerResultFuture, seller.psm.id)
}
@ -402,15 +408,16 @@ class TwoPartyTradeProtocolTests {
notaryNode = net.createNotaryNode(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 aliceKey = aliceNode.services.legalIdentityKey
val bobKey = bobNode.services.legalIdentityKey
val issuer = MEGA_CORP.ref(1, 2, 3)
val bobKey = bobNode.keyManagement.freshKey()
val bobsBadCash = fillUpForBuyer(bobError, bobKey.public).second
val alicesFakePaper = fillUpForSeller(aliceError, aliceNode.storage.myLegalIdentity.owningKey,
1200.DOLLARS `issued by` issuer, null).second
val bobsBadCash = fillUpForBuyer(bobError, bobKey.public, 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, bobNode.storage.myLegalIdentityKey, bobNode.storage.myLegalIdentityKey)
insertFakeTransactions(alicesFakePaper, aliceNode, aliceNode.storage.myLegalIdentityKey)
insertFakeTransactions(bobsBadCash, bobNode, bobKey)
insertFakeTransactions(alicesFakePaper, aliceNode, aliceKey)
net.runNetwork() // Clear network map registration messages
@ -452,14 +459,15 @@ class TwoPartyTradeProtocolTests {
private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForBuyer(
withError: Boolean,
owner: PublicKey = BOB_PUBKEY): Pair<Vault, List<WireTransaction>> {
owner: PublicKey = BOB_PUBKEY,
notary: Party): Pair<Vault, List<WireTransaction>> {
val issuer = DUMMY_CASH_ISSUER
// Bob (Buyer) has some cash he got from the Bank of Elbonia, Alice (Seller) has some commercial paper she
// wants to sell to Bob.
val eb1 = transaction {
val eb1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
// Issued money to itself.
output("elbonian money 1") { 800.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY }
output("elbonian money 2") { 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` MEGA_CORP_PUBKEY }
output("elbonian money 2", notary = notary) { 1000.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY }
if (!withError)
command(DUMMY_CASH_ISSUER_KEY.public) { Cash.Commands.Issue() }
else
@ -474,17 +482,17 @@ class TwoPartyTradeProtocolTests {
}
// Bob gets some cash onto the ledger from BoE
val bc1 = transaction {
val bc1 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
input("elbonian money 1")
output("bob cash 1") { 800.DOLLARS.CASH `issued by` issuer `owned by` owner }
output("bob cash 1", notary = notary) { 800.DOLLARS.CASH `issued by` issuer `owned by` owner }
command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() }
this.verifies()
}
val bc2 = transaction {
val bc2 = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
input("elbonian money 2")
output("bob cash 2") { 300.DOLLARS.CASH `issued by` issuer `owned by` owner }
output { 700.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } // Change output.
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() }
this.verifies()
}
@ -497,9 +505,10 @@ class TwoPartyTradeProtocolTests {
withError: Boolean,
owner: PublicKey,
amount: Amount<Issued<Currency>>,
attachmentID: SecureHash?): Pair<Vault, List<WireTransaction>> {
val ap = transaction {
output("alice's paper") {
attachmentID: SecureHash?,
notary: Party): Pair<Vault, List<WireTransaction>> {
val ap = transaction(transactionBuilder = TransactionBuilder(notary = notary)) {
output("alice's paper", notary = notary) {
CommercialPaper.State(MEGA_CORP.ref(1, 2, 3), owner, amount, TEST_TX_TIME + 7.days)
}
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }

View File

@ -41,19 +41,19 @@ abstract class AbstractNetworkMapServiceTest {
// Confirm the service contains no nodes as own node only registered if network is run.
assertEquals(0, service().nodes.count())
assertNull(service().processQueryRequest(NetworkMapService.QueryIdentityRequest(registerNode.info.identity, mapServiceNode.info.address, Long.MIN_VALUE)).node)
assertNull(service().processQueryRequest(NetworkMapService.QueryIdentityRequest(registerNode.info.legalIdentity, mapServiceNode.info.address, Long.MIN_VALUE)).node)
// Register the new node
val instant = Instant.now()
val expires = instant + NetworkMapService.DEFAULT_EXPIRATION_PERIOD
val nodeKey = registerNode.storage.myLegalIdentityKey
val nodeKey = registerNode.services.legalIdentityKey
val addChange = NodeRegistration(registerNode.info, instant.toEpochMilli(), AddOrRemove.ADD, expires)
val addWireChange = addChange.toWire(nodeKey.private)
service().processRegistrationChangeRequest(RegistrationRequest(addWireChange, mapServiceNode.info.address, Long.MIN_VALUE))
swizzle()
assertEquals(1, service().nodes.count())
assertEquals(registerNode.info, service().processQueryRequest(NetworkMapService.QueryIdentityRequest(registerNode.info.identity, mapServiceNode.info.address, Long.MIN_VALUE)).node)
assertEquals(registerNode.info, service().processQueryRequest(NetworkMapService.QueryIdentityRequest(registerNode.info.legalIdentity, mapServiceNode.info.address, Long.MIN_VALUE)).node)
// Re-registering should be a no-op
service().processRegistrationChangeRequest(RegistrationRequest(addWireChange, mapServiceNode.info.address, Long.MIN_VALUE))
@ -67,7 +67,7 @@ abstract class AbstractNetworkMapServiceTest {
assert(service().processRegistrationChangeRequest(RegistrationRequest(removeWireChange, mapServiceNode.info.address, Long.MIN_VALUE)).success)
swizzle()
assertNull(service().processQueryRequest(NetworkMapService.QueryIdentityRequest(registerNode.info.identity, mapServiceNode.info.address, Long.MIN_VALUE)).node)
assertNull(service().processQueryRequest(NetworkMapService.QueryIdentityRequest(registerNode.info.legalIdentity, mapServiceNode.info.address, Long.MIN_VALUE)).node)
swizzle()
// Trying to de-register a node that doesn't exist should fail
@ -88,7 +88,7 @@ abstract class AbstractNetworkMapServiceTest {
assertEquals(2, fetchPsm.get()?.count())
// Forcibly deregister the second node
val nodeKey = registerNode.storage.myLegalIdentityKey
val nodeKey = registerNode.services.legalIdentityKey
val instant = Instant.now()
val expires = instant + NetworkMapService.DEFAULT_EXPIRATION_PERIOD
val reg = NodeRegistration(registerNode.info, instant.toEpochMilli()+1, AddOrRemove.REMOVE, expires)
@ -126,7 +126,7 @@ abstract class AbstractNetworkMapServiceTest {
assertEquals(0, service().getUnacknowledgedCount(registerNode.info.address, startingMapVersion))
// Fire off an update
val nodeKey = registerNode.storage.myLegalIdentityKey
val nodeKey = registerNode.services.legalIdentityKey
var seq = 0L
val expires = Instant.now() + NetworkMapService.DEFAULT_EXPIRATION_PERIOD
var reg = NodeRegistration(registerNode.info, seq++, AddOrRemove.ADD, expires)

View File

@ -3,6 +3,7 @@ package com.r3corda.node.services
import com.codahale.metrics.MetricRegistry
import com.google.common.util.concurrent.ListenableFuture
import com.r3corda.core.crypto.Party
import com.r3corda.core.node.NodeInfo
import com.r3corda.core.node.services.*
import com.r3corda.core.protocols.ProtocolLogic
import com.r3corda.core.protocols.ProtocolLogicRefFactory
@ -51,6 +52,8 @@ open class MockServiceHubInternal(
get() = scheduler ?: throw UnsupportedOperationException()
override val clock: Clock
get() = overrideClock ?: throw UnsupportedOperationException()
override val myInfo: NodeInfo
get() = throw UnsupportedOperationException()
override val monitoringService: MonitoringService = MonitoringService(MetricRegistry())
override val protocolLogicRefFactory: ProtocolLogicRefFactory

View File

@ -259,7 +259,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
private fun scheduleTX(instant: Instant, increment: Int = 1): ScheduledStateRef? {
var scheduledRef: ScheduledStateRef? = null
apply {
val freshKey = services.storageService.myLegalIdentityKey
val freshKey = services.keyManagementService.freshKey()
val state = TestState(factory.create(TestProtocolLogic::class.java, increment), instant)
val usefulTX = TransactionType.General.Builder(null).apply {
addOutputState(state, DUMMY_NOTARY)

View File

@ -36,18 +36,18 @@ class NotaryChangeTests {
oldNotaryNode = net.createNode(
legalName = DUMMY_NOTARY.name,
keyPair = DUMMY_NOTARY_KEY,
advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type)))
advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)))
clientNodeA = net.createNode(networkMapAddress = oldNotaryNode.info.address)
clientNodeB = net.createNode(networkMapAddress = oldNotaryNode.info.address)
newNotaryNode = net.createNode(networkMapAddress = oldNotaryNode.info.address, advertisedServices = ServiceInfo(SimpleNotaryService.Type))
newNotaryNode = net.createNode(networkMapAddress = oldNotaryNode.info.address, advertisedServices = ServiceInfo(SimpleNotaryService.type))
net.runNetwork() // Clear network map registration messages
}
@Test
fun `should change notary for a state with single participant`() {
val state = issueState(clientNodeA)
val newNotary = newNotaryNode.info.identity
val state = issueState(clientNodeA, oldNotaryNode)
val newNotary = newNotaryNode.info.notaryIdentity
val protocol = Instigator(state, newNotary)
val future = clientNodeA.services.startProtocol("notary-change", protocol)
@ -59,8 +59,8 @@ class NotaryChangeTests {
@Test
fun `should change notary for a state with multiple participants`() {
val state = issueMultiPartyState(clientNodeA, clientNodeB)
val newNotary = newNotaryNode.info.identity
val state = issueMultiPartyState(clientNodeA, clientNodeB, oldNotaryNode)
val newNotary = newNotaryNode.info.notaryIdentity
val protocol = Instigator(state, newNotary)
val future = clientNodeA.services.startProtocol("notary-change", protocol)
@ -75,7 +75,7 @@ class NotaryChangeTests {
@Test
fun `should throw when a participant refuses to change Notary`() {
val state = issueMultiPartyState(clientNodeA, clientNodeB)
val state = issueMultiPartyState(clientNodeA, clientNodeB, oldNotaryNode)
val newEvilNotary = Party("Evil Notary", generateKeyPair().public)
val protocol = Instigator(state, newEvilNotary)
val future = clientNodeA.services.startProtocol("notary-change", protocol)
@ -96,22 +96,27 @@ class NotaryChangeTests {
// - The transaction type is not a notary change transaction at all.
}
fun issueState(node: AbstractNode): StateAndRef<*> {
val tx = DummyContract.generateInitial(node.info.identity.ref(0), Random().nextInt(), DUMMY_NOTARY)
tx.signWith(node.storage.myLegalIdentityKey)
tx.signWith(DUMMY_NOTARY_KEY)
fun issueState(node: AbstractNode, notaryNode: AbstractNode): StateAndRef<*> {
val tx = DummyContract.generateInitial(node.info.legalIdentity.ref(0), Random().nextInt(), notaryNode.info.notaryIdentity)
val nodeKey = node.services.legalIdentityKey
tx.signWith(nodeKey)
val notaryKeyPair = notaryNode.services.notaryIdentityKey
tx.signWith(notaryKeyPair)
val stx = tx.toSignedTransaction()
node.services.recordTransactions(listOf(stx))
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
}
fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode): StateAndRef<DummyContract.MultiOwnerState> {
fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode, notaryNode: AbstractNode): StateAndRef<DummyContract.MultiOwnerState> {
val state = TransactionState(DummyContract.MultiOwnerState(0,
listOf(nodeA.info.identity.owningKey, nodeB.info.identity.owningKey)), DUMMY_NOTARY)
val tx = TransactionType.NotaryChange.Builder(DUMMY_NOTARY).withItems(state)
tx.signWith(nodeA.storage.myLegalIdentityKey)
tx.signWith(nodeB.storage.myLegalIdentityKey)
tx.signWith(DUMMY_NOTARY_KEY)
listOf(nodeA.info.legalIdentity.owningKey, nodeB.info.legalIdentity.owningKey)), 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()
nodeA.services.recordTransactions(listOf(stx))
nodeB.services.recordTransactions(listOf(stx))
@ -119,10 +124,11 @@ fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode): StateAndRef<
return stateAndRef
}
fun issueInvalidState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateAndRef<*> {
val tx = DummyContract.generateInitial(node.info.identity.ref(0), Random().nextInt(), notary)
fun issueInvalidState(node: AbstractNode, notary: Party): StateAndRef<*> {
val tx = DummyContract.generateInitial(node.info.legalIdentity.ref(0), Random().nextInt(), notary)
tx.setTime(Instant.now(), 30.seconds)
tx.signWith(node.storage.myLegalIdentityKey)
val nodeKey = node.services.legalIdentityKey
tx.signWith(nodeKey)
val stx = tx.toSignedTransaction(false)
node.services.recordTransactions(listOf(stx))
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))

View File

@ -1,6 +1,9 @@
package com.r3corda.node.services
import com.google.common.util.concurrent.ListenableFuture
import com.r3corda.core.contracts.DummyContract
import com.r3corda.core.contracts.StateAndRef
import com.r3corda.core.contracts.StateRef
import com.r3corda.core.contracts.TransactionType
import com.r3corda.core.node.services.ServiceInfo
import com.r3corda.core.crypto.DigitalSignature
@ -8,6 +11,7 @@ import com.r3corda.core.seconds
import com.r3corda.core.transactions.SignedTransaction
import com.r3corda.core.utilities.DUMMY_NOTARY
import com.r3corda.core.utilities.DUMMY_NOTARY_KEY
import com.r3corda.node.internal.AbstractNode
import com.r3corda.node.services.network.NetworkMapService
import com.r3corda.node.services.transactions.SimpleNotaryService
import com.r3corda.protocols.NotaryError
@ -18,6 +22,7 @@ import com.r3corda.testing.node.MockNetwork
import org.junit.Before
import org.junit.Test
import java.time.Instant
import java.util.*
import java.util.concurrent.ExecutionException
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
@ -33,7 +38,7 @@ class NotaryServiceTests {
notaryNode = net.createNode(
legalName = DUMMY_NOTARY.name,
keyPair = DUMMY_NOTARY_KEY,
advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type)))
advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)))
clientNode = net.createNode(networkMapAddress = notaryNode.info.address, keyPair = MINI_CORP_KEY)
net.runNetwork() // Clear network map registration messages
}
@ -41,7 +46,7 @@ class NotaryServiceTests {
@Test fun `should sign a unique transaction with a valid timestamp`() {
val stx = run {
val inputState = issueState(clientNode)
val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState)
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
tx.setTime(Instant.now(), 30.seconds)
tx.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false)
@ -55,7 +60,7 @@ class NotaryServiceTests {
@Test fun `should sign a unique transaction without a timestamp`() {
val stx = run {
val inputState = issueState(clientNode)
val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState)
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
tx.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false)
}
@ -68,7 +73,7 @@ class NotaryServiceTests {
@Test fun `should report error for transaction with an invalid timestamp`() {
val stx = run {
val inputState = issueState(clientNode)
val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState)
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
tx.setTime(Instant.now().plusSeconds(3600), 30.seconds)
tx.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false)
@ -84,7 +89,7 @@ class NotaryServiceTests {
@Test fun `should report conflict for a duplicate transaction`() {
val stx = run {
val inputState = issueState(clientNode)
val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState)
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
tx.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false)
}
@ -109,4 +114,15 @@ class NotaryServiceTests {
net.runNetwork()
return future
}
fun issueState(node: AbstractNode): StateAndRef<*> {
val tx = DummyContract.generateInitial(node.info.legalIdentity.ref(0), Random().nextInt(), notaryNode.info.notaryIdentity)
val nodeKey = node.services.legalIdentityKey
tx.signWith(nodeKey)
val notaryKeyPair = notaryNode.services.notaryIdentityKey
tx.signWith(notaryKeyPair)
val stx = tx.toSignedTransaction()
node.services.recordTransactions(listOf(stx))
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
}
}

View File

@ -1,14 +1,13 @@
package com.r3corda.node.services
import com.google.common.util.concurrent.ListenableFuture
import com.r3corda.core.contracts.Command
import com.r3corda.core.contracts.DummyContract
import com.r3corda.core.contracts.TransactionType
import com.r3corda.core.contracts.*
import com.r3corda.core.crypto.DigitalSignature
import com.r3corda.core.node.services.ServiceInfo
import com.r3corda.core.transactions.SignedTransaction
import com.r3corda.core.utilities.DUMMY_NOTARY
import com.r3corda.core.utilities.DUMMY_NOTARY_KEY
import com.r3corda.node.internal.AbstractNode
import com.r3corda.node.services.network.NetworkMapService
import com.r3corda.node.services.transactions.ValidatingNotaryService
import com.r3corda.protocols.NotaryError
@ -20,6 +19,7 @@ import com.r3corda.testing.node.MockNetwork
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import java.util.*
import java.util.concurrent.ExecutionException
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
@ -34,7 +34,7 @@ class ValidatingNotaryServiceTests {
notaryNode = net.createNode(
legalName = DUMMY_NOTARY.name,
keyPair = DUMMY_NOTARY_KEY,
advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(ValidatingNotaryService.Type))
advertisedServices = *arrayOf(ServiceInfo(NetworkMapService.type), ServiceInfo(ValidatingNotaryService.type))
)
clientNode = net.createNode(networkMapAddress = notaryNode.info.address, keyPair = MINI_CORP_KEY)
net.runNetwork() // Clear network map registration messages
@ -42,8 +42,8 @@ class ValidatingNotaryServiceTests {
@Test fun `should report error for invalid transaction dependency`() {
val stx = run {
val inputState = issueInvalidState(clientNode)
val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState)
val inputState = issueInvalidState(clientNode, notaryNode.info.notaryIdentity)
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
tx.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false)
}
@ -61,7 +61,7 @@ class ValidatingNotaryServiceTests {
val inputState = issueState(clientNode)
val command = Command(DummyContract.Commands.Move(), expectedMissingKey)
val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState, command)
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState, command)
tx.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false)
}
@ -82,4 +82,15 @@ class ValidatingNotaryServiceTests {
net.runNetwork()
return future
}
fun issueState(node: AbstractNode): StateAndRef<*> {
val tx = DummyContract.generateInitial(node.info.legalIdentity.ref(0), Random().nextInt(), notaryNode.info.notaryIdentity)
val nodeKey = node.services.legalIdentityKey
tx.signWith(nodeKey)
val notaryKeyPair = notaryNode.services.notaryIdentityKey
tx.signWith(notaryKeyPair)
val stx = tx.toSignedTransaction()
node.services.recordTransactions(listOf(stx))
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
}
}

View File

@ -84,7 +84,7 @@ class VaultWithCashTest {
fun `issue and spend total correctly and irrelevant ignored`() {
databaseTransaction(database) {
// A tx that sends us money.
val freshKey = services.storageService.myLegalIdentityKey
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, DUMMY_NOTARY)
signWith(MEGA_CORP_KEY)
@ -122,7 +122,7 @@ class VaultWithCashTest {
@Test
fun `branching LinearStates fails to verify`() {
databaseTransaction(database) {
val freshKey = services.storageService.myLegalIdentityKey
val freshKey = services.keyManagementService.freshKey()
val linearId = UniqueIdentifier()
// Issue a linear state
@ -142,7 +142,7 @@ class VaultWithCashTest {
@Test
fun `sequencing LinearStates works`() {
databaseTransaction(database) {
val freshKey = services.storageService.myLegalIdentityKey
val freshKey = services.keyManagementService.freshKey()
val linearId = UniqueIdentifier()

View File

@ -33,8 +33,8 @@ class DataVendingServiceTests {
@Test
fun `notify of transaction`() {
val (vaultServiceNode, registerNode) = network.createTwoNodes()
val beneficiary = vaultServiceNode.services.storageService.myLegalIdentityKey.public
val deposit = registerNode.services.storageService.myLegalIdentity.ref(1)
val beneficiary = vaultServiceNode.info.legalIdentity.owningKey
val deposit = registerNode.info.legalIdentity.ref(1)
network.runNetwork()
// Generate an issuance transaction
@ -42,7 +42,8 @@ class DataVendingServiceTests {
Cash().generateIssue(ptx, Amount(100, Issued(deposit, USD)), beneficiary, DUMMY_NOTARY)
// Complete the cash transaction, and then manually relay it
ptx.signWith(registerNode.services.storageService.myLegalIdentityKey)
val registerKey = registerNode.services.legalIdentityKey
ptx.signWith(registerKey)
val tx = ptx.toSignedTransaction()
assertEquals(0, vaultServiceNode.services.vaultService.currentVault.states.toList().size)
@ -61,7 +62,7 @@ class DataVendingServiceTests {
@Test
fun `notify failure`() {
val (vaultServiceNode, registerNode) = network.createTwoNodes()
val beneficiary = vaultServiceNode.services.storageService.myLegalIdentityKey.public
val beneficiary = vaultServiceNode.info.legalIdentity.owningKey
val deposit = MEGA_CORP.ref(1)
network.runNetwork()
@ -70,7 +71,8 @@ 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
ptx.signWith(registerNode.services.storageService.myLegalIdentityKey)
val registerKey = registerNode.services.legalIdentityKey
ptx.signWith(registerKey)
val tx = ptx.toSignedTransaction(false)
assertEquals(0, vaultServiceNode.services.vaultService.currentVault.states.toList().size)
@ -82,7 +84,7 @@ class DataVendingServiceTests {
private fun MockNode.sendNotifyTx(tx: SignedTransaction, walletServiceNode: MockNode) {
walletServiceNode.services.registerProtocolInitiator(NotifyTxProtocol::class, ::NotifyTransactionHandler)
services.startProtocol("notify-tx", NotifyTxProtocol(walletServiceNode.info.identity, tx))
services.startProtocol("notify-tx", NotifyTxProtocol(walletServiceNode.info.legalIdentity, tx))
network.runNetwork()
}

View File

@ -60,7 +60,7 @@ class StateMachineManagerTests {
fun `protocol restarted just after receiving payload`() {
node2.services.registerProtocolInitiator(SendProtocol::class) { ReceiveThenSuspendProtocol(it) }
val payload = random63BitValue()
node1.smm.add("test", SendProtocol(payload, node2.info.identity))
node1.smm.add("test", SendProtocol(payload, node2.info.legalIdentity))
// We push through just enough messages to get only the SessionData sent
// TODO We should be able to give runNetwork a predicate for when to stop
@ -108,7 +108,7 @@ class StateMachineManagerTests {
fun `protocol loaded from checkpoint will respond to messages from before start`() {
val payload = random63BitValue()
node1.services.registerProtocolInitiator(ReceiveThenSuspendProtocol::class) { SendProtocol(payload, it) }
val receiveProtocol = ReceiveThenSuspendProtocol(node1.info.identity)
val receiveProtocol = ReceiveThenSuspendProtocol(node1.info.legalIdentity)
node2.smm.add("test", receiveProtocol) // Prepare checkpointed receive protocol
node2.stop() // kill receiver
val restoredProtocol = node2.restartAndGetRestoredProtocol<ReceiveThenSuspendProtocol>(node1.info.address)
@ -135,7 +135,7 @@ class StateMachineManagerTests {
}
// Kick off first send and receive
node2.smm.add("test", PingPongProtocol(node3.info.identity, payload))
node2.smm.add("test", PingPongProtocol(node3.info.legalIdentity, payload))
assertEquals(1, node2.checkpointStorage.checkpoints().count())
// Restart node and thus reload the checkpoint and resend the message with same UUID
node2.stop()
@ -165,7 +165,7 @@ class StateMachineManagerTests {
node2.services.registerProtocolInitiator(SendProtocol::class) { ReceiveThenSuspendProtocol(it) }
node3.services.registerProtocolInitiator(SendProtocol::class) { ReceiveThenSuspendProtocol(it) }
val payload = random63BitValue()
node1.smm.add("multiple-send", SendProtocol(payload, node2.info.identity, node3.info.identity))
node1.smm.add("multiple-send", SendProtocol(payload, node2.info.legalIdentity, node3.info.legalIdentity))
net.runNetwork()
val node2Protocol = node2.getSingleProtocol<ReceiveThenSuspendProtocol>().first
val node3Protocol = node3.getSingleProtocol<ReceiveThenSuspendProtocol>().first
@ -181,7 +181,7 @@ class StateMachineManagerTests {
val node3Payload = random63BitValue()
node2.services.registerProtocolInitiator(ReceiveThenSuspendProtocol::class) { SendProtocol(node2Payload, it) }
node3.services.registerProtocolInitiator(ReceiveThenSuspendProtocol::class) { SendProtocol(node3Payload, it) }
val multiReceiveProtocol = ReceiveThenSuspendProtocol(node2.info.identity, node3.info.identity)
val multiReceiveProtocol = ReceiveThenSuspendProtocol(node2.info.legalIdentity, node3.info.legalIdentity)
node1.smm.add("multiple-receive", multiReceiveProtocol)
net.runNetwork(1) // session handshaking
// have the messages arrive in reverse order of receive
@ -195,7 +195,7 @@ class StateMachineManagerTests {
@Test
fun `exception thrown on other side`() {
node2.services.registerProtocolInitiator(ReceiveThenSuspendProtocol::class) { ExceptionProtocol }
val future = node1.smm.add("exception", ReceiveThenSuspendProtocol(node2.info.identity)).resultFuture
val future = node1.smm.add("exception", ReceiveThenSuspendProtocol(node2.info.legalIdentity)).resultFuture
net.runNetwork()
assertThatThrownBy { future.get() }.hasCauseInstanceOf(ProtocolSessionException::class.java)
}

View File

@ -406,11 +406,11 @@ private fun startNode(params: CliParams.RunNode, networkMap: SingleMessageRecipi
val networkMapId =
when (params.node) {
IRSDemoNode.NodeA -> {
advertisedServices = setOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type))
advertisedServices = setOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type))
null
}
IRSDemoNode.NodeB -> {
advertisedServices = setOf(ServiceInfo(NodeInterestRates.Type))
advertisedServices = setOf(ServiceInfo(NodeInterestRates.type))
networkMap
}
}
@ -475,7 +475,7 @@ private fun loadConfigFile(baseDir: Path, configFile: Path, configOverrides: Map
private fun createIdentities(nodeConf: NodeConfiguration) {
val mockNetwork = MockNetwork(false)
val node = MockNetwork.MockNode(nodeConf, mockNetwork, null, setOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type)), 0, null)
val node = MockNetwork.MockNode(nodeConf, mockNetwork, null, setOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)), 0, null)
node.start()
node.stop()
}

View File

@ -78,12 +78,12 @@ fun main(args: Array<String>) {
}
node.networkMapRegistrationFuture.get()
val notaryNode = node.services.networkMapCache.notaryNodes[0]
val rateOracle = node.services.networkMapCache.get(InterestRateSwap.OracleType).first()
val rateOracle = node.services.networkMapCache.get(InterestRateSwap.oracleType).first()
// Make a garbage transaction that includes a rate fix.
val tx = TransactionType.General.Builder(notaryNode.identity)
tx.addOutputState(TransactionState(Cash.State(1500.DOLLARS `issued by` node.storage.myLegalIdentity.ref(1), node.storage.myLegalIdentityKey.public), notaryNode.identity))
val protocol = RatesFixProtocol(tx, rateOracle.identity, fixOf, expectedRate, rateTolerance)
val tx = TransactionType.General.Builder(notaryNode.notaryIdentity)
tx.addOutputState(TransactionState(Cash.State(1500.DOLLARS `issued by` node.info.legalIdentity.ref(1), node.info.legalIdentity.owningKey), notaryNode.notaryIdentity))
val protocol = RatesFixProtocol(tx, rateOracle.serviceIdentities(InterestRateSwap.oracleType).first(), fixOf, expectedRate, rateTolerance)
node.services.startProtocol("demo.ratefix", protocol).get()
node.stop()

View File

@ -141,7 +141,7 @@ fun main(args: Array<String>) {
// the map is not very helpful, but we need one anyway. So just make the buyer side run the network map as it's
// the side that sticks around waiting for the seller.
val networkMapId = if (role == Role.BUYER) {
advertisedServices = setOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type))
advertisedServices = setOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type))
null
} else {
advertisedServices = emptySet()
@ -160,7 +160,7 @@ fun main(args: Array<String>) {
runBuyer(node, amount)
} else {
node.networkMapRegistrationFuture.success {
val party = node.netMapCache.getNodeByLegalName("Bank A")?.identity ?: throw IllegalStateException("Cannot find other node?!")
val party = node.netMapCache.getNodeByLegalName("Bank A")?.legalIdentity ?: throw IllegalStateException("Cannot find other node?!")
runSeller(node, amount, party)
}
}
@ -211,8 +211,8 @@ private fun runBuyer(node: Node, amount: Amount<Currency>) {
// TODO: At some point this demo should be extended to have a central bank node.
databaseTransaction(node.database) {
node.services.fillWithSomeTestCash(300000.DOLLARS,
outputNotary = node.info.identity, // In this demo, the buyer and notary are the same.
ownedBy = node.storage.myLegalIdentityKey.public)
outputNotary = node.info.notaryIdentity, // In this demo, the buyer and notary are on the same node, but need to use right key.
ownedBy = node.info.legalIdentity.owningKey)
}
// Wait around until a node asks to start a trade with us. In a real system, this part would happen out of band
@ -241,7 +241,7 @@ private class TraderDemoProtocolBuyer(val otherSide: Party,
val notary: NodeInfo = serviceHub.networkMapCache.notaryNodes[0]
val buyer = TwoPartyTradeProtocol.Buyer(
otherSide,
notary.identity,
notary.notaryIdentity,
amount,
CommercialPaper.State::class.java)
@ -304,7 +304,7 @@ private class TraderDemoProtocolSeller(val otherSide: Party,
progressTracker.currentStep = SELF_ISSUING
val notary: NodeInfo = serviceHub.networkMapCache.notaryNodes[0]
val cpOwnerKey = serviceHub.storageService.myLegalIdentityKey
val cpOwnerKey = serviceHub.legalIdentityKey
val commercialPaper = selfIssueSomeCommercialPaper(cpOwnerKey.public, notary)
progressTracker.currentStep = TRADING
@ -330,7 +330,7 @@ private class TraderDemoProtocolSeller(val otherSide: Party,
val issuance: SignedTransaction = run {
val tx = CommercialPaper().generateIssue(party.ref(1, 2, 3), 1100.DOLLARS `issued by` DUMMY_CASH_ISSUER,
Instant.now() + 10.days, notaryNode.identity)
Instant.now() + 10.days, notaryNode.notaryIdentity)
// TODO: Consider moving these two steps below into generateIssue.
@ -356,7 +356,7 @@ private class TraderDemoProtocolSeller(val otherSide: Party,
// Now make a dummy transaction that moves it to a new key, just to show that resolving dependencies works.
val move: SignedTransaction = run {
val builder = TransactionType.General.Builder(notaryNode.identity)
val builder = TransactionType.General.Builder(notaryNode.notaryIdentity)
CommercialPaper().generateMove(builder, issuance.tx.outRef(0), ownedBy)
builder.signWith(keyPair)
val notarySignature = subProtocol(NotaryProtocol.Client(builder.toSignedTransaction(false)))

View File

@ -42,7 +42,7 @@ import javax.annotation.concurrent.ThreadSafe
* for signing.
*/
object NodeInterestRates {
object Type : ServiceType("corda.interest_rates")
val type = ServiceType.corda.getSubType("interest_rates")
/**
* Register the protocol that is used with the Fixing integration tests.
@ -55,25 +55,31 @@ object NodeInterestRates {
/**
* The Service that wraps [Oracle] and handles messages/network interaction/request scrubbing.
*/
class Service(services: ServiceHubInternal) : AcceptsFileUpload, SingletonSerializeAsToken() {
val ss = services.storageService
val oracle = Oracle(ss.myLegalIdentity, ss.myLegalIdentityKey, services.clock)
init {
services.registerProtocolInitiator(FixSignProtocol::class) { FixSignHandler(it, oracle) }
services.registerProtocolInitiator(FixQueryProtocol::class) { FixQueryHandler(it, oracle) }
class Service(val services: ServiceHubInternal) : AcceptsFileUpload, SingletonSerializeAsToken() {
val oracle: Oracle by lazy {
val myNodeInfo = services.myInfo
val myIdentity = myNodeInfo.serviceIdentities(type).first()
val mySigningKey = services.keyManagementService.toKeyPair(myIdentity.owningKey)
Oracle(myIdentity, mySigningKey, services.clock)
}
init {
// Note access to the singleton oracle property is via the registered SingletonSerializeAsToken Service.
// Otherwise the Kryo serialisation of the call stack in the Quasar Fiber extends to include
// the framework Oracle and the protocol will crash.
services.registerProtocolInitiator(FixSignProtocol::class) { FixSignHandler(it, this) }
services.registerProtocolInitiator(FixQueryProtocol::class) { FixQueryHandler(it, this) }
}
private class FixSignHandler(val otherParty: Party, val oracle: Oracle) : ProtocolLogic<Unit>() {
private class FixSignHandler(val otherParty: Party, val service: Service) : ProtocolLogic<Unit>() {
@Suspendable
override fun call() {
val request = receive<SignRequest>(otherParty).unwrap { it }
send(otherParty, oracle.sign(request.tx))
send(otherParty, service.oracle.sign(request.tx))
}
}
private class FixQueryHandler(val otherParty: Party, val oracle: Oracle) : ProtocolLogic<Unit>() {
private class FixQueryHandler(val otherParty: Party, val service: Service) : ProtocolLogic<Unit>() {
companion object {
object RECEIVED : ProgressTracker.Step("Received fix request")
@ -89,7 +95,7 @@ object NodeInterestRates {
@Suspendable
override fun call(): Unit {
val request = receive<QueryRequest>(otherParty).unwrap { it }
val answers = oracle.query(request.queries, request.deadline)
val answers = service.oracle.query(request.queries, request.deadline)
progressTracker.currentStep = SENDING
send(otherParty, answers)
}

View File

@ -111,7 +111,7 @@ fun main(args: Array<String>) {
// the map is not very helpful, but we need one anyway. So just make the recipient side run the network map as it's
// the side that sticks around waiting for the sender.
val networkMapId = if (role == Role.SENDER) {
advertisedServices = setOf(ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type))
advertisedServices = setOf(ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type))
null
} else {
advertisedServices = emptySet()
@ -131,7 +131,7 @@ fun main(args: Array<String>) {
node.networkMapRegistrationFuture.success {
// Pause a moment to give the network map time to update
Thread.sleep(100L)
val party = node.netMapCache.getNodeByLegalName(Role.RECIPIENT.legalName)?.identity ?: throw IllegalStateException("Cannot find other node?!")
val party = node.netMapCache.getNodeByLegalName(Role.RECIPIENT.legalName)?.legalIdentity ?: throw IllegalStateException("Cannot find other node?!")
runSender(node, party)
}
}

View File

@ -62,14 +62,15 @@ object AutoOfferProtocol {
@Suspendable
override fun call(): SignedTransaction {
require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" }
val notary = serviceHub.networkMapCache.notaryNodes.first().identity
val notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity
// need to pick which ever party is not us
val otherParty = notUs(dealToBeOffered.parties).single()
progressTracker.currentStep = DEALING
val myKey = serviceHub.legalIdentityKey
val instigator = Instigator(
otherParty,
AutoOffer(notary, dealToBeOffered),
serviceHub.storageService.myLegalIdentityKey,
myKey,
progressTracker.getChildProgressTracker(DEALING)!!
)
val stx = subProtocol(instigator)
@ -79,7 +80,7 @@ object AutoOfferProtocol {
private fun notUs(parties: List<Party>): List<Party> {
val notUsParties: MutableList<Party> = arrayListOf()
for (party in parties) {
if (serviceHub.storageService.myLegalIdentity != party) {
if (serviceHub.myInfo.legalIdentity != party) {
notUsParties.add(party)
}
}

View File

@ -66,7 +66,7 @@ object ExitServerProtocol {
if (recipient.address is MockNetworkMapCache.MockAddress) {
// Ignore
} else {
send(recipient.identity, ExitMessage(exitCode))
send(recipient.legalIdentity, ExitMessage(exitCode))
}
}
}

View File

@ -60,7 +60,7 @@ object UpdateBusinessDayProtocol {
if (recipient.address is MockNetworkMapCache.MockAddress) {
// Ignore
} else {
send(recipient.identity, UpdateBusinessDayMessage(date))
send(recipient.legalIdentity, UpdateBusinessDayMessage(date))
}
}
}

View File

@ -108,15 +108,15 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten
// have the convenient copy() method that'd let us make small adjustments. Instead they're partly mutable.
// TODO: We should revisit this in post-Excalibur cleanup and fix, e.g. by introducing an interface.
val irs = om.readValue<InterestRateSwap.State>(javaClass.getResource("trade.json"))
irs.fixedLeg.fixedRatePayer = node1.info.identity
irs.floatingLeg.floatingRatePayer = node2.info.identity
irs.fixedLeg.fixedRatePayer = node1.info.legalIdentity
irs.floatingLeg.floatingRatePayer = node2.info.legalIdentity
val acceptorTx = node2.initiateSingleShotProtocol(Instigator::class) { Acceptor(it) }.flatMap { it.resultFuture }
showProgressFor(listOf(node1, node2))
showConsensusFor(listOf(node1, node2, regulators[0]))
val instigator = Instigator(node2.info.identity, AutoOffer(notary.info.identity, irs), node1.keyPair!!)
val instigator = Instigator(node2.info.legalIdentity, AutoOffer(notary.info.notaryIdentity, irs), node1.keyPair!!)
val instigatorTx = node1.services.startProtocol("instigator", instigator)
return Futures.allAsList(instigatorTx, acceptorTx).flatMap { instigatorTx }

View File

@ -87,7 +87,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
object NetworkMapNodeFactory : MockNetwork.Factory {
override fun create(config: NodeConfiguration, network: MockNetwork,
networkMapAddr: SingleMessageRecipient?, advertisedServices: Set<ServiceInfo>, id: Int, keyPair: KeyPair?): MockNetwork.MockNode {
require(advertisedServices.containsType(NetworkMapService.Type))
require(advertisedServices.containsType(NetworkMapService.type))
// TODO: create a base class that provides a default implementation
val cfg = object : NodeConfiguration {
@ -109,7 +109,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
object NotaryNodeFactory : MockNetwork.Factory {
override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?,
advertisedServices: Set<ServiceInfo>, id: Int, keyPair: KeyPair?): MockNetwork.MockNode {
require(advertisedServices.containsType(SimpleNotaryService.Type))
require(advertisedServices.containsType(SimpleNotaryService.type))
// TODO: create a base class that provides a default implementation
val cfg = object : NodeConfiguration {
@ -130,7 +130,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
object RatesOracleFactory : MockNetwork.Factory {
override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?,
advertisedServices: Set<ServiceInfo>, id: Int, keyPair: KeyPair?): MockNetwork.MockNode {
require(advertisedServices.containsType(NodeInterestRates.Type))
require(advertisedServices.containsType(NodeInterestRates.type))
// TODO: create a base class that provides a default implementation
val cfg = object : NodeConfiguration {
@ -188,12 +188,12 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
val network = MockNetwork(networkSendManuallyPumped, runAsync)
// This one must come first.
val networkMap: SimulatedNode
= network.createNode(null, nodeFactory = NetworkMapNodeFactory, advertisedServices = ServiceInfo(NetworkMapService.Type)) as SimulatedNode
= network.createNode(null, nodeFactory = NetworkMapNodeFactory, advertisedServices = ServiceInfo(NetworkMapService.type)) as SimulatedNode
val notary: SimulatedNode
= network.createNode(networkMap.info.address, nodeFactory = NotaryNodeFactory, advertisedServices = ServiceInfo(SimpleNotaryService.Type)) as SimulatedNode
= network.createNode(networkMap.info.address, nodeFactory = NotaryNodeFactory, advertisedServices = ServiceInfo(SimpleNotaryService.type)) as SimulatedNode
val regulators: List<SimulatedNode> = listOf(network.createNode(networkMap.info.address, start = false, nodeFactory = RegulatorFactory) as SimulatedNode)
val ratesOracle: SimulatedNode
= network.createNode(networkMap.info.address, start = false, nodeFactory = RatesOracleFactory, advertisedServices = ServiceInfo(NodeInterestRates.Type)) as SimulatedNode
= network.createNode(networkMap.info.address, start = false, nodeFactory = RatesOracleFactory, advertisedServices = ServiceInfo(NodeInterestRates.type)) as SimulatedNode
// All nodes must be in one of these two lists for the purposes of the visualiser tool.
val serviceProviders: List<SimulatedNode> = listOf(notary, ratesOracle, networkMap)

View File

@ -33,14 +33,16 @@ class TradeSimulation(runAsync: Boolean, latencyInjector: InMemoryMessagingNetwo
val buyer = banks[buyerBankIndex]
val seller = banks[sellerBankIndex]
buyer.services.fillWithSomeTestCash(1500.DOLLARS, notary.info.identity)
buyer.services.fillWithSomeTestCash(1500.DOLLARS, notary.info.notaryIdentity)
val issuance = run {
val tx = CommercialPaper().generateIssue(seller.info.identity.ref(1, 2, 3), 1100.DOLLARS `issued by` DUMMY_CASH_ISSUER,
Instant.now() + 10.days, notary.info.identity)
val tx = CommercialPaper().generateIssue(seller.info.legalIdentity.ref(1, 2, 3), 1100.DOLLARS `issued by` DUMMY_CASH_ISSUER,
Instant.now() + 10.days, notary.info.notaryIdentity)
tx.setTime(Instant.now(), 30.seconds)
tx.signWith(notary.storage.myLegalIdentityKey)
tx.signWith(seller.storage.myLegalIdentityKey)
val notaryKey = notary.services.notaryIdentityKey
val sellerKey = seller.services.legalIdentityKey
tx.signWith(notaryKey)
tx.signWith(sellerKey)
tx.toSignedTransaction(true)
}
seller.services.recordTransactions(issuance)
@ -48,15 +50,16 @@ class TradeSimulation(runAsync: Boolean, latencyInjector: InMemoryMessagingNetwo
val amount = 1000.DOLLARS
val buyerFuture = buyer.initiateSingleShotProtocol(Seller::class) {
Buyer(it, notary.info.identity, amount, CommercialPaper.State::class.java)
Buyer(it, notary.info.notaryIdentity, amount, CommercialPaper.State::class.java)
}.flatMap { it.resultFuture }
val sellerKey = seller.services.legalIdentityKey
val sellerProtocol = Seller(
buyer.info.identity,
buyer.info.legalIdentity,
notary.info,
issuance.tx.outRef<OwnableState>(0),
amount,
seller.storage.myLegalIdentityKey)
sellerKey)
showConsensusFor(listOf(buyer, seller, notary))
showProgressFor(listOf(buyer, seller))

View File

@ -11,6 +11,7 @@ import com.r3corda.core.contracts.TransactionType
import com.r3corda.core.contracts.`with notary`
import com.r3corda.core.crypto.Party
import com.r3corda.core.crypto.generateKeyPair
import com.r3corda.core.node.services.ServiceInfo
import com.r3corda.core.utilities.DUMMY_NOTARY
import com.r3corda.core.utilities.LogHelper
import com.r3corda.testing.node.MockNetwork
@ -141,13 +142,14 @@ class NodeInterestRatesTest {
@Test
fun network() {
val net = MockNetwork()
val (n1, n2) = net.createTwoNodes()
val n1 = net.createNotaryNode()
val n2 = net.createNode(n1.info.address, advertisedServices = ServiceInfo(NodeInterestRates.type))
databaseTransaction(n2.database) {
n2.findService<NodeInterestRates.Service>().oracle.knownFixes = TEST_DATA
}
val tx = TransactionType.General.Builder(null)
val fixOf = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M")
val protocol = RatesFixProtocol(tx, n2.info.identity, fixOf, "0.675".bd, "0.1".bd)
val protocol = RatesFixProtocol(tx, n2.info.serviceIdentities(NodeInterestRates.type).first(), fixOf, "0.675".bd, "0.1".bd)
LogHelper.setLevel("rates")
net.runNetwork()
val future = n1.services.startProtocol("rates", protocol)

View File

@ -20,8 +20,8 @@ class MockNetworkMapCache() : com.r3corda.node.services.network.InMemoryNetworkM
init {
val mockNodeA = NodeInfo(MockAddress("bankC:8080"), Party("Bank C", DummyPublicKey("Bank C")))
val mockNodeB = NodeInfo(MockAddress("bankD:8080"), Party("Bank D", DummyPublicKey("Bank D")))
registeredNodes[mockNodeA.identity] = mockNodeA
registeredNodes[mockNodeB.identity] = mockNodeB
registeredNodes[mockNodeA.legalIdentity] = mockNodeA
registeredNodes[mockNodeB.legalIdentity] = mockNodeB
runWithoutMapService()
}
@ -31,7 +31,7 @@ class MockNetworkMapCache() : com.r3corda.node.services.network.InMemoryNetworkM
*/
@VisibleForTesting
fun addRegistration(node: NodeInfo) {
registeredNodes[node.identity] = node
registeredNodes[node.legalIdentity] = node
}
/**
@ -39,7 +39,7 @@ class MockNetworkMapCache() : com.r3corda.node.services.network.InMemoryNetworkM
* not a change being received.
*/
@VisibleForTesting
fun deleteRegistration(identity: Party) : Boolean {
return registeredNodes.remove(identity) != null
fun deleteRegistration(legalIdentity: Party) : Boolean {
return registeredNodes.remove(legalIdentity) != null
}
}

View File

@ -107,7 +107,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
override fun makeVaultService(): VaultService = InMemoryVaultService(services)
override fun makeKeyManagementService(): KeyManagementService = E2ETestKeyManagementService(setOf(storage.myLegalIdentityKey))
override fun makeKeyManagementService(): KeyManagementService = E2ETestKeyManagementService(partyKeys)
override fun startMessagingService(cordaRPCOps: CordaRPCOps?) {
// Nothing to do
@ -129,7 +129,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
override fun start(): MockNode {
super.start()
mockNet.identities.add(storage.myLegalIdentity)
mockNet.identities.add(info.legalIdentity)
return this
}
@ -212,7 +212,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
fun createTwoNodes(nodeFactory: Factory = defaultFactory, notaryKeyPair: KeyPair? = null): Pair<MockNode, MockNode> {
require(nodes.isEmpty())
return Pair(
createNode(null, -1, nodeFactory, true, null, notaryKeyPair, ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type)),
createNode(null, -1, nodeFactory, true, null, notaryKeyPair, ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type)),
createNode(nodes[0].info.address, -1, nodeFactory, true, null)
)
}
@ -229,9 +229,9 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
*/
fun createSomeNodes(numPartyNodes: Int = 2, nodeFactory: Factory = defaultFactory, notaryKeyPair: KeyPair? = DUMMY_NOTARY_KEY): BasketOfNodes {
require(nodes.isEmpty())
val mapNode = createNode(null, nodeFactory = nodeFactory, advertisedServices = ServiceInfo(NetworkMapService.Type))
val mapNode = createNode(null, nodeFactory = nodeFactory, advertisedServices = ServiceInfo(NetworkMapService.type))
val notaryNode = createNode(mapNode.info.address, nodeFactory = nodeFactory, keyPair = notaryKeyPair,
advertisedServices = ServiceInfo(SimpleNotaryService.Type))
advertisedServices = ServiceInfo(SimpleNotaryService.type))
val nodes = ArrayList<MockNode>()
repeat(numPartyNodes) {
nodes += createPartyNode(mapNode.info.address)
@ -240,7 +240,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
}
fun createNotaryNode(legalName: String? = null, keyPair: KeyPair? = null): MockNode {
return createNode(null, -1, defaultFactory, true, legalName, keyPair, ServiceInfo(NetworkMapService.Type), ServiceInfo(SimpleNotaryService.Type))
return createNode(null, -1, defaultFactory, true, legalName, keyPair, ServiceInfo(NetworkMapService.type), ServiceInfo(SimpleNotaryService.type))
}
fun createPartyNode(networkMapAddr: SingleMessageRecipient, legalName: String? = null, keyPair: KeyPair? = null): MockNode {

View File

@ -7,6 +7,8 @@ import com.r3corda.core.crypto.SecureHash
import com.r3corda.core.crypto.generateKeyPair
import com.r3corda.core.crypto.sha256
import com.r3corda.core.messaging.MessagingService
import com.r3corda.core.messaging.SingleMessageRecipient
import com.r3corda.core.node.NodeInfo
import com.r3corda.core.node.ServiceHub
import com.r3corda.core.node.services.*
import com.r3corda.core.protocols.ProtocolLogic
@ -52,7 +54,7 @@ open class MockServices(val key: KeyPair = generateKeyPair()) : ServiceHub {
}
}
override val storageService: TxWritableStorageService = MockStorageService(myLegalIdentityKey = key)
override val storageService: TxWritableStorageService = MockStorageService()
override val identityService: MockIdentityService = MockIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_NOTARY))
override val keyManagementService: MockKeyManagementService = MockKeyManagementService(key)
@ -61,6 +63,7 @@ open class MockServices(val key: KeyPair = generateKeyPair()) : ServiceHub {
override val networkMapCache: NetworkMapCache get() = throw UnsupportedOperationException()
override val clock: Clock get() = throw UnsupportedOperationException()
override val schedulerService: SchedulerService get() = throw UnsupportedOperationException()
override val myInfo: NodeInfo get() = NodeInfo(object : SingleMessageRecipient {} , Party("MegaCorp", key.public))
}
@ThreadSafe
@ -150,8 +153,6 @@ open class MockTransactionStorage : TransactionStorage {
@ThreadSafe
class MockStorageService(override val attachments: AttachmentStorage = MockAttachmentStorage(),
override val validatedTransactions: TransactionStorage = MockTransactionStorage(),
override val myLegalIdentityKey: KeyPair = generateKeyPair(),
override val myLegalIdentity: Party = Party("Unit test party", myLegalIdentityKey.public),
override val stateMachineRecordedTransactionMapping: StateMachineRecordedTransactionMappingStorage = MockStateMachineRecordedTransactionMappingStorage())
: SingletonSerializeAsToken(), TxWritableStorageService