diff --git a/contracts/src/main/kotlin/contracts/IRSUtils.kt b/contracts/src/main/kotlin/contracts/IRSUtils.kt index 936b73584a..4cab943f50 100644 --- a/contracts/src/main/kotlin/contracts/IRSUtils.kt +++ b/contracts/src/main/kotlin/contracts/IRSUtils.kt @@ -1,8 +1,8 @@ package contracts -import core.* +import core.Amount +import core.Tenor import java.math.BigDecimal -import java.security.PublicKey // Things in here will move to the general utils class when we've hammered out various discussions regarding amounts, dates, oracle etc. @@ -41,53 +41,6 @@ open class PercentageRatioUnit(percentageAsString: String) : RatioUnit(BigDecima */ val String.percent: PercentageRatioUnit get() = PercentageRatioUnit(this) -/** - * Interface representing an agreement that exposes various attributes that are common. Implementing it simplifies - * implementation of general protocols that manipulate many agreement types. - */ -interface DealState : LinearState { - - /** Human readable well known reference (e.g. trade reference) */ - val ref: String - - /** Exposes the Parties involved in a generic way */ - val parties: Array - - // TODO: This works by editing the keys used by a Party which is invalid. - fun withPublicKey(before: Party, after: PublicKey): DealState - - /** - * Generate a partial transaction representing an agreement (command) to this deal, allowing a general - * deal/agreement protocol to generate the necessary transaction for potential implementations - * - * TODO: Currently this is the "inception" transaction but in future an offer of some description might be an input state ref - * - * TODO: This should more likely be a method on the Contract (on a common interface) and the changes to reference a - * Contract instance from a ContractState are imminent, at which point we can move this out of here - */ - fun generateAgreement(): TransactionBuilder -} - -/** - * Interface adding fixing specific methods - */ -interface FixableDealState : DealState { - /** - * When is the next fixing and what is the fixing for? - * - * TODO: In future we would use this to register for an event to trigger a/the fixing protocol - */ - fun nextFixingOf(): FixOf? - - /** - * Generate a fixing command for this deal and fix - * - * TODO: This would also likely move to methods on the Contract once the changes to reference - * the Contract from the ContractState are in - */ - fun generateFix(ptx: TransactionBuilder, oldStateRef: StateRef, fix: Fix) -} - /** * Parent of the Rate family. Used to denote fixed rates, floating rates, reference rates etc */ diff --git a/core/src/main/kotlin/core/Structures.kt b/core/src/main/kotlin/core/Structures.kt index 8c9a8e9b1c..f9831972f1 100644 --- a/core/src/main/kotlin/core/Structures.kt +++ b/core/src/main/kotlin/core/Structures.kt @@ -59,6 +59,53 @@ interface LinearState : ContractState { fun isRelevant(ourKeys: Set): Boolean } +/** + * Interface representing an agreement that exposes various attributes that are common. Implementing it simplifies + * implementation of general protocols that manipulate many agreement types. + */ +interface DealState : LinearState { + + /** Human readable well known reference (e.g. trade reference) */ + val ref: String + + /** Exposes the Parties involved in a generic way */ + val parties: Array + + // TODO: This works by editing the keys used by a Party which is invalid. + fun withPublicKey(before: Party, after: PublicKey): DealState + + /** + * Generate a partial transaction representing an agreement (command) to this deal, allowing a general + * deal/agreement protocol to generate the necessary transaction for potential implementations + * + * TODO: Currently this is the "inception" transaction but in future an offer of some description might be an input state ref + * + * TODO: This should more likely be a method on the Contract (on a common interface) and the changes to reference a + * Contract instance from a ContractState are imminent, at which point we can move this out of here + */ + fun generateAgreement(): TransactionBuilder +} + +/** + * Interface adding fixing specific methods + */ +interface FixableDealState : DealState { + /** + * When is the next fixing and what is the fixing for? + * + * TODO: In future we would use this to register for an event to trigger a/the fixing protocol + */ + fun nextFixingOf(): FixOf? + + /** + * Generate a fixing command for this deal and fix + * + * TODO: This would also likely move to methods on the Contract once the changes to reference + * the Contract from the ContractState are in + */ + fun generateFix(ptx: TransactionBuilder, oldStateRef: StateRef, fix: Fix) +} + /** Returns the SHA-256 hash of the serialised contents of this state (not cached!) */ fun ContractState.hash(): SecureHash = SecureHash.sha256(serialize().bits) diff --git a/core/src/main/kotlin/core/node/NodeInfo.kt b/core/src/main/kotlin/core/node/NodeInfo.kt index 1e57e10640..a5abf72df2 100644 --- a/core/src/main/kotlin/core/node/NodeInfo.kt +++ b/core/src/main/kotlin/core/node/NodeInfo.kt @@ -1,10 +1,3 @@ -/* - * Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members - * pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms - * set forth therein. - * - * All other rights reserved. - */ package core.node import core.Party diff --git a/core/src/main/kotlin/core/node/PhysicalLocationStructures.kt b/core/src/main/kotlin/core/node/PhysicalLocationStructures.kt index ac0a33d5dc..7fba96aea9 100644 --- a/core/src/main/kotlin/core/node/PhysicalLocationStructures.kt +++ b/core/src/main/kotlin/core/node/PhysicalLocationStructures.kt @@ -1,11 +1,3 @@ -/* - * Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members - * pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms - * set forth therein. - * - * All other rights reserved. - */ - package core.node import java.util.* diff --git a/src/main/kotlin/core/protocols/ProtocolLogic.kt b/core/src/main/kotlin/core/protocols/ProtocolLogic.kt similarity index 100% rename from src/main/kotlin/core/protocols/ProtocolLogic.kt rename to core/src/main/kotlin/core/protocols/ProtocolLogic.kt diff --git a/src/main/kotlin/protocols/FetchAttachmentsProtocol.kt b/core/src/main/kotlin/protocols/FetchAttachmentsProtocol.kt similarity index 100% rename from src/main/kotlin/protocols/FetchAttachmentsProtocol.kt rename to core/src/main/kotlin/protocols/FetchAttachmentsProtocol.kt diff --git a/src/main/kotlin/protocols/FetchDataProtocol.kt b/core/src/main/kotlin/protocols/FetchDataProtocol.kt similarity index 94% rename from src/main/kotlin/protocols/FetchDataProtocol.kt rename to core/src/main/kotlin/protocols/FetchDataProtocol.kt index f4366ce4f9..6c4e09732a 100644 --- a/src/main/kotlin/protocols/FetchDataProtocol.kt +++ b/core/src/main/kotlin/protocols/FetchDataProtocol.kt @@ -4,7 +4,6 @@ import co.paralleluniverse.fibers.Suspendable import core.NamedByHash import core.crypto.SecureHash import core.messaging.SingleMessageRecipient -import core.node.subsystems.DataVendingService import core.protocols.ProtocolLogic import core.random63BitValue import core.utilities.UntrustworthyData @@ -34,6 +33,7 @@ abstract class FetchDataProtocol( class HashNotFound(val requested: SecureHash) : BadAnswer() class DownloadedVsRequestedDataMismatch(val requested: SecureHash, val got: SecureHash) : BadAnswer() + class Request(val hashes: List, replyTo: SingleMessageRecipient, sessionID: Long) : AbstractRequestMessage(replyTo, sessionID) data class Result(val fromDisk: List, val downloaded: List) protected abstract val queryTopic: String @@ -49,7 +49,7 @@ abstract class FetchDataProtocol( logger.trace("Requesting ${toFetch.size} dependency(s) for verification") val sid = random63BitValue() - val fetchReq = DataVendingService.Request(toFetch, serviceHub.networkService.myAddress, sid) + val fetchReq = Request(toFetch, serviceHub.networkService.myAddress, sid) // TODO: Support "large message" response streaming so response sizes are not limited by RAM. val maybeItems = sendAndReceive>(queryTopic, otherSide, 0, sid, fetchReq) // Check for a buggy/malicious peer answering with something that we didn't ask for. @@ -98,4 +98,5 @@ abstract class FetchDataProtocol( answers } + } \ No newline at end of file diff --git a/src/main/kotlin/protocols/FetchTransactionsProtocol.kt b/core/src/main/kotlin/protocols/FetchTransactionsProtocol.kt similarity index 100% rename from src/main/kotlin/protocols/FetchTransactionsProtocol.kt rename to core/src/main/kotlin/protocols/FetchTransactionsProtocol.kt diff --git a/src/main/kotlin/protocols/RatesFixProtocol.kt b/core/src/main/kotlin/protocols/RatesFixProtocol.kt similarity index 100% rename from src/main/kotlin/protocols/RatesFixProtocol.kt rename to core/src/main/kotlin/protocols/RatesFixProtocol.kt diff --git a/src/main/kotlin/protocols/ResolveTransactionsProtocol.kt b/core/src/main/kotlin/protocols/ResolveTransactionsProtocol.kt similarity index 100% rename from src/main/kotlin/protocols/ResolveTransactionsProtocol.kt rename to core/src/main/kotlin/protocols/ResolveTransactionsProtocol.kt diff --git a/src/main/kotlin/protocols/TimestampingProtocol.kt b/core/src/main/kotlin/protocols/TimestampingProtocol.kt similarity index 77% rename from src/main/kotlin/protocols/TimestampingProtocol.kt rename to core/src/main/kotlin/protocols/TimestampingProtocol.kt index b6ce07c5b5..6d10bb5f4d 100644 --- a/src/main/kotlin/protocols/TimestampingProtocol.kt +++ b/core/src/main/kotlin/protocols/TimestampingProtocol.kt @@ -1,14 +1,10 @@ package protocols import co.paralleluniverse.fibers.Suspendable -import core.Party import core.WireTransaction import core.crypto.DigitalSignature import core.messaging.MessageRecipients -import core.messaging.StateMachineManager import core.node.NodeInfo -import core.node.services.NodeTimestamperService -import core.node.services.TimestamperService import core.protocols.ProtocolLogic import core.random63BitValue import core.serialization.SerializedBytes @@ -27,19 +23,13 @@ class TimestampingProtocol(private val node: NodeInfo, private val wtxBytes: SerializedBytes, override val progressTracker: ProgressTracker = TimestampingProtocol.tracker()) : ProtocolLogic() { - class Client(private val stateMachineManager: StateMachineManager, private val node: NodeInfo) : TimestamperService { - override val identity: Party = node.identity - - override fun timestamp(wtxBytes: SerializedBytes): DigitalSignature.LegallyIdentifiable { - return stateMachineManager.add("platform.timestamping", TimestampingProtocol(node, wtxBytes)).get() - } - } - companion object { object REQUESTING : ProgressTracker.Step("Requesting signature by timestamping service") object VALIDATING : ProgressTracker.Step("Validating received signature from timestamping service") fun tracker() = ProgressTracker(REQUESTING, VALIDATING) + + val TOPIC = "platform.timestamping.request" } @@ -49,8 +39,7 @@ class TimestampingProtocol(private val node: NodeInfo, val sessionID = random63BitValue() val req = Request(wtxBytes, serviceHub.networkService.myAddress, sessionID) - val maybeSignature = sendAndReceive( - NodeTimestamperService.TIMESTAMPING_PROTOCOL_TOPIC, node.address, 0, sessionID, req) + val maybeSignature = sendAndReceive(TOPIC, node.address, 0, sessionID, req) // Check that the timestamping authority gave us back a valid signature and didn't break somehow progressTracker.currentStep = VALIDATING diff --git a/src/main/kotlin/protocols/TwoPartyDealProtocol.kt b/core/src/main/kotlin/protocols/TwoPartyDealProtocol.kt similarity index 99% rename from src/main/kotlin/protocols/TwoPartyDealProtocol.kt rename to core/src/main/kotlin/protocols/TwoPartyDealProtocol.kt index 4928c4cbe3..35f1deb05b 100644 --- a/src/main/kotlin/protocols/TwoPartyDealProtocol.kt +++ b/core/src/main/kotlin/protocols/TwoPartyDealProtocol.kt @@ -1,8 +1,6 @@ package protocols import co.paralleluniverse.fibers.Suspendable -import contracts.DealState -import contracts.FixableDealState import core.* import core.crypto.DigitalSignature import core.crypto.signWithECDSA diff --git a/src/main/kotlin/api/APIServerImpl.kt b/src/main/kotlin/api/APIServerImpl.kt index ebda1cd4ab..c92c117d1e 100644 --- a/src/main/kotlin/api/APIServerImpl.kt +++ b/src/main/kotlin/api/APIServerImpl.kt @@ -1,11 +1,7 @@ package api import com.google.common.util.concurrent.ListenableFuture -import contracts.DealState -import core.ContractState -import core.SignedTransaction -import core.StateRef -import core.WireTransaction +import core.* import core.crypto.DigitalSignature import core.crypto.SecureHash import core.node.AbstractNode diff --git a/src/main/kotlin/core/node/services/NodeTimestamperService.kt b/src/main/kotlin/core/node/services/NodeTimestamperService.kt index fb5c19fb68..cadd3d4d3b 100644 --- a/src/main/kotlin/core/node/services/NodeTimestamperService.kt +++ b/src/main/kotlin/core/node/services/NodeTimestamperService.kt @@ -5,11 +5,9 @@ import core.Party import core.TimestampCommand import core.crypto.DigitalSignature import core.crypto.signWithECDSA -import core.messaging.Message import core.messaging.MessagingService import core.seconds import core.serialization.deserialize -import core.serialization.serialize import core.until import org.slf4j.LoggerFactory import protocols.TimestampingProtocol @@ -31,14 +29,12 @@ class NodeTimestamperService(net: MessagingService, val clock: Clock = Clock.systemDefaultZone(), val tolerance: Duration = 30.seconds) : AbstractNodeService(net) { companion object { - val TIMESTAMPING_PROTOCOL_TOPIC = "platform.timestamping.request" - private val logger = LoggerFactory.getLogger(NodeTimestamperService::class.java) } init { require(identity.owningKey == signingKey.public) - addMessageHandler(TIMESTAMPING_PROTOCOL_TOPIC, + addMessageHandler(TimestampingProtocol.TOPIC, { req: TimestampingProtocol.Request -> processRequest(req) }, { message, e -> if (e is TimestampingError) { diff --git a/src/main/kotlin/core/node/subsystems/DataVendingService.kt b/src/main/kotlin/core/node/subsystems/DataVendingService.kt index 728e142e0f..44925bac57 100644 --- a/src/main/kotlin/core/node/subsystems/DataVendingService.kt +++ b/src/main/kotlin/core/node/subsystems/DataVendingService.kt @@ -1,17 +1,11 @@ package core.node.subsystems import core.SignedTransaction -import core.crypto.SecureHash -import core.messaging.Message import core.messaging.MessagingService -import core.messaging.SingleMessageRecipient -import core.messaging.send import core.node.services.AbstractNodeService -import core.node.subsystems.StorageService -import core.serialization.deserialize import core.utilities.loggerFor -import protocols.AbstractRequestMessage import protocols.FetchAttachmentsProtocol +import protocols.FetchDataProtocol import protocols.FetchTransactionsProtocol import java.io.InputStream import javax.annotation.concurrent.ThreadSafe @@ -36,18 +30,16 @@ class DataVendingService(net: MessagingService, private val storage: StorageServ init { addMessageHandler(FetchTransactionsProtocol.TOPIC, - { req: Request -> handleTXRequest(req) }, + { req: FetchDataProtocol.Request -> handleTXRequest(req) }, { message, e -> logger.error("Failure processing data vending request.", e) } ) addMessageHandler(FetchAttachmentsProtocol.TOPIC, - { req: Request -> handleAttachmentRequest(req) }, + { req: FetchDataProtocol.Request -> handleAttachmentRequest(req) }, { message, e -> logger.error("Failure processing data vending request.", e) } ) } - class Request(val hashes: List, replyTo: SingleMessageRecipient, sessionID: Long) : AbstractRequestMessage(replyTo, sessionID) - - private fun handleTXRequest(req: Request): List { + private fun handleTXRequest(req: FetchDataProtocol.Request): List { require(req.hashes.isNotEmpty()) return req.hashes.map { val tx = storage.validatedTransactions[it] @@ -57,7 +49,7 @@ class DataVendingService(net: MessagingService, private val storage: StorageServ } } - private fun handleAttachmentRequest(req: Request): List { + private fun handleAttachmentRequest(req: FetchDataProtocol.Request): List { // TODO: Use Artemis message streaming support here, called "large messages". This avoids the need to buffer. require(req.hashes.isNotEmpty()) return req.hashes.map { diff --git a/src/main/kotlin/demos/protocols/AutoOfferProtocol.kt b/src/main/kotlin/demos/protocols/AutoOfferProtocol.kt index 0f4cb5732a..74b3707f58 100644 --- a/src/main/kotlin/demos/protocols/AutoOfferProtocol.kt +++ b/src/main/kotlin/demos/protocols/AutoOfferProtocol.kt @@ -3,7 +3,7 @@ package demos.protocols import co.paralleluniverse.fibers.Suspendable import com.google.common.util.concurrent.FutureCallback import com.google.common.util.concurrent.Futures -import contracts.DealState +import core.DealState import core.Party import core.SignedTransaction import core.messaging.SingleMessageRecipient diff --git a/src/main/kotlin/demos/protocols/UpdateBusinessDayProtocol.kt b/src/main/kotlin/demos/protocols/UpdateBusinessDayProtocol.kt index be8ef4fdb4..784b7837e3 100644 --- a/src/main/kotlin/demos/protocols/UpdateBusinessDayProtocol.kt +++ b/src/main/kotlin/demos/protocols/UpdateBusinessDayProtocol.kt @@ -1,8 +1,8 @@ package demos.protocols import co.paralleluniverse.fibers.Suspendable -import contracts.DealState import contracts.InterestRateSwap +import core.DealState import core.StateAndRef import core.node.Node import core.node.NodeInfo @@ -15,7 +15,6 @@ import core.utilities.ANSIProgressRenderer import core.utilities.ProgressTracker import demos.DemoClock import protocols.TwoPartyDealProtocol -import java.security.KeyPair import java.time.LocalDate /** diff --git a/src/test/kotlin/core/node/services/TimestamperNodeServiceTest.kt b/src/test/kotlin/core/node/services/TimestamperNodeServiceTest.kt index fc7d21f55c..98f19b7807 100644 --- a/src/test/kotlin/core/node/services/TimestamperNodeServiceTest.kt +++ b/src/test/kotlin/core/node/services/TimestamperNodeServiceTest.kt @@ -4,7 +4,6 @@ import co.paralleluniverse.fibers.Suspendable import core.* import core.crypto.SecureHash import core.node.NodeInfo -import core.node.services.* import core.protocols.ProtocolLogic import core.serialization.serialize import core.testing.MockNetwork @@ -57,7 +56,7 @@ class TimestamperNodeServiceTest { @Test fun successWithNetwork() { val timestamperNode = network.createNode(null, advertisedServices = TimestamperService.Type) - val logName = NodeTimestamperService.TIMESTAMPING_PROTOCOL_TOPIC + val logName = TimestampingProtocol.TOPIC val psm = TestPSM(timestamperNode.info, clock.instant()) val future = timestamperNode.smm.add(logName, psm)