mirror of
https://github.com/corda/corda.git
synced 2024-12-20 05:28:21 +00:00
Merged in mnesbit-fix-irs (pull request #399)
Fix IRS Demo by giving advertised services an identity
This commit is contained in:
commit
7a440d890d
@ -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
|
||||
|
@ -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,10 +124,11 @@ fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode): StateAndRef<
|
||||
return stateAndRef
|
||||
}
|
||||
|
||||
fun issueInvalidState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateAndRef<*> {
|
||||
val tx = DummyContract.generateInitial(node.info.identity.ref(0), Random().nextInt(), notary)
|
||||
fun issueInvalidState(node: AbstractNode, notary: Party): StateAndRef<*> {
|
||||
val tx = DummyContract.generateInitial(node.info.legalIdentity.ref(0), Random().nextInt(), notary)
|
||||
tx.setTime(Instant.now(), 30.seconds)
|
||||
tx.signWith(node.storage.myLegalIdentityKey)
|
||||
val nodeKey = node.services.legalIdentityKey
|
||||
tx.signWith(nodeKey)
|
||||
val stx = tx.toSignedTransaction(false)
|
||||
node.services.recordTransactions(listOf(stx))
|
||||
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
|
||||
|
@ -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…
Reference in New Issue
Block a user