mirror of
https://github.com/corda/corda.git
synced 2025-02-01 08:48:09 +00:00
First working commit
First working commit Formatting clean up Revert All_tests.xml Remove extra space Feedback from code review First working commit Revert All_tests.xml Remove extra space Feedback from code review
This commit is contained in:
parent
c450c70f9a
commit
791022f130
@ -8,6 +8,15 @@
|
|||||||
|
|
||||||
package contracts
|
package contracts
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator
|
||||||
|
import com.fasterxml.jackson.core.JsonParser
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext
|
||||||
|
import com.fasterxml.jackson.databind.JsonDeserializer
|
||||||
|
import com.fasterxml.jackson.databind.JsonSerializer
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize
|
||||||
|
import com.fasterxml.jackson.databind.type.SimpleType
|
||||||
import core.*
|
import core.*
|
||||||
import core.crypto.SecureHash
|
import core.crypto.SecureHash
|
||||||
import core.node.services.DummyTimestampingAuthority
|
import core.node.services.DummyTimestampingAuthority
|
||||||
@ -15,6 +24,7 @@ import org.apache.commons.jexl3.JexlBuilder
|
|||||||
import org.apache.commons.jexl3.MapContext
|
import org.apache.commons.jexl3.MapContext
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.math.RoundingMode
|
import java.math.RoundingMode
|
||||||
|
import java.security.PublicKey
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@ -167,8 +177,6 @@ class InterestRateSwap() : Contract {
|
|||||||
val hashLegalDocs: String
|
val hashLegalDocs: String
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Expression(val expr: String)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Calculation data class is "mutable" through out the life of the swap, as in, it's the only thing that contains
|
* The Calculation data class is "mutable" through out the life of the swap, as in, it's the only thing that contains
|
||||||
* data that will changed from state to state (Recall that the design insists that everything is immutable, so we actually
|
* data that will changed from state to state (Recall that the design insists that everything is immutable, so we actually
|
||||||
@ -177,7 +185,7 @@ class InterestRateSwap() : Contract {
|
|||||||
data class Calculation(
|
data class Calculation(
|
||||||
val expression: Expression,
|
val expression: Expression,
|
||||||
val floatingLegPaymentSchedule: Map<LocalDate, FloatingRatePaymentEvent>,
|
val floatingLegPaymentSchedule: Map<LocalDate, FloatingRatePaymentEvent>,
|
||||||
val fixedLegpaymentSchedule: Map<LocalDate, FixedRatePaymentEvent>
|
val fixedLegPaymentSchedule: Map<LocalDate, FixedRatePaymentEvent>
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* Gets the date of the next fixing.
|
* Gets the date of the next fixing.
|
||||||
@ -185,7 +193,7 @@ class InterestRateSwap() : Contract {
|
|||||||
*/
|
*/
|
||||||
fun nextFixingDate(): LocalDate? {
|
fun nextFixingDate(): LocalDate? {
|
||||||
return floatingLegPaymentSchedule.
|
return floatingLegPaymentSchedule.
|
||||||
filter { it.value.rate is OracleRetrievableReferenceRate }.// TODO - a better way to determine what fixings remain to be fixed
|
filter { it.value.rate is ReferenceRate }.// TODO - a better way to determine what fixings remain to be fixed
|
||||||
minBy { it.value.fixingDate.toEpochDay() }?.value?.fixingDate
|
minBy { it.value.fixingDate.toEpochDay() }?.value?.fixingDate
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +211,7 @@ class InterestRateSwap() : Contract {
|
|||||||
val newFloatingLPS = floatingLegPaymentSchedule + (paymentEvent.date to paymentEvent.withNewRate(newRate))
|
val newFloatingLPS = floatingLegPaymentSchedule + (paymentEvent.date to paymentEvent.withNewRate(newRate))
|
||||||
return Calculation(expression = expression,
|
return Calculation(expression = expression,
|
||||||
floatingLegPaymentSchedule = newFloatingLPS,
|
floatingLegPaymentSchedule = newFloatingLPS,
|
||||||
fixedLegpaymentSchedule = fixedLegpaymentSchedule)
|
fixedLegPaymentSchedule = fixedLegPaymentSchedule)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun exportSchedule() {
|
fun exportSchedule() {
|
||||||
@ -297,7 +305,7 @@ class InterestRateSwap() : Contract {
|
|||||||
*/
|
*/
|
||||||
override fun verify(tx: TransactionForVerification) {
|
override fun verify(tx: TransactionForVerification) {
|
||||||
val command = tx.commands.requireSingleCommand<InterestRateSwap.Commands>()
|
val command = tx.commands.requireSingleCommand<InterestRateSwap.Commands>()
|
||||||
val time = tx.getTimestampBy(DummyTimestampingAuthority.identity)?.midpoint
|
val time = tx.commands.getTimestampByName("Mock Company 0", "Bank of Zurich")?.midpoint
|
||||||
if (time == null) throw IllegalArgumentException("must be timestamped")
|
if (time == null) throw IllegalArgumentException("must be timestamped")
|
||||||
|
|
||||||
val irs = tx.outStates.filterIsInstance<InterestRateSwap.State>().single()
|
val irs = tx.outStates.filterIsInstance<InterestRateSwap.State>().single()
|
||||||
@ -306,7 +314,7 @@ class InterestRateSwap() : Contract {
|
|||||||
requireThat {
|
requireThat {
|
||||||
"There are no in states for an agreement" by tx.inStates.isEmpty()
|
"There are no in states for an agreement" by tx.inStates.isEmpty()
|
||||||
"The fixed rate is non zero" by (irs.fixedLeg.fixedRate != FixedRate(PercentageRatioUnit("0.0")))
|
"The fixed rate is non zero" by (irs.fixedLeg.fixedRate != FixedRate(PercentageRatioUnit("0.0")))
|
||||||
"There are events in the fix schedule" by (irs.calculation.fixedLegpaymentSchedule.size > 0)
|
"There are events in the fix schedule" by (irs.calculation.fixedLegPaymentSchedule.size > 0)
|
||||||
"There are events in the float schedule" by (irs.calculation.floatingLegPaymentSchedule.size > 0)
|
"There are events in the float schedule" by (irs.calculation.floatingLegPaymentSchedule.size > 0)
|
||||||
// "There are fixes in the schedule" by (irs.calculation.floatingLegPaymentSchedule!!.size > 0)
|
// "There are fixes in the schedule" by (irs.calculation.floatingLegPaymentSchedule!!.size > 0)
|
||||||
// TODO: shortlist of other tests
|
// TODO: shortlist of other tests
|
||||||
@ -348,8 +356,14 @@ class InterestRateSwap() : Contract {
|
|||||||
val floatingLeg: FloatingLeg,
|
val floatingLeg: FloatingLeg,
|
||||||
val calculation: Calculation,
|
val calculation: Calculation,
|
||||||
val common: Common
|
val common: Common
|
||||||
) : ContractState {
|
) : LinearState {
|
||||||
override val programRef = IRS_PROGRAM_ID
|
override val programRef = IRS_PROGRAM_ID
|
||||||
|
override val thread = SecureHash.sha256(common.tradeID)
|
||||||
|
override val ref = common.tradeID
|
||||||
|
|
||||||
|
override fun isRelevant(ourKeys: Set<PublicKey>): Boolean {
|
||||||
|
return (fixedLeg.fixedRatePayer.owningKey in ourKeys) || (floatingLeg.floatingRatePayer.owningKey in ourKeys)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For evaluating arbitrary java on the platform
|
* For evaluating arbitrary java on the platform
|
||||||
@ -408,9 +422,6 @@ class InterestRateSwap() : Contract {
|
|||||||
var floatingLegPaymentSchedule: MutableMap<LocalDate, FloatingRatePaymentEvent> = HashMap()
|
var floatingLegPaymentSchedule: MutableMap<LocalDate, FloatingRatePaymentEvent> = HashMap()
|
||||||
periodStartDate = floatingLeg.effectiveDate
|
periodStartDate = floatingLeg.effectiveDate
|
||||||
|
|
||||||
// TODO: Temporary until implemented via Rates Oracle.
|
|
||||||
val telerate = TelerateOracle("3750")
|
|
||||||
|
|
||||||
// Now create a schedule for the floating and fixes.
|
// Now create a schedule for the floating and fixes.
|
||||||
for (periodEndDate in dates) {
|
for (periodEndDate in dates) {
|
||||||
val paymentEvent = FloatingRatePaymentEvent(
|
val paymentEvent = FloatingRatePaymentEvent(
|
||||||
@ -421,8 +432,7 @@ class InterestRateSwap() : Contract {
|
|||||||
floatingLeg.dayCountBasisYear,
|
floatingLeg.dayCountBasisYear,
|
||||||
calcFixingDate(periodStartDate, floatingLeg.fixingPeriod, floatingLeg.fixingCalendar),
|
calcFixingDate(periodStartDate, floatingLeg.fixingPeriod, floatingLeg.fixingCalendar),
|
||||||
floatingLeg.notional,
|
floatingLeg.notional,
|
||||||
// TODO: OracleRetrievableReferenceRate will be replaced via oracle v soon.
|
ReferenceRate(floatingLeg.indexSource, floatingLeg.indexTenor, floatingLeg.index)
|
||||||
OracleRetrievableReferenceRate(telerate, floatingLeg.indexTenor, floatingLeg.index)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
floatingLegPaymentSchedule.put(periodEndDate, paymentEvent)
|
floatingLegPaymentSchedule.put(periodEndDate, paymentEvent)
|
||||||
|
@ -10,6 +10,6 @@ package contracts
|
|||||||
|
|
||||||
fun InterestRateSwap.State.exportIRSToCSV() : String =
|
fun InterestRateSwap.State.exportIRSToCSV() : String =
|
||||||
"Fixed Leg\n" + FixedRatePaymentEvent.CSVHeader + "\n" +
|
"Fixed Leg\n" + FixedRatePaymentEvent.CSVHeader + "\n" +
|
||||||
this.calculation.fixedLegpaymentSchedule.toSortedMap().values.map{ it.asCSV() }.joinToString("\n") + "\n" +
|
this.calculation.fixedLegPaymentSchedule.toSortedMap().values.map{ it.asCSV() }.joinToString("\n") + "\n" +
|
||||||
"Floating Leg\n" + FloatingRatePaymentEvent.CSVHeader + "\n" +
|
"Floating Leg\n" + FloatingRatePaymentEvent.CSVHeader + "\n" +
|
||||||
this.calculation.floatingLegPaymentSchedule.toSortedMap().values.map{ it.asCSV() }.joinToString("\n") + "\n"
|
this.calculation.floatingLegPaymentSchedule.toSortedMap().values.map{ it.asCSV() }.joinToString("\n") + "\n"
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
package contracts
|
package contracts
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParseException
|
||||||
|
import com.fasterxml.jackson.core.JsonParser
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext
|
||||||
|
import com.fasterxml.jackson.databind.JsonDeserializer
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer
|
||||||
|
import com.fasterxml.jackson.databind.type.SimpleType
|
||||||
import core.Amount
|
import core.Amount
|
||||||
import core.Tenor
|
import core.Tenor
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
@ -50,43 +58,7 @@ open class FloatingRate: Rate(null)
|
|||||||
* So a reference rate is a rate that takes its value from a source at a given date
|
* So a reference rate is a rate that takes its value from a source at a given date
|
||||||
* e.g. LIBOR 6M as of 17 March 2016. Hence it requires a source (name) and a value date in the getAsOf(..) method.
|
* e.g. LIBOR 6M as of 17 March 2016. Hence it requires a source (name) and a value date in the getAsOf(..) method.
|
||||||
*/
|
*/
|
||||||
abstract class ReferenceRate(val name: String): FloatingRate() {
|
class ReferenceRate(val oracle: String, val tenor: Tenor, val name: String) : FloatingRate() {
|
||||||
abstract fun getAsOf(date: LocalDate?) : RatioUnit
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A concrete implementation of the above for testing purposes
|
|
||||||
*/
|
|
||||||
open class TestReferenceRate(val testrate: String) : ReferenceRate(testrate) {
|
|
||||||
override fun getAsOf(date: LocalDate?) : RatioUnit {
|
|
||||||
return testrate.percent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This represents a source of data.
|
|
||||||
*/
|
|
||||||
abstract class Oracle() { abstract fun retrieve(tenor: Tenor, date: LocalDate) : RatioUnit }
|
|
||||||
|
|
||||||
class ReutersOracle() : Oracle() {
|
|
||||||
override fun retrieve(tenor: Tenor, date: LocalDate): RatioUnit {
|
|
||||||
TODO("Reuters Oracle retrieval")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TelerateOracle(page: String) : Oracle() {
|
|
||||||
override fun retrieve(tenor: Tenor, date: LocalDate): RatioUnit {
|
|
||||||
TODO("Telerate Oracle retrieval")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Reference rate that is retrieved via an Oracle.
|
|
||||||
*/
|
|
||||||
open class OracleRetrievableReferenceRate(val oracle: Oracle, val tenor: Tenor, referenceRate: String) : ReferenceRate(referenceRate) {
|
|
||||||
override fun getAsOf(date: LocalDate?): RatioUnit {
|
|
||||||
return oracle.retrieve(tenor,date!!)
|
|
||||||
}
|
|
||||||
override fun toString(): String = "$name - $tenor"
|
override fun toString(): String = "$name - $tenor"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,4 +47,7 @@ dependencies {
|
|||||||
// Apache JEXL: An embeddable expression evaluation library.
|
// Apache JEXL: An embeddable expression evaluation library.
|
||||||
// This may be temporary until we experiment with other ways to do on-the-fly contract specialisation via an API.
|
// This may be temporary until we experiment with other ways to do on-the-fly contract specialisation via an API.
|
||||||
compile "org.apache.commons:commons-jexl3:3.0"
|
compile "org.apache.commons:commons-jexl3:3.0"
|
||||||
|
|
||||||
|
// For JSON
|
||||||
|
compile "com.fasterxml.jackson.core:jackson-databind:2.5.5"
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,14 @@
|
|||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator
|
||||||
|
import com.fasterxml.jackson.core.JsonParser
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext
|
||||||
|
import com.fasterxml.jackson.databind.JsonDeserializer
|
||||||
|
import com.fasterxml.jackson.databind.JsonSerializer
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.time.DayOfWeek
|
import java.time.DayOfWeek
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
@ -82,7 +90,25 @@ data class FixOf(val name: String, val forDay: LocalDate, val ofTenor: Tenor)
|
|||||||
/** A [Fix] represents a named interest rate, on a given day, for a given duration. It can be embedded in a tx. */
|
/** A [Fix] represents a named interest rate, on a given day, for a given duration. It can be embedded in a tx. */
|
||||||
data class Fix(val of: FixOf, val value: BigDecimal) : CommandData
|
data class Fix(val of: FixOf, val value: BigDecimal) : CommandData
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a textual expression of e.g. a formula
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@JsonDeserialize(using = ExpressionDeserializer::class)
|
||||||
|
@JsonSerialize(using = ExpressionSerializer::class)
|
||||||
|
data class Expression(val expr: String)
|
||||||
|
|
||||||
|
object ExpressionSerializer: JsonSerializer<Expression>() {
|
||||||
|
override fun serialize(expr: Expression, generator: JsonGenerator, provider: SerializerProvider) {
|
||||||
|
generator.writeString(expr.expr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object ExpressionDeserializer: JsonDeserializer<Expression>() {
|
||||||
|
override fun deserialize(parser: JsonParser, context: DeserializationContext): Expression {
|
||||||
|
return Expression(parser.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Placeholder class for the Tenor datatype - which is a standardised duration of time until maturity */
|
* Placeholder class for the Tenor datatype - which is a standardised duration of time until maturity */
|
||||||
|
@ -4,3 +4,48 @@ LIBOR 2016-03-16 1M = 0.678
|
|||||||
LIBOR 2016-03-16 2M = 0.655
|
LIBOR 2016-03-16 2M = 0.655
|
||||||
EURIBOR 2016-03-15 1M = 0.123
|
EURIBOR 2016-03-15 1M = 0.123
|
||||||
EURIBOR 2016-03-15 2M = 0.111
|
EURIBOR 2016-03-15 2M = 0.111
|
||||||
|
|
||||||
|
LIBOR 2016-03-08 3M = 0.01
|
||||||
|
LIBOR 2016-06-08 3M = 0.01
|
||||||
|
LIBOR 2016-09-08 3M = 0.01
|
||||||
|
LIBOR 2016-12-08 3M = 0.01
|
||||||
|
LIBOR 2017-03-08 3M = 0.01
|
||||||
|
LIBOR 2017-06-08 3M = 0.01
|
||||||
|
LIBOR 2017-09-07 3M = 0.01
|
||||||
|
LIBOR 2017-12-07 3M = 0.01
|
||||||
|
LIBOR 2018-03-08 3M = 0.01
|
||||||
|
LIBOR 2018-06-07 3M = 0.01
|
||||||
|
LIBOR 2018-09-06 3M = 0.01
|
||||||
|
LIBOR 2018-12-06 3M = 0.01
|
||||||
|
LIBOR 2019-03-07 3M = 0.01
|
||||||
|
LIBOR 2019-06-06 3M = 0.01
|
||||||
|
LIBOR 2019-09-06 3M = 0.01
|
||||||
|
LIBOR 2019-12-06 3M = 0.01
|
||||||
|
LIBOR 2020-03-06 3M = 0.01
|
||||||
|
LIBOR 2020-06-08 3M = 0.01
|
||||||
|
LIBOR 2020-09-08 3M = 0.01
|
||||||
|
LIBOR 2020-12-08 3M = 0.01
|
||||||
|
LIBOR 2021-03-08 3M = 0.01
|
||||||
|
LIBOR 2021-06-08 3M = 0.01
|
||||||
|
LIBOR 2021-09-08 3M = 0.01
|
||||||
|
LIBOR 2021-12-08 3M = 0.01
|
||||||
|
LIBOR 2022-03-08 3M = 0.01
|
||||||
|
LIBOR 2022-06-08 3M = 0.01
|
||||||
|
LIBOR 2022-09-08 3M = 0.01
|
||||||
|
LIBOR 2022-12-08 3M = 0.01
|
||||||
|
LIBOR 2023-03-08 3M = 0.01
|
||||||
|
LIBOR 2023-06-08 3M = 0.01
|
||||||
|
LIBOR 2023-09-07 3M = 0.01
|
||||||
|
LIBOR 2023-12-07 3M = 0.01
|
||||||
|
LIBOR 2024-03-07 3M = 0.01
|
||||||
|
LIBOR 2024-06-06 3M = 0.01
|
||||||
|
LIBOR 2024-09-06 3M = 0.01
|
||||||
|
LIBOR 2024-12-06 3M = 0.01
|
||||||
|
LIBOR 2025-03-06 3M = 0.01
|
||||||
|
LIBOR 2025-06-06 3M = 0.01
|
||||||
|
LIBOR 2025-09-08 3M = 0.01
|
||||||
|
LIBOR 2025-12-08 3M = 0.01
|
||||||
|
LIBOR 2026-03-06 3M = 0.01
|
||||||
|
LIBOR 2026-06-08 3M = 0.01
|
||||||
|
LIBOR 2026-09-08 3M = 0.01
|
||||||
|
LIBOR 2026-12-08 3M = 0.01
|
||||||
|
@ -7,6 +7,7 @@ import core.crypto.SecureHash
|
|||||||
import core.node.AbstractNode
|
import core.node.AbstractNode
|
||||||
import core.protocols.ProtocolLogic
|
import core.protocols.ProtocolLogic
|
||||||
import core.serialization.SerializedBytes
|
import core.serialization.SerializedBytes
|
||||||
|
import core.utilities.ANSIProgressRenderer
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.reflect.KParameter
|
import kotlin.reflect.KParameter
|
||||||
@ -87,6 +88,7 @@ class APIServerImpl(val node: AbstractNode): APIServer {
|
|||||||
}
|
}
|
||||||
// If we get here then we matched every parameter
|
// If we get here then we matched every parameter
|
||||||
val protocol = constructor.callBy(params) as ProtocolLogic<*>
|
val protocol = constructor.callBy(params) as ProtocolLogic<*>
|
||||||
|
ANSIProgressRenderer.progressTracker = protocol.progressTracker
|
||||||
val future = node.smm.add("api-call",protocol)
|
val future = node.smm.add("api-call",protocol)
|
||||||
return future
|
return future
|
||||||
}
|
}
|
||||||
|
33
src/main/kotlin/api/ResponseFilter.kt
Normal file
33
src/main/kotlin/api/ResponseFilter.kt
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import javax.ws.rs.container.ContainerRequestContext
|
||||||
|
import javax.ws.rs.container.ContainerResponseContext
|
||||||
|
import javax.ws.rs.container.ContainerResponseFilter
|
||||||
|
import javax.ws.rs.ext.Provider
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This adds headers needed for cross site scripting on API clients
|
||||||
|
*/
|
||||||
|
@Provider
|
||||||
|
class ResponseFilter: ContainerResponseFilter {
|
||||||
|
override fun filter(requestContext: ContainerRequestContext, responseContext: ContainerResponseContext) {
|
||||||
|
val headers = responseContext.headers
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO we need to revisit this for security reasons
|
||||||
|
*
|
||||||
|
* We don't want this scriptable from any web page anywhere, but for demo reasons
|
||||||
|
* we're making this really easy to access pending a proper security approach including
|
||||||
|
* access control and authentication at a network and software level
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
headers.add("Access-Control-Allow-Origin","*")
|
||||||
|
|
||||||
|
if(requestContext.method == "OPTIONS") {
|
||||||
|
headers.add("Access-Control-Allow-Headers", "Content-Type,Accept,Origin")
|
||||||
|
headers.add("Access-Control-Allow-Methods", "POST,PUT,GET,OPTIONS")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -26,6 +26,7 @@ data class LegallyIdentifiableNode(val address: SingleMessageRecipient, val iden
|
|||||||
*/
|
*/
|
||||||
interface NetworkMapService {
|
interface NetworkMapService {
|
||||||
val timestampingNodes: List<LegallyIdentifiableNode>
|
val timestampingNodes: List<LegallyIdentifiableNode>
|
||||||
|
val ratesOracleNodes: List<LegallyIdentifiableNode>
|
||||||
val partyNodes: List<LegallyIdentifiableNode>
|
val partyNodes: List<LegallyIdentifiableNode>
|
||||||
|
|
||||||
fun nodeForPartyName(name: String): LegallyIdentifiableNode? = partyNodes.singleOrNull { it.identity.name == name }
|
fun nodeForPartyName(name: String): LegallyIdentifiableNode? = partyNodes.singleOrNull { it.identity.name == name }
|
||||||
@ -37,6 +38,7 @@ class MockNetworkMapService : NetworkMapService {
|
|||||||
data class MockAddress(val id: String): SingleMessageRecipient
|
data class MockAddress(val id: String): SingleMessageRecipient
|
||||||
|
|
||||||
override val timestampingNodes = Collections.synchronizedList(ArrayList<LegallyIdentifiableNode>())
|
override val timestampingNodes = Collections.synchronizedList(ArrayList<LegallyIdentifiableNode>())
|
||||||
|
override val ratesOracleNodes = Collections.synchronizedList(ArrayList<LegallyIdentifiableNode>())
|
||||||
override val partyNodes = Collections.synchronizedList(ArrayList<LegallyIdentifiableNode>())
|
override val partyNodes = Collections.synchronizedList(ArrayList<LegallyIdentifiableNode>())
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -168,10 +168,11 @@ class StateMachineManager(val serviceHub: ServiceHub, val runInThread: Executor)
|
|||||||
fun <T> add(loggerName: String, logic: ProtocolLogic<T>): ListenableFuture<T> {
|
fun <T> add(loggerName: String, logic: ProtocolLogic<T>): ListenableFuture<T> {
|
||||||
val logger = LoggerFactory.getLogger(loggerName)
|
val logger = LoggerFactory.getLogger(loggerName)
|
||||||
val fiber = ProtocolStateMachine(logic)
|
val fiber = ProtocolStateMachine(logic)
|
||||||
|
// Need to add before iterating in case of immediate completion
|
||||||
|
_stateMachines.add(logic)
|
||||||
iterateStateMachine(fiber, serviceHub.networkService, logger, null, null) {
|
iterateStateMachine(fiber, serviceHub.networkService, logger, null, null) {
|
||||||
it.start()
|
it.start()
|
||||||
}
|
}
|
||||||
_stateMachines.add(logic)
|
|
||||||
totalStartedProtocols.inc()
|
totalStartedProtocols.inc()
|
||||||
return fiber.resultFuture
|
return fiber.resultFuture
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,8 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration,
|
|||||||
CASH_PROGRAM_ID to Cash::class.java,
|
CASH_PROGRAM_ID to Cash::class.java,
|
||||||
CP_PROGRAM_ID to CommercialPaper::class.java,
|
CP_PROGRAM_ID to CommercialPaper::class.java,
|
||||||
CROWDFUND_PROGRAM_ID to CrowdFund::class.java,
|
CROWDFUND_PROGRAM_ID to CrowdFund::class.java,
|
||||||
DUMMY_PROGRAM_ID to DummyContract::class.java
|
DUMMY_PROGRAM_ID to DummyContract::class.java,
|
||||||
|
IRS_PROGRAM_ID to InterestRateSwap::class.java
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun <T : Contract> get(hash: SecureHash): T {
|
override fun <T : Contract> get(hash: SecureHash): T {
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
package core.node
|
package core.node
|
||||||
|
|
||||||
import api.Config
|
import api.Config
|
||||||
|
import api.ResponseFilter
|
||||||
import com.codahale.metrics.JmxReporter
|
import com.codahale.metrics.JmxReporter
|
||||||
import com.google.common.net.HostAndPort
|
import com.google.common.net.HostAndPort
|
||||||
import core.messaging.LegallyIdentifiableNode
|
import core.messaging.LegallyIdentifiableNode
|
||||||
@ -94,6 +95,7 @@ class Node(dir: Path, val p2pAddr: HostAndPort, configuration: NodeConfiguration
|
|||||||
val resourceConfig = ResourceConfig()
|
val resourceConfig = ResourceConfig()
|
||||||
// Add your API provider classes (annotated for JAX-RS) here
|
// Add your API provider classes (annotated for JAX-RS) here
|
||||||
resourceConfig.register(Config(services))
|
resourceConfig.register(Config(services))
|
||||||
|
resourceConfig.register(ResponseFilter())
|
||||||
resourceConfig.register(api)
|
resourceConfig.register(api)
|
||||||
// Give the app a slightly better name in JMX rather than a randomly generated one and enable JMX
|
// Give the app a slightly better name in JMX rather than a randomly generated one and enable JMX
|
||||||
resourceConfig.addProperties(mapOf(ServerProperties.APPLICATION_NAME to "node.api",
|
resourceConfig.addProperties(mapOf(ServerProperties.APPLICATION_NAME to "node.api",
|
||||||
|
@ -135,9 +135,9 @@ class ArtemisMessagingService(val directory: Path, val myHostPort: HostAndPort)
|
|||||||
session.createQueue(myHostPort.toString(), "inbound", false)
|
session.createQueue(myHostPort.toString(), "inbound", false)
|
||||||
inboundConsumer = session.createConsumer("inbound").setMessageHandler { message: ClientMessage ->
|
inboundConsumer = session.createConsumer("inbound").setMessageHandler { message: ClientMessage ->
|
||||||
// This code runs for every inbound message.
|
// This code runs for every inbound message.
|
||||||
|
try {
|
||||||
if (!message.containsProperty(TOPIC_PROPERTY)) {
|
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
|
return@setMessageHandler
|
||||||
}
|
}
|
||||||
val topic = message.getStringProperty(TOPIC_PROPERTY)
|
val topic = message.getStringProperty(TOPIC_PROPERTY)
|
||||||
@ -171,8 +171,10 @@ class ArtemisMessagingService(val directory: Path, val myHostPort: HostAndPort)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
message.acknowledge()
|
message.acknowledge()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
session.start()
|
session.start()
|
||||||
|
|
||||||
mutex.locked { running = true }
|
mutex.locked { running = true }
|
||||||
|
34
src/main/kotlin/demos/DemoClock.kt
Normal file
34
src/main/kotlin/demos/DemoClock.kt
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package demos
|
||||||
|
|
||||||
|
import java.time.*
|
||||||
|
import javax.annotation.concurrent.ThreadSafe
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A [Clock] that can have the date advanced for use in demos
|
||||||
|
*/
|
||||||
|
@ThreadSafe
|
||||||
|
class DemoClock(private var delegateClock: Clock = Clock.systemUTC()) : Clock() {
|
||||||
|
|
||||||
|
@Synchronized fun updateDate(date: LocalDate): Boolean {
|
||||||
|
val currentDate = LocalDate.now(this)
|
||||||
|
if(currentDate.isBefore(date)) {
|
||||||
|
// It's ok to increment
|
||||||
|
delegateClock = Clock.offset(delegateClock, Duration.between(currentDate.atStartOfDay(),date.atStartOfDay()))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized override fun instant(): Instant {
|
||||||
|
return delegateClock.instant()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized override fun withZone(zone: ZoneId): Clock {
|
||||||
|
return DemoClock(delegateClock.withZone(zone))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized override fun getZone(): ZoneId {
|
||||||
|
return delegateClock.zone
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -50,10 +50,13 @@ open class RatesFixProtocol(protected val tx: TransactionBuilder,
|
|||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call() {
|
override fun call() {
|
||||||
|
progressTracker.currentStep = progressTracker.steps[0]
|
||||||
val fix = query()
|
val fix = query()
|
||||||
|
progressTracker.currentStep = WORKING
|
||||||
checkFixIsNearExpected(fix)
|
checkFixIsNearExpected(fix)
|
||||||
tx.addCommand(fix, oracle.identity.owningKey)
|
tx.addCommand(fix, oracle.identity.owningKey)
|
||||||
beforeSigning(fix)
|
beforeSigning(fix)
|
||||||
|
progressTracker.currentStep = SIGNING
|
||||||
tx.addSignatureUnchecked(sign())
|
tx.addSignatureUnchecked(sign())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import core.node.services.TimestamperService
|
|||||||
import core.protocols.ProtocolLogic
|
import core.protocols.ProtocolLogic
|
||||||
import core.random63BitValue
|
import core.random63BitValue
|
||||||
import core.serialization.SerializedBytes
|
import core.serialization.SerializedBytes
|
||||||
|
import core.utilities.ProgressTracker
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The TimestampingProtocol class is the client code that talks to a [NodeTimestamperService] 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
|
||||||
@ -31,7 +32,8 @@ import core.serialization.SerializedBytes
|
|||||||
* a network message: use it only from spare application threads that don't have to respond to anything.
|
* a network message: use it only from spare application threads that don't have to respond to anything.
|
||||||
*/
|
*/
|
||||||
class TimestampingProtocol(private val node: LegallyIdentifiableNode,
|
class TimestampingProtocol(private val node: LegallyIdentifiableNode,
|
||||||
private val wtxBytes: SerializedBytes<WireTransaction>) : ProtocolLogic<DigitalSignature.LegallyIdentifiable>() {
|
private val wtxBytes: SerializedBytes<WireTransaction>,
|
||||||
|
override val progressTracker: ProgressTracker = TimestampingProtocol.tracker()) : ProtocolLogic<DigitalSignature.LegallyIdentifiable>() {
|
||||||
|
|
||||||
class Client(private val stateMachineManager: StateMachineManager, private val node: LegallyIdentifiableNode) : TimestamperService {
|
class Client(private val stateMachineManager: StateMachineManager, private val node: LegallyIdentifiableNode) : TimestamperService {
|
||||||
override val identity: Party = node.identity
|
override val identity: Party = node.identity
|
||||||
@ -41,9 +43,18 @@ class TimestampingProtocol(private val node: LegallyIdentifiableNode,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
object REQUESTING : ProgressTracker.Step("Requesting signature by timestamping service")
|
||||||
|
object VALIDATING : ProgressTracker.Step("Validating received signature from timestamping service")
|
||||||
|
|
||||||
|
fun tracker() = ProgressTracker(REQUESTING, VALIDATING)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call(): DigitalSignature.LegallyIdentifiable {
|
override fun call(): DigitalSignature.LegallyIdentifiable {
|
||||||
|
progressTracker.currentStep = REQUESTING
|
||||||
val sessionID = random63BitValue()
|
val sessionID = random63BitValue()
|
||||||
val replyTopic = "${NodeTimestamperService.TIMESTAMPING_PROTOCOL_TOPIC}.$sessionID"
|
val replyTopic = "${NodeTimestamperService.TIMESTAMPING_PROTOCOL_TOPIC}.$sessionID"
|
||||||
val req = Request(wtxBytes, serviceHub.networkService.myAddress, replyTopic)
|
val req = Request(wtxBytes, serviceHub.networkService.myAddress, replyTopic)
|
||||||
@ -52,6 +63,7 @@ class TimestampingProtocol(private val node: LegallyIdentifiableNode,
|
|||||||
NodeTimestamperService.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
|
// Check that the timestamping authority gave us back a valid signature and didn't break somehow
|
||||||
|
progressTracker.currentStep = VALIDATING
|
||||||
maybeSignature.validate { sig ->
|
maybeSignature.validate { sig ->
|
||||||
sig.verifyWithECDSA(wtxBytes)
|
sig.verifyWithECDSA(wtxBytes)
|
||||||
return sig
|
return sig
|
||||||
|
@ -74,11 +74,11 @@ fun createDummyIRS(irsSelect: Int): InterestRateSwap.State {
|
|||||||
//expression = "( fixedLeg.notional * (fixedLeg.fixedRate)) - (floatingLeg.notional * (rateSchedule.get(context.getDate('currentDate'))))",
|
//expression = "( fixedLeg.notional * (fixedLeg.fixedRate)) - (floatingLeg.notional * (rateSchedule.get(context.getDate('currentDate'))))",
|
||||||
|
|
||||||
// How it's ended up looking, which I think is now broken but it's a WIP.
|
// How it's ended up looking, which I think is now broken but it's a WIP.
|
||||||
expression = InterestRateSwap.Expression("( fixedLeg.notional.pennies * (fixedLeg.fixedRate.ratioUnit.value)) -" +
|
expression = Expression("( fixedLeg.notional.pennies * (fixedLeg.fixedRate.ratioUnit.value)) -" +
|
||||||
"(floatingLeg.notional.pennies * (calculation.fixingSchedule.get(context.getDate('currentDate')).rate.ratioUnit.value))"),
|
"(floatingLeg.notional.pennies * (calculation.fixingSchedule.get(context.getDate('currentDate')).rate.ratioUnit.value))"),
|
||||||
|
|
||||||
floatingLegPaymentSchedule = HashMap(),
|
floatingLegPaymentSchedule = HashMap(),
|
||||||
fixedLegpaymentSchedule = HashMap()
|
fixedLegPaymentSchedule = HashMap()
|
||||||
)
|
)
|
||||||
|
|
||||||
val EUR = currency("EUR")
|
val EUR = currency("EUR")
|
||||||
@ -94,13 +94,13 @@ fun createDummyIRS(irsSelect: Int): InterestRateSwap.State {
|
|||||||
valuationDate = "Every Local Business Day",
|
valuationDate = "Every Local Business Day",
|
||||||
notificationTime = "2:00pm London",
|
notificationTime = "2:00pm London",
|
||||||
resolutionTime = "2:00pm London time on the first LocalBusiness Day following the date on which the notice is given ",
|
resolutionTime = "2:00pm London time on the first LocalBusiness Day following the date on which the notice is given ",
|
||||||
interestRate = OracleRetrievableReferenceRate(TelerateOracle("T3270"), Tenor("6M"), "EONIA"),
|
interestRate = ReferenceRate("T3270", Tenor("6M"), "EONIA"),
|
||||||
addressForTransfers = "",
|
addressForTransfers = "",
|
||||||
exposure = UnknownType(),
|
exposure = UnknownType(),
|
||||||
localBusinessDay = BusinessCalendar.getInstance("London"),
|
localBusinessDay = BusinessCalendar.getInstance("London"),
|
||||||
tradeID = "trade1",
|
tradeID = "trade1",
|
||||||
hashLegalDocs = "put hash here",
|
hashLegalDocs = "put hash here",
|
||||||
dailyInterestAmount = InterestRateSwap.Expression("(CashAmount * InterestRate ) / (fixedLeg.notional.currency.currencyCode.equals('GBP')) ? 365 : 360")
|
dailyInterestAmount = Expression("(CashAmount * InterestRate ) / (fixedLeg.notional.currency.currencyCode.equals('GBP')) ? 365 : 360")
|
||||||
)
|
)
|
||||||
|
|
||||||
InterestRateSwap.State(fixedLeg = fixedLeg, floatingLeg = floatingLeg, calculation = calculation, common = common)
|
InterestRateSwap.State(fixedLeg = fixedLeg, floatingLeg = floatingLeg, calculation = calculation, common = common)
|
||||||
@ -165,11 +165,11 @@ fun createDummyIRS(irsSelect: Int): InterestRateSwap.State {
|
|||||||
//expression = "( fixedLeg.notional * (fixedLeg.fixedRate)) - (floatingLeg.notional * (rateSchedule.get(context.getDate('currentDate'))))",
|
//expression = "( fixedLeg.notional * (fixedLeg.fixedRate)) - (floatingLeg.notional * (rateSchedule.get(context.getDate('currentDate'))))",
|
||||||
|
|
||||||
// How it's ended up looking, which I think is now broken but it's a WIP.
|
// How it's ended up looking, which I think is now broken but it's a WIP.
|
||||||
expression = InterestRateSwap.Expression("( fixedLeg.notional.pennies * (fixedLeg.fixedRate.ratioUnit.value)) -" +
|
expression = Expression("( fixedLeg.notional.pennies * (fixedLeg.fixedRate.ratioUnit.value)) -" +
|
||||||
"(floatingLeg.notional.pennies * (calculation.fixingSchedule.get(context.getDate('currentDate')).rate.ratioUnit.value))"),
|
"(floatingLeg.notional.pennies * (calculation.fixingSchedule.get(context.getDate('currentDate')).rate.ratioUnit.value))"),
|
||||||
|
|
||||||
floatingLegPaymentSchedule = HashMap(),
|
floatingLegPaymentSchedule = HashMap(),
|
||||||
fixedLegpaymentSchedule = HashMap()
|
fixedLegPaymentSchedule = HashMap()
|
||||||
)
|
)
|
||||||
|
|
||||||
val EUR = currency("EUR")
|
val EUR = currency("EUR")
|
||||||
@ -185,13 +185,13 @@ fun createDummyIRS(irsSelect: Int): InterestRateSwap.State {
|
|||||||
valuationDate = "Every Local Business Day",
|
valuationDate = "Every Local Business Day",
|
||||||
notificationTime = "2:00pm London",
|
notificationTime = "2:00pm London",
|
||||||
resolutionTime = "2:00pm London time on the first LocalBusiness Day following the date on which the notice is given ",
|
resolutionTime = "2:00pm London time on the first LocalBusiness Day following the date on which the notice is given ",
|
||||||
interestRate = OracleRetrievableReferenceRate(TelerateOracle("T3270"), Tenor("6M"), "EONIA"),
|
interestRate = ReferenceRate("T3270", Tenor("6M"), "EONIA"),
|
||||||
addressForTransfers = "",
|
addressForTransfers = "",
|
||||||
exposure = UnknownType(),
|
exposure = UnknownType(),
|
||||||
localBusinessDay = BusinessCalendar.getInstance("London"),
|
localBusinessDay = BusinessCalendar.getInstance("London"),
|
||||||
tradeID = "trade1",
|
tradeID = "trade1",
|
||||||
hashLegalDocs = "put hash here",
|
hashLegalDocs = "put hash here",
|
||||||
dailyInterestAmount = InterestRateSwap.Expression("(CashAmount * InterestRate ) / (fixedLeg.notional.currency.currencyCode.equals('GBP')) ? 365 : 360")
|
dailyInterestAmount = Expression("(CashAmount * InterestRate ) / (fixedLeg.notional.currency.currencyCode.equals('GBP')) ? 365 : 360")
|
||||||
)
|
)
|
||||||
|
|
||||||
return InterestRateSwap.State(fixedLeg = fixedLeg, floatingLeg = floatingLeg, calculation = calculation, common = common)
|
return InterestRateSwap.State(fixedLeg = fixedLeg, floatingLeg = floatingLeg, calculation = calculation, common = common)
|
||||||
@ -335,12 +335,6 @@ class IRSTests {
|
|||||||
// TODO: r1*r2 ?
|
// TODO: r1*r2 ?
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `reference rate testing`() {
|
|
||||||
val r1 = TestReferenceRate("5")
|
|
||||||
assert(100 * r1.getAsOf(null) == 5)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `expression calculation testing`() {
|
fun `expression calculation testing`() {
|
||||||
val dummyIRS = singleIRS()
|
val dummyIRS = singleIRS()
|
||||||
@ -366,7 +360,7 @@ class IRSTests {
|
|||||||
|
|
||||||
for (i in stuffToPrint) {
|
for (i in stuffToPrint) {
|
||||||
println(i)
|
println(i)
|
||||||
var z = dummyIRS.evaluateCalculation(LocalDate.of(2016, 9, 12), InterestRateSwap.Expression(i))
|
var z = dummyIRS.evaluateCalculation(LocalDate.of(2016, 9, 12), Expression(i))
|
||||||
println(z.javaClass)
|
println(z.javaClass)
|
||||||
println(z)
|
println(z)
|
||||||
println("-----------")
|
println("-----------")
|
||||||
|
@ -38,6 +38,8 @@ object TestUtils {
|
|||||||
val keypair = generateKeyPair()
|
val keypair = generateKeyPair()
|
||||||
val keypair2 = generateKeyPair()
|
val keypair2 = generateKeyPair()
|
||||||
val keypair3 = generateKeyPair()
|
val keypair3 = generateKeyPair()
|
||||||
|
val keypair4 = generateKeyPair()
|
||||||
|
val keypair5 = generateKeyPair()
|
||||||
}
|
}
|
||||||
// A dummy time at which we will be pretending test transactions are created.
|
// A dummy time at which we will be pretending test transactions are created.
|
||||||
val TEST_TX_TIME = Instant.parse("2015-04-17T12:00:00.00Z")
|
val TEST_TX_TIME = Instant.parse("2015-04-17T12:00:00.00Z")
|
||||||
@ -49,6 +51,14 @@ val MEGA_CORP_PUBKEY = MEGA_CORP_KEY.public
|
|||||||
val MINI_CORP_KEY = TestUtils.keypair2
|
val MINI_CORP_KEY = TestUtils.keypair2
|
||||||
val MINI_CORP_PUBKEY = MINI_CORP_KEY.public
|
val MINI_CORP_PUBKEY = MINI_CORP_KEY.public
|
||||||
|
|
||||||
|
// TODO remove once mock API is retired
|
||||||
|
val EXCALIBUR_BANK_KEY = TestUtils.keypair4
|
||||||
|
val EXCALIBUR_BANK_PUBKEY = EXCALIBUR_BANK_KEY.public
|
||||||
|
|
||||||
|
// TODO remove once mock API is retired
|
||||||
|
val A_N_OTHER_BANK_KEY = TestUtils.keypair5
|
||||||
|
val A_N_OTHER_BANK_PUBKEY = A_N_OTHER_BANK_KEY.public
|
||||||
|
|
||||||
val ORACLE_KEY = TestUtils.keypair3
|
val ORACLE_KEY = TestUtils.keypair3
|
||||||
val ORACLE_PUBKEY = ORACLE_KEY.public
|
val ORACLE_PUBKEY = ORACLE_KEY.public
|
||||||
|
|
||||||
@ -64,11 +74,17 @@ val BOB = BOB_KEY.public
|
|||||||
val MEGA_CORP = Party("MegaCorp", MEGA_CORP_PUBKEY)
|
val MEGA_CORP = Party("MegaCorp", MEGA_CORP_PUBKEY)
|
||||||
val MINI_CORP = Party("MiniCorp", MINI_CORP_PUBKEY)
|
val MINI_CORP = Party("MiniCorp", MINI_CORP_PUBKEY)
|
||||||
|
|
||||||
val ALL_TEST_KEYS = listOf(MEGA_CORP_KEY, MINI_CORP_KEY, ALICE_KEY, BOB_KEY, DummyTimestampingAuthority.key)
|
// TODO remove once mock API is retired
|
||||||
|
val EXCALIBUR_BANK = Party("Excalibur", EXCALIBUR_BANK_PUBKEY)
|
||||||
|
val A_N_OTHER_BANK = Party("ANOther",A_N_OTHER_BANK_PUBKEY)
|
||||||
|
|
||||||
|
val ALL_TEST_KEYS = listOf(MEGA_CORP_KEY, MINI_CORP_KEY, ALICE_KEY, BOB_KEY, EXCALIBUR_BANK_KEY, A_N_OTHER_BANK_KEY, DummyTimestampingAuthority.key)
|
||||||
|
|
||||||
val TEST_KEYS_TO_CORP_MAP: Map<PublicKey, Party> = mapOf(
|
val TEST_KEYS_TO_CORP_MAP: Map<PublicKey, Party> = mapOf(
|
||||||
MEGA_CORP_PUBKEY to MEGA_CORP,
|
MEGA_CORP_PUBKEY to MEGA_CORP,
|
||||||
MINI_CORP_PUBKEY to MINI_CORP,
|
MINI_CORP_PUBKEY to MINI_CORP,
|
||||||
|
EXCALIBUR_BANK_PUBKEY to EXCALIBUR_BANK,
|
||||||
|
A_N_OTHER_BANK_PUBKEY to A_N_OTHER_BANK,
|
||||||
DUMMY_TIMESTAMPER.identity.owningKey to DUMMY_TIMESTAMPER.identity
|
DUMMY_TIMESTAMPER.identity.owningKey to DUMMY_TIMESTAMPER.identity
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user