mirror of
https://github.com/corda/corda.git
synced 2025-04-07 11:27:01 +00:00
Change ServiceType to a sealed class from an abstract class
Allow AdvertisedServices to have their own identity and keys. Also, rationalise legalIdentity onto the local node's NodeInfo which is available on ServiceHub Fixup after rebase Remove legal identity that was on storage service. Now access via myInfo.legalIdentity and key via keyManagement lookup. Enforce singleton notary per node for now Tidy up based upon Rick's suggestions Handle PR comments clean up imports Fix typo Fixup rename Capitalise comment Eliminate unused variable warning Make changes based upon PR comments Cleanup whitespace changes
This commit is contained in:
parent
4e2f0e0ff9
commit
1e836edd78
@ -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
|
||||
}
|
||||
)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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 }
|
||||
}
|
||||
|
@ -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
|
||||
@ -59,4 +78,4 @@ interface ServiceHub {
|
||||
*
|
||||
* @param txs The transactions to record.
|
||||
*/
|
||||
fun ServiceHub.recordTransactions(vararg txs: SignedTransaction) = recordTransactions(txs.toList())
|
||||
fun ServiceHub.recordTransactions(vararg txs: SignedTransaction) = recordTransactions(txs.toList())
|
@ -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)
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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 ->
|
||||
|
@ -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}")
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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() } })
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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" }
|
||||
|
@ -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) }
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -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() }
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() }
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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,11 +124,12 @@ 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))
|
||||
}
|
||||
}
|
@ -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))
|
||||
}
|
||||
}
|
@ -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))
|
||||
}
|
||||
}
|
@ -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()
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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)))
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ object ExitServerProtocol {
|
||||
if (recipient.address is MockNetworkMapCache.MockAddress) {
|
||||
// Ignore
|
||||
} else {
|
||||
send(recipient.identity, ExitMessage(exitCode))
|
||||
send(recipient.legalIdentity, ExitMessage(exitCode))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ object UpdateBusinessDayProtocol {
|
||||
if (recipient.address is MockNetworkMapCache.MockAddress) {
|
||||
// Ignore
|
||||
} else {
|
||||
send(recipient.identity, UpdateBusinessDayMessage(date))
|
||||
send(recipient.legalIdentity, UpdateBusinessDayMessage(date))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 }
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user