mirror of
https://github.com/corda/corda.git
synced 2025-02-21 01:42:24 +00:00
Merged in rnicoll-nodeinfo-services (pull request #54)
Infrastructure work for network map service
This commit is contained in:
commit
ff5078fbbc
@ -9,6 +9,7 @@ import java.security.PublicKey
|
||||
* service would provide.
|
||||
*/
|
||||
interface IdentityService {
|
||||
object Type : ServiceType("corda.identity")
|
||||
fun partyFromKey(key: PublicKey): Party?
|
||||
fun partyFromName(name: String): Party?
|
||||
}
|
||||
|
33
core/src/main/kotlin/core/node/services/ServiceType.kt
Normal file
33
core/src/main/kotlin/core/node/services/ServiceType.kt
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2016 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
|
||||
|
||||
/**
|
||||
* Identifier for service types a node can expose.
|
||||
*/
|
||||
abstract class ServiceType(val id: String) {
|
||||
init {
|
||||
// Enforce:
|
||||
//
|
||||
// * IDs must start with a lower case letter
|
||||
// * IDs can only contain alphanumeric, full stop and underscore ASCII characters
|
||||
require(id.matches(Regex("[a-z][a-zA-Z0-9._]+")))
|
||||
}
|
||||
|
||||
override operator fun equals(other: Any?): Boolean =
|
||||
if (other is ServiceType) {
|
||||
id == other.id
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
|
||||
override fun toString(): String = id.toString()
|
||||
}
|
@ -15,6 +15,7 @@ import core.serialization.SerializedBytes
|
||||
* themselves.
|
||||
*/
|
||||
interface TimestamperService {
|
||||
object Type : ServiceType("corda.timestamper")
|
||||
@Suspendable
|
||||
fun timestamp(wtxBytes: SerializedBytes<WireTransaction>): DigitalSignature.LegallyIdentifiable
|
||||
|
||||
|
@ -15,6 +15,7 @@ import core.messaging.StateMachineManager
|
||||
import core.node.services.*
|
||||
import core.serialization.deserialize
|
||||
import core.serialization.serialize
|
||||
import core.testing.MockNetworkMapCache
|
||||
import org.slf4j.Logger
|
||||
import java.nio.file.FileAlreadyExistsException
|
||||
import java.nio.file.Files
|
||||
@ -58,7 +59,7 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration,
|
||||
}
|
||||
|
||||
val info: NodeInfo by lazy {
|
||||
NodeInfo(net.myAddress, storage.myLegalIdentity, findMyLocation())
|
||||
NodeInfo(net.myAddress, storage.myLegalIdentity, emptySet(), findMyLocation())
|
||||
}
|
||||
|
||||
protected open fun findMyLocation(): PhysicalLocation? = CityDatabase[configuration.nearestCity]
|
||||
@ -90,6 +91,8 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration,
|
||||
lateinit var api: APIServer
|
||||
|
||||
open fun start(): AbstractNode {
|
||||
require(timestamperAddress == null || timestamperAddress.advertisedServices.contains(TimestamperService.Type))
|
||||
{"Timestamper address must indicate a node that provides timestamping services"}
|
||||
log.info("Node starting up ...")
|
||||
|
||||
storage = initialiseStorageService(dir)
|
||||
@ -117,7 +120,7 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration,
|
||||
timestamperAddress
|
||||
} else {
|
||||
inNodeTimestampingService = NodeTimestamperService(net, storage.myLegalIdentity, storage.myLegalIdentityKey, platformClock)
|
||||
NodeInfo(net.myAddress, storage.myLegalIdentity)
|
||||
NodeInfo(net.myAddress, storage.myLegalIdentity, setOf(TimestamperService.Type))
|
||||
}
|
||||
(services.networkMapCache as MockNetworkMapCache).timestampingNodes.add(tsid)
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import com.codahale.metrics.JmxReporter
|
||||
import com.google.common.net.HostAndPort
|
||||
import core.messaging.MessagingService
|
||||
import core.node.services.ArtemisMessagingService
|
||||
import core.node.services.NodeInfo
|
||||
import core.node.servlets.AttachmentDownloadServlet
|
||||
import core.node.servlets.DataUploadServlet
|
||||
import core.utilities.loggerFor
|
||||
|
19
src/main/kotlin/core/node/NodeInfo.kt
Normal file
19
src/main/kotlin/core/node/NodeInfo.kt
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
|
||||
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
|
||||
* set forth therein.
|
||||
*
|
||||
* All other rights reserved.
|
||||
*/
|
||||
package core.node
|
||||
|
||||
import core.Party
|
||||
import core.messaging.SingleMessageRecipient
|
||||
import core.node.services.ServiceType
|
||||
|
||||
/**
|
||||
* Info about a network node that acts on behalf of some form of contract party.
|
||||
*/
|
||||
data class NodeInfo(val address: SingleMessageRecipient, val identity: Party,
|
||||
var advertisedServices: Set<ServiceType> = emptySet(),
|
||||
val physicalLocation: PhysicalLocation? = null)
|
68
src/main/kotlin/core/node/PhysicalLocationStructures.kt
Normal file
68
src/main/kotlin/core/node/PhysicalLocationStructures.kt
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
|
||||
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
|
||||
* set forth therein.
|
||||
*
|
||||
* All other rights reserved.
|
||||
*/
|
||||
|
||||
package core.node
|
||||
|
||||
import java.util.*
|
||||
|
||||
/** A latitude/longitude pair. */
|
||||
data class WorldCoordinate(val latitude: Double, val longitude: Double) {
|
||||
init {
|
||||
require(latitude in -90..90)
|
||||
require(longitude in -180..180)
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to screen coordinates using the Mercator projection. You should have a world map image that
|
||||
* you know the precise extents of for this function to work.
|
||||
*
|
||||
* Note that no world map ever has latitude extents of -90 to 90 because at these extremes the mapping tends
|
||||
* to infinity. Google Maps, for example, uses a square map image, and square maps yield latitude extents
|
||||
* of 85.0511 to -85.0511 = arctan(sinh(π)).
|
||||
*/
|
||||
fun project(screenWidth: Double, screenHeight: Double, topLatitude: Double, bottomLatitude: Double,
|
||||
leftLongitude: Double, rightLongitude: Double): Pair<Double, Double> {
|
||||
require(latitude in bottomLatitude..topLatitude)
|
||||
require(longitude in leftLongitude..rightLongitude)
|
||||
|
||||
fun deg2rad(deg: Double) = deg * Math.PI / 180.0
|
||||
val leftLngRad = deg2rad(leftLongitude)
|
||||
val rightLngRad = deg2rad(rightLongitude)
|
||||
fun longitudeToScreenX(lng: Double) = screenWidth * (deg2rad(lng) - leftLngRad) / (rightLngRad - leftLngRad)
|
||||
fun screenYRelative(latDeg: Double) = Math.log(Math.tan(latDeg / 360.0 * Math.PI + Math.PI / 4))
|
||||
val topLatRel = screenYRelative(topLatitude)
|
||||
val bottomLatRel = screenYRelative(bottomLatitude)
|
||||
fun latitudeToScreenY(lat: Double) = screenHeight * (screenYRelative(lat) - topLatRel) / (bottomLatRel - topLatRel)
|
||||
return Pair(longitudeToScreenX(longitude), latitudeToScreenY(latitude))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A labelled [WorldCoordinate], where the label is human meaningful. For example, the name of the nearest city.
|
||||
* Labels should not refer to non-landmarks, for example, they should not contain the names of organisations.
|
||||
*/
|
||||
data class PhysicalLocation(val coordinate: WorldCoordinate, val description: String)
|
||||
|
||||
/**
|
||||
* A simple lookup table of city names to their coordinates. Lookups are case insensitive.
|
||||
*/
|
||||
object CityDatabase {
|
||||
private val cityMap = HashMap<String, PhysicalLocation>()
|
||||
|
||||
init {
|
||||
javaClass.getResourceAsStream("cities.txt").bufferedReader().useLines { lines ->
|
||||
for (line in lines) {
|
||||
if (line.startsWith("#")) continue
|
||||
val (name, lng, lat) = line.split('\t')
|
||||
cityMap[name.toLowerCase()] = PhysicalLocation(WorldCoordinate(lat.toDouble(), lng.toDouble()), name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
operator fun get(name: String) = cityMap[name.toLowerCase()]
|
||||
}
|
@ -3,14 +3,10 @@ package core.node.services
|
||||
import core.Party
|
||||
import core.crypto.DummyPublicKey
|
||||
import core.messaging.SingleMessageRecipient
|
||||
import core.node.NodeInfo
|
||||
import core.node.PhysicalLocation
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Info about a network node that acts on behalf of some sort of verified identity.
|
||||
*/
|
||||
data class NodeInfo(val address: SingleMessageRecipient, val identity: Party,
|
||||
val physicalLocation: PhysicalLocation? = null)
|
||||
|
||||
/**
|
||||
* A network map contains lists of nodes on the network along with information about their identity keys, services
|
||||
* they provide and host names or IP addresses where they can be connected to. A reasonable architecture for the
|
||||
@ -21,6 +17,7 @@ data class NodeInfo(val address: SingleMessageRecipient, val identity: Party,
|
||||
* This interface assumes fast, synchronous access to an in-memory map.
|
||||
*/
|
||||
interface NetworkMapCache {
|
||||
object Type : ServiceType("corda.network_map")
|
||||
val timestampingNodes: List<NodeInfo>
|
||||
val ratesOracleNodes: List<NodeInfo>
|
||||
val partyNodes: List<NodeInfo>
|
||||
@ -29,74 +26,3 @@ interface NetworkMapCache {
|
||||
fun nodeForPartyName(name: String): NodeInfo? = partyNodes.singleOrNull { it.identity.name == name }
|
||||
}
|
||||
|
||||
// TODO: Move this to the test tree once a real network map is implemented and this scaffolding is no longer needed.
|
||||
class MockNetworkMapCache : NetworkMapCache {
|
||||
data class MockAddress(val id: String) : SingleMessageRecipient
|
||||
|
||||
override val timestampingNodes = Collections.synchronizedList(ArrayList<NodeInfo>())
|
||||
override val ratesOracleNodes = Collections.synchronizedList(ArrayList<NodeInfo>())
|
||||
override val partyNodes = Collections.synchronizedList(ArrayList<NodeInfo>())
|
||||
override val regulators = Collections.synchronizedList(ArrayList<NodeInfo>())
|
||||
|
||||
init {
|
||||
partyNodes.add(NodeInfo(MockAddress("bankC:8080"), Party("Bank C", DummyPublicKey("Bank C"))))
|
||||
partyNodes.add(NodeInfo(MockAddress("bankD:8080"), Party("Bank D", DummyPublicKey("Bank D"))))
|
||||
}
|
||||
}
|
||||
|
||||
/** A latitude/longitude pair. */
|
||||
data class WorldCoordinate(val latitude: Double, val longitude: Double) {
|
||||
init {
|
||||
require(latitude in -90..90)
|
||||
require(longitude in -180..180)
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to screen coordinates using the Mercator projection. You should have a world map image that
|
||||
* you know the precise extents of for this function to work.
|
||||
*
|
||||
* Note that no world map ever has latitude extents of -90 to 90 because at these extremes the mapping tends
|
||||
* to infinity. Google Maps, for example, uses a square map image, and square maps yield latitude extents
|
||||
* of 85.0511 to -85.0511 = arctan(sinh(π)).
|
||||
*/
|
||||
fun project(screenWidth: Double, screenHeight: Double, topLatitude: Double, bottomLatitude: Double,
|
||||
leftLongitude: Double, rightLongitude: Double): Pair<Double, Double> {
|
||||
require(latitude in bottomLatitude..topLatitude)
|
||||
require(longitude in leftLongitude..rightLongitude)
|
||||
|
||||
fun deg2rad(deg: Double) = deg * Math.PI / 180.0
|
||||
val leftLngRad = deg2rad(leftLongitude)
|
||||
val rightLngRad = deg2rad(rightLongitude)
|
||||
fun longitudeToScreenX(lng: Double) = screenWidth * (deg2rad(lng) - leftLngRad) / (rightLngRad - leftLngRad)
|
||||
fun screenYRelative(latDeg: Double) = Math.log(Math.tan(latDeg / 360.0 * Math.PI + Math.PI / 4))
|
||||
val topLatRel = screenYRelative(topLatitude)
|
||||
val bottomLatRel = screenYRelative(bottomLatitude)
|
||||
fun latitudeToScreenY(lat: Double) = screenHeight * (screenYRelative(lat) - topLatRel) / (bottomLatRel - topLatRel)
|
||||
return Pair(longitudeToScreenX(longitude), latitudeToScreenY(latitude))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A labelled [WorldCoordinate], where the label is human meaningful. For example, the name of the nearest city.
|
||||
* Labels should not refer to non-landmarks, for example, they should not contain the names of organisations.
|
||||
*/
|
||||
data class PhysicalLocation(val coordinate: WorldCoordinate, val description: String)
|
||||
|
||||
/**
|
||||
* A simple lookup table of city names to their coordinates. Lookups are case insensitive.
|
||||
*/
|
||||
object CityDatabase {
|
||||
private val cityMap = HashMap<String, PhysicalLocation>()
|
||||
|
||||
init {
|
||||
javaClass.getResourceAsStream("cities.txt").bufferedReader().useLines { lines ->
|
||||
for (line in lines) {
|
||||
if (line.startsWith("#")) continue
|
||||
val (name, lng, lat) = line.split('\t')
|
||||
cityMap[name.toLowerCase()] = PhysicalLocation(WorldCoordinate(lat.toDouble(), lng.toDouble()), name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
operator fun get(name: String) = cityMap[name.toLowerCase()]
|
||||
}
|
@ -25,6 +25,7 @@ import javax.annotation.concurrent.ThreadSafe
|
||||
* for signing.
|
||||
*/
|
||||
object NodeInterestRates {
|
||||
object Type : ServiceType("corda.interest_rates")
|
||||
/** Parses a string of the form "LIBOR 16-March-2016 1M = 0.678" into a [FixOf] and [Fix] */
|
||||
fun parseOneRate(s: String): Pair<FixOf, Fix> {
|
||||
val (key, value) = s.split('=').map { it.trim() }
|
||||
|
@ -47,6 +47,7 @@ data class Wallet(val states: List<StateAndRef<ContractState>>) {
|
||||
* consumed by someone else first!
|
||||
*/
|
||||
interface WalletService {
|
||||
object Type : ServiceType("corda.wallet")
|
||||
/**
|
||||
* Returns a read-only snapshot of the wallet at the time the call is made. Note that if you consume states or
|
||||
* keys in this wallet, you must inform the wallet service so it can update its internal state.
|
||||
@ -101,6 +102,7 @@ inline fun <reified T : LinearState> WalletService.linearHeadsOfType() = linearH
|
||||
* interface if/when one is developed.
|
||||
*/
|
||||
interface KeyManagementService {
|
||||
object Type : ServiceType("corda.key_management")
|
||||
/** Returns a snapshot of the current pubkey->privkey mapping. */
|
||||
val keys: Map<PublicKey, PrivateKey>
|
||||
|
||||
@ -116,6 +118,7 @@ interface KeyManagementService {
|
||||
* anything like that, this interface is only big enough to support the prototyping work.
|
||||
*/
|
||||
interface StorageService {
|
||||
object Type : ServiceType("corda.storage")
|
||||
/**
|
||||
* A map of hash->tx where tx has been signature/contract validated and the states are known to be correct.
|
||||
* The signatures aren't technically needed after that point, but we keep them around so that we can relay
|
||||
@ -172,7 +175,9 @@ interface AttachmentStorage {
|
||||
* Provides access to various metrics and ways to notify monitoring services of things, for sysadmin purposes.
|
||||
* This is not an interface because it is too lightweight to bother mocking out.
|
||||
*/
|
||||
class MonitoringService(val metrics: MetricRegistry)
|
||||
class MonitoringService(val metrics: MetricRegistry) {
|
||||
object Type : ServiceType("corda.monitoring")
|
||||
}
|
||||
|
||||
/**
|
||||
* A service hub simply vends references to the other services a node has. Some of those services may be missing or
|
||||
|
@ -6,9 +6,11 @@ import com.google.common.util.concurrent.MoreExecutors
|
||||
import core.ThreadBox
|
||||
import core.crypto.sha256
|
||||
import core.messaging.*
|
||||
import core.node.NodeInfo
|
||||
import core.node.services.DummyTimestampingAuthority
|
||||
import core.node.services.NodeInfo
|
||||
import core.node.services.NodeTimestamperService
|
||||
import core.node.services.ServiceType
|
||||
import core.node.services.TimestamperService
|
||||
import core.utilities.loggerFor
|
||||
import rx.Observable
|
||||
import rx.subjects.PublishSubject
|
||||
@ -150,7 +152,7 @@ class InMemoryMessagingNetwork {
|
||||
val (handle, builder) = createNode(manuallyPumped)
|
||||
val node = builder.start().get()
|
||||
NodeTimestamperService(node, DummyTimestampingAuthority.identity, DummyTimestampingAuthority.key)
|
||||
timestampingAdvert = NodeInfo(handle, DummyTimestampingAuthority.identity)
|
||||
timestampingAdvert = NodeInfo(handle, DummyTimestampingAuthority.identity, setOf(TimestamperService.Type))
|
||||
return Pair(timestampingAdvert!!, node)
|
||||
}
|
||||
|
||||
|
29
src/main/kotlin/core/testing/MockNetworkMapCache.kt
Normal file
29
src/main/kotlin/core/testing/MockNetworkMapCache.kt
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2016 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.testing
|
||||
|
||||
import core.Party
|
||||
import core.crypto.DummyPublicKey
|
||||
import core.messaging.SingleMessageRecipient
|
||||
import core.node.services.NetworkMapCache
|
||||
import core.node.NodeInfo
|
||||
import java.util.*
|
||||
|
||||
class MockNetworkMapCache : NetworkMapCache {
|
||||
data class MockAddress(val id: String) : SingleMessageRecipient
|
||||
|
||||
override val timestampingNodes = Collections.synchronizedList(ArrayList<NodeInfo>())
|
||||
override val ratesOracleNodes = Collections.synchronizedList(ArrayList<NodeInfo>())
|
||||
override val partyNodes = Collections.synchronizedList(ArrayList<NodeInfo>())
|
||||
override val regulators = Collections.synchronizedList(ArrayList<NodeInfo>())
|
||||
|
||||
init {
|
||||
partyNodes.add(NodeInfo(MockAddress("bankC:8080"), Party("Bank C", DummyPublicKey("Bank C"))))
|
||||
partyNodes.add(NodeInfo(MockAddress("bankD:8080"), Party("Bank D", DummyPublicKey("Bank D"))))
|
||||
}
|
||||
}
|
@ -7,9 +7,11 @@ import core.messaging.MessagingService
|
||||
import core.messaging.SingleMessageRecipient
|
||||
import core.node.AbstractNode
|
||||
import core.node.NodeConfiguration
|
||||
import core.node.NodeInfo
|
||||
import core.node.PhysicalLocation
|
||||
import core.node.services.FixedIdentityService
|
||||
import core.node.services.NodeInfo
|
||||
import core.node.services.PhysicalLocation
|
||||
import core.node.services.ServiceType
|
||||
import core.node.services.TimestamperService
|
||||
import core.utilities.loggerFor
|
||||
import org.slf4j.Logger
|
||||
import java.nio.file.Files
|
||||
@ -90,7 +92,8 @@ class MockNetwork(private val threadPerNode: Boolean = false,
|
||||
}
|
||||
|
||||
/** Returns a started node, optionally created by the passed factory method */
|
||||
fun createNode(withTimestamper: NodeInfo?, forcedID: Int = -1, nodeFactory: Factory = defaultFactory): MockNode {
|
||||
fun createNode(withTimestamper: NodeInfo?, forcedID: Int = -1, nodeFactory: Factory = defaultFactory,
|
||||
advertisedServices: Set<ServiceType> = emptySet()): MockNode {
|
||||
val newNode = forcedID == -1
|
||||
val id = if (newNode) counter++ else forcedID
|
||||
|
||||
@ -103,6 +106,7 @@ class MockNetwork(private val threadPerNode: Boolean = false,
|
||||
override val nearestCity: String = "Atlantis"
|
||||
}
|
||||
val node = nodeFactory.create(path, config, this, withTimestamper).start()
|
||||
node.info.advertisedServices = advertisedServices
|
||||
_nodes.add(node)
|
||||
return node
|
||||
}
|
||||
@ -127,7 +131,10 @@ class MockNetwork(private val threadPerNode: Boolean = false,
|
||||
*/
|
||||
fun createTwoNodes(nodeFactory: Factory = defaultFactory): Pair<MockNode, MockNode> {
|
||||
require(nodes.isEmpty())
|
||||
return Pair(createNode(null, -1, nodeFactory), createNode(nodes[0].info, -1, nodeFactory))
|
||||
return Pair(
|
||||
createNode(null, -1, nodeFactory, setOf(TimestamperService.Type)),
|
||||
createNode(nodes[0].info, -1, nodeFactory)
|
||||
)
|
||||
}
|
||||
|
||||
fun addressToNode(address: SingleMessageRecipient): MockNode = nodes.single { it.net.myAddress == address }
|
||||
|
@ -1,11 +1,10 @@
|
||||
package core.testing
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import core.node.CityDatabase
|
||||
import core.node.NodeConfiguration
|
||||
import core.node.services.CityDatabase
|
||||
import core.node.services.MockNetworkMapCache
|
||||
import core.node.services.NodeInfo
|
||||
import core.node.services.PhysicalLocation
|
||||
import core.node.NodeInfo
|
||||
import core.node.PhysicalLocation
|
||||
import core.protocols.ProtocolLogic
|
||||
import core.then
|
||||
import core.utilities.ProgressTracker
|
||||
|
@ -7,9 +7,12 @@ import core.logElapsedTime
|
||||
import core.node.Node
|
||||
import core.node.NodeConfiguration
|
||||
import core.node.NodeConfigurationFromConfig
|
||||
import core.node.NodeInfo
|
||||
import core.node.services.ArtemisMessagingService
|
||||
import core.node.services.MockNetworkMapCache
|
||||
import core.node.services.NodeInfo
|
||||
import core.node.services.NodeInterestRates
|
||||
import core.node.services.ServiceType
|
||||
import core.node.services.TimestamperService
|
||||
import core.testing.MockNetworkMapCache
|
||||
import core.serialization.deserialize
|
||||
import core.utilities.BriefLogFormatter
|
||||
import demos.protocols.AutoOfferProtocol
|
||||
@ -71,7 +74,7 @@ fun main(args: Array<String>) {
|
||||
null
|
||||
} else {
|
||||
try {
|
||||
nodeInfo(options.valueOf(timestamperNetAddr), options.valueOf(timestamperIdentityFile))
|
||||
nodeInfo(options.valueOf(timestamperNetAddr), options.valueOf(timestamperIdentityFile), setOf(TimestamperService.Type))
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
@ -82,7 +85,7 @@ fun main(args: Array<String>) {
|
||||
null
|
||||
} else {
|
||||
try {
|
||||
nodeInfo(options.valueOf(rateOracleNetAddr), options.valueOf(rateOracleIdentityFile))
|
||||
nodeInfo(options.valueOf(rateOracleNetAddr), options.valueOf(rateOracleIdentityFile), setOf(NodeInterestRates.Type))
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
@ -122,12 +125,12 @@ fun main(args: Array<String>) {
|
||||
exitProcess(0)
|
||||
}
|
||||
|
||||
fun nodeInfo(hostAndPortString: String, identityFile: String): NodeInfo {
|
||||
fun nodeInfo(hostAndPortString: String, identityFile: String, advertisedServices: Set<ServiceType> = emptySet()): NodeInfo {
|
||||
try {
|
||||
val addr = HostAndPort.fromString(hostAndPortString).withDefaultPort(Node.DEFAULT_PORT)
|
||||
val path = Paths.get(identityFile)
|
||||
val party = Files.readAllBytes(path).deserialize<Party>(includeClassName = true)
|
||||
return NodeInfo(ArtemisMessagingService.makeRecipient(addr), party)
|
||||
return NodeInfo(ArtemisMessagingService.makeRecipient(addr), party, advertisedServices)
|
||||
} catch (e: Exception) {
|
||||
println("Could not find identify file $identityFile. If the file has just been created as part of starting the demo, please restart this node")
|
||||
throw e
|
||||
|
@ -5,7 +5,7 @@ import core.*
|
||||
import core.node.Node
|
||||
import core.node.NodeConfiguration
|
||||
import core.node.services.ArtemisMessagingService
|
||||
import core.node.services.NodeInfo
|
||||
import core.node.NodeInfo
|
||||
import core.node.services.NodeInterestRates
|
||||
import core.serialization.deserialize
|
||||
import core.utilities.ANSIProgressRenderer
|
||||
|
@ -12,8 +12,8 @@ import core.node.Node
|
||||
import core.node.NodeConfiguration
|
||||
import core.node.NodeConfigurationFromConfig
|
||||
import core.node.services.ArtemisMessagingService
|
||||
import core.node.NodeInfo
|
||||
import core.node.services.NodeAttachmentService
|
||||
import core.node.services.NodeInfo
|
||||
import core.node.services.NodeWalletService
|
||||
import core.protocols.ProtocolLogic
|
||||
import core.serialization.deserialize
|
||||
|
@ -3,10 +3,10 @@ package demos.protocols
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import co.paralleluniverse.strands.Strand
|
||||
import core.node.Node
|
||||
import core.node.services.MockNetworkMapCache
|
||||
import core.node.services.NodeInfo
|
||||
import core.node.NodeInfo
|
||||
import core.protocols.ProtocolLogic
|
||||
import core.serialization.deserialize
|
||||
import core.testing.MockNetworkMapCache
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
|
@ -6,12 +6,12 @@ import contracts.DealState
|
||||
import contracts.InterestRateSwap
|
||||
import core.StateAndRef
|
||||
import core.node.Node
|
||||
import core.node.services.MockNetworkMapCache
|
||||
import core.node.services.NodeInfo
|
||||
import core.node.NodeInfo
|
||||
import core.node.services.linearHeadsOfType
|
||||
import core.protocols.ProtocolLogic
|
||||
import core.random63BitValue
|
||||
import core.serialization.deserialize
|
||||
import core.testing.MockNetworkMapCache
|
||||
import core.utilities.ANSIProgressRenderer
|
||||
import core.utilities.ProgressTracker
|
||||
import demos.DemoClock
|
||||
|
@ -4,7 +4,7 @@ import co.paralleluniverse.fibers.Suspendable
|
||||
import core.*
|
||||
import core.crypto.DigitalSignature
|
||||
import core.messaging.SingleMessageRecipient
|
||||
import core.node.services.NodeInfo
|
||||
import core.node.NodeInfo
|
||||
import core.protocols.ProtocolLogic
|
||||
import core.utilities.ProgressTracker
|
||||
import java.math.BigDecimal
|
||||
|
@ -6,7 +6,7 @@ import core.WireTransaction
|
||||
import core.crypto.DigitalSignature
|
||||
import core.messaging.MessageRecipients
|
||||
import core.messaging.StateMachineManager
|
||||
import core.node.services.NodeInfo
|
||||
import core.node.NodeInfo
|
||||
import core.node.services.NodeTimestamperService
|
||||
import core.node.services.TimestamperService
|
||||
import core.protocols.ProtocolLogic
|
||||
|
@ -7,7 +7,7 @@ import core.*
|
||||
import core.crypto.DigitalSignature
|
||||
import core.crypto.signWithECDSA
|
||||
import core.messaging.SingleMessageRecipient
|
||||
import core.node.services.NodeInfo
|
||||
import core.node.NodeInfo
|
||||
import core.protocols.ProtocolLogic
|
||||
import core.utilities.ProgressTracker
|
||||
import core.utilities.UntrustworthyData
|
||||
|
@ -9,7 +9,7 @@ import core.crypto.DigitalSignature
|
||||
import core.crypto.signWithECDSA
|
||||
import core.messaging.SingleMessageRecipient
|
||||
import core.messaging.StateMachineManager
|
||||
import core.node.services.NodeInfo
|
||||
import core.node.NodeInfo
|
||||
import core.protocols.ProtocolLogic
|
||||
import core.utilities.ProgressTracker
|
||||
import core.utilities.trace
|
||||
|
@ -6,6 +6,7 @@ import core.messaging.MessagingService
|
||||
import core.node.services.*
|
||||
import core.serialization.SerializedBytes
|
||||
import core.serialization.deserialize
|
||||
import core.testing.MockNetworkMapCache
|
||||
import core.testutils.MockIdentityService
|
||||
import core.testutils.TEST_PROGRAM_MAP
|
||||
import core.testutils.TEST_TX_TIME
|
||||
|
@ -4,8 +4,9 @@ import core.Attachment
|
||||
import core.crypto.SecureHash
|
||||
import core.crypto.sha256
|
||||
import core.node.NodeConfiguration
|
||||
import core.node.NodeInfo
|
||||
import core.node.services.NodeAttachmentService
|
||||
import core.node.services.NodeInfo
|
||||
import core.node.services.TimestamperService
|
||||
import core.serialization.OpaqueBytes
|
||||
import core.testing.MockNetwork
|
||||
import core.testutils.rootCauseExceptions
|
||||
@ -95,7 +96,7 @@ class AttachmentTests {
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}, advertisedServices = setOf(TimestamperService.Type))
|
||||
val n1 = network.createNode(n0.info)
|
||||
|
||||
// Insert an attachment into node zero's store directly.
|
||||
|
@ -5,6 +5,7 @@ import contracts.CommercialPaper
|
||||
import core.*
|
||||
import core.crypto.SecureHash
|
||||
import core.node.NodeConfiguration
|
||||
import core.node.NodeInfo
|
||||
import core.node.services.*
|
||||
import core.testing.InMemoryMessagingNetwork
|
||||
import core.testing.MockNetwork
|
||||
|
@ -9,6 +9,7 @@ import core.node.services.*
|
||||
import core.protocols.ProtocolLogic
|
||||
import core.serialization.serialize
|
||||
import core.testing.InMemoryMessagingNetwork
|
||||
import core.testing.MockNetworkMapCache
|
||||
import core.testutils.ALICE
|
||||
import core.testutils.ALICE_KEY
|
||||
import core.testutils.CASH
|
||||
|
Loading…
x
Reference in New Issue
Block a user