From e9fddbc7097011e2c5ccfcb2ce34bf6dd7915f1a Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 8 Mar 2016 11:06:16 +0100 Subject: [PATCH 01/35] Reorganise the file hierarchy a bit. --- .../src/main/java/contracts/JavaCommercialPaper.java | 1 + contracts/src/main/kotlin/{ => contracts}/Cash.kt | 0 .../main/kotlin/{ => contracts}/CommercialPaper.kt | 0 .../src}/main/kotlin/contracts/CrowdFund.kt | 1 + .../src}/main/kotlin/contracts/DummyContract.kt | 0 core/src/main/kotlin/core/Transactions.kt | 1 + .../core/{ => node/services}/TimestamperService.kt | 12 +++++++++++- src/main/kotlin/core/TransactionTools.kt | 1 + .../kotlin/core/messaging/StateMachineManager.kt | 2 +- src/main/kotlin/core/node/AbstractNode.kt | 1 + src/main/kotlin/core/node/Node.kt | 1 + src/main/kotlin/core/node/TraderDemo.kt | 6 +++++- .../node/{ => services}/ArtemisMessagingService.kt | 4 ++-- .../core/node/{ => services}/DataVendingService.kt | 8 ++++---- .../{ => services}/E2ETestKeyManagementService.kt | 4 ++-- .../core/node/{ => services}/FixedIdentityService.kt | 2 +- .../node/{ => services}/NodeAttachmentStorage.kt | 4 ++-- .../core/node/{ => services}/NodeWalletService.kt | 2 +- src/main/kotlin/core/{ => node/services}/Services.kt | 3 ++- .../node/{ => services}/TimestamperNodeService.kt | 4 +++- .../core/node/servlets/AttachmentDownloadServlet.kt | 2 +- .../core/node/servlets/AttachmentUploadServlet.kt | 2 +- src/main/kotlin/core/protocols/ProtocolLogic.kt | 2 +- .../kotlin/core/protocols/ProtocolStateMachine.kt | 2 +- .../protocols/FetchAttachmentsProtocol.kt | 2 +- .../{contracts => }/protocols/FetchDataProtocol.kt | 4 ++-- .../protocols/FetchTransactionsProtocol.kt | 2 +- .../protocols/ResolveTransactionsProtocol.kt | 2 +- .../protocols/TwoPartyTradeProtocol.kt | 10 +++++----- src/test/kotlin/contracts/CommercialPaperTests.kt | 1 + src/test/kotlin/contracts/CrowdFundTests.kt | 1 + src/test/kotlin/core/MockServices.kt | 2 +- src/test/kotlin/core/messaging/AttachmentTests.kt | 6 +++--- .../core/messaging/InMemoryMessagingNetwork.kt | 4 ++-- .../core/messaging/TwoPartyTradeProtocolTests.kt | 5 ++--- src/test/kotlin/core/node/MockNode.kt | 1 + .../kotlin/core/node/NodeAttachmentStorageTest.kt | 1 + src/test/kotlin/core/node/NodeWalletServiceTest.kt | 2 ++ .../kotlin/core/node/TimestamperNodeServiceTest.kt | 4 ++++ src/test/kotlin/core/testutils/TestUtils.kt | 1 + 40 files changed, 73 insertions(+), 40 deletions(-) rename contracts/src/main/kotlin/{ => contracts}/Cash.kt (100%) rename contracts/src/main/kotlin/{ => contracts}/CommercialPaper.kt (100%) rename {src => contracts/src}/main/kotlin/contracts/CrowdFund.kt (99%) rename {src => contracts/src}/main/kotlin/contracts/DummyContract.kt (100%) rename core/src/main/kotlin/core/{ => node/services}/TimestamperService.kt (79%) rename src/main/kotlin/core/node/{ => services}/ArtemisMessagingService.kt (99%) rename src/main/kotlin/core/node/{ => services}/DataVendingService.kt (95%) rename src/main/kotlin/core/node/{ => services}/E2ETestKeyManagementService.kt (95%) rename src/main/kotlin/core/node/{ => services}/FixedIdentityService.kt (96%) rename src/main/kotlin/core/node/{ => services}/NodeAttachmentStorage.kt (98%) rename src/main/kotlin/core/node/{ => services}/NodeWalletService.kt (99%) rename src/main/kotlin/core/{ => node/services}/Services.kt (99%) rename src/main/kotlin/core/node/{ => services}/TimestamperNodeService.kt (98%) rename src/main/kotlin/{contracts => }/protocols/FetchAttachmentsProtocol.kt (98%) rename src/main/kotlin/{contracts => }/protocols/FetchDataProtocol.kt (98%) rename src/main/kotlin/{contracts => }/protocols/FetchTransactionsProtocol.kt (97%) rename src/main/kotlin/{contracts => }/protocols/ResolveTransactionsProtocol.kt (99%) rename src/main/kotlin/{contracts => }/protocols/TwoPartyTradeProtocol.kt (98%) diff --git a/contracts/src/main/java/contracts/JavaCommercialPaper.java b/contracts/src/main/java/contracts/JavaCommercialPaper.java index 314031d75d..798ff960d2 100644 --- a/contracts/src/main/java/contracts/JavaCommercialPaper.java +++ b/contracts/src/main/java/contracts/JavaCommercialPaper.java @@ -12,6 +12,7 @@ import core.*; import core.TransactionForVerification.InOutGroup; import core.crypto.NullPublicKey; import core.crypto.SecureHash; +import core.node.services.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/contracts/src/main/kotlin/Cash.kt b/contracts/src/main/kotlin/contracts/Cash.kt similarity index 100% rename from contracts/src/main/kotlin/Cash.kt rename to contracts/src/main/kotlin/contracts/Cash.kt diff --git a/contracts/src/main/kotlin/CommercialPaper.kt b/contracts/src/main/kotlin/contracts/CommercialPaper.kt similarity index 100% rename from contracts/src/main/kotlin/CommercialPaper.kt rename to contracts/src/main/kotlin/contracts/CommercialPaper.kt diff --git a/src/main/kotlin/contracts/CrowdFund.kt b/contracts/src/main/kotlin/contracts/CrowdFund.kt similarity index 99% rename from src/main/kotlin/contracts/CrowdFund.kt rename to contracts/src/main/kotlin/contracts/CrowdFund.kt index 5294e049ae..8c7590821e 100644 --- a/src/main/kotlin/contracts/CrowdFund.kt +++ b/contracts/src/main/kotlin/contracts/CrowdFund.kt @@ -10,6 +10,7 @@ package contracts import core.* import core.crypto.SecureHash +import core.node.services.DummyTimestampingAuthority import java.security.PublicKey import java.time.Instant import java.util.* diff --git a/src/main/kotlin/contracts/DummyContract.kt b/contracts/src/main/kotlin/contracts/DummyContract.kt similarity index 100% rename from src/main/kotlin/contracts/DummyContract.kt rename to contracts/src/main/kotlin/contracts/DummyContract.kt diff --git a/core/src/main/kotlin/core/Transactions.kt b/core/src/main/kotlin/core/Transactions.kt index e895b78e3c..a444ffe0de 100644 --- a/core/src/main/kotlin/core/Transactions.kt +++ b/core/src/main/kotlin/core/Transactions.kt @@ -14,6 +14,7 @@ import core.crypto.SecureHash import core.crypto.signWithECDSA import core.crypto.toStringShort import core.node.TimestampingError +import core.node.services.TimestamperService import core.serialization.SerializedBytes import core.serialization.deserialize import core.serialization.serialize diff --git a/core/src/main/kotlin/core/TimestamperService.kt b/core/src/main/kotlin/core/node/services/TimestamperService.kt similarity index 79% rename from core/src/main/kotlin/core/TimestamperService.kt rename to core/src/main/kotlin/core/node/services/TimestamperService.kt index bcd835fb40..110911b305 100644 --- a/core/src/main/kotlin/core/TimestamperService.kt +++ b/core/src/main/kotlin/core/node/services/TimestamperService.kt @@ -1,6 +1,16 @@ -package core +/* + * 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.services import co.paralleluniverse.fibers.Suspendable +import core.Party +import core.WireTransaction import core.crypto.DigitalSignature import core.crypto.generateKeyPair import core.serialization.SerializedBytes diff --git a/src/main/kotlin/core/TransactionTools.kt b/src/main/kotlin/core/TransactionTools.kt index a0b3d5dbe8..de2ee79b91 100644 --- a/src/main/kotlin/core/TransactionTools.kt +++ b/src/main/kotlin/core/TransactionTools.kt @@ -8,6 +8,7 @@ package core +import core.node.services.AttachmentStorage import java.io.FileNotFoundException /** diff --git a/src/main/kotlin/core/messaging/StateMachineManager.kt b/src/main/kotlin/core/messaging/StateMachineManager.kt index 2d7136373d..2783a12f55 100644 --- a/src/main/kotlin/core/messaging/StateMachineManager.kt +++ b/src/main/kotlin/core/messaging/StateMachineManager.kt @@ -15,7 +15,7 @@ import com.esotericsoftware.kryo.io.Input import com.google.common.base.Throwables import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.MoreExecutors -import core.ServiceHub +import core.node.services.ServiceHub import core.crypto.SecureHash import core.crypto.sha256 import core.protocols.ProtocolLogic diff --git a/src/main/kotlin/core/node/AbstractNode.kt b/src/main/kotlin/core/node/AbstractNode.kt index 1373a975c6..29fe751d03 100644 --- a/src/main/kotlin/core/node/AbstractNode.kt +++ b/src/main/kotlin/core/node/AbstractNode.kt @@ -21,6 +21,7 @@ import core.* import core.crypto.SecureHash import core.crypto.generateKeyPair import core.messaging.* +import core.node.services.* import core.serialization.deserialize import core.serialization.serialize import org.slf4j.Logger diff --git a/src/main/kotlin/core/node/Node.kt b/src/main/kotlin/core/node/Node.kt index 55baf61c73..f43f0ee993 100644 --- a/src/main/kotlin/core/node/Node.kt +++ b/src/main/kotlin/core/node/Node.kt @@ -11,6 +11,7 @@ package core.node import com.google.common.net.HostAndPort import core.messaging.LegallyIdentifiableNode import core.messaging.MessagingService +import core.node.services.ArtemisMessagingService import core.node.servlets.AttachmentDownloadServlet import core.node.servlets.AttachmentUploadServlet import core.utilities.loggerFor diff --git a/src/main/kotlin/core/node/TraderDemo.kt b/src/main/kotlin/core/node/TraderDemo.kt index c2027ae3bc..5b4ebb4a78 100644 --- a/src/main/kotlin/core/node/TraderDemo.kt +++ b/src/main/kotlin/core/node/TraderDemo.kt @@ -11,13 +11,17 @@ package core.node import co.paralleluniverse.fibers.Suspendable import com.google.common.net.HostAndPort import contracts.CommercialPaper -import contracts.protocols.TwoPartyTradeProtocol +import protocols.TwoPartyTradeProtocol import core.* import core.crypto.DigitalSignature import core.crypto.SecureHash import core.crypto.generateKeyPair import core.messaging.LegallyIdentifiableNode import core.messaging.SingleMessageRecipient +import core.node.services.ArtemisMessagingService +import core.node.services.NodeAttachmentStorage +import core.node.services.NodeWalletService +import core.node.services.TimestampingProtocol import core.protocols.ProtocolLogic import core.serialization.deserialize import core.utilities.ANSIProgressRenderer diff --git a/src/main/kotlin/core/node/ArtemisMessagingService.kt b/src/main/kotlin/core/node/services/ArtemisMessagingService.kt similarity index 99% rename from src/main/kotlin/core/node/ArtemisMessagingService.kt rename to src/main/kotlin/core/node/services/ArtemisMessagingService.kt index 1eb835eec5..cc0fa633c5 100644 --- a/src/main/kotlin/core/node/ArtemisMessagingService.kt +++ b/src/main/kotlin/core/node/services/ArtemisMessagingService.kt @@ -6,7 +6,7 @@ * All other rights reserved. */ -package core.node +package core.node.services import com.google.common.net.HostAndPort import core.RunOnCallerThread @@ -133,7 +133,7 @@ class ArtemisMessagingService(val directory: Path, val myHostPort: HostAndPort) inboundConsumer = session.createConsumer("inbound").setMessageHandler { message: ClientMessage -> // This code runs for every inbound message. if (!message.containsProperty(TOPIC_PROPERTY)) { - log.warn("Received message without a $TOPIC_PROPERTY property, ignoring") + log.warn("Received message without a ${TOPIC_PROPERTY} property, ignoring") // TODO: Figure out whether we always need to acknowledge messages, even when invalid. return@setMessageHandler } diff --git a/src/main/kotlin/core/node/DataVendingService.kt b/src/main/kotlin/core/node/services/DataVendingService.kt similarity index 95% rename from src/main/kotlin/core/node/DataVendingService.kt rename to src/main/kotlin/core/node/services/DataVendingService.kt index 2e39572dea..d47b2ef799 100644 --- a/src/main/kotlin/core/node/DataVendingService.kt +++ b/src/main/kotlin/core/node/services/DataVendingService.kt @@ -6,11 +6,11 @@ * All other rights reserved. */ -package core.node +package core.node.services -import contracts.protocols.FetchAttachmentsProtocol -import contracts.protocols.FetchTransactionsProtocol -import core.StorageService +import protocols.FetchAttachmentsProtocol +import protocols.FetchTransactionsProtocol +import core.node.services.StorageService import core.crypto.SecureHash import core.messaging.Message import core.messaging.MessagingService diff --git a/src/main/kotlin/core/node/E2ETestKeyManagementService.kt b/src/main/kotlin/core/node/services/E2ETestKeyManagementService.kt similarity index 95% rename from src/main/kotlin/core/node/E2ETestKeyManagementService.kt rename to src/main/kotlin/core/node/services/E2ETestKeyManagementService.kt index 9943454736..c8e699f7d8 100644 --- a/src/main/kotlin/core/node/E2ETestKeyManagementService.kt +++ b/src/main/kotlin/core/node/services/E2ETestKeyManagementService.kt @@ -6,9 +6,9 @@ * All other rights reserved. */ -package core.node +package core.node.services -import core.KeyManagementService +import core.node.services.KeyManagementService import core.ThreadBox import core.crypto.generateKeyPair import java.security.KeyPair diff --git a/src/main/kotlin/core/node/FixedIdentityService.kt b/src/main/kotlin/core/node/services/FixedIdentityService.kt similarity index 96% rename from src/main/kotlin/core/node/FixedIdentityService.kt rename to src/main/kotlin/core/node/services/FixedIdentityService.kt index 00d3bf0bb5..7a8eaabf3b 100644 --- a/src/main/kotlin/core/node/FixedIdentityService.kt +++ b/src/main/kotlin/core/node/services/FixedIdentityService.kt @@ -6,7 +6,7 @@ * All other rights reserved. */ -package core.node +package core.node.services import core.IdentityService import core.Party diff --git a/src/main/kotlin/core/node/NodeAttachmentStorage.kt b/src/main/kotlin/core/node/services/NodeAttachmentStorage.kt similarity index 98% rename from src/main/kotlin/core/node/NodeAttachmentStorage.kt rename to src/main/kotlin/core/node/services/NodeAttachmentStorage.kt index a141b1f626..7b90c7a817 100644 --- a/src/main/kotlin/core/node/NodeAttachmentStorage.kt +++ b/src/main/kotlin/core/node/services/NodeAttachmentStorage.kt @@ -6,14 +6,14 @@ * All other rights reserved. */ -package core.node +package core.node.services import com.google.common.annotations.VisibleForTesting import com.google.common.hash.Hashing import com.google.common.hash.HashingInputStream import com.google.common.io.CountingInputStream import core.Attachment -import core.AttachmentStorage +import core.node.services.AttachmentStorage import core.crypto.SecureHash import core.extractZipFile import core.utilities.loggerFor diff --git a/src/main/kotlin/core/node/NodeWalletService.kt b/src/main/kotlin/core/node/services/NodeWalletService.kt similarity index 99% rename from src/main/kotlin/core/node/NodeWalletService.kt rename to src/main/kotlin/core/node/services/NodeWalletService.kt index 3c53978d15..4a5ac90660 100644 --- a/src/main/kotlin/core/node/NodeWalletService.kt +++ b/src/main/kotlin/core/node/services/NodeWalletService.kt @@ -6,7 +6,7 @@ * All other rights reserved. */ -package core.node +package core.node.services import contracts.Cash import core.* diff --git a/src/main/kotlin/core/Services.kt b/src/main/kotlin/core/node/services/Services.kt similarity index 99% rename from src/main/kotlin/core/Services.kt rename to src/main/kotlin/core/node/services/Services.kt index b64c3eef54..18377f3c4a 100644 --- a/src/main/kotlin/core/Services.kt +++ b/src/main/kotlin/core/node/services/Services.kt @@ -6,8 +6,9 @@ * All other rights reserved. */ -package core +package core.node.services +import core.* import core.crypto.SecureHash import core.messaging.MessagingService import core.messaging.NetworkMap diff --git a/src/main/kotlin/core/node/TimestamperNodeService.kt b/src/main/kotlin/core/node/services/TimestamperNodeService.kt similarity index 98% rename from src/main/kotlin/core/node/TimestamperNodeService.kt rename to src/main/kotlin/core/node/services/TimestamperNodeService.kt index 35d768401f..fca0e6926c 100644 --- a/src/main/kotlin/core/node/TimestamperNodeService.kt +++ b/src/main/kotlin/core/node/services/TimestamperNodeService.kt @@ -6,7 +6,7 @@ * All other rights reserved. */ -package core.node +package core.node.services import co.paralleluniverse.common.util.VisibleForTesting import co.paralleluniverse.fibers.Suspendable @@ -17,6 +17,8 @@ import core.messaging.LegallyIdentifiableNode import core.messaging.MessageRecipients import core.messaging.MessagingService import core.messaging.StateMachineManager +import core.node.TimestampingError +import core.node.services.TimestamperService import core.protocols.ProtocolLogic import core.serialization.SerializedBytes import core.serialization.deserialize diff --git a/src/main/kotlin/core/node/servlets/AttachmentDownloadServlet.kt b/src/main/kotlin/core/node/servlets/AttachmentDownloadServlet.kt index 9462019915..e24b4d9778 100644 --- a/src/main/kotlin/core/node/servlets/AttachmentDownloadServlet.kt +++ b/src/main/kotlin/core/node/servlets/AttachmentDownloadServlet.kt @@ -8,7 +8,7 @@ package core.node.servlets -import core.StorageService +import core.node.services.StorageService import core.crypto.SecureHash import core.utilities.loggerFor import java.io.FileNotFoundException diff --git a/src/main/kotlin/core/node/servlets/AttachmentUploadServlet.kt b/src/main/kotlin/core/node/servlets/AttachmentUploadServlet.kt index 45e08f7e11..cee0f39695 100644 --- a/src/main/kotlin/core/node/servlets/AttachmentUploadServlet.kt +++ b/src/main/kotlin/core/node/servlets/AttachmentUploadServlet.kt @@ -8,7 +8,7 @@ package core.node.servlets -import core.StorageService +import core.node.services.StorageService import core.utilities.loggerFor import org.apache.commons.fileupload.servlet.ServletFileUpload import javax.servlet.http.HttpServlet diff --git a/src/main/kotlin/core/protocols/ProtocolLogic.kt b/src/main/kotlin/core/protocols/ProtocolLogic.kt index 0d9bbc78a0..d26263309d 100644 --- a/src/main/kotlin/core/protocols/ProtocolLogic.kt +++ b/src/main/kotlin/core/protocols/ProtocolLogic.kt @@ -9,7 +9,7 @@ package core.protocols import co.paralleluniverse.fibers.Suspendable -import core.ServiceHub +import core.node.services.ServiceHub import core.messaging.MessageRecipients import core.utilities.ProgressTracker import core.utilities.UntrustworthyData diff --git a/src/main/kotlin/core/protocols/ProtocolStateMachine.kt b/src/main/kotlin/core/protocols/ProtocolStateMachine.kt index c942b7d4e4..eef801888c 100644 --- a/src/main/kotlin/core/protocols/ProtocolStateMachine.kt +++ b/src/main/kotlin/core/protocols/ProtocolStateMachine.kt @@ -14,7 +14,7 @@ import co.paralleluniverse.io.serialization.kryo.KryoSerializer import com.esotericsoftware.kryo.io.Output import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.SettableFuture -import core.ServiceHub +import core.node.services.ServiceHub import core.messaging.MessageRecipients import core.messaging.StateMachineManager import core.serialization.createKryo diff --git a/src/main/kotlin/contracts/protocols/FetchAttachmentsProtocol.kt b/src/main/kotlin/protocols/FetchAttachmentsProtocol.kt similarity index 98% rename from src/main/kotlin/contracts/protocols/FetchAttachmentsProtocol.kt rename to src/main/kotlin/protocols/FetchAttachmentsProtocol.kt index 437736106a..5ec27be551 100644 --- a/src/main/kotlin/contracts/protocols/FetchAttachmentsProtocol.kt +++ b/src/main/kotlin/protocols/FetchAttachmentsProtocol.kt @@ -6,7 +6,7 @@ * All other rights reserved. */ -package contracts.protocols +package protocols import core.Attachment import core.crypto.SecureHash diff --git a/src/main/kotlin/contracts/protocols/FetchDataProtocol.kt b/src/main/kotlin/protocols/FetchDataProtocol.kt similarity index 98% rename from src/main/kotlin/contracts/protocols/FetchDataProtocol.kt rename to src/main/kotlin/protocols/FetchDataProtocol.kt index 030a4f3ca6..fcf7ef94ed 100644 --- a/src/main/kotlin/contracts/protocols/FetchDataProtocol.kt +++ b/src/main/kotlin/protocols/FetchDataProtocol.kt @@ -6,13 +6,13 @@ * All other rights reserved. */ -package contracts.protocols +package protocols import co.paralleluniverse.fibers.Suspendable import core.NamedByHash import core.crypto.SecureHash import core.messaging.SingleMessageRecipient -import core.node.DataVendingService +import core.node.services.DataVendingService import core.protocols.ProtocolLogic import core.random63BitValue import core.utilities.UntrustworthyData diff --git a/src/main/kotlin/contracts/protocols/FetchTransactionsProtocol.kt b/src/main/kotlin/protocols/FetchTransactionsProtocol.kt similarity index 97% rename from src/main/kotlin/contracts/protocols/FetchTransactionsProtocol.kt rename to src/main/kotlin/protocols/FetchTransactionsProtocol.kt index 59f08bdf2b..d35b1cde6c 100644 --- a/src/main/kotlin/contracts/protocols/FetchTransactionsProtocol.kt +++ b/src/main/kotlin/protocols/FetchTransactionsProtocol.kt @@ -6,7 +6,7 @@ * All other rights reserved. */ -package contracts.protocols +package protocols import core.SignedTransaction import core.crypto.SecureHash diff --git a/src/main/kotlin/contracts/protocols/ResolveTransactionsProtocol.kt b/src/main/kotlin/protocols/ResolveTransactionsProtocol.kt similarity index 99% rename from src/main/kotlin/contracts/protocols/ResolveTransactionsProtocol.kt rename to src/main/kotlin/protocols/ResolveTransactionsProtocol.kt index 0b5029a23b..8e6a638c9d 100644 --- a/src/main/kotlin/contracts/protocols/ResolveTransactionsProtocol.kt +++ b/src/main/kotlin/protocols/ResolveTransactionsProtocol.kt @@ -6,7 +6,7 @@ * All other rights reserved. */ -package contracts.protocols +package protocols import co.paralleluniverse.fibers.Suspendable import core.* diff --git a/src/main/kotlin/contracts/protocols/TwoPartyTradeProtocol.kt b/src/main/kotlin/protocols/TwoPartyTradeProtocol.kt similarity index 98% rename from src/main/kotlin/contracts/protocols/TwoPartyTradeProtocol.kt rename to src/main/kotlin/protocols/TwoPartyTradeProtocol.kt index 848dbaa33a..1714d8fdea 100644 --- a/src/main/kotlin/contracts/protocols/TwoPartyTradeProtocol.kt +++ b/src/main/kotlin/protocols/TwoPartyTradeProtocol.kt @@ -6,7 +6,7 @@ * All other rights reserved. */ -package contracts.protocols +package protocols import co.paralleluniverse.fibers.Suspendable import com.google.common.util.concurrent.ListenableFuture @@ -18,7 +18,7 @@ import core.crypto.signWithECDSA import core.messaging.LegallyIdentifiableNode import core.messaging.SingleMessageRecipient import core.messaging.StateMachineManager -import core.node.TimestampingProtocol +import core.node.services.TimestampingProtocol import core.protocols.ProtocolLogic import core.utilities.ProgressTracker import core.utilities.trace @@ -57,14 +57,14 @@ object TwoPartyTradeProtocol { otherSide: SingleMessageRecipient, assetToSell: StateAndRef, price: Amount, myKeyPair: KeyPair, buyerSessionID: Long): ListenableFuture { val seller = Seller(otherSide, timestampingAuthority, assetToSell, price, myKeyPair, buyerSessionID) - return smm.add("$TRADE_TOPIC.seller", seller) + return smm.add("${TRADE_TOPIC}.seller", seller) } fun runBuyer(smm: StateMachineManager, timestampingAuthority: LegallyIdentifiableNode, otherSide: SingleMessageRecipient, acceptablePrice: Amount, typeToBuy: Class, sessionID: Long): ListenableFuture { val buyer = Buyer(otherSide, timestampingAuthority.identity, acceptablePrice, typeToBuy, sessionID) - return smm.add("$TRADE_TOPIC.buyer", buyer) + return smm.add("${TRADE_TOPIC}.buyer", buyer) } class UnacceptablePriceException(val givenPrice: Amount) : Exception() @@ -179,7 +179,7 @@ object TwoPartyTradeProtocol { @Suspendable private fun sendSignatures(partialTX: SignedTransaction, ourSignature: DigitalSignature.WithKey, - tsaSig: DigitalSignature.LegallyIdentifiable): SignedTransaction { + tsaSig: DigitalSignature.LegallyIdentifiable): SignedTransaction { progressTracker.currentStep = SENDING_SIGS val fullySigned = partialTX + tsaSig + ourSignature diff --git a/src/test/kotlin/contracts/CommercialPaperTests.kt b/src/test/kotlin/contracts/CommercialPaperTests.kt index 9f6b3a8a2c..c853a4bcb9 100644 --- a/src/test/kotlin/contracts/CommercialPaperTests.kt +++ b/src/test/kotlin/contracts/CommercialPaperTests.kt @@ -11,6 +11,7 @@ package contracts import core.* import core.crypto.SecureHash import core.node.TimestampingError +import core.node.services.DummyTimestampingAuthority import core.testutils.* import org.junit.Test import org.junit.runner.RunWith diff --git a/src/test/kotlin/contracts/CrowdFundTests.kt b/src/test/kotlin/contracts/CrowdFundTests.kt index f07440d5c7..e7dd5ed531 100644 --- a/src/test/kotlin/contracts/CrowdFundTests.kt +++ b/src/test/kotlin/contracts/CrowdFundTests.kt @@ -10,6 +10,7 @@ package contracts import core.* import core.crypto.SecureHash +import core.node.services.DummyTimestampingAuthority import core.testutils.* import org.junit.Test import java.time.Instant diff --git a/src/test/kotlin/core/MockServices.kt b/src/test/kotlin/core/MockServices.kt index f1fd64aff3..b570eb89ce 100644 --- a/src/test/kotlin/core/MockServices.kt +++ b/src/test/kotlin/core/MockServices.kt @@ -12,8 +12,8 @@ import core.crypto.* import core.messaging.MessagingService import core.messaging.MockNetworkMap import core.messaging.NetworkMap -import core.node.DataVendingService import core.node.TimestampingError +import core.node.services.* import core.serialization.SerializedBytes import core.serialization.deserialize import core.testutils.RecordingMap diff --git a/src/test/kotlin/core/messaging/AttachmentTests.kt b/src/test/kotlin/core/messaging/AttachmentTests.kt index bff2693027..6f24cf4441 100644 --- a/src/test/kotlin/core/messaging/AttachmentTests.kt +++ b/src/test/kotlin/core/messaging/AttachmentTests.kt @@ -8,13 +8,13 @@ package core.messaging -import contracts.protocols.FetchAttachmentsProtocol -import contracts.protocols.FetchDataProtocol +import protocols.FetchAttachmentsProtocol +import protocols.FetchDataProtocol import core.Attachment import core.crypto.SecureHash import core.crypto.sha256 import core.node.MockNetwork -import core.node.NodeAttachmentStorage +import core.node.services.NodeAttachmentStorage import core.serialization.OpaqueBytes import core.testutils.rootCauseExceptions import core.utilities.BriefLogFormatter diff --git a/src/test/kotlin/core/messaging/InMemoryMessagingNetwork.kt b/src/test/kotlin/core/messaging/InMemoryMessagingNetwork.kt index 9a1a4416a8..16519fa882 100644 --- a/src/test/kotlin/core/messaging/InMemoryMessagingNetwork.kt +++ b/src/test/kotlin/core/messaging/InMemoryMessagingNetwork.kt @@ -11,10 +11,10 @@ package core.messaging import com.google.common.util.concurrent.Futures import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.MoreExecutors -import core.DummyTimestampingAuthority +import core.node.services.DummyTimestampingAuthority import core.ThreadBox import core.crypto.sha256 -import core.node.TimestamperNodeService +import core.node.services.TimestamperNodeService import core.utilities.loggerFor import java.time.Instant import java.util.* diff --git a/src/test/kotlin/core/messaging/TwoPartyTradeProtocolTests.kt b/src/test/kotlin/core/messaging/TwoPartyTradeProtocolTests.kt index 28786c0f68..e9ee89ec7a 100644 --- a/src/test/kotlin/core/messaging/TwoPartyTradeProtocolTests.kt +++ b/src/test/kotlin/core/messaging/TwoPartyTradeProtocolTests.kt @@ -10,12 +10,11 @@ package core.messaging import contracts.Cash import contracts.CommercialPaper -import contracts.protocols.TwoPartyTradeProtocol +import protocols.TwoPartyTradeProtocol import core.* import core.crypto.SecureHash import core.node.MockNetwork -import core.node.NodeAttachmentStorage -import core.node.NodeWalletService +import core.node.services.* import core.testutils.* import core.utilities.BriefLogFormatter import org.junit.After diff --git a/src/test/kotlin/core/node/MockNode.kt b/src/test/kotlin/core/node/MockNode.kt index af41fa13d1..ab6e7ffbfa 100644 --- a/src/test/kotlin/core/node/MockNode.kt +++ b/src/test/kotlin/core/node/MockNode.kt @@ -23,6 +23,7 @@ import core.Party import core.messaging.InMemoryMessagingNetwork import core.messaging.LegallyIdentifiableNode import core.messaging.MessagingService +import core.node.services.FixedIdentityService import core.testutils.TEST_KEYS_TO_CORP_MAP import core.utilities.loggerFor import org.slf4j.Logger diff --git a/src/test/kotlin/core/node/NodeAttachmentStorageTest.kt b/src/test/kotlin/core/node/NodeAttachmentStorageTest.kt index cea62c9614..0533de45d1 100644 --- a/src/test/kotlin/core/node/NodeAttachmentStorageTest.kt +++ b/src/test/kotlin/core/node/NodeAttachmentStorageTest.kt @@ -11,6 +11,7 @@ package core.node import com.google.common.jimfs.Configuration import com.google.common.jimfs.Jimfs import core.crypto.SecureHash +import core.node.services.NodeAttachmentStorage import core.use import org.junit.Before import org.junit.Test diff --git a/src/test/kotlin/core/node/NodeWalletServiceTest.kt b/src/test/kotlin/core/node/NodeWalletServiceTest.kt index 5f23698431..de461e9559 100644 --- a/src/test/kotlin/core/node/NodeWalletServiceTest.kt +++ b/src/test/kotlin/core/node/NodeWalletServiceTest.kt @@ -10,6 +10,8 @@ package core.node import contracts.Cash import core.* +import core.node.services.NodeWalletService +import core.node.services.ServiceHub import core.testutils.* import core.utilities.BriefLogFormatter import org.junit.After diff --git a/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt b/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt index 57969a7b68..36c26645e1 100644 --- a/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt +++ b/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt @@ -12,6 +12,10 @@ import co.paralleluniverse.fibers.Suspendable import core.* import core.crypto.SecureHash import core.messaging.* +import core.node.services.ServiceHub +import core.node.services.TimestamperNodeService +import core.node.services.TimestampingMessages +import core.node.services.TimestampingProtocol import core.protocols.ProtocolLogic import core.serialization.serialize import core.testutils.ALICE diff --git a/src/test/kotlin/core/testutils/TestUtils.kt b/src/test/kotlin/core/testutils/TestUtils.kt index e7167d1e1d..349389c6f8 100644 --- a/src/test/kotlin/core/testutils/TestUtils.kt +++ b/src/test/kotlin/core/testutils/TestUtils.kt @@ -14,6 +14,7 @@ import com.google.common.base.Throwables import contracts.* import core.* import core.crypto.* +import core.node.services.DummyTimestampingAuthority import core.serialization.serialize import core.visualiser.GraphVisualiser import java.security.KeyPair From bf3aed11e7eaeb4f3ef4356356df01804310f5e4 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 8 Mar 2016 11:10:31 +0100 Subject: [PATCH 02/35] Minor: another small move --- .../core/{ => node/services}/IdentityService.kt | 11 ++++++++++- src/main/kotlin/core/TransactionTools.kt | 1 + .../kotlin/core/node/services/FixedIdentityService.kt | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) rename core/src/main/kotlin/core/{ => node/services}/IdentityService.kt (54%) diff --git a/core/src/main/kotlin/core/IdentityService.kt b/core/src/main/kotlin/core/node/services/IdentityService.kt similarity index 54% rename from core/src/main/kotlin/core/IdentityService.kt rename to core/src/main/kotlin/core/node/services/IdentityService.kt index d3f0622614..1665c8e677 100644 --- a/core/src/main/kotlin/core/IdentityService.kt +++ b/core/src/main/kotlin/core/node/services/IdentityService.kt @@ -1,5 +1,14 @@ -package core +/* + * 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.services + +import core.Party import java.security.PublicKey /** diff --git a/src/main/kotlin/core/TransactionTools.kt b/src/main/kotlin/core/TransactionTools.kt index de2ee79b91..0c35c347d8 100644 --- a/src/main/kotlin/core/TransactionTools.kt +++ b/src/main/kotlin/core/TransactionTools.kt @@ -9,6 +9,7 @@ package core import core.node.services.AttachmentStorage +import core.node.services.IdentityService import java.io.FileNotFoundException /** diff --git a/src/main/kotlin/core/node/services/FixedIdentityService.kt b/src/main/kotlin/core/node/services/FixedIdentityService.kt index 7a8eaabf3b..4f12117310 100644 --- a/src/main/kotlin/core/node/services/FixedIdentityService.kt +++ b/src/main/kotlin/core/node/services/FixedIdentityService.kt @@ -8,7 +8,7 @@ package core.node.services -import core.IdentityService +import core.node.services.IdentityService import core.Party import java.security.PublicKey From 8d041a6b1a4b5cf52e36b1021a6c6578b6b09ae2 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 8 Mar 2016 11:12:45 +0100 Subject: [PATCH 03/35] Minor: yet another small move --- core/src/main/kotlin/core/Transactions.kt | 2 +- .../main/kotlin/core/node/TimestampingError.kt | 15 --------------- .../core/node/services/TimestamperService.kt | 13 +++++++++++++ .../core/node/services/TimestamperNodeService.kt | 2 -- src/test/kotlin/contracts/CommercialPaperTests.kt | 2 +- src/test/kotlin/core/MockServices.kt | 1 - .../core/node/TimestamperNodeServiceTest.kt | 5 +---- 7 files changed, 16 insertions(+), 24 deletions(-) delete mode 100644 core/src/main/kotlin/core/node/TimestampingError.kt diff --git a/core/src/main/kotlin/core/Transactions.kt b/core/src/main/kotlin/core/Transactions.kt index a444ffe0de..4f911c0d55 100644 --- a/core/src/main/kotlin/core/Transactions.kt +++ b/core/src/main/kotlin/core/Transactions.kt @@ -13,8 +13,8 @@ import core.crypto.DigitalSignature import core.crypto.SecureHash import core.crypto.signWithECDSA import core.crypto.toStringShort -import core.node.TimestampingError import core.node.services.TimestamperService +import core.node.services.TimestampingError import core.serialization.SerializedBytes import core.serialization.deserialize import core.serialization.serialize diff --git a/core/src/main/kotlin/core/node/TimestampingError.kt b/core/src/main/kotlin/core/node/TimestampingError.kt deleted file mode 100644 index 97a772f6cc..0000000000 --- a/core/src/main/kotlin/core/node/TimestampingError.kt +++ /dev/null @@ -1,15 +0,0 @@ -package core.node - -sealed class TimestampingError : Exception() { - class RequiresExactlyOneCommand : TimestampingError() - /** - * Thrown if an attempt is made to timestamp a transaction using a trusted timestamper, but the time on the - * transaction is too far in the past or future relative to the local clock and thus the timestamper would reject - * it. - */ - class NotOnTimeException : TimestampingError() - - /** Thrown if the command in the transaction doesn't list this timestamping authorities public key as a signer */ - class NotForMe : TimestampingError() -} - diff --git a/core/src/main/kotlin/core/node/services/TimestamperService.kt b/core/src/main/kotlin/core/node/services/TimestamperService.kt index 110911b305..f4ddfd7147 100644 --- a/core/src/main/kotlin/core/node/services/TimestamperService.kt +++ b/core/src/main/kotlin/core/node/services/TimestamperService.kt @@ -37,3 +37,16 @@ object DummyTimestampingAuthority { val key = generateKeyPair() val identity = Party("Mock Company 0", key.public) } + +sealed class TimestampingError : Exception() { + class RequiresExactlyOneCommand : TimestampingError() + /** + * Thrown if an attempt is made to timestamp a transaction using a trusted timestamper, but the time on the + * transaction is too far in the past or future relative to the local clock and thus the timestamper would reject + * it. + */ + class NotOnTimeException : TimestampingError() + + /** Thrown if the command in the transaction doesn't list this timestamping authorities public key as a signer */ + class NotForMe : TimestampingError() +} diff --git a/src/main/kotlin/core/node/services/TimestamperNodeService.kt b/src/main/kotlin/core/node/services/TimestamperNodeService.kt index fca0e6926c..c42e6ec1f0 100644 --- a/src/main/kotlin/core/node/services/TimestamperNodeService.kt +++ b/src/main/kotlin/core/node/services/TimestamperNodeService.kt @@ -17,8 +17,6 @@ import core.messaging.LegallyIdentifiableNode import core.messaging.MessageRecipients import core.messaging.MessagingService import core.messaging.StateMachineManager -import core.node.TimestampingError -import core.node.services.TimestamperService import core.protocols.ProtocolLogic import core.serialization.SerializedBytes import core.serialization.deserialize diff --git a/src/test/kotlin/contracts/CommercialPaperTests.kt b/src/test/kotlin/contracts/CommercialPaperTests.kt index c853a4bcb9..b252f24e38 100644 --- a/src/test/kotlin/contracts/CommercialPaperTests.kt +++ b/src/test/kotlin/contracts/CommercialPaperTests.kt @@ -10,8 +10,8 @@ package contracts import core.* import core.crypto.SecureHash -import core.node.TimestampingError import core.node.services.DummyTimestampingAuthority +import core.node.services.TimestampingError import core.testutils.* import org.junit.Test import org.junit.runner.RunWith diff --git a/src/test/kotlin/core/MockServices.kt b/src/test/kotlin/core/MockServices.kt index b570eb89ce..bd45ddb294 100644 --- a/src/test/kotlin/core/MockServices.kt +++ b/src/test/kotlin/core/MockServices.kt @@ -12,7 +12,6 @@ import core.crypto.* import core.messaging.MessagingService import core.messaging.MockNetworkMap import core.messaging.NetworkMap -import core.node.TimestampingError import core.node.services.* import core.serialization.SerializedBytes import core.serialization.deserialize diff --git a/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt b/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt index 36c26645e1..53c2fbed89 100644 --- a/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt +++ b/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt @@ -12,10 +12,7 @@ import co.paralleluniverse.fibers.Suspendable import core.* import core.crypto.SecureHash import core.messaging.* -import core.node.services.ServiceHub -import core.node.services.TimestamperNodeService -import core.node.services.TimestampingMessages -import core.node.services.TimestampingProtocol +import core.node.services.* import core.protocols.ProtocolLogic import core.serialization.serialize import core.testutils.ALICE From 2c4475b0d9047296b2a56c7751a69e04ef9868aa Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 8 Mar 2016 12:01:49 +0100 Subject: [PATCH 04/35] Minor: TimestamperNodeService -> NodeTimestamperService for consistency --- src/main/kotlin/core/node/AbstractNode.kt | 4 ++-- ...stamperNodeService.kt => NodeTimestamperService.kt} | 10 +++++----- .../kotlin/core/messaging/InMemoryMessagingNetwork.kt | 4 ++-- .../kotlin/core/node/TimestamperNodeServiceTest.kt | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) rename src/main/kotlin/core/node/services/{TimestamperNodeService.kt => NodeTimestamperService.kt} (94%) diff --git a/src/main/kotlin/core/node/AbstractNode.kt b/src/main/kotlin/core/node/AbstractNode.kt index 29fe751d03..cba8cf19f3 100644 --- a/src/main/kotlin/core/node/AbstractNode.kt +++ b/src/main/kotlin/core/node/AbstractNode.kt @@ -79,7 +79,7 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, lateinit var smm: StateMachineManager lateinit var wallet: WalletService lateinit var keyManagement: E2ETestKeyManagementService - var inNodeTimestampingService: TimestamperNodeService? = null + var inNodeTimestampingService: NodeTimestamperService? = null lateinit var identity: IdentityService lateinit var net: MessagingService @@ -97,7 +97,7 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, inNodeTimestampingService = null timestamperAddress } else { - inNodeTimestampingService = TimestamperNodeService(net, storage.myLegalIdentity, storage.myLegalIdentityKey) + inNodeTimestampingService = NodeTimestamperService(net, storage.myLegalIdentity, storage.myLegalIdentityKey) LegallyIdentifiableNode(net.myAddress, storage.myLegalIdentity) } (services.networkMapService as MockNetworkMap).timestampingNodes.add(tsid) diff --git a/src/main/kotlin/core/node/services/TimestamperNodeService.kt b/src/main/kotlin/core/node/services/NodeTimestamperService.kt similarity index 94% rename from src/main/kotlin/core/node/services/TimestamperNodeService.kt rename to src/main/kotlin/core/node/services/NodeTimestamperService.kt index c42e6ec1f0..9c46e19a3f 100644 --- a/src/main/kotlin/core/node/services/TimestamperNodeService.kt +++ b/src/main/kotlin/core/node/services/NodeTimestamperService.kt @@ -39,7 +39,7 @@ class TimestampingMessages { * See the doc site to learn more about timestamping authorities (nodes) and the role they play in the data model. */ @ThreadSafe -class TimestamperNodeService(private val net: MessagingService, +class NodeTimestamperService(private val net: MessagingService, val identity: Party, val signingKey: KeyPair, val clock: Clock = Clock.systemDefaultZone(), @@ -47,7 +47,7 @@ class TimestamperNodeService(private val net: MessagingService, companion object { val TIMESTAMPING_PROTOCOL_TOPIC = "platform.timestamping.request" - private val logger = LoggerFactory.getLogger(TimestamperNodeService::class.java) + private val logger = LoggerFactory.getLogger(NodeTimestamperService::class.java) } init { @@ -97,7 +97,7 @@ class TimestamperNodeService(private val net: MessagingService, } /** - * The TimestampingProtocol class is the client code that talks to a [TimestamperNodeService] on some remote node. It is a + * The TimestampingProtocol class is the client code that talks to a [NodeTimestamperService] on some remote node. It is a * [ProtocolLogic], meaning it can either be a sub-protocol of some other protocol, or be driven independently. * * If you are not yourself authoring a protocol and want to timestamp something, the [TimestampingProtocol.Client] class @@ -120,11 +120,11 @@ class TimestampingProtocol(private val node: LegallyIdentifiableNode, @Suspendable override fun call(): DigitalSignature.LegallyIdentifiable { val sessionID = random63BitValue() - val replyTopic = "${TimestamperNodeService.TIMESTAMPING_PROTOCOL_TOPIC}.$sessionID" + val replyTopic = "${NodeTimestamperService.TIMESTAMPING_PROTOCOL_TOPIC}.$sessionID" val req = TimestampingMessages.Request(wtxBytes, serviceHub.networkService.myAddress, replyTopic) val maybeSignature = sendAndReceive( - TimestamperNodeService.TIMESTAMPING_PROTOCOL_TOPIC, node.address, 0, sessionID, req) + NodeTimestamperService.TIMESTAMPING_PROTOCOL_TOPIC, node.address, 0, sessionID, req) // Check that the timestamping authority gave us back a valid signature and didn't break somehow maybeSignature.validate { sig -> diff --git a/src/test/kotlin/core/messaging/InMemoryMessagingNetwork.kt b/src/test/kotlin/core/messaging/InMemoryMessagingNetwork.kt index 16519fa882..2056286347 100644 --- a/src/test/kotlin/core/messaging/InMemoryMessagingNetwork.kt +++ b/src/test/kotlin/core/messaging/InMemoryMessagingNetwork.kt @@ -14,7 +14,7 @@ import com.google.common.util.concurrent.MoreExecutors import core.node.services.DummyTimestampingAuthority import core.ThreadBox import core.crypto.sha256 -import core.node.services.TimestamperNodeService +import core.node.services.NodeTimestamperService import core.utilities.loggerFor import java.time.Instant import java.util.* @@ -126,7 +126,7 @@ class InMemoryMessagingNetwork { check(timestampingAdvert == null) val (handle, builder) = createNode(manuallyPumped) val node = builder.start().get() - TimestamperNodeService(node, DummyTimestampingAuthority.identity, DummyTimestampingAuthority.key) + NodeTimestamperService(node, DummyTimestampingAuthority.identity, DummyTimestampingAuthority.key) timestampingAdvert = LegallyIdentifiableNode(handle, DummyTimestampingAuthority.identity) return Pair(timestampingAdvert!!, node) } diff --git a/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt b/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt index 53c2fbed89..8d036a7d8e 100644 --- a/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt +++ b/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt @@ -33,7 +33,7 @@ import kotlin.test.assertTrue class TimestamperNodeServiceTest : TestWithInMemoryNetwork() { lateinit var myMessaging: Pair lateinit var serviceMessaging: Pair - lateinit var service: TimestamperNodeService + lateinit var service: NodeTimestamperService val ptx = TransactionBuilder().apply { addInputState(StateRef(SecureHash.randomSHA256(), 0)) @@ -59,7 +59,7 @@ class TimestamperNodeServiceTest : TestWithInMemoryNetwork() { serverKey = timestampingNodeID.identity.owningKey // And a separate one to be tested directly, to make the unit tests a bit faster. - service = TimestamperNodeService(serviceMessaging.second, Party("Unit test suite", ALICE), ALICE_KEY) + service = NodeTimestamperService(serviceMessaging.second, Party("Unit test suite", ALICE), ALICE_KEY) } class TestPSM(val server: LegallyIdentifiableNode, val now: Instant) : ProtocolLogic() { @@ -82,7 +82,7 @@ class TimestamperNodeServiceTest : TestWithInMemoryNetwork() { fun successWithNetwork() { val psm = runNetwork { val smm = StateMachineManager(MockServices(net = myMessaging.second), RunOnCallerThread) - val logName = TimestamperNodeService.TIMESTAMPING_PROTOCOL_TOPIC + val logName = NodeTimestamperService.TIMESTAMPING_PROTOCOL_TOPIC val psm = TestPSM(mockServices.networkMapService.timestampingNodes[0], clock.instant()) smm.add(logName, psm) } From dc6ef73b6b7149758cb42bc8f6f67b03053b1391 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 8 Mar 2016 12:17:07 +0100 Subject: [PATCH 05/35] Minor: more code motion ... TimestampingProtocol now split to top level class and moved to same location as the other protocols. Few other timestamping related classes reorganised. --- src/main/kotlin/core/node/TraderDemo.kt | 2 +- .../node/services/NodeTimestamperService.kt | 59 +++-------------- .../kotlin/protocols/TimestampingProtocol.kt | 63 +++++++++++++++++++ .../kotlin/protocols/TwoPartyTradeProtocol.kt | 2 +- .../core/node/TimestamperNodeServiceTest.kt | 15 +++-- 5 files changed, 81 insertions(+), 60 deletions(-) create mode 100644 src/main/kotlin/protocols/TimestampingProtocol.kt diff --git a/src/main/kotlin/core/node/TraderDemo.kt b/src/main/kotlin/core/node/TraderDemo.kt index 5b4ebb4a78..bdede36081 100644 --- a/src/main/kotlin/core/node/TraderDemo.kt +++ b/src/main/kotlin/core/node/TraderDemo.kt @@ -21,7 +21,7 @@ import core.messaging.SingleMessageRecipient import core.node.services.ArtemisMessagingService import core.node.services.NodeAttachmentStorage import core.node.services.NodeWalletService -import core.node.services.TimestampingProtocol +import protocols.TimestampingProtocol import core.protocols.ProtocolLogic import core.serialization.deserialize import core.utilities.ANSIProgressRenderer diff --git a/src/main/kotlin/core/node/services/NodeTimestamperService.kt b/src/main/kotlin/core/node/services/NodeTimestamperService.kt index 9c46e19a3f..c37a6e940a 100644 --- a/src/main/kotlin/core/node/services/NodeTimestamperService.kt +++ b/src/main/kotlin/core/node/services/NodeTimestamperService.kt @@ -9,29 +9,22 @@ package core.node.services import co.paralleluniverse.common.util.VisibleForTesting -import co.paralleluniverse.fibers.Suspendable -import core.* +import core.Party +import core.TimestampCommand import core.crypto.DigitalSignature import core.crypto.signWithECDSA -import core.messaging.LegallyIdentifiableNode -import core.messaging.MessageRecipients import core.messaging.MessagingService -import core.messaging.StateMachineManager -import core.protocols.ProtocolLogic -import core.serialization.SerializedBytes +import core.seconds import core.serialization.deserialize import core.serialization.serialize +import core.until import org.slf4j.LoggerFactory +import protocols.TimestampingProtocol import java.security.KeyPair import java.time.Clock import java.time.Duration import javax.annotation.concurrent.ThreadSafe -class TimestampingMessages { - // TODO: Improve the messaging api to have a notion of sender+replyTo topic (optional?) - data class Request(val tx: SerializedBytes, val replyTo: MessageRecipients, val replyToTopic: String) -} - /** * This class implements the server side of the timestamping protocol, using the local clock. A future version might * add features like checking against other NTP servers to make sure the clock hasn't drifted by too much. @@ -54,7 +47,7 @@ class NodeTimestamperService(private val net: MessagingService, require(identity.owningKey == signingKey.public) net.addMessageHandler(TIMESTAMPING_PROTOCOL_TOPIC + ".0", null) { message, r -> try { - val req = message.data.deserialize() + val req = message.data.deserialize() val signature = processRequest(req) val msg = net.createMessage(req.replyToTopic, signature.serialize().bits) net.send(msg, req.replyTo) @@ -67,7 +60,7 @@ class NodeTimestamperService(private val net: MessagingService, } @VisibleForTesting - fun processRequest(req: TimestampingMessages.Request): DigitalSignature.LegallyIdentifiable { + fun processRequest(req: TimestampingProtocol.Request): DigitalSignature.LegallyIdentifiable { // We don't bother verifying signatures anything about the transaction here: we simply don't need to see anything // except the relevant command, and a future privacy upgrade should ensure we only get a torn-off command // rather than the full transaction. @@ -96,41 +89,3 @@ class NodeTimestamperService(private val net: MessagingService, } } -/** - * The TimestampingProtocol class is the client code that talks to a [NodeTimestamperService] on some remote node. It is a - * [ProtocolLogic], meaning it can either be a sub-protocol of some other protocol, or be driven independently. - * - * If you are not yourself authoring a protocol and want to timestamp something, the [TimestampingProtocol.Client] class - * implements the [TimestamperService] interface, meaning it can be passed to [TransactionBuilder.timestamp] to timestamp - * the built transaction. Please be aware that this will block, meaning it should not be used on a thread that is handling - * a network message: use it only from spare application threads that don't have to respond to anything. - */ -class TimestampingProtocol(private val node: LegallyIdentifiableNode, - private val wtxBytes: SerializedBytes) : ProtocolLogic() { - - class Client(private val stateMachineManager: StateMachineManager, private val node: LegallyIdentifiableNode) : TimestamperService { - override val identity: Party = node.identity - - override fun timestamp(wtxBytes: SerializedBytes): DigitalSignature.LegallyIdentifiable { - return stateMachineManager.add("platform.timestamping", TimestampingProtocol(node, wtxBytes)).get() - } - } - - - @Suspendable - override fun call(): DigitalSignature.LegallyIdentifiable { - val sessionID = random63BitValue() - val replyTopic = "${NodeTimestamperService.TIMESTAMPING_PROTOCOL_TOPIC}.$sessionID" - val req = TimestampingMessages.Request(wtxBytes, serviceHub.networkService.myAddress, replyTopic) - - val maybeSignature = sendAndReceive( - NodeTimestamperService.TIMESTAMPING_PROTOCOL_TOPIC, node.address, 0, sessionID, req) - - // Check that the timestamping authority gave us back a valid signature and didn't break somehow - maybeSignature.validate { sig -> - sig.verifyWithECDSA(wtxBytes) - return sig - } - } -} - diff --git a/src/main/kotlin/protocols/TimestampingProtocol.kt b/src/main/kotlin/protocols/TimestampingProtocol.kt new file mode 100644 index 0000000000..32604e31ca --- /dev/null +++ b/src/main/kotlin/protocols/TimestampingProtocol.kt @@ -0,0 +1,63 @@ +/* + * 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 protocols + +import co.paralleluniverse.fibers.Suspendable +import core.Party +import core.WireTransaction +import core.crypto.DigitalSignature +import core.messaging.LegallyIdentifiableNode +import core.messaging.MessageRecipients +import core.messaging.StateMachineManager +import core.node.services.NodeTimestamperService +import core.node.services.TimestamperService +import core.protocols.ProtocolLogic +import core.random63BitValue +import core.serialization.SerializedBytes + +/** + * The TimestampingProtocol class is the client code that talks to a [NodeTimestamperService] on some remote node. It is a + * [ProtocolLogic], meaning it can either be a sub-protocol of some other protocol, or be driven independently. + * + * If you are not yourself authoring a protocol and want to timestamp something, the [TimestampingProtocol.Client] class + * implements the [TimestamperService] interface, meaning it can be passed to [TransactionBuilder.timestamp] to timestamp + * the built transaction. Please be aware that this will block, meaning it should not be used on a thread that is handling + * a network message: use it only from spare application threads that don't have to respond to anything. + */ +class TimestampingProtocol(private val node: LegallyIdentifiableNode, + private val wtxBytes: SerializedBytes) : ProtocolLogic() { + + class Client(private val stateMachineManager: StateMachineManager, private val node: LegallyIdentifiableNode) : TimestamperService { + override val identity: Party = node.identity + + override fun timestamp(wtxBytes: SerializedBytes): DigitalSignature.LegallyIdentifiable { + return stateMachineManager.add("platform.timestamping", TimestampingProtocol(node, wtxBytes)).get() + } + } + + + @Suspendable + override fun call(): DigitalSignature.LegallyIdentifiable { + val sessionID = random63BitValue() + val replyTopic = "${NodeTimestamperService.TIMESTAMPING_PROTOCOL_TOPIC}.$sessionID" + val req = Request(wtxBytes, serviceHub.networkService.myAddress, replyTopic) + + val maybeSignature = sendAndReceive( + NodeTimestamperService.TIMESTAMPING_PROTOCOL_TOPIC, node.address, 0, sessionID, req) + + // Check that the timestamping authority gave us back a valid signature and didn't break somehow + maybeSignature.validate { sig -> + sig.verifyWithECDSA(wtxBytes) + return sig + } + } + + // TODO: Improve the messaging api to have a notion of sender+replyTo topic (optional?) + data class Request(val tx: SerializedBytes, val replyTo: MessageRecipients, val replyToTopic: String) +} \ No newline at end of file diff --git a/src/main/kotlin/protocols/TwoPartyTradeProtocol.kt b/src/main/kotlin/protocols/TwoPartyTradeProtocol.kt index 1714d8fdea..669c35e67a 100644 --- a/src/main/kotlin/protocols/TwoPartyTradeProtocol.kt +++ b/src/main/kotlin/protocols/TwoPartyTradeProtocol.kt @@ -18,7 +18,7 @@ import core.crypto.signWithECDSA import core.messaging.LegallyIdentifiableNode import core.messaging.SingleMessageRecipient import core.messaging.StateMachineManager -import core.node.services.TimestampingProtocol +import protocols.TimestampingProtocol import core.protocols.ProtocolLogic import core.utilities.ProgressTracker import core.utilities.trace diff --git a/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt b/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt index 8d036a7d8e..ef8cb478c2 100644 --- a/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt +++ b/src/test/kotlin/core/node/TimestamperNodeServiceTest.kt @@ -12,7 +12,9 @@ import co.paralleluniverse.fibers.Suspendable import core.* import core.crypto.SecureHash import core.messaging.* -import core.node.services.* +import core.node.services.NodeTimestamperService +import core.node.services.ServiceHub +import core.node.services.TimestampingError import core.protocols.ProtocolLogic import core.serialization.serialize import core.testutils.ALICE @@ -21,6 +23,7 @@ import core.testutils.CASH import core.utilities.BriefLogFormatter import org.junit.Before import org.junit.Test +import protocols.TimestampingProtocol import java.security.PublicKey import java.time.Clock import java.time.Instant @@ -94,14 +97,14 @@ class TimestamperNodeServiceTest : TestWithInMemoryNetwork() { // Zero commands is not OK. assertFailsWith(TimestampingError.RequiresExactlyOneCommand::class) { val wtx = ptx.toWireTransaction() - service.processRequest(TimestampingMessages.Request(wtx.serialize(), myMessaging.first, "ignored")) + service.processRequest(TimestampingProtocol.Request(wtx.serialize(), myMessaging.first, "ignored")) } // More than one command is not OK. assertFailsWith(TimestampingError.RequiresExactlyOneCommand::class) { ptx.addCommand(TimestampCommand(clock.instant(), 30.seconds), ALICE) ptx.addCommand(TimestampCommand(clock.instant(), 40.seconds), ALICE) val wtx = ptx.toWireTransaction() - service.processRequest(TimestampingMessages.Request(wtx.serialize(), myMessaging.first, "ignored")) + service.processRequest(TimestampingProtocol.Request(wtx.serialize(), myMessaging.first, "ignored")) } } @@ -111,7 +114,7 @@ class TimestamperNodeServiceTest : TestWithInMemoryNetwork() { val now = clock.instant() ptx.addCommand(TimestampCommand(now - 60.seconds, now - 40.seconds), ALICE) val wtx = ptx.toWireTransaction() - service.processRequest(TimestampingMessages.Request(wtx.serialize(), myMessaging.first, "ignored")) + service.processRequest(TimestampingProtocol.Request(wtx.serialize(), myMessaging.first, "ignored")) } } @@ -121,7 +124,7 @@ class TimestamperNodeServiceTest : TestWithInMemoryNetwork() { val now = clock.instant() ptx.addCommand(TimestampCommand(now - 60.seconds, now - 40.seconds), ALICE) val wtx = ptx.toWireTransaction() - service.processRequest(TimestampingMessages.Request(wtx.serialize(), myMessaging.first, "ignored")) + service.processRequest(TimestampingProtocol.Request(wtx.serialize(), myMessaging.first, "ignored")) } } @@ -130,7 +133,7 @@ class TimestamperNodeServiceTest : TestWithInMemoryNetwork() { val now = clock.instant() ptx.addCommand(TimestampCommand(now - 20.seconds, now + 20.seconds), ALICE) val wtx = ptx.toWireTransaction() - val sig = service.processRequest(TimestampingMessages.Request(wtx.serialize(), myMessaging.first, "ignored")) + val sig = service.processRequest(TimestampingProtocol.Request(wtx.serialize(), myMessaging.first, "ignored")) ptx.checkAndAddSignature(sig) ptx.toSignedTransaction(false).verifySignatures() } From c18579fd60b85d50cc2081c1c2c3eda4298e92a0 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 8 Mar 2016 13:55:03 +0100 Subject: [PATCH 06/35] Minor: add extension method to support "1.234".d to create a BigDecimal --- core/src/main/kotlin/core/Utils.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/kotlin/core/Utils.kt b/core/src/main/kotlin/core/Utils.kt index 5d140972e9..59243ac333 100644 --- a/core/src/main/kotlin/core/Utils.kt +++ b/core/src/main/kotlin/core/Utils.kt @@ -15,6 +15,7 @@ import com.google.common.util.concurrent.SettableFuture import org.slf4j.Logger import java.io.BufferedInputStream import java.io.InputStream +import java.math.BigDecimal import java.nio.file.Files import java.nio.file.Path import java.security.SecureRandom @@ -32,6 +33,8 @@ val Int.hours: Duration get() = Duration.ofHours(this.toLong()) val Int.minutes: Duration get() = Duration.ofMinutes(this.toLong()) val Int.seconds: Duration get() = Duration.ofSeconds(this.toLong()) +val String.d: BigDecimal get() = BigDecimal(this) + /** * Returns a random positive long generated using a secure RNG. This function sacrifies a bit of entropy in order to * avoid potential bugs where the value is used in a context where negative numbers are not expected. From 9069a80bc3975f55232c0084899d1f3b44929372 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 8 Mar 2016 13:55:20 +0100 Subject: [PATCH 07/35] Minor: add another variant of signWithECDSA --- core/src/main/kotlin/core/crypto/CryptoUtilities.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/kotlin/core/crypto/CryptoUtilities.kt b/core/src/main/kotlin/core/crypto/CryptoUtilities.kt index 7827f279eb..6453a987f4 100644 --- a/core/src/main/kotlin/core/crypto/CryptoUtilities.kt +++ b/core/src/main/kotlin/core/crypto/CryptoUtilities.kt @@ -99,6 +99,7 @@ fun PrivateKey.signWithECDSA(bitsToSign: ByteArray, publicKey: PublicKey): Digit } fun KeyPair.signWithECDSA(bitsToSign: ByteArray) = private.signWithECDSA(bitsToSign, public) fun KeyPair.signWithECDSA(bitsToSign: OpaqueBytes) = private.signWithECDSA(bitsToSign.bits, public) +fun KeyPair.signWithECDSA(bitsToSign: OpaqueBytes, party: Party) = signWithECDSA(bitsToSign.bits, party) fun KeyPair.signWithECDSA(bitsToSign: ByteArray, party: Party): DigitalSignature.LegallyIdentifiable { check(public == party.owningKey) val sig = signWithECDSA(bitsToSign) From 5eda0e066e2b8e6d731914e78395206dd786903a Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 8 Mar 2016 15:18:01 +0100 Subject: [PATCH 08/35] Minor: add a TODO about a little rpc framework to StateMachineManager --- src/main/kotlin/core/messaging/StateMachineManager.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/core/messaging/StateMachineManager.kt b/src/main/kotlin/core/messaging/StateMachineManager.kt index 2783a12f55..369c76c7a5 100644 --- a/src/main/kotlin/core/messaging/StateMachineManager.kt +++ b/src/main/kotlin/core/messaging/StateMachineManager.kt @@ -15,9 +15,9 @@ import com.esotericsoftware.kryo.io.Input import com.google.common.base.Throwables import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.MoreExecutors -import core.node.services.ServiceHub import core.crypto.SecureHash import core.crypto.sha256 +import core.node.services.ServiceHub import core.protocols.ProtocolLogic import core.protocols.ProtocolStateMachine import core.serialization.THREAD_LOCAL_KRYO @@ -54,6 +54,7 @@ import javax.annotation.concurrent.ThreadSafe * TODO: Ability to control checkpointing explicitly, for cases where you know replaying a message can't hurt * TODO: Make Kryo (de)serialize markers for heavy objects that are currently in the service hub. This avoids mistakes * where services are temporarily put on the stack. + * TODO: Implement stub/skel classes that provide a basic RPC framework on top of this. */ @ThreadSafe class StateMachineManager(val serviceHub: ServiceHub, val runInThread: Executor) { From 57ec40775554c11e65b2940ca3b5aca754a1772e Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 8 Mar 2016 15:18:32 +0100 Subject: [PATCH 09/35] Minor: TransactionBuilder: split up checkAndAddSignature --- core/src/main/kotlin/core/Transactions.kt | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/core/src/main/kotlin/core/Transactions.kt b/core/src/main/kotlin/core/Transactions.kt index 4f911c0d55..ddd08f6d78 100644 --- a/core/src/main/kotlin/core/Transactions.kt +++ b/core/src/main/kotlin/core/Transactions.kt @@ -200,7 +200,7 @@ class TransactionBuilder(private val inputs: MutableList = arrayListOf check(currentSigs.none { it.by == key.public }) { "This partial transaction was already signed by ${key.public}" } check(commands.count { it.pubkeys.contains(key.public) } > 0) { "Trying to sign with a key that isn't in any command" } val data = toWireTransaction().serialize() - currentSigs.add(key.signWithECDSA(data.bits)) + addSignatureUnchecked(key.signWithECDSA(data.bits)) } /** @@ -211,8 +211,23 @@ class TransactionBuilder(private val inputs: MutableList = arrayListOf * @throws IllegalArgumentException if the signature key doesn't appear in any command. */ fun checkAndAddSignature(sig: DigitalSignature.WithKey) { + checkSignature(sig) + addSignatureUnchecked(sig) + } + + /** + * Checks that the given signature matches one of the commands and that it is a correct signature over the tx. + * + * @throws SignatureException if the signature didn't match the transaction contents + * @throws IllegalArgumentException if the signature key doesn't appear in any command. + */ + fun checkSignature(sig: DigitalSignature.WithKey) { require(commands.count { it.pubkeys.contains(sig.by) } > 0) { "Signature key doesn't match any command" } - sig.verifyWithECDSA(toWireTransaction().serialize()) + sig.verifyWithECDSA(toWireTransaction().serialized) + } + + /** Adds the signature directly to the transaction, without checking it for validity. */ + fun addSignatureUnchecked(sig: DigitalSignature.WithKey) { currentSigs.add(sig) } @@ -239,7 +254,7 @@ class TransactionBuilder(private val inputs: MutableList = arrayListOf // boundary of t.notAfter and network latency pushes us over the edge. By "synchronised" here we mean relative // to GPS time i.e. the United States Naval Observatory. val sig = timestamper.timestamp(toWireTransaction().serialize()) - currentSigs.add(sig) + addSignatureUnchecked(sig) } fun toWireTransaction() = WireTransaction(ArrayList(inputs), ArrayList(attachments), From ffcc0507c4c35020eedc646973526471b9fc27d4 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 8 Mar 2016 15:41:44 +0100 Subject: [PATCH 10/35] Return the hashes of newly uploaded attachments to the uploader. --- src/main/kotlin/core/node/Node.kt | 2 +- .../kotlin/core/node/services/NodeAttachmentStorage.kt | 8 ++++++-- .../kotlin/core/node/servlets/AttachmentUploadServlet.kt | 8 ++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/core/node/Node.kt b/src/main/kotlin/core/node/Node.kt index f43f0ee993..c99898779f 100644 --- a/src/main/kotlin/core/node/Node.kt +++ b/src/main/kotlin/core/node/Node.kt @@ -60,7 +60,7 @@ class Node(dir: Path, val p2pAddr: HostAndPort, configuration: NodeConfiguration val server = Server(port) val handler = ServletContextHandler() handler.setAttribute("storage", storage) - handler.addServlet(AttachmentUploadServlet::class.java, "/attachments") + handler.addServlet(AttachmentUploadServlet::class.java, "/attachments/upload") handler.addServlet(AttachmentDownloadServlet::class.java, "/attachments/*") server.handler = handler server.start() diff --git a/src/main/kotlin/core/node/services/NodeAttachmentStorage.kt b/src/main/kotlin/core/node/services/NodeAttachmentStorage.kt index 7b90c7a817..ccb4ad5f8e 100644 --- a/src/main/kotlin/core/node/services/NodeAttachmentStorage.kt +++ b/src/main/kotlin/core/node/services/NodeAttachmentStorage.kt @@ -13,7 +13,6 @@ import com.google.common.hash.Hashing import com.google.common.hash.HashingInputStream import com.google.common.io.CountingInputStream import core.Attachment -import core.node.services.AttachmentStorage import core.crypto.SecureHash import core.extractZipFile import core.utilities.loggerFor @@ -106,16 +105,21 @@ class NodeAttachmentStorage(val storePath: Path) : AttachmentStorage { try { // Move into place atomically or fail if that isn't possible. We don't want a half moved attachment to // be exposed to parallel threads. This gives us thread safety. + if (!Files.exists(finalPath)) + log.info("Stored new attachment $id") + else + log.info("Replacing attachment $id - only bother doing this if you're trying to repair file corruption") Files.move(tmp, finalPath, StandardCopyOption.ATOMIC_MOVE) } finally { Files.deleteIfExists(tmp) } - log.info("Stored new attachment $id") if (automaticallyExtractAttachments) { val extractTo = storePath.resolve("${id}.jar") try { Files.createDirectory(extractTo) extractZipFile(finalPath, extractTo) + } catch(e: java.nio.file.FileAlreadyExistsException) { + log.trace("Did not extract attachment jar to directory because it already exists") } catch(e: Exception) { log.error("Failed to extract attachment jar $id, ", e) // TODO: Delete the extractTo directory here. diff --git a/src/main/kotlin/core/node/servlets/AttachmentUploadServlet.kt b/src/main/kotlin/core/node/servlets/AttachmentUploadServlet.kt index cee0f39695..1b3c7341d2 100644 --- a/src/main/kotlin/core/node/servlets/AttachmentUploadServlet.kt +++ b/src/main/kotlin/core/node/servlets/AttachmentUploadServlet.kt @@ -8,9 +8,11 @@ package core.node.servlets +import core.crypto.SecureHash import core.node.services.StorageService import core.utilities.loggerFor import org.apache.commons.fileupload.servlet.ServletFileUpload +import java.util.* import javax.servlet.http.HttpServlet import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse @@ -30,6 +32,7 @@ class AttachmentUploadServlet : HttpServlet() { val upload = ServletFileUpload() val iterator = upload.getItemIterator(req) + val ids = ArrayList() while (iterator.hasNext()) { val item = iterator.next() if (!item.name.endsWith(".jar")) { @@ -45,7 +48,12 @@ class AttachmentUploadServlet : HttpServlet() { item.openStream().use { val id = storage.attachments.importAttachment(it) log.info("${item.name} successfully inserted into the attachment store with id $id") + ids += id } } + + // Send back the hashes as a convenience for the user. + val writer = resp.writer + ids.forEach { writer.println(it) } } } From 5aaa6bd2044b1b3cb04bd64ac47ee0ea7d486c81 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 8 Mar 2016 15:49:16 +0100 Subject: [PATCH 11/35] Minor: rename NodeAttachmentStorage -> NodeAttachmentService --- src/main/kotlin/core/node/AbstractNode.kt | 8 ++++---- src/main/kotlin/core/node/TraderDemo.kt | 4 ++-- ...deAttachmentStorage.kt => NodeAttachmentService.kt} | 4 ++-- src/test/kotlin/core/messaging/AttachmentTests.kt | 4 ++-- .../core/messaging/TwoPartyTradeProtocolTests.kt | 4 ++-- src/test/kotlin/core/node/NodeAttachmentStorageTest.kt | 10 +++++----- 6 files changed, 17 insertions(+), 17 deletions(-) rename src/main/kotlin/core/node/services/{NodeAttachmentStorage.kt => NodeAttachmentService.kt} (98%) diff --git a/src/main/kotlin/core/node/AbstractNode.kt b/src/main/kotlin/core/node/AbstractNode.kt index cba8cf19f3..0e02c858e7 100644 --- a/src/main/kotlin/core/node/AbstractNode.kt +++ b/src/main/kotlin/core/node/AbstractNode.kt @@ -134,10 +134,10 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, return constructStorageService(attachments, identity, keypair) } - protected open fun constructStorageService(attachments: NodeAttachmentStorage, identity: Party, keypair: KeyPair) = + protected open fun constructStorageService(attachments: NodeAttachmentService, identity: Party, keypair: KeyPair) = StorageServiceImpl(attachments, identity, keypair) - open inner class StorageServiceImpl(attachments: NodeAttachmentStorage, identity: Party, keypair: KeyPair) : StorageService { + open inner class StorageServiceImpl(attachments: NodeAttachmentService, identity: Party, keypair: KeyPair) : StorageService { protected val tables = HashMap>() @Suppress("UNCHECKED_CAST") @@ -189,13 +189,13 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, } } - private fun makeAttachmentStorage(dir: Path): NodeAttachmentStorage { + private fun makeAttachmentStorage(dir: Path): NodeAttachmentService { val attachmentsDir = dir.resolve("attachments") try { Files.createDirectory(attachmentsDir) } catch (e: FileAlreadyExistsException) { } - val attachments = NodeAttachmentStorage(attachmentsDir) + val attachments = NodeAttachmentService(attachmentsDir) return attachments } } \ No newline at end of file diff --git a/src/main/kotlin/core/node/TraderDemo.kt b/src/main/kotlin/core/node/TraderDemo.kt index bdede36081..bb4c6bb71e 100644 --- a/src/main/kotlin/core/node/TraderDemo.kt +++ b/src/main/kotlin/core/node/TraderDemo.kt @@ -19,7 +19,7 @@ import core.crypto.generateKeyPair import core.messaging.LegallyIdentifiableNode import core.messaging.SingleMessageRecipient import core.node.services.ArtemisMessagingService -import core.node.services.NodeAttachmentStorage +import core.node.services.NodeAttachmentService import core.node.services.NodeWalletService import protocols.TimestampingProtocol import core.protocols.ProtocolLogic @@ -101,7 +101,7 @@ fun main(args: Array) { if (listening) { // For demo purposes just extract attachment jars when saved to disk, so the user can explore them. // Buyer will fetch the attachment from the seller. - val attachmentsPath = (node.storage.attachments as NodeAttachmentStorage).let { + val attachmentsPath = (node.storage.attachments as NodeAttachmentService).let { it.automaticallyExtractAttachments = true it.storePath } diff --git a/src/main/kotlin/core/node/services/NodeAttachmentStorage.kt b/src/main/kotlin/core/node/services/NodeAttachmentService.kt similarity index 98% rename from src/main/kotlin/core/node/services/NodeAttachmentStorage.kt rename to src/main/kotlin/core/node/services/NodeAttachmentService.kt index ccb4ad5f8e..8e973ec7bb 100644 --- a/src/main/kotlin/core/node/services/NodeAttachmentStorage.kt +++ b/src/main/kotlin/core/node/services/NodeAttachmentService.kt @@ -30,8 +30,8 @@ import javax.annotation.concurrent.ThreadSafe * Stores attachments in the specified local directory, which must exist. Doesn't allow new attachments to be uploaded. */ @ThreadSafe -class NodeAttachmentStorage(val storePath: Path) : AttachmentStorage { - private val log = loggerFor() +class NodeAttachmentService(val storePath: Path) : AttachmentStorage { + private val log = loggerFor() @VisibleForTesting var checkAttachmentsOnLoad = true diff --git a/src/test/kotlin/core/messaging/AttachmentTests.kt b/src/test/kotlin/core/messaging/AttachmentTests.kt index 6f24cf4441..60be7c0730 100644 --- a/src/test/kotlin/core/messaging/AttachmentTests.kt +++ b/src/test/kotlin/core/messaging/AttachmentTests.kt @@ -14,7 +14,7 @@ import core.Attachment import core.crypto.SecureHash import core.crypto.sha256 import core.node.MockNetwork -import core.node.services.NodeAttachmentStorage +import core.node.services.NodeAttachmentService import core.serialization.OpaqueBytes import core.testutils.rootCauseExceptions import core.utilities.BriefLogFormatter @@ -94,7 +94,7 @@ class AttachmentTests { object : MockNetwork.MockNode(path, config, mock, ts) { override fun start(): MockNetwork.MockNode { super.start() - (storage.attachments as NodeAttachmentStorage).checkAttachmentsOnLoad = false + (storage.attachments as NodeAttachmentService).checkAttachmentsOnLoad = false return this } } diff --git a/src/test/kotlin/core/messaging/TwoPartyTradeProtocolTests.kt b/src/test/kotlin/core/messaging/TwoPartyTradeProtocolTests.kt index e9ee89ec7a..6ce6107398 100644 --- a/src/test/kotlin/core/messaging/TwoPartyTradeProtocolTests.kt +++ b/src/test/kotlin/core/messaging/TwoPartyTradeProtocolTests.kt @@ -10,7 +10,6 @@ package core.messaging import contracts.Cash import contracts.CommercialPaper -import protocols.TwoPartyTradeProtocol import core.* import core.crypto.SecureHash import core.node.MockNetwork @@ -21,6 +20,7 @@ import org.junit.After import org.junit.Before import org.junit.Test import org.slf4j.LoggerFactory +import protocols.TwoPartyTradeProtocol import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.nio.file.Path @@ -195,7 +195,7 @@ class TwoPartyTradeProtocolTests : TestWithInMemoryNetwork() { return net.createNode(null) { path, config, net, tsNode -> object : MockNetwork.MockNode(path, config, net, tsNode) { // That constructs the storage service object in a customised way ... - override fun constructStorageService(attachments: NodeAttachmentStorage, identity: Party, keypair: KeyPair): StorageServiceImpl { + override fun constructStorageService(attachments: NodeAttachmentService, identity: Party, keypair: KeyPair): StorageServiceImpl { // By tweaking the standard StorageServiceImpl class ... return object : StorageServiceImpl(attachments, identity, keypair) { // To use RecordingMaps instead of ordinary HashMaps. diff --git a/src/test/kotlin/core/node/NodeAttachmentStorageTest.kt b/src/test/kotlin/core/node/NodeAttachmentStorageTest.kt index 0533de45d1..16dc8ef4c8 100644 --- a/src/test/kotlin/core/node/NodeAttachmentStorageTest.kt +++ b/src/test/kotlin/core/node/NodeAttachmentStorageTest.kt @@ -11,7 +11,7 @@ package core.node import com.google.common.jimfs.Configuration import com.google.common.jimfs.Jimfs import core.crypto.SecureHash -import core.node.services.NodeAttachmentStorage +import core.node.services.NodeAttachmentService import core.use import org.junit.Before import org.junit.Test @@ -40,7 +40,7 @@ class NodeAttachmentStorageTest { val testJar = makeTestJar() val expectedHash = SecureHash.sha256(Files.readAllBytes(testJar)) - val storage = NodeAttachmentStorage(fs.getPath("/")) + val storage = NodeAttachmentService(fs.getPath("/")) val id = testJar.use { storage.importAttachment(it) } assertEquals(expectedHash, id) @@ -57,7 +57,7 @@ class NodeAttachmentStorageTest { @Test fun `duplicates not allowed`() { val testJar = makeTestJar() - val storage = NodeAttachmentStorage(fs.getPath("/")) + val storage = NodeAttachmentService(fs.getPath("/")) testJar.use { storage.importAttachment(it) } assertFailsWith { testJar.use { storage.importAttachment(it) } @@ -67,13 +67,13 @@ class NodeAttachmentStorageTest { @Test fun `corrupt entry throws exception`() { val testJar = makeTestJar() - val storage = NodeAttachmentStorage(fs.getPath("/")) + val storage = NodeAttachmentService(fs.getPath("/")) val id = testJar.use { storage.importAttachment(it) } // Corrupt the file in the store. Files.write(fs.getPath("/", id.toString()), "arggghhhh".toByteArray(), StandardOpenOption.WRITE) - val e = assertFailsWith { + val e = assertFailsWith { storage.openAttachment(id)!!.open().use { it.readBytes() } } assertEquals(e.file, storage.storePath.resolve(id.toString())) From 92a7363c830c46eb0feffa494157c5528a88357c Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 8 Mar 2016 17:27:05 +0100 Subject: [PATCH 12/35] Minor: add a couple more utilities for converting strings into the type safe endpoint address objects --- src/main/kotlin/core/node/services/ArtemisMessagingService.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/kotlin/core/node/services/ArtemisMessagingService.kt b/src/main/kotlin/core/node/services/ArtemisMessagingService.kt index cc0fa633c5..8d58a42ebe 100644 --- a/src/main/kotlin/core/node/services/ArtemisMessagingService.kt +++ b/src/main/kotlin/core/node/services/ArtemisMessagingService.kt @@ -12,6 +12,7 @@ import com.google.common.net.HostAndPort import core.RunOnCallerThread import core.ThreadBox import core.messaging.* +import core.node.Node import core.utilities.loggerFor import org.apache.activemq.artemis.api.core.SimpleString import org.apache.activemq.artemis.api.core.TransportConfiguration @@ -68,6 +69,8 @@ class ArtemisMessagingService(val directory: Path, val myHostPort: HostAndPort) /** Temp helper until network map is established. */ fun makeRecipient(hostAndPort: HostAndPort): SingleMessageRecipient = Address(hostAndPort) + fun makeRecipient(hostname: String) = makeRecipient(toHostAndPort(hostname)) + fun toHostAndPort(hostname: String) = HostAndPort.fromString(hostname).withDefaultPort(Node.DEFAULT_PORT) } private lateinit var mq: EmbeddedActiveMQ From 8d3c9643e9f703d76cf64e3c2eb04cdea55b4bf0 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 8 Mar 2016 16:42:03 +0100 Subject: [PATCH 13/35] Minor: Move TraderDemo to demos package --- .idea/runConfigurations/Node__buyer.xml | 2 +- .idea/runConfigurations/Node__seller.xml | 2 +- build.gradle | 2 +- src/main/kotlin/{core/node => demos}/TraderDemo.kt | 9 ++++++--- 4 files changed, 9 insertions(+), 6 deletions(-) rename src/main/kotlin/{core/node => demos}/TraderDemo.kt (99%) diff --git a/.idea/runConfigurations/Node__buyer.xml b/.idea/runConfigurations/Node__buyer.xml index da1cc05083..22d4b37b07 100644 --- a/.idea/runConfigurations/Node__buyer.xml +++ b/.idea/runConfigurations/Node__buyer.xml @@ -1,7 +1,7 @@ -