Merged in plt-141-moves-only-part-3 (pull request #93)

File and interface moves to core module for scheduler
This commit is contained in:
Rick Parker 2016-05-13 15:17:32 +01:00
commit 539e23a0b1
18 changed files with 65 additions and 110 deletions

View File

@ -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<Party>
// 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
*/

View File

@ -59,6 +59,53 @@ interface LinearState : ContractState {
fun isRelevant(ourKeys: Set<PublicKey>): 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<Party>
// 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)

View File

@ -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

View File

@ -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.*

View File

@ -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<T : NamedByHash, W : Any>(
class HashNotFound(val requested: SecureHash) : BadAnswer()
class DownloadedVsRequestedDataMismatch(val requested: SecureHash, val got: SecureHash) : BadAnswer()
class Request(val hashes: List<SecureHash>, replyTo: SingleMessageRecipient, sessionID: Long) : AbstractRequestMessage(replyTo, sessionID)
data class Result<T : NamedByHash>(val fromDisk: List<T>, val downloaded: List<T>)
protected abstract val queryTopic: String
@ -49,7 +49,7 @@ abstract class FetchDataProtocol<T : NamedByHash, W : Any>(
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<ArrayList<W?>>(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<T : NamedByHash, W : Any>(
answers
}
}

View File

@ -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<WireTransaction>,
override val progressTracker: ProgressTracker = TimestampingProtocol.tracker()) : ProtocolLogic<DigitalSignature.LegallyIdentifiable>() {
class Client(private val stateMachineManager: StateMachineManager, private val node: NodeInfo) : TimestamperService {
override val identity: Party = node.identity
override fun timestamp(wtxBytes: SerializedBytes<WireTransaction>): 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<DigitalSignature.LegallyIdentifiable>(
NodeTimestamperService.TIMESTAMPING_PROTOCOL_TOPIC, node.address, 0, sessionID, req)
val maybeSignature = sendAndReceive<DigitalSignature.LegallyIdentifiable>(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

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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<SecureHash>, replyTo: SingleMessageRecipient, sessionID: Long) : AbstractRequestMessage(replyTo, sessionID)
private fun handleTXRequest(req: Request): List<SignedTransaction?> {
private fun handleTXRequest(req: FetchDataProtocol.Request): List<SignedTransaction?> {
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<ByteArray?> {
private fun handleAttachmentRequest(req: FetchDataProtocol.Request): List<ByteArray?> {
// TODO: Use Artemis message streaming support here, called "large messages". This avoids the need to buffer.
require(req.hashes.isNotEmpty())
return req.hashes.map {

View File

@ -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

View File

@ -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
/**

View File

@ -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)