Merged in rnicoll-cleanup (pull request #74)

Split internal/external services
This commit is contained in:
Ross Nicoll 2016-04-29 15:13:59 +01:00
commit f0fc18fe21
33 changed files with 114 additions and 76 deletions

View File

@ -9,7 +9,7 @@ import core.WireTransaction
import core.crypto.DigitalSignature
import core.crypto.SecureHash
import core.node.AbstractNode
import core.node.services.linearHeadsOfType
import core.node.subsystems.linearHeadsOfType
import core.protocols.ProtocolLogic
import core.serialization.SerializedBytes
import core.utilities.ANSIProgressRenderer

View File

@ -1,7 +1,7 @@
package api
import com.fasterxml.jackson.databind.ObjectMapper
import core.node.services.ServiceHub
import core.node.ServiceHub
import core.utilities.JsonSupport
import javax.ws.rs.ext.ContextResolver
import javax.ws.rs.ext.Provider

View File

@ -9,7 +9,7 @@ import com.google.common.base.Throwables
import com.google.common.util.concurrent.ListenableFuture
import core.crypto.SecureHash
import core.crypto.sha256
import core.node.services.ServiceHub
import core.node.ServiceHub
import core.protocols.ProtocolLogic
import core.protocols.ProtocolStateMachine
import core.serialization.THREAD_LOCAL_KRYO

View File

@ -11,6 +11,7 @@ import core.crypto.generateKeyPair
import core.messaging.MessagingService
import core.messaging.StateMachineManager
import core.messaging.runOnNextMessage
import core.node.subsystems.*
import core.node.services.*
import core.random63BitValue
import core.serialization.deserialize

View File

@ -6,7 +6,7 @@ import api.ResponseFilter
import com.codahale.metrics.JmxReporter
import com.google.common.net.HostAndPort
import core.messaging.MessagingService
import core.node.services.ArtemisMessagingService
import core.node.subsystems.ArtemisMessagingService
import core.node.services.ServiceType
import core.node.servlets.AttachmentDownloadServlet
import core.node.servlets.DataUploadServlet

View File

@ -0,0 +1,58 @@
package core.node
import core.*
import core.crypto.SecureHash
import core.messaging.MessagingService
import core.node.subsystems.*
import core.node.services.*
import core.utilities.RecordingMap
import java.time.Clock
/**
* A service hub simply vends references to the other services a node has. Some of those services may be missing or
* mocked out. This class is useful to pass to chunks of pluggable code that might have need of many different kinds of
* functionality and you don't want to hard-code which types in the interface.
*/
interface ServiceHub {
val walletService: WalletService
val keyManagementService: KeyManagementService
val identityService: IdentityService
val storageService: StorageService
val networkService: MessagingService
val networkMapCache: NetworkMapCache
val monitoringService: MonitoringService
val clock: Clock
/**
* Given a [LedgerTransaction], looks up all its dependencies in the local database, uses the identity service to map
* the [SignedTransaction]s the DB gives back into [LedgerTransaction]s, and then runs the smart contracts for the
* transaction. If no exception is thrown, the transaction is valid.
*/
fun verifyTransaction(ltx: LedgerTransaction) {
val dependencies = ltx.inputs.map {
storageService.validatedTransactions[it.txhash] ?: throw TransactionResolutionException(it.txhash)
}
val ltxns = dependencies.map { it.verifyToLedgerTransaction(identityService, storageService.attachments) }
TransactionGroup(setOf(ltx), ltxns.toSet()).verify()
}
/**
* Given a list of [SignedTransaction]s, writes them to the local storage for validated transactions and then
* sends them to the wallet for further processing.
*
* TODO: Need to come up with a way for preventing transactions being written other than by this method.
* TODO: RecordingMap is test infrastructure. Refactor it away or find a way to ensure it's only used in tests.
*
* @param txs The transactions to record
* @param skipRecordingMap This is used in unit testing and can be ignored most of the time.
*/
fun recordTransactions(txs: List<SignedTransaction>, skipRecordingMap: Boolean = false) {
val txns: Map<SecureHash, SignedTransaction> = txs.groupBy { it.id }.mapValues { it.value.first() }
val txStorage = storageService.validatedTransactions
if (txStorage is RecordingMap && skipRecordingMap)
txStorage.putAllUnrecorded(txns)
else
txStorage.putAll(txns)
walletService.notifyAll(txs.map { it.tx })
}
}

View File

@ -2,6 +2,7 @@ package core.node.services
import core.messaging.Message
import core.messaging.MessagingService
import core.node.subsystems.TOPIC_DEFAULT_POSTFIX
import core.serialization.deserialize
import core.serialization.serialize
import protocols.AbstractRequestMessage

View File

@ -11,6 +11,8 @@ import core.messaging.MessageRecipients
import core.messaging.MessagingService
import core.messaging.SingleMessageRecipient
import core.node.NodeInfo
import core.node.subsystems.NetworkMapCache
import core.node.subsystems.TOPIC_DEFAULT_POSTFIX
import core.serialization.SerializedBytes
import core.serialization.deserialize
import core.serialization.serialize

View File

@ -1,7 +1,7 @@
package core.node.servlets
import core.crypto.SecureHash
import core.node.services.StorageService
import core.node.subsystems.StorageService
import core.utilities.loggerFor
import java.io.FileNotFoundException
import javax.servlet.http.HttpServlet

View File

@ -1,4 +1,4 @@
package core.node.services
package core.node.subsystems
import com.google.common.net.HostAndPort
import core.RunOnCallerThread
@ -141,7 +141,7 @@ class ArtemisMessagingService(val directory: Path, val myHostPort: HostAndPort,
// This code runs for every inbound message.
try {
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")
return@setMessageHandler
}
val topic = message.getStringProperty(TOPIC_PROPERTY)

View File

@ -1,4 +1,4 @@
package core.node.services
package core.node.subsystems
import core.SignedTransaction
import core.crypto.SecureHash
@ -6,6 +6,8 @@ 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

View File

@ -1,7 +1,8 @@
package core.node.services
package core.node.subsystems
import core.ThreadBox
import core.crypto.generateKeyPair
import core.node.subsystems.KeyManagementService
import java.security.KeyPair
import java.security.PrivateKey
import java.security.PublicKey

View File

@ -1,6 +1,7 @@
package core.node.services
package core.node.subsystems
import core.Party
import core.node.services.IdentityService
import java.security.PublicKey
import java.util.concurrent.ConcurrentHashMap
import javax.annotation.concurrent.ThreadSafe

View File

@ -1,4 +1,4 @@
package core.node.services
package core.node.subsystems
import com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.MoreExecutors
@ -10,6 +10,7 @@ import core.messaging.MessagingService
import core.messaging.StateMachineManager
import core.messaging.runOnNextMessage
import core.node.NodeInfo
import core.node.services.*
import core.random63BitValue
import core.serialization.deserialize
import core.serialization.serialize

View File

@ -1,9 +1,12 @@
package core.node.services
package core.node.subsystems
import com.codahale.metrics.Gauge
import contracts.Cash
import core.*
import core.crypto.SecureHash
import core.node.ServiceHub
import core.node.subsystems.Wallet
import core.node.subsystems.WalletService
import core.utilities.loggerFor
import core.utilities.trace
import java.security.PublicKey

View File

@ -1,10 +1,12 @@
package core.node.services
package core.node.subsystems
import com.codahale.metrics.MetricRegistry
import contracts.Cash
import core.*
import core.crypto.SecureHash
import core.messaging.MessagingService
import core.node.subsystems.NetworkMapCache
import core.node.services.AttachmentStorage
import core.utilities.RecordingMap
import java.security.KeyPair
import java.security.PrivateKey
@ -147,51 +149,3 @@ interface StorageService {
*/
class MonitoringService(val metrics: MetricRegistry)
/**
* A service hub simply vends references to the other services a node has. Some of those services may be missing or
* mocked out. This class is useful to pass to chunks of pluggable code that might have need of many different kinds of
* functionality and you don't want to hard-code which types in the interface.
*/
interface ServiceHub {
val walletService: WalletService
val keyManagementService: KeyManagementService
val identityService: IdentityService
val storageService: StorageService
val networkService: MessagingService
val networkMapCache: NetworkMapCache
val monitoringService: MonitoringService
val clock: Clock
/**
* Given a [LedgerTransaction], looks up all its dependencies in the local database, uses the identity service to map
* the [SignedTransaction]s the DB gives back into [LedgerTransaction]s, and then runs the smart contracts for the
* transaction. If no exception is thrown, the transaction is valid.
*/
fun verifyTransaction(ltx: LedgerTransaction) {
val dependencies = ltx.inputs.map {
storageService.validatedTransactions[it.txhash] ?: throw TransactionResolutionException(it.txhash)
}
val ltxns = dependencies.map { it.verifyToLedgerTransaction(identityService, storageService.attachments) }
TransactionGroup(setOf(ltx), ltxns.toSet()).verify()
}
/**
* Given a list of [SignedTransaction]s, writes them to the local storage for validated transactions and then
* sends them to the wallet for further processing.
*
* TODO: Need to come up with a way for preventing transactions being written other than by this method.
* TODO: RecordingMap is test infrastructure. Refactor it away or find a way to ensure it's only used in tests.
*
* @param txs The transactions to record
* @param skipRecordingMap This is used in unit testing and can be ignored most of the time.
*/
fun recordTransactions(txs: List<SignedTransaction>, skipRecordingMap: Boolean = false) {
val txns: Map<SecureHash, SignedTransaction> = txs.groupBy { it.id }.mapValues { it.value.first() }
val txStorage = storageService.validatedTransactions
if (txStorage is RecordingMap && skipRecordingMap)
txStorage.putAllUnrecorded(txns)
else
txStorage.putAll(txns)
walletService.notifyAll(txs.map { it.tx })
}
}

View File

@ -1,8 +1,10 @@
package core.node.services
package core.node.subsystems
import core.Party
import core.SignedTransaction
import core.crypto.SecureHash
import core.node.services.AttachmentStorage
import core.node.subsystems.StorageService
import core.utilities.RecordingMap
import org.slf4j.LoggerFactory
import java.security.KeyPair

View File

@ -2,7 +2,7 @@ package core.protocols
import co.paralleluniverse.fibers.Suspendable
import core.messaging.MessageRecipients
import core.node.services.ServiceHub
import core.node.ServiceHub
import core.utilities.ProgressTracker
import core.utilities.UntrustworthyData
import org.slf4j.Logger

View File

@ -9,7 +9,7 @@ import com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.SettableFuture
import core.messaging.MessageRecipients
import core.messaging.StateMachineManager
import core.node.services.ServiceHub
import core.node.ServiceHub
import core.serialization.createKryo
import core.utilities.UntrustworthyData
import org.slf4j.Logger

View File

@ -8,7 +8,7 @@ import contracts.InterestRateSwap
import core.*
import core.crypto.SecureHash
import core.testing.MockIdentityService
import core.node.services.linearHeadsOfType
import core.node.subsystems.linearHeadsOfType
import core.utilities.JsonSupport
import protocols.TwoPartyDealProtocol
import java.time.LocalDate

View File

@ -11,7 +11,7 @@ import co.paralleluniverse.common.util.VisibleForTesting
import core.Party
import core.crypto.DummyPublicKey
import core.messaging.SingleMessageRecipient
import core.node.services.InMemoryNetworkMapCache
import core.node.subsystems.InMemoryNetworkMapCache
import core.node.NodeInfo
/**

View File

@ -4,7 +4,7 @@ import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture
import contracts.CommercialPaper
import core.*
import core.node.services.NodeWalletService
import core.node.subsystems.NodeWalletService
import core.utilities.BriefLogFormatter
import protocols.TwoPartyTradeProtocol
import java.time.Instant

View File

@ -8,6 +8,7 @@ import core.node.Node
import core.node.NodeConfiguration
import core.node.NodeConfigurationFromConfig
import core.node.NodeInfo
import core.node.subsystems.ArtemisMessagingService
import core.node.services.*
import core.serialization.deserialize
import core.utilities.BriefLogFormatter

View File

@ -5,7 +5,7 @@ import core.*
import core.node.Node
import core.node.NodeConfiguration
import core.node.NodeInfo
import core.node.services.ArtemisMessagingService
import core.node.subsystems.ArtemisMessagingService
import core.node.services.NodeInterestRates
import core.node.services.ServiceType
import core.serialization.deserialize

View File

@ -12,6 +12,8 @@ import core.node.Node
import core.node.NodeConfiguration
import core.node.NodeConfigurationFromConfig
import core.node.NodeInfo
import core.node.subsystems.ArtemisMessagingService
import core.node.subsystems.NodeWalletService
import core.node.services.*
import core.protocols.ProtocolLogic
import core.serialization.deserialize

View File

@ -6,7 +6,7 @@ import contracts.InterestRateSwap
import core.StateAndRef
import core.node.Node
import core.node.NodeInfo
import core.node.services.linearHeadsOfType
import core.node.subsystems.linearHeadsOfType
import core.protocols.ProtocolLogic
import core.random63BitValue
import core.serialization.deserialize

View File

@ -4,7 +4,7 @@ import co.paralleluniverse.fibers.Suspendable
import core.NamedByHash
import core.crypto.SecureHash
import core.messaging.SingleMessageRecipient
import core.node.services.DataVendingService
import core.node.subsystems.DataVendingService
import core.protocols.ProtocolLogic
import core.random63BitValue
import core.utilities.UntrustworthyData

View File

@ -3,6 +3,8 @@ package core
import com.codahale.metrics.MetricRegistry
import core.crypto.*
import core.messaging.MessagingService
import core.node.ServiceHub
import core.node.subsystems.*
import core.node.services.*
import core.serialization.SerializedBytes
import core.serialization.deserialize

View File

@ -6,6 +6,11 @@ import core.*
import core.crypto.SecureHash
import core.node.NodeConfiguration
import core.node.NodeInfo
import core.node.ServiceHub
import core.node.subsystems.NodeWalletService
import core.node.subsystems.StorageService
import core.node.subsystems.StorageServiceImpl
import core.node.subsystems.Wallet
import core.node.services.*
import core.testing.InMemoryMessagingNetwork
import core.testing.MockNetwork

View File

@ -1,8 +1,9 @@
package core.node
package core.node.services
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

View File

@ -1,7 +1,8 @@
package core.node.services
package core.node.subsystems
import core.messaging.Message
import core.messaging.MessageRecipients
import core.node.subsystems.ArtemisMessagingService
import core.testutils.freeLocalHostAndPort
import org.assertj.core.api.Assertions.assertThat
import org.junit.After

View File

@ -1,4 +1,4 @@
package core.node.services
package core.node.subsystems
import core.testing.MockNetwork
import org.junit.Before

View File

@ -1,9 +1,9 @@
package core.node
package core.node.subsystems
import contracts.Cash
import core.*
import core.node.services.NodeWalletService
import core.node.services.ServiceHub
import core.node.subsystems.NodeWalletService
import core.node.ServiceHub
import core.testutils.*
import core.utilities.BriefLogFormatter
import org.junit.After