mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
IRS demo fixes (#782)
* Increase max network map request size so the notary can register * Suppress oracle service installation errors in non-oracle nodes * Make demos automatically build capsule jars
This commit is contained in:
parent
c510e67ed5
commit
51ea9fec1a
@ -11,10 +11,13 @@ import kotlin.annotation.AnnotationTarget.CLASS
|
||||
*
|
||||
* The service class has to implement [net.corda.core.serialization.SerializeAsToken] to ensure correct usage within flows.
|
||||
* (If possible extend [net.corda.core.serialization.SingletonSerializeAsToken] instead as it removes the boilerplate.)
|
||||
*
|
||||
* The annotated class should expose its [ServiceType] via a public static field named `type`, so that the service is
|
||||
* only loaded in nodes that declare the type in their advertisedServices.
|
||||
*/
|
||||
// TODO Handle the singleton serialisation of Corda services automatically, removing the need to implement SerializeAsToken
|
||||
// TODO Currently all nodes which load the plugin will attempt to load the service even if it's not revelant to them. The
|
||||
// underlying problem is that the entire CorDapp jar is used as a dependency, when in fact it's just the client-facing
|
||||
// bit of the CorDapp that should be depended on (e.g. the initiating flows).
|
||||
@Target(CLASS)
|
||||
annotation class CordaService
|
||||
annotation class CordaService
|
||||
|
@ -43,8 +43,8 @@ dependencies {
|
||||
exclude group: "bouncycastle"
|
||||
}
|
||||
|
||||
runtime project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
runtime project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
}
|
||||
|
||||
mainClassName = "net.corda.docs.ClientRpcTutorialKt"
|
||||
|
@ -268,16 +268,31 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
|
||||
private fun installCordaServices(scanResult: ScanResult): List<SerializeAsToken> {
|
||||
return scanResult.getClassesWithAnnotation(SerializeAsToken::class, CordaService::class).mapNotNull {
|
||||
try {
|
||||
installCordaService(it)
|
||||
} catch (e: NoSuchMethodException) {
|
||||
log.error("${it.name}, as a Corda service, must have a constructor with a single parameter " +
|
||||
"of type ${PluginServiceHub::class.java.name}")
|
||||
null
|
||||
} catch (e: Exception) {
|
||||
log.error("Unable to install Corda service ${it.name}", e)
|
||||
null
|
||||
}
|
||||
tryInstallCordaService(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T : SerializeAsToken> tryInstallCordaService(serviceClass: Class<T>): T? {
|
||||
/** TODO: This mechanism may get replaced by a different one, see comments on [CordaService]. */
|
||||
val typeField = try {
|
||||
serviceClass.getField("type")
|
||||
} catch (e: NoSuchFieldException) {
|
||||
null
|
||||
}
|
||||
if (typeField == null) {
|
||||
log.warn("${serviceClass.name} does not have a type field, optimistically proceeding with install.")
|
||||
} else if (info.serviceIdentities(typeField.get(null) as ServiceType).isEmpty()) {
|
||||
return null
|
||||
}
|
||||
return try {
|
||||
installCordaService(serviceClass)
|
||||
} catch (e: NoSuchMethodException) {
|
||||
log.error("${serviceClass.name}, as a Corda service, must have a constructor with a single parameter " +
|
||||
"of type ${PluginServiceHub::class.java.name}")
|
||||
null
|
||||
} catch (e: Exception) {
|
||||
log.error("Unable to install Corda service ${serviceClass.name}", e)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.serialization.SerializedBytes
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.debug
|
||||
import net.corda.core.utilities.loggerFor
|
||||
import net.corda.node.services.api.AbstractNodeService
|
||||
import net.corda.node.services.api.ServiceHubInternal
|
||||
@ -135,10 +136,10 @@ abstract class AbstractNetworkMapService(services: ServiceHubInternal,
|
||||
val minimumPlatformVersion: Int) : NetworkMapService, AbstractNodeService(services) {
|
||||
companion object {
|
||||
/**
|
||||
* Maximum credible size for a registration request. Generally requests are around 500-600 bytes, so this gives a
|
||||
* Maximum credible size for a registration request. Generally requests are around 2000-6000 bytes, so this gives a
|
||||
* 10 times overhead.
|
||||
*/
|
||||
private const val MAX_SIZE_REGISTRATION_REQUEST_BYTES = 5500
|
||||
private const val MAX_SIZE_REGISTRATION_REQUEST_BYTES = 40000
|
||||
private val logger = loggerFor<AbstractNetworkMapService>()
|
||||
}
|
||||
|
||||
@ -232,7 +233,9 @@ abstract class AbstractNetworkMapService(services: ServiceHubInternal,
|
||||
}
|
||||
|
||||
private fun processRegistrationRequest(request: RegistrationRequest): RegistrationResponse {
|
||||
if (request.wireReg.raw.size > MAX_SIZE_REGISTRATION_REQUEST_BYTES) {
|
||||
val requestSize = request.wireReg.raw.size
|
||||
logger.debug { "Received registration request of size: $requestSize" }
|
||||
if (requestSize > MAX_SIZE_REGISTRATION_REQUEST_BYTES) {
|
||||
return RegistrationResponse("Request is too big")
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,8 @@ dependencies {
|
||||
testCompile "junit:junit:$junit_version"
|
||||
|
||||
// Corda integration dependencies
|
||||
runtime project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
runtime project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
compile project(':core')
|
||||
compile project(':test-utils')
|
||||
|
||||
|
@ -26,8 +26,8 @@ dependencies {
|
||||
testCompile "junit:junit:$junit_version"
|
||||
|
||||
// Corda integration dependencies
|
||||
runtime project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
runtime project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
compile project(':core')
|
||||
compile project(':client:jfx')
|
||||
compile project(':client:rpc')
|
||||
|
@ -30,8 +30,8 @@ dependencies {
|
||||
testCompile "org.assertj:assertj-core:${assertj_version}"
|
||||
|
||||
// Corda integration dependencies
|
||||
runtime project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
runtime project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
compile project(':core')
|
||||
compile project(':finance')
|
||||
compile project(':webserver')
|
||||
|
@ -39,7 +39,7 @@ class IRSDemoTest : IntegrationTestCategory {
|
||||
systemProperties = mapOf("net.corda.node.cordapp.scan.package" to "net.corda.irs"))
|
||||
{
|
||||
val (controller, nodeA, nodeB) = Futures.allAsList(
|
||||
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type), ServiceInfo(NodeInterestRates.type))),
|
||||
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type), ServiceInfo(NodeInterestRates.Oracle.type))),
|
||||
startNode(DUMMY_BANK_A.name, rpcUsers = listOf(rpcUser)),
|
||||
startNode(DUMMY_BANK_B.name)
|
||||
).getOrThrow()
|
||||
|
@ -17,7 +17,7 @@ import net.corda.node.services.transactions.SimpleNotaryService
|
||||
fun main(args: Array<String>) {
|
||||
driver(dsl = {
|
||||
val (controller, nodeA, nodeB) = Futures.allAsList(
|
||||
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type), ServiceInfo(NodeInterestRates.type))),
|
||||
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type), ServiceInfo(NodeInterestRates.Oracle.type))),
|
||||
startNode(DUMMY_BANK_A.name),
|
||||
startNode(DUMMY_BANK_B.name)
|
||||
).getOrThrow()
|
||||
|
@ -49,8 +49,6 @@ import kotlin.collections.set
|
||||
* for signing.
|
||||
*/
|
||||
object NodeInterestRates {
|
||||
val type = ServiceType.corda.getSubType("interest_rates")
|
||||
|
||||
// DOCSTART 2
|
||||
@InitiatedBy(RatesFixFlow.FixSignFlow::class)
|
||||
class FixSignHandler(val otherParty: Party) : FlowLogic<Unit>() {
|
||||
@ -95,6 +93,11 @@ object NodeInterestRates {
|
||||
)
|
||||
// DOCEND 3
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val type = ServiceType.corda.getSubType("interest_rates")
|
||||
}
|
||||
|
||||
private object Table : JDBCHashedTable("demo_interest_rate_fixes") {
|
||||
val name = varchar("index_name", length = 255)
|
||||
val forDay = localDate("for_day")
|
||||
|
@ -10,6 +10,7 @@ import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.ServiceType
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.transactions.TransactionBuilder
|
||||
import net.corda.irs.api.NodeInterestRates
|
||||
import net.corda.irs.flows.FixingFlow
|
||||
import net.corda.irs.utilities.suggestInterestRateAnnouncementTimeWindow
|
||||
import org.apache.commons.jexl3.JexlBuilder
|
||||
@ -190,10 +191,6 @@ class FloatingRatePaymentEvent(date: LocalDate,
|
||||
class InterestRateSwap : Contract {
|
||||
override val legalContractReference = SecureHash.sha256("is_this_the_text_of_the_contract ? TBD")
|
||||
|
||||
companion object {
|
||||
val oracleType = ServiceType.corda.getSubType("interest_rates")
|
||||
}
|
||||
|
||||
/**
|
||||
* This Common area contains all the information that is not leg specific.
|
||||
*/
|
||||
@ -665,7 +662,7 @@ class InterestRateSwap : Contract {
|
||||
override val contract = IRS_PROGRAM_ID
|
||||
|
||||
override val oracleType: ServiceType
|
||||
get() = InterestRateSwap.oracleType
|
||||
get() = NodeInterestRates.Oracle.type
|
||||
|
||||
override val ref = common.tradeID
|
||||
|
||||
|
@ -121,7 +121,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
|
||||
override fun create(config: NodeConfiguration, network: MockNetwork, networkMapAddr: SingleMessageRecipient?,
|
||||
advertisedServices: Set<ServiceInfo>, id: Int, overrideServices: Map<ServiceInfo, KeyPair>?,
|
||||
entropyRoot: BigInteger): MockNetwork.MockNode {
|
||||
require(advertisedServices.containsType(NodeInterestRates.type))
|
||||
require(advertisedServices.containsType(NodeInterestRates.Oracle.type))
|
||||
val cfg = TestNodeConfiguration(
|
||||
baseDirectory = config.baseDirectory,
|
||||
myLegalName = RATES_SERVICE_NAME,
|
||||
@ -166,7 +166,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
|
||||
= network.createNode(networkMap.info.address, nodeFactory = NotaryNodeFactory, advertisedServices = ServiceInfo(SimpleNotaryService.type)) as SimulatedNode
|
||||
val regulators: List<SimulatedNode> = listOf(network.createNode(networkMap.info.address, start = false, nodeFactory = RegulatorFactory) as SimulatedNode)
|
||||
val ratesOracle: SimulatedNode
|
||||
= network.createNode(networkMap.info.address, start = false, nodeFactory = RatesOracleFactory, advertisedServices = ServiceInfo(NodeInterestRates.type)) as SimulatedNode
|
||||
= network.createNode(networkMap.info.address, start = false, nodeFactory = RatesOracleFactory, advertisedServices = ServiceInfo(NodeInterestRates.Oracle.type)) as SimulatedNode
|
||||
|
||||
// All nodes must be in one of these two lists for the purposes of the visualiser tool.
|
||||
val serviceProviders: List<SimulatedNode> = listOf(notary, ratesOracle, networkMap)
|
||||
|
@ -209,7 +209,7 @@ class NodeInterestRatesTest {
|
||||
fun `network tearoff`() {
|
||||
val net = MockNetwork()
|
||||
val n1 = net.createNotaryNode()
|
||||
val n2 = net.createNode(n1.info.address, advertisedServices = ServiceInfo(NodeInterestRates.type))
|
||||
val n2 = net.createNode(n1.info.address, advertisedServices = ServiceInfo(NodeInterestRates.Oracle.type))
|
||||
n2.registerInitiatedFlow(NodeInterestRates.FixQueryHandler::class.java)
|
||||
n2.registerInitiatedFlow(NodeInterestRates.FixSignHandler::class.java)
|
||||
n2.database.transaction {
|
||||
@ -217,7 +217,7 @@ class NodeInterestRatesTest {
|
||||
}
|
||||
val tx = TransactionType.General.Builder(null)
|
||||
val fixOf = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M")
|
||||
val oracle = n2.info.serviceIdentities(NodeInterestRates.type).first()
|
||||
val oracle = n2.info.serviceIdentities(NodeInterestRates.Oracle.type).first()
|
||||
val flow = FilteredRatesFlow(tx, oracle, fixOf, "0.675".bd, "0.1".bd)
|
||||
LogHelper.setLevel("rates")
|
||||
net.runNetwork()
|
||||
|
@ -12,8 +12,8 @@ dependencies {
|
||||
testCompile "junit:junit:$junit_version"
|
||||
|
||||
// Corda integration dependencies
|
||||
runtime project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
runtime project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
compile project(':core')
|
||||
compile project(':finance')
|
||||
testCompile project(':test-utils')
|
||||
|
@ -18,8 +18,8 @@ dependencies {
|
||||
testCompile "junit:junit:$junit_version"
|
||||
|
||||
// Corda integration dependencies
|
||||
runtime project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
runtime project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
compile project(':core')
|
||||
compile project(':client:jfx')
|
||||
compile project(':client:rpc')
|
||||
|
@ -31,8 +31,8 @@ dependencies {
|
||||
testCompile "org.assertj:assertj-core:${assertj_version}"
|
||||
|
||||
// Corda integration dependencies
|
||||
runtime project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
runtime project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
compile project(':core')
|
||||
compile project(':node')
|
||||
compile project(':webserver')
|
||||
|
@ -27,8 +27,8 @@ dependencies {
|
||||
testCompile "org.assertj:assertj-core:${assertj_version}"
|
||||
|
||||
// Corda integration dependencies
|
||||
runtime project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
runtime project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":node:capsule", configuration: 'runtimeArtifacts')
|
||||
compile project(path: ":webserver:webcapsule", configuration: 'runtimeArtifacts')
|
||||
compile project(':core')
|
||||
compile project(':finance')
|
||||
compile project(':test-utils')
|
||||
|
Loading…
Reference in New Issue
Block a user